Merge branch 'master' of github.com:OBattler/86Box

This commit is contained in:
TC1995
2018-07-18 00:58:55 +02:00
245 changed files with 35209 additions and 32569 deletions

View File

@@ -8,6 +8,8 @@ PCI bus.
86Box is released under the GNU General Public License, version 2. For more
information, see the `LICENSE` file.
The project maintainer is OBattler.
Community
---------
We operate an IRC channel and a Discord server for discussing anything related

View File

@@ -8,7 +8,7 @@
*
* Main include file for the application.
*
* Version: @(#)86box.h 1.0.21 2018/03/19
* Version: @(#)86box.h 1.0.23 2018/05/25
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -90,8 +90,7 @@ extern int vid_cga_contrast, /* (C) video */
video_fullscreen_scale, /* (C) video */
enable_overscan, /* (C) video */
force_43, /* (C) video */
gfxcard, /* (C) graphics/video card */
video_speed; /* (C) video */
gfxcard; /* (C) graphics/video card */
extern int serial_enabled[], /* (C) enable serial ports */
lpt_enabled, /* (C) enable LPT ports */
bugger_enabled; /* (C) enable ISAbugger */
@@ -100,7 +99,7 @@ extern int sound_is_float, /* (C) sound uses FP values */
GUS, /* (C) sound option */
SSI2001, /* (C) sound option */
voodoo_enabled; /* (C) video option */
extern int mem_size; /* (C) memory size */
extern uint32_t mem_size; /* (C) memory size */
extern int cpu_manufacturer, /* (C) cpu manufacturer */
cpu, /* (C) cpu type */
cpu_use_dynarec, /* (C) cpu uses/needs Dyna */
@@ -127,6 +126,7 @@ extern wchar_t cfg_path[1024]; /* full path of config file */
extern FILE *stdlog; /* file to log output to */
extern int scrnsz_x, /* current screen size, X */
scrnsz_y; /* current screen size, Y */
extern int efscrnsz_y;
extern int config_changed; /* config has changed */
@@ -139,7 +139,9 @@ extern void pclog(const char *fmt, ...);
extern void fatal(const char *fmt, ...);
extern void set_screen_size(int x, int y);
extern void set_screen_size_natural(void);
#if 0
extern void pc_reload(wchar_t *fn);
#endif
extern int pc_init_modules(void);
extern int pc_init(int argc, wchar_t *argv[]);
extern void pc_close(void *threadid);

View File

@@ -10,7 +10,7 @@
# settings, so we can avoid changing the main one for all of
# our local setups.
#
# Version: @(#)Makefile.local 1.0.10 2018/03/20
# Version: @(#)Makefile.local 1.0.14 2018/05/26
#
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
#
@@ -34,31 +34,103 @@ STUFF :=
# -DANSI_CFG forces the config file to ANSI encoding.
# -DENABLE_VRAM_DUMP enables Video Ram dumping.
# -DENABLE_LOG_BREAKPOINT enables extra logging.
# Root logging:
# -DENABLE_BUGGER_LOG=N sets logging level at N.
# -DENABLE_CONFIG_LOG=N sets logging level at N.
# -DENABLE_DEVICE_LOG=N sets logging level at N.
# -DENABLE_KEYBOARD_AMSTRAD_LOG=N sets logging level at N.
# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N.
# -DENABLE_KEYBOARD_LOG=N sets logging level at N.
# -DENABLE_IO_LOG=N sets logging level at N.
# -DENABLE_MEM_LOG=N sets logging level at N.
# -DENABLE_MOUSE_LOG=N sets logging level at N.
# -DENABLE_MOUSE_BUS_LOG=N sets logging level at N.
# -DENABLE_MOUSE_PS2_LOG=N sets logging level at N.
# -DENABLE_MOUSE_SERIAL_LOG=N sets logging level at N.
# -DENABLE_NVR_LOG=N sets logging level at N.
# -DENABLE_PC_LOG=N sets logging level at N.
# -DENABLE_PCI_LOG=N sets logging level at N.
# -DENABLE_PIC_LOG=N sets logging level at N.
# -DENABLE_PIIX_LOG=N sets logging level at N.
# -DENABLE_ROM_LOG=N sets logging level at N.
# -DENABLE_SERIAL_LOG=N sets logging level at N.
# -DENABLE_VNC_LOG=N sets logging level at N.
# cdrom/ logging:
# -DENABLE_CDROM_LOG=N sets logging level at N.
# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N.
# -DENABLE_CDROM_IOCTL_LOG=N sets logging level at N.
# -DENABLE_HDD_LOG=N sets logging level at N.
# cpu/ logging:
# -DENABLE_386_LOG=N sets logging level at N.
# -DENABLE_386_DYNAREC_LOG=N sets logging level at N.
# -DENABLE_808X_LOG=N sets logging level at N.
# -DENABLE_X86SEG_LOG=N sets logging level at N.
# disk/ logging:
# -DENABLE_ESDI_AT_LOG=N sets logging level at N.
# -DENABLE_ESDI_MCA_LOG=N sets logging level at N.
# -DENABLE_HDC_LOG=N sets logging level at N.
# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N.
# -DENABLE_IDE_LOG=N sets logging level at N.
# -DENABLE_FDC_LOG=N sets logging level at N.
# -DENABLE_MFM_AT_LOG=N sets logging level at N.
# -DENABLE_MFM_XT_LOG=N sets logging level at N.
# -DENABLE_XTA_LOG=N sets logging level at N.
# -DENABLE_ZIP_LOG=N sets logging level at N.
# floppy/ logging:
# -DENABLE_D86F_LOG=N sets logging level at N.
# -DENABLE_FDC_LOG=N sets logging level at N.
# -DENABLE_FDD_LOG=N sets logging level at N.
# -DENABLE_FDI_LOG=N sets logging level at N.
# -DENABLE_FDI2RAW_LOG=N sets logging level at N.
# -DENABLE_IMD_LOG=N sets logging level at N.
# -DENABLE_IMG_LOG=N sets logging level at N.
# -DENABLE_JSON_LOG=N sets logging level at N.
# -DENABLE_TD0_LOG=N sets logging level at N.
# machine/ logging:
# -DENABLE_AMSTRAD_LOG=N sets logging level at N.
# -DENABLE_EUROPC_LOG=N sets logging level at N.
# -DENABLE_MACHINE_LOG=N sets logging level at N.
# -DENABLE_PS1_HDC_LOG=N sets logging level at N.
# -DENABLE_PS2_MCA_LOG=N sets logging level at N.
# -DENABLE_T1000_LOG=N sets logging level at N.
# -DENABLE_T3100E_LOG=N sets logging level at N.
# -DENABLE_TANDY_LOG=N sets logging level at N.
# network/ logging:
# -DENABLE_NETWORK_LOG=N sets logging level at N.
# -DENABLE_NIC_LOG=N sets logging level at N.
# -DENABLE_SCAT_LOG=N sets logging level at N.
# -DENABLE_SCSI_BUS_LOG=N sets logging level at N.
# -DENABLE_SCSI_DISK_LOG=N sets logging level at N.
# -DENABLE_X54X_LOG=N sets logging level at N.
# -DENABLE_PCAP_LOG=N sets logging level at N.
# -DENABLE_SLIRP_LOG=N sets logging level at N.
# scsi/ logging:
# -DENABLE_AHA154X_LOG=N sets logging level at N.
# -DENABLE_BUSLOGIC_LOG=N sets logging level at N.
# -DENABLE_NCR5380_LOG=N sets logging level at N.
# -DENABLE_NCR53C810_LOG=N sets logging level at N.
# -DENABLE_SCSI_LOG=N sets logging level at N.
# -DENABLE_SCSI_BUS_LOG=N sets logging level at N.
# -DENABLE_SCSI_DISK_LOG=N sets logging level at N.
# -DENABLE_X54X_LOG=N sets logging level at N.
# sound/ logging:
# -DENABLE_ADLIB_LOG=N sets logging level at N.
# -DENABLE_AUDIOPCI_LOG=N sets logging level at N.
# -DENABLE_EMU8K_LOG=N sets logging level at N.
# -DENABLE_MPU401_LOG=N sets logging level at N.
# -DENABLE_PAS16_LOG=N sets logging level at N.
# -DENABLE_SB_LOG=N sets logging level at N.
# -DENABLE_SB_DSP_LOG=N sets logging level at N.
# -DENABLE_SOUND_LOG=N sets logging level at N.
# video/ logging:
# -DENABLE_ATI28800_LOG=N sets logging level at N.
# -DENABLE_MACH64_LOG=N sets logging level at N.
# -DENABLE_ET4000W32_LOG=N sets logging level at N.
# -DENABLE_NV_RIVA_LOG=N sets logging level at N.
# -DENABLE_NVIDIA_LOG=N sets logging level at N.
# -DENABLE_S3_VIRGE_LOG=N sets logging level at N.
# -DENABLE_VID_TABLE_LOG=N sets logging level at N.
# -DENABLE_VOODOO_LOG=N sets logging level at N.
# -DENABLE_VRAM_DUMP=N sets logging level at N.
# -DENABLE_SERIAL_LOG=N sets logging level at N.
# win/ logging:
# -DENABLE_DDRAW_LOG=N sets logging level at N.
# -DENABLE_DYNLD_LOG=N sets logging level at N.
# -DENABLE_JOYSTICK_LOG=N sets logging level at N.
# -DENABLE_SDL_LOG=N sets logging level at N.
# -DENABLE_WIN_LOG=N sets logging level at N.
EXTRAS :=

View File

@@ -44,15 +44,17 @@
* configuration register (CTRL_SPCFG bit set) but have to
* remember that stuff first...
*
* Version: @(#)bugger.c 1.0.10 2018/03/18
* Version: @(#)bugger.c 1.0.12 2018/04/29
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 1989-2018 Fred N. van Kempen.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "86box.h"
#include "io.h"
#include "device.h"
@@ -89,6 +91,26 @@ static char bug_str[UISTR_LEN]; /* UI output string */
extern void ui_sb_bugui(char *__str);
#ifdef ENABLE_BUGGER_LOG
int bugger_do_log = ENABLE_BUGGER_LOG;
#endif
static void
bugger_log(const char *format, ...)
{
#ifdef ENABLE_BUGGER_LOG
va_list ap;
if (bugger_do_log) {
va_start(ap, format);
pclog_ex(format, ap);
va_end(ap);
}
#endif
}
/* Update the system's UI with the actual Bugger status. */
static void
bug_setui(void)
@@ -115,7 +137,7 @@ static void
bug_spflsh(void)
{
*bug_bptr = '\0';
pclog("BUGGER- serial port [%s]\n", bug_buff);
bugger_log("BUGGER- serial port [%s]\n", bug_buff);
bug_bptr = bug_buff;
}
@@ -141,7 +163,7 @@ bug_wsport(uint8_t val)
/* Restore the SPORT bit. */
bug_ctrl |= (old & CTRL_SPORT);
pclog("BUGGER- sport %02x\n", val);
bugger_log("BUGGER- sport %02x\n", val);
}
@@ -151,7 +173,7 @@ bug_wspcfg(uint8_t val)
{
bug_spcfg = val;
pclog("BUGGER- spcfg %02x\n", bug_spcfg);
bugger_log("BUGGER- spcfg %02x\n", bug_spcfg);
}
@@ -201,7 +223,7 @@ bug_wctrl(uint8_t val)
}
/* Update the UI with active settings. */
pclog("BUGGER- ctrl %02x\n", bug_ctrl);
bugger_log("BUGGER- ctrl %02x\n", bug_ctrl);
bug_setui();
}
@@ -226,7 +248,7 @@ bug_wdata(uint8_t val)
else
bug_ledr = val;
pclog("BUGGER- data %02x\n", bug_data);
bugger_log("BUGGER- data %02x\n", bug_data);
}
/* Update the UI with active settings. */
@@ -311,7 +333,7 @@ bug_read(uint16_t port, void *priv)
static void *
bug_init(const device_t *info)
{
pclog("%s, I/O=%04x\n", info->name, BUGGER_ADDR);
bugger_log("%s, I/O=%04x\n", info->name, BUGGER_ADDR);
/* Initialize local registers. */
bug_reset();
@@ -338,6 +360,6 @@ const device_t bugger_device = {
DEVICE_ISA | DEVICE_AT,
0,
bug_init, bug_close, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL
};

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
* Implementation of the CD-ROM drive with SCSI(-like)
* commands, for both ATAPI and SCSI usage.
*
* Version: @(#)cdrom.h 1.0.10 2018/03/20
* Version: @(#)cdrom.h 1.0.13 2018/06/18
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
@@ -19,204 +19,131 @@
#define EMU_CDROM_H
#define CDROM_NUM 4
#define CDROM_NUM 4
#define CD_STATUS_EMPTY 0
#define CD_STATUS_DATA_ONLY 1
#define CD_STATUS_PLAYING 2
#define CD_STATUS_PAUSED 3
#define CD_STATUS_STOPPED 4
#define CD_STATUS_EMPTY 0
#define CD_STATUS_DATA_ONLY 1
#define CD_STATUS_PLAYING 2
#define CD_STATUS_PAUSED 3
#define CD_STATUS_STOPPED 4
#define CDROM_PHASE_IDLE 0
#define CDROM_PHASE_COMMAND 1
#define CDROM_PHASE_COMPLETE 2
#define CDROM_PHASE_DATA_IN 3
#define CDROM_PHASE_DATA_IN_DMA 4
#define CDROM_PHASE_DATA_OUT 5
#define CDROM_PHASE_DATA_OUT_DMA 6
#define CDROM_PHASE_ERROR 0x80
#define CDROM_PHASE_IDLE 0x00
#define CDROM_PHASE_COMMAND 0x01
#define CDROM_PHASE_COMPLETE 0x02
#define CDROM_PHASE_DATA_IN 0x03
#define CDROM_PHASE_DATA_IN_DMA 0x04
#define CDROM_PHASE_DATA_OUT 0x05
#define CDROM_PHASE_DATA_OUT_DMA 0x06
#define CDROM_PHASE_ERROR 0x80
#define BUF_SIZE 32768
#define CDROM_IMAGE 200
#define IDE_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
#define CDROM_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
enum {
CDROM_BUS_DISABLED = 0,
CDROM_BUS_ATAPI_PIO_ONLY = 4,
CDROM_BUS_ATAPI_PIO_AND_DMA,
CDROM_BUS_ATAPI = 4,
CDROM_BUS_SCSI,
CDROM_BUS_USB = 8
CDROM_BUS_USB
};
typedef struct {
int (*ready)(uint8_t id);
int (*medium_changed)(uint8_t id);
int (*media_type_id)(uint8_t id);
int (*ready)(uint8_t id);
int (*medium_changed)(uint8_t id);
int (*media_type_id)(uint8_t id);
void (*audio_callback)(uint8_t id, int16_t *output, int len);
void (*audio_stop)(uint8_t id);
int (*readtoc)(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single);
int (*readtoc_session)(uint8_t id, uint8_t *b, int msf, int maxlen);
int (*readtoc_raw)(uint8_t id, uint8_t *b, int maxlen);
uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf);
int (*pass_through)(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len);
int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len);
void (*playaudio)(uint8_t id, uint32_t pos, uint32_t len, int ismsf);
void (*load)(uint8_t id);
void (*eject)(uint8_t id);
void (*pause)(uint8_t id);
void (*resume)(uint8_t id);
uint32_t (*size)(uint8_t id);
int (*status)(uint8_t id);
int (*is_track_audio)(uint8_t id, uint32_t pos, int ismsf);
void (*stop)(uint8_t id);
void (*exit)(uint8_t id);
int (*audio_callback)(uint8_t id, int16_t *output, int len);
void (*audio_stop)(uint8_t id);
int (*readtoc)(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single);
int (*readtoc_session)(uint8_t id, uint8_t *b, int msf, int maxlen);
int (*readtoc_raw)(uint8_t id, uint8_t *b, int maxlen);
uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf);
int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len);
uint8_t (*playaudio)(uint8_t id, uint32_t pos, uint32_t len, int ismsf);
void (*pause)(uint8_t id);
void (*resume)(uint8_t id);
uint32_t (*size)(uint8_t id);
int (*status)(uint8_t id);
void (*stop)(uint8_t id);
void (*exit)(uint8_t id);
} CDROM;
typedef struct {
uint8_t previous_command;
int host_drive;
int prev_host_drive;
int toctimes;
int media_status;
unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */
int is_dma;
uint8_t speed, ide_channel,
bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
int requested_blocks; /* This will be set to something other than 1 when block reads are implemented. */
uint64_t current_page_code;
int current_page_len;
int current_page_pos;
int mode_select_phase;
int total_length;
int written_length;
int do_page_save;
uint8_t error;
uint8_t features;
uint16_t request_length;
uint16_t max_transfer_len;
uint8_t status;
uint8_t phase;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
int packet_status;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint32_t pos;
int callback;
int data_pos;
uint32_t seek_diff;
int cdb_len_setting;
int cdb_len;
int cd_status;
int prev_status;
int unit_attention;
uint8_t sense[256];
int request_pos;
uint8_t *buffer;
int times;
uint32_t seek_pos;
int total_read;
int block_total;
int all_blocks_total;
int old_len;
int block_descriptor_len;
int init_length;
int16_t cd_buffer[BUF_SIZE];
uint8_t rcbuf[16];
uint8_t sub_q_data_format[16];
uint8_t sub_q_channel_data[256];
int last_subchannel_pos;
uint32_t cd_end;
uint32_t cdrom_capacity;
int cd_buflen;
int cd_state;
int handler_inited;
int disc_changed;
int cur_speed;
} cdrom_t;
typedef struct {
CDROM *handler;
int host_drive;
int prev_host_drive;
unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t ide_channel;
unsigned int scsi_device_id;
unsigned int scsi_device_lun;
unsigned int sound_on;
unsigned int atapi_dma;
uint8_t speed;
unsigned int scsi_device_id, sound_on;
} cdrom_drive_t;
typedef struct {
int image_is_iso;
wchar_t image_path[1024];
wchar_t *prev_image_path;
FILE* image;
} cdrom_image_t;
mode_sense_pages_t ms_pages_saved;
CDROM *handler;
cdrom_drive_t *drv;
uint8_t previous_command,
error, features,
status, phase,
id, *buffer,
atapi_cdb[16],
current_cdb[16],
sense[256];
uint16_t request_length, max_transfer_len;
int16_t cd_buffer[BUF_SIZE];
int media_status, is_dma,
packet_status, requested_blocks,
current_page_len, current_page_pos,
mode_select_phase, do_page_save,
total_length, written_length,
callback, data_pos,
cd_status, prev_status,
unit_attention, request_pos,
total_read, cur_speed,
block_total, all_blocks_total,
old_len, block_descriptor_len,
init_length, last_subchannel_pos,
cd_buflen, cd_state,
handler_inited, disc_changed;
uint32_t sector_pos, sector_len,
seek_pos, seek_diff,
pos, packet_len,
cdb_len, cd_end,
cdrom_capacity;
uint64_t current_page_code;
} cdrom_t;
typedef struct {
char ioctl_path[8];
int actual_requested_blocks;
int last_track_pos;
int last_track_nr;
int capacity_read;
} cdrom_ioctl_t;
int image_is_iso;
wchar_t image_path[1024],
*prev_image_path;
FILE* image;
} cdrom_image_t;
extern cdrom_t *cdrom[CDROM_NUM];
extern cdrom_drive_t cdrom_drives[CDROM_NUM];
extern cdrom_image_t cdrom_image[CDROM_NUM];
extern cdrom_ioctl_t cdrom_ioctl[CDROM_NUM];
extern uint8_t atapi_cdrom_drives[8];
extern uint8_t scsi_cdrom_drives[16][8];
extern uint8_t scsi_cdrom_drives[16];
#define cdrom_sense_error cdrom[id]->sense[0]
#define cdrom_sense_key cdrom[id]->sense[2]
#define cdrom_asc cdrom[id]->sense[12]
#define cdrom_ascq cdrom[id]->sense[13]
#define cdrom_sense_error dev->sense[0]
#define cdrom_sense_key dev->sense[2]
#define cdrom_asc dev->sense[12]
#define cdrom_ascq dev->sense[13]
#define cdrom_drive cdrom_drives[id].host_drive
@@ -224,35 +151,34 @@ extern uint8_t scsi_cdrom_drives[16][8];
extern "C" {
#endif
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length);
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length);
extern void (*ide_bus_master_set_irq)(int channel);
extern void ioctl_close(uint8_t id);
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv);
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
extern void *ide_bus_master_priv[2];
extern uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel);
extern uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel);
extern uint32_t cdrom_mode_sense_get_channel(cdrom_t *dev, int channel);
extern uint32_t cdrom_mode_sense_get_volume(cdrom_t *dev, int channel);
extern void build_atapi_cdrom_map(void);
extern void build_scsi_cdrom_map(void);
extern int cdrom_CDROM_PHASE_to_scsi(uint8_t id);
extern int cdrom_atapi_phase_to_scsi(uint8_t id);
extern void cdrom_command(uint8_t id, uint8_t *cdb);
extern void cdrom_phase_callback(uint8_t id);
extern int cdrom_CDROM_PHASE_to_scsi(cdrom_t *dev);
extern int cdrom_atapi_phase_to_scsi(cdrom_t *dev);
extern void cdrom_command(cdrom_t *dev, uint8_t *cdb);
extern void cdrom_phase_callback(cdrom_t *dev);
extern uint32_t cdrom_read(uint8_t channel, int length);
extern void cdrom_write(uint8_t channel, uint32_t val, int length);
extern int cdrom_lba_to_msf_accurate(int lba);
extern void cdrom_destroy_drives(void);
extern void cdrom_close(uint8_t id);
extern void cdrom_reset(uint8_t id);
extern void cdrom_set_signature(int id);
extern void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length);
extern void cdrom_close_handler(uint8_t id);
extern void cdrom_close(void);
extern void cdrom_reset(cdrom_t *dev);
extern void cdrom_set_signature(cdrom_t *dev);
extern void cdrom_request_sense_for_scsi(cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length);
extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks);
extern void cdrom_insert(uint8_t id);
extern void cdrom_new_image(uint8_t id);
extern void cdrom_insert(cdrom_t *dev);
extern int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun);
extern int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
extern int find_cdrom_for_scsi_id(uint8_t scsi_id);
extern int cdrom_read_capacity(cdrom_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
extern void cdrom_global_init(void);
extern void cdrom_global_reset(void);

View File

@@ -87,12 +87,12 @@ uint64_t CDROM_Interface_Image::BinaryFile::getLength()
CDROM_Interface_Image::CDROM_Interface_Image()
{
printf("CDROM_Interface_Image constructor\n");
// printf("CDROM_Interface_Image constructor\n");
}
CDROM_Interface_Image::~CDROM_Interface_Image()
{
printf("CDROM_Interface_Image destructor\n");
// printf("CDROM_Interface_Image destructor\n");
ClearTracks();
}
@@ -263,7 +263,7 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename)
tracks.clear();
// data track
Track track = {0, 0, 0, 0, 0, 0, 0, false, NULL};
Track track = {0, 0, 0, 0, 0, 0, 0, 0, false, NULL};
bool error;
track.file = new BinaryFile(filename, error);
if (error) {
@@ -343,7 +343,7 @@ static string dirname(char * file) {
bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
{
Track track = {0, 0, 0, 0, 0, 0, 0, false, NULL};
Track track = {0, 0, 0, 0, 0, 0, 0, 0, false, NULL};
tracks.clear();
uint64_t shift = 0;
uint64_t currPregap = 0;
@@ -357,7 +357,6 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
ifstream in;
in.open(cuefile, ios::in);
if (in.fail()) return false;
int last_attr;
while(!in.eof()) {
// get next line
@@ -429,7 +428,6 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
track.attr = DATA_TRACK;
track.mode2 = true;
} else success = false;
last_attr = track.attr;
canAddTrack = true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,19 +9,20 @@
* Implementation of the CD-ROM null interface for unmounted
* guest CD-ROM drives.
*
* Version: @(#)cdrom_null.c 1.0.6 2017/11/04
* Version: @(#)cdrom_null.c 1.0.7 2018/03/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2016 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../scsi/scsi.h"
#include "cdrom.h"
@@ -50,17 +51,6 @@ null_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf)
}
static void
null_eject(uint8_t id)
{
}
static void
null_load(uint8_t id)
{
}
static int
null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len)
{
@@ -114,7 +104,7 @@ cdrom_null_reset(uint8_t id)
void cdrom_set_null_handler(uint8_t id);
int
cdrom_null_open(uint8_t id, char d)
cdrom_null_open(uint8_t id)
{
cdrom_set_null_handler(id);
@@ -134,20 +124,6 @@ void null_exit(uint8_t id)
}
static int
null_is_track_audio(uint8_t id, uint32_t pos, int ismsf)
{
return(0);
}
static int
null_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len)
{
return(0);
}
static int
null_media_type_id(uint8_t id)
{
@@ -158,7 +134,7 @@ null_media_type_id(uint8_t id)
void
cdrom_set_null_handler(uint8_t id)
{
cdrom_drives[id].handler = &null_cdrom;
cdrom[id]->handler = &null_cdrom;
cdrom_drives[id].host_drive = 0;
memset(cdrom_image[id].image_path, 0, sizeof(cdrom_image[id].image_path));
}
@@ -174,16 +150,12 @@ static CDROM null_cdrom = {
null_readtoc_session,
null_readtoc_raw,
null_getcurrentsubchannel,
null_pass_through,
null_readsector_raw,
NULL,
null_load,
null_eject,
NULL,
NULL,
null_size,
null_status,
null_is_track_audio,
NULL,
null_exit
};

View File

@@ -9,18 +9,18 @@
* Implementation of the CD-ROM null interface for unmounted
* guest CD-ROM drives.
*
* Version: @(#)cdrom_null.h 1.0.3 2017/09/03
* Version: @(#)cdrom_null.h 1.0.4 2018/03/31
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2016 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#ifndef EMU_CDROM_NULL_H
#define EMU_CDROM_NULL_H
extern int cdrom_null_open(uint8_t id, char d);
extern int cdrom_null_open(uint8_t id);
extern void cdrom_null_reset(uint8_t id);
extern void null_close(uint8_t id);

View File

@@ -8,7 +8,7 @@
*
* Configuration file handler.
*
* Version: @(#)config.c 1.0.46 2018/03/18
* Version: @(#)config.c 1.0.48 2018/05/25
*
* Authors: Sarah Walker,
* Miran Grca, <mgrca8@gmail.com>
@@ -23,23 +23,23 @@
* it on Windows XP, and possibly also Vista. Use the
* -DANSI_CFG for use on these systems.
*/
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <inttypes.h>
#define HAVE_STDARG_H
#include "86box.h"
#include "cpu/cpu.h"
#include "device.h"
#include "nvr.h"
#include "config.h"
#include "device.h"
#include "lpt.h"
#include "cdrom/cdrom.h"
#include "disk/hdd.h"
#include "disk/hdc.h"
#include "disk/hdc_ide.h"
#include "disk/zip.h"
#include "floppy/fdd.h"
#include "floppy/fdc.h"
#include "game/gameport.h"
@@ -47,6 +47,8 @@
#include "mouse.h"
#include "network/network.h"
#include "scsi/scsi.h"
#include "cdrom/cdrom.h"
#include "disk/zip.h"
#include "sound/sound.h"
#include "sound/midi.h"
#include "sound/snd_dbopl.h"
@@ -103,6 +105,26 @@ typedef struct {
static list_t config_head;
#ifdef ENABLE_CONFIG_LOG
int config_do_log = ENABLE_CONFIG_LOG;
#endif
static void
config_log(const char *format, ...)
{
#ifdef ENABLE_CONFIG_LOG
va_list ap;
if (config_do_log) {
va_start(ap, format);
pclog_ex(format, ap);
va_end(ap);
}
#endif
}
static section_t *
find_section(char *name)
{
@@ -522,7 +544,6 @@ load_video(void)
if (machines[machine].fixed_gfxcard) {
config_delete_var(cat, "gfxcard");
config_delete_var(cat, "voodoo");
gfxcard = GFX_INTERNAL;
} else {
p = config_get_string(cat, "gfxcard", NULL);
@@ -536,11 +557,9 @@ load_video(void)
}
}
gfxcard = video_get_video_from_internal_name(p);
video_speed = config_get_int(cat, "video_speed", -1);
voodoo_enabled = !!config_get_int(cat, "voodoo", 0);
}
voodoo_enabled = !!config_get_int(cat, "voodoo", 0);
}
@@ -612,12 +631,12 @@ load_sound(void)
GUS = !!config_get_int(cat, "gus", 0);
memset(temp, '\0', sizeof(temp));
p = config_get_string(cat, "opl3_type", "dbopl");
p = config_get_string(cat, "opl_type", "dbopl");
strcpy(temp, p);
if (!strcmp(temp, "nukedopl") || !strcmp(temp, "1"))
opl3_type = 1;
else
opl3_type = 0;
opl_type = 1;
else
opl_type = 0;
memset(temp, '\0', sizeof(temp));
p = config_get_string(cat, "sound_type", "float");
@@ -658,9 +677,9 @@ load_network(void)
if (p != NULL) {
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
if ((network_ndev == 1) && strcmp(network_host, "none")) {
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2140);
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2103);
} else if (network_dev_to_id(p) == -1) {
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2141);
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2104);
}
strcpy(network_host, "none");
@@ -714,8 +733,7 @@ static void
load_other_peripherals(void)
{
char *cat = "Other peripherals";
char temp[512], *p;
int c;
char *p;
p = config_get_string(cat, "scsicard", NULL);
if (p != NULL)
@@ -747,34 +765,13 @@ load_other_peripherals(void)
}
config_set_string(cat, "hdc", hdc_name);
memset(temp, '\0', sizeof(temp));
for (c=2; c<4; c++) {
sprintf(temp, "ide_%02i", c + 1);
p = config_get_string(cat, temp, NULL);
if (p == NULL)
p = "0, 00";
sscanf(p, "%i, %02i", &ide_enable[c], &ide_irq[c]);
}
ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0);
ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0);
bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0);
}
static int
tally_char(char *str, char c)
{
int tally;
tally = 0;
if (str != NULL) {
while (*str)
if (*str++ == c) tally++;
}
return(tally);
}
/* Load "Hard Disks" section. */
static void
load_hard_disks(void)
@@ -785,21 +782,17 @@ load_hard_disks(void)
int c;
char *p;
wchar_t *wp;
int max_spt, max_hpc, max_tracks;
int board = 0, dev = 0;
uint32_t max_spt, max_hpc, max_tracks;
uint32_t board = 0, dev = 0;
/* FIXME: Remove in a month. */
int lun;
memset(temp, '\0', sizeof(temp));
for (c=0; c<HDD_NUM; c++) {
sprintf(temp, "hdd_%02i_parameters", c+1);
p = config_get_string(cat, temp, "0, 0, 0, 0, none");
if (tally_char(p, ',') == 3) {
sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s",
&hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, s);
hdd[c].wp = 0;
} else {
sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s",
&hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, (int *)&hdd[c].wp, s);
}
sscanf(p, "%u, %u, %u, %i, %s",
&hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, (int *)&hdd[c].wp, s);
hdd[c].bus = hdd_string_to_bus(s, 0);
switch(hdd[c].bus) {
@@ -815,21 +808,19 @@ load_hard_disks(void)
break;
case HDD_BUS_ESDI:
case HDD_BUS_XTIDE:
case HDD_BUS_XTA:
max_spt = 63;
max_hpc = 16;
max_tracks = 1023;
break;
case HDD_BUS_IDE_PIO_ONLY:
case HDD_BUS_IDE_PIO_AND_DMA:
case HDD_BUS_IDE:
max_spt = 63;
max_hpc = 16;
max_tracks = 266305;
break;
case HDD_BUS_SCSI:
case HDD_BUS_SCSI_REMOVABLE:
max_spt = 99;
max_hpc = 255;
max_tracks = 266305;
@@ -850,10 +841,10 @@ load_hard_disks(void)
else
config_delete_var(cat, temp);
/* XT IDE */
sprintf(temp, "hdd_%02i_xtide_channel", c+1);
if (hdd[c].bus == HDD_BUS_XTIDE)
hdd[c].xtide_channel = !!config_get_int(cat, temp, c & 1);
/* XTA */
sprintf(temp, "hdd_%02i_xta_channel", c+1);
if (hdd[c].bus == HDD_BUS_XTA)
hdd[c].xta_channel = !!config_get_int(cat, temp, c & 1);
else
config_delete_var(cat, temp);
@@ -865,21 +856,21 @@ load_hard_disks(void)
config_delete_var(cat, temp);
/* IDE */
// FIXME: Remove in a month.
sprintf(temp, "hdd_%02i_xtide_channel", c+1);
if (hdd[c].bus == HDD_BUS_IDE)
hdd[c].ide_channel = !!config_get_int(cat, temp, c & 1);
else
config_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c+1);
if ((hdd[c].bus == HDD_BUS_IDE_PIO_ONLY) ||
(hdd[c].bus == HDD_BUS_IDE_PIO_AND_DMA)) {
if (hdd[c].bus == HDD_BUS_IDE) {
sprintf(tmp2, "%01u:%01u", c>>1, c&1);
p = config_get_string(cat, temp, tmp2);
if (! strstr(p, ":")) {
sscanf(p, "%i", (int *)&hdd[c].ide_channel);
hdd[c].ide_channel &= 7;
} else {
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
hdd[c].ide_channel = (board<<1) + dev;
}
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
hdd[c].ide_channel = (board<<1) + dev;
if (hdd[c].ide_channel > 7)
hdd[c].ide_channel = 7;
@@ -888,22 +879,29 @@ load_hard_disks(void)
}
/* SCSI */
sprintf(temp, "hdd_%02i_scsi_location", c+1);
if ((hdd[c].bus == HDD_BUS_SCSI) ||
(hdd[c].bus == HDD_BUS_SCSI_REMOVABLE)) {
sprintf(tmp2, "%02u:%02u", c, 0);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%02u:%02u",
(int *)&hdd[c].scsi_id, (int *)&hdd[c].scsi_lun);
sprintf(temp, "hdd_%02i_scsi_id", c+1);
if (hdd[c].bus == HDD_BUS_SCSI) {
hdd[c].scsi_id = config_get_int(cat, temp, c);
if (hdd[c].scsi_id > 15)
hdd[c].scsi_id = 15;
if (hdd[c].scsi_lun > 7)
hdd[c].scsi_lun = 7;
} else {
} else
config_delete_var(cat, temp);
/* FIXME: Remove in a month. */
sprintf(temp, "hdd_%02i_scsi_location", c+1);
if (hdd[c].bus == HDD_BUS_SCSI) {
p = config_get_string(cat, temp, NULL);
if (p) {
sscanf(p, "%02i:%02i",
(int *)&hdd[c].scsi_id, (int *)&lun);
if (hdd[c].scsi_id > 15)
hdd[c].scsi_id = 15;
}
}
config_delete_var(cat, temp);
memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn));
memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn));
@@ -940,6 +938,10 @@ load_hard_disks(void)
sprintf(temp, "hdd_%02i_ide_channels", c+1);
config_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_scsi_id", c+1);
config_delete_var(cat, temp);
/* FIXME: Remove in a month. */
sprintf(temp, "hdd_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
@@ -956,181 +958,6 @@ load_hard_disks(void)
}
/* Load old "Removable Devices" section. */
static void
load_removable_devices(void)
{
char *cat = "Removable devices";
char temp[512], tmp2[512], *p;
char s[512];
unsigned int board = 0, dev = 0;
wchar_t *wp;
int c;
if (find_section(cat) == NULL)
return;
for (c=0; c<FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c+1);
p = config_get_string(cat, temp, (c < 2) ? "525_2dd" : "none");
fdd_set_type(c, fdd_get_from_internal_name(p));
if (fdd_get_type(c) > 13)
fdd_set_type(c, 13);
sprintf(temp, "fdd_%02i_fn", c + 1);
wp = config_get_wstring(cat, temp, L"");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c]));
} else
#endif
wcsncpy(floppyfns[c], wp, sizeof_w(floppyfns[c]));
/* if (*wp != L'\0')
pclog("Floppy%d: %ls\n", c, floppyfns[c]); */
sprintf(temp, "fdd_%02i_writeprot", c+1);
ui_writeprot[c] = !!config_get_int(cat, temp, 0);
sprintf(temp, "fdd_%02i_turbo", c + 1);
fdd_set_turbo(c, !!config_get_int(cat, temp, 0));
sprintf(temp, "fdd_%02i_check_bpb", c+1);
fdd_set_check_bpb(c, !!config_get_int(cat, temp, 1));
/* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */
sprintf(temp, "fdd_%02i_type", c+1);
config_delete_var(cat, temp);
sprintf(temp, "fdd_%02i_fn", c+1);
config_delete_var(cat, temp);
sprintf(temp, "fdd_%02i_writeprot", c+1);
config_delete_var(cat, temp);
sprintf(temp, "fdd_%02i_turbo", c+1);
config_delete_var(cat, temp);
sprintf(temp, "fdd_%02i_check_bpb", c+1);
config_delete_var(cat, temp);
}
memset(temp, 0x00, sizeof(temp));
for (c=0; c<CDROM_NUM; c++) {
sprintf(temp, "cdrom_%02i_host_drive", c+1);
cdrom_drives[c].host_drive = config_get_int(cat, temp, 0);
cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive;
sprintf(temp, "cdrom_%02i_parameters", c+1);
p = config_get_string(cat, temp, NULL);
if (p != NULL)
sscanf(p, "%01u, %s", &cdrom_drives[c].sound_on, s);
else
sscanf("0, none", "%01u, %s", &cdrom_drives[c].sound_on, s);
cdrom_drives[c].bus_type = hdd_string_to_bus(s, 1);
/* Default values, needed for proper operation of the Settings dialog. */
cdrom_drives[c].ide_channel = cdrom_drives[c].scsi_device_id = c + 2;
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
if ((cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) ||
(cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) {
sprintf(tmp2, "%01u:%01u", (c+2)>>1, (c+2)&1);
p = config_get_string(cat, temp, tmp2);
if (! strstr(p, ":")) {
sscanf(p, "%i", (int *)&cdrom_drives[c].ide_channel);
cdrom_drives[c].ide_channel &= 7;
} else {
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
cdrom_drives[c].ide_channel = (board<<1)+dev;
}
if (cdrom_drives[c].ide_channel > 7)
cdrom_drives[c].ide_channel = 7;
} else {
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) {
sprintf(tmp2, "%02u:%02u", c+2, 0);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%02u:%02u",
&cdrom_drives[c].scsi_device_id,
&cdrom_drives[c].scsi_device_lun);
if (cdrom_drives[c].scsi_device_id > 15)
cdrom_drives[c].scsi_device_id = 15;
if (cdrom_drives[c].scsi_device_lun > 7)
cdrom_drives[c].scsi_device_lun = 7;
} else {
config_delete_var(cat, temp);
}
}
sprintf(temp, "cdrom_%02i_image_path", c+1);
wp = config_get_wstring(cat, temp, L"");
#if 0
/*
* NOTE:
* Temporary hack to remove the absolute
* path currently saved in most config
* files. We should remove this before
* finalizing this release! --FvK
*/
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
/*
* Yep, its absolute and prefixed
* with the EXE path. Just strip
* that off for now...
*/
wcsncpy(cdrom_image[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom_image[c].image_path));
} else
#endif
wcsncpy(cdrom_image[c].image_path, wp, sizeof_w(cdrom_image[c].image_path));
if (cdrom_drives[c].host_drive < 'A')
cdrom_drives[c].host_drive = 0;
if ((cdrom_drives[c].host_drive == 0x200) &&
(wcslen(cdrom_image[c].image_path) == 0))
cdrom_drives[c].host_drive = 0;
/* If the CD-ROM is disabled, delete all its variables. */
sprintf(temp, "cdrom_%02i_host_drive", c+1);
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_parameters", c+1);
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_image_path", c+1);
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_iso_path", c+1);
config_delete_var(cat, temp);
}
delete_section_if_empty(cat);
}
/* Load "Floppy Drives" section. */
static void
load_floppy_drives(void)
@@ -1170,7 +997,7 @@ load_floppy_drives(void)
wcsncpy(floppyfns[c], wp, sizeof_w(floppyfns[c]));
/* if (*wp != L'\0')
pclog("Floppy%d: %ls\n", c, floppyfns[c]); */
config_log("Floppy%d: %ls\n", c, floppyfns[c]); */
sprintf(temp, "fdd_%02i_writeprot", c+1);
ui_writeprot[c] = !!config_get_int(cat, temp, 0);
sprintf(temp, "fdd_%02i_turbo", c + 1);
@@ -1213,6 +1040,8 @@ load_other_removable_devices(void)
unsigned int board = 0, dev = 0;
wchar_t *wp;
int c;
/* FIXME: Remove in a month. */
int lun;
memset(temp, 0x00, sizeof(temp));
for (c=0; c<CDROM_NUM; c++) {
@@ -1235,39 +1064,39 @@ load_other_removable_devices(void)
cdrom_drives[c].ide_channel = cdrom_drives[c].scsi_device_id = c + 2;
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
if ((cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) ||
(cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) {
if (cdrom_drives[c].bus_type == CDROM_BUS_ATAPI) {
sprintf(tmp2, "%01u:%01u", (c+2)>>1, (c+2)&1);
p = config_get_string(cat, temp, tmp2);
if (! strstr(p, ":")) {
sscanf(p, "%i", (int *)&cdrom_drives[c].ide_channel);
cdrom_drives[c].ide_channel &= 7;
} else {
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
cdrom_drives[c].ide_channel = (board<<1)+dev;
}
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
cdrom_drives[c].ide_channel = (board<<1)+dev;
if (cdrom_drives[c].ide_channel > 7)
cdrom_drives[c].ide_channel = 7;
} else {
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) {
sprintf(tmp2, "%02u:%02u", c+2, 0);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%02u:%02u",
&cdrom_drives[c].scsi_device_id,
&cdrom_drives[c].scsi_device_lun);
cdrom_drives[c].scsi_device_id = config_get_int(cat, temp, c+2);
if (cdrom_drives[c].scsi_device_id > 15)
cdrom_drives[c].scsi_device_id = 15;
if (cdrom_drives[c].scsi_device_lun > 7)
cdrom_drives[c].scsi_device_lun = 7;
} else {
} else
config_delete_var(cat, temp);
/* FIXME: Remove in a month. */
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) {
p = config_get_string(cat, temp, NULL);
if (p) {
sscanf(p, "%02u:%02u",
&cdrom_drives[c].scsi_device_id, &lun);
if (cdrom_drives[c].scsi_device_id > 15)
cdrom_drives[c].scsi_device_id = 15;
}
}
config_delete_var(cat, temp);
}
sprintf(temp, "cdrom_%02i_image_path", c+1);
@@ -1310,6 +1139,10 @@ load_other_removable_devices(void)
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
config_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
config_delete_var(cat, temp);
/* FIXME: Remove in a month. */
sprintf(temp, "cdrom_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
@@ -1335,39 +1168,39 @@ load_other_removable_devices(void)
zip_drives[c].ide_channel = zip_drives[c].scsi_device_id = c + 2;
sprintf(temp, "zip_%02i_ide_channel", c+1);
if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI_PIO_ONLY) ||
(zip_drives[c].bus_type == ZIP_BUS_ATAPI_PIO_AND_DMA)) {
if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) {
sprintf(tmp2, "%01u:%01u", (c+2)>>1, (c+2)&1);
p = config_get_string(cat, temp, tmp2);
if (! strstr(p, ":")) {
sscanf(p, "%i", (int *)&zip_drives[c].ide_channel);
zip_drives[c].ide_channel &= 7;
} else {
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
zip_drives[c].ide_channel = (board<<1)+dev;
}
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
zip_drives[c].ide_channel = (board<<1)+dev;
if (zip_drives[c].ide_channel > 7)
zip_drives[c].ide_channel = 7;
} else {
sprintf(temp, "zip_%02i_scsi_location", c+1);
sprintf(temp, "zip_%02i_scsi_id", c+1);
if (zip_drives[c].bus_type == CDROM_BUS_SCSI) {
sprintf(tmp2, "%02u:%02u", c+2, 0);
p = config_get_string(cat, temp, tmp2);
sscanf(p, "%02u:%02u",
&zip_drives[c].scsi_device_id,
&zip_drives[c].scsi_device_lun);
zip_drives[c].scsi_device_id = config_get_int(cat, temp, c+2);
if (zip_drives[c].scsi_device_id > 15)
zip_drives[c].scsi_device_id = 15;
if (zip_drives[c].scsi_device_lun > 7)
zip_drives[c].scsi_device_lun = 7;
} else {
} else
config_delete_var(cat, temp);
/* FIXME: Remove in a month. */
sprintf(temp, "zip_%02i_scsi_location", c+1);
if (zip_drives[c].bus_type == CDROM_BUS_SCSI) {
p = config_get_string(cat, temp, NULL);
if (p) {
sscanf(p, "%02u:%02u",
&zip_drives[c].scsi_device_id, &lun);
if (zip_drives[c].scsi_device_id > 15)
zip_drives[c].scsi_device_id = 15;
}
}
config_delete_var(cat, temp);
}
sprintf(temp, "zip_%02i_image_path", c+1);
@@ -1403,6 +1236,10 @@ load_other_removable_devices(void)
sprintf(temp, "zip_%02i_ide_channel", c+1);
config_delete_var(cat, temp);
sprintf(temp, "zip_%02i_scsi_id", c+1);
config_delete_var(cat, temp);
/* FIXME: Remove in a month. */
sprintf(temp, "zip_%02i_scsi_location", c+1);
config_delete_var(cat, temp);
@@ -1420,7 +1257,17 @@ load_other_removable_devices(void)
void
config_load(void)
{
pclog("Loading config file '%ls'..\n", cfg_path);
int i;
config_log("Loading config file '%ls'..\n", cfg_path);
memset(hdd, 0, sizeof(hard_disk_t));
memset(cdrom_drives, 0, sizeof(cdrom_drive_t) * CDROM_NUM);
memset(cdrom_image, 0, sizeof(cdrom_image_t) * CDROM_NUM);
#ifdef USE_IOCTL
memset(cdrom_ioctl, 0, sizeof(cdrom_ioctl_t) * CDROM_NUM);
#endif
memset(zip_drives, 0, sizeof(zip_drive_t));
if (! config_read(cfg_path)) {
cpu = 0;
@@ -1428,8 +1275,9 @@ config_load(void)
plat_langid = 0x0409;
#endif
scale = 1;
machine = machine_get_machine_from_internal_name("ibmpc");
gfxcard = GFX_CGA;
vid_api = plat_vidapi("default");;
vid_api = plat_vidapi("default");
enable_sync = 1;
joystick_type = 7;
if (hdc_name) {
@@ -1438,14 +1286,22 @@ config_load(void)
}
hdc_name = (char *) malloc((strlen("none")+1) * sizeof(char));
strcpy(hdc_name, "none");
serial_enabled[0] = 0;
serial_enabled[1] = 0;
lpt_enabled = 0;
fdd_set_type(0, 2);
fdd_set_type(1, 2);
mem_size = 640;
serial_enabled[0] = 1;
serial_enabled[1] = 1;
lpt_enabled = 1;
for (i = 0; i < FDD_NUM; i++) {
if (i < 2)
fdd_set_type(i, 2);
else
fdd_set_type(i, 0);
pclog("Config file not present or invalid!\n");
fdd_set_turbo(i, 0);
fdd_set_check_bpb(i, 1);
}
mem_size = 640;
opl_type = 0;
config_log("Config file not present or invalid!\n");
return;
}
@@ -1460,12 +1316,11 @@ config_load(void)
load_hard_disks(); /* Hard disks */
load_floppy_drives(); /* Floppy drives */
load_other_removable_devices(); /* Other removable devices */
load_removable_devices(); /* Removable devices (legacy) */
/* Mark the configuration as changed. */
config_changed = 1;
pclog("Config loaded.\n\n");
config_log("Config loaded.\n\n");
}
@@ -1618,11 +1473,6 @@ save_video(void)
config_set_string(cat, "gfxcard",
video_get_internal_name(video_old_to_new(gfxcard)));
if (video_speed == 3)
config_delete_var(cat, "video_speed");
else
config_set_int(cat, "video_speed", video_speed);
if (voodoo_enabled == 0)
config_delete_var(cat, "voodoo");
else
@@ -1730,10 +1580,10 @@ save_sound(void)
else
config_set_int(cat, "gus", GUS);
if (opl3_type == 0)
config_delete_var(cat, "opl3_type");
if (opl_type == 0)
config_delete_var(cat, "opl_type");
else
config_set_string(cat, "opl3_type", (opl3_type == 1) ? "nukedopl" : "dbopl");
config_set_string(cat, "opl_type", (opl_type == 1) ? "nukedopl" : "dbopl");
if (sound_is_float == 1)
config_delete_var(cat, "sound_type");
@@ -1821,8 +1671,6 @@ static void
save_other_peripherals(void)
{
char *cat = "Other peripherals";
char temp[512], tmp2[512];
int c;
if (scsi_card_current == 0)
config_delete_var(cat, "scsicard");
@@ -1832,15 +1680,15 @@ save_other_peripherals(void)
config_set_string(cat, "hdc", hdc_name);
memset(temp, '\0', sizeof(temp));
for (c=2; c<4; c++) {
sprintf(temp, "ide_%02i", c + 1);
sprintf(tmp2, "%i, %02i", !!ide_enable[c], ide_irq[c]);
if (ide_enable[c] == 0)
config_delete_var(cat, temp);
else
config_set_string(cat, temp, tmp2);
}
if (ide_ter_enabled == 0)
config_delete_var(cat, "ide_ter");
else
config_set_int(cat, "ide_ter", ide_ter_enabled);
if (ide_qua_enabled == 0)
config_delete_var(cat, "ide_qua");
else
config_set_int(cat, "ide_qua", ide_qua_enabled);
if (bugger_enabled == 0)
config_delete_var(cat, "bugger_enabled");
@@ -1865,7 +1713,7 @@ save_hard_disks(void)
sprintf(temp, "hdd_%02i_parameters", c+1);
if (hdd_is_valid(c)) {
p = hdd_bus_to_string(hdd[c].bus, 0);
sprintf(tmp2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s",
sprintf(tmp2, "%u, %u, %u, %i, %s",
hdd[c].spt, hdd[c].hpc, hdd[c].tracks, hdd[c].wp, p);
config_set_string(cat, temp, tmp2);
} else {
@@ -1878,38 +1726,36 @@ save_hard_disks(void)
else
config_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_xtide_channel", c+1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_XTIDE))
config_set_int(cat, temp, hdd[c].xtide_channel);
sprintf(temp, "hdd_%02i_xta_channel", c+1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_XTA))
config_set_int(cat, temp, hdd[c].xta_channel);
else
config_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_esdi_channel", c+1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_ESDI))
config_set_int(cat, temp, hdd[c].esdi_channel);
else
else
config_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c+1);
if (! hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_IDE_PIO_ONLY) && (hdd[c].bus != HDD_BUS_IDE_PIO_AND_DMA))) {
if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE)) {
config_delete_var(cat, temp);
} else {
sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "hdd_%02i_scsi_location", c+1);
if (! hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_SCSI) && (hdd[c].bus != HDD_BUS_SCSI_REMOVABLE))) {
sprintf(temp, "hdd_%02i_scsi_id", c+1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_SCSI))
config_set_int(cat, temp, hdd[c].scsi_id);
else
config_delete_var(cat, temp);
} else {
sprintf(tmp2, "%02u:%02u", hdd[c].scsi_id, hdd[c].scsi_lun);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "hdd_%02i_fn", c+1);
if (hdd_is_valid(c) && (wcslen(hdd[c].fn) != 0))
config_set_wstring(cat, temp, hdd[c].fn);
else
else
config_delete_var(cat, temp);
}
@@ -2002,22 +1848,19 @@ save_other_removable_devices(void)
}
sprintf(temp, "cdrom_%02i_ide_channel", c+1);
if ((cdrom_drives[c].bus_type != CDROM_BUS_ATAPI_PIO_ONLY) &&
(cdrom_drives[c].bus_type != CDROM_BUS_ATAPI_PIO_AND_DMA)) {
if (cdrom_drives[c].bus_type != CDROM_BUS_ATAPI)
config_delete_var(cat, temp);
} else {
else {
sprintf(tmp2, "%01u:%01u", cdrom_drives[c].ide_channel>>1,
cdrom_drives[c].ide_channel & 1);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "cdrom_%02i_scsi_location", c + 1);
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
if (cdrom_drives[c].bus_type != CDROM_BUS_SCSI) {
config_delete_var(cat, temp);
} else {
sprintf(tmp2, "%02u:%02u", cdrom_drives[c].scsi_device_id,
cdrom_drives[c].scsi_device_lun);
config_set_string(cat, temp, tmp2);
config_set_int(cat, temp, cdrom_drives[c].scsi_device_id);
}
sprintf(temp, "cdrom_%02i_image_path", c + 1);
@@ -2040,22 +1883,19 @@ save_other_removable_devices(void)
}
sprintf(temp, "zip_%02i_ide_channel", c+1);
if ((zip_drives[c].bus_type != ZIP_BUS_ATAPI_PIO_ONLY) &&
(zip_drives[c].bus_type != ZIP_BUS_ATAPI_PIO_AND_DMA)) {
if (zip_drives[c].bus_type != ZIP_BUS_ATAPI)
config_delete_var(cat, temp);
} else {
else {
sprintf(tmp2, "%01u:%01u", zip_drives[c].ide_channel>>1,
zip_drives[c].ide_channel & 1);
config_set_string(cat, temp, tmp2);
}
sprintf(temp, "zip_%02i_scsi_location", c + 1);
sprintf(temp, "zip_%02i_scsi_id", c + 1);
if (zip_drives[c].bus_type != ZIP_BUS_SCSI) {
config_delete_var(cat, temp);
} else {
sprintf(tmp2, "%02u:%02u", zip_drives[c].scsi_device_id,
zip_drives[c].scsi_device_lun);
config_set_string(cat, temp, tmp2);
config_set_int(cat, temp, zip_drives[c].scsi_device_id);
}
sprintf(temp, "zip_%02i_image_path", c + 1);
@@ -2100,11 +1940,11 @@ config_dump(void)
entry_t *ent;
if (sec->name && sec->name[0])
pclog("[%s]\n", sec->name);
config_log("[%s]\n", sec->name);
ent = (entry_t *)sec->entry_head.next;
while (ent != NULL) {
pclog("%s = %ls\n", ent->name, ent->wdata);
config_log("%s = %ls\n", ent->name, ent->wdata);
ent = (entry_t *)ent->list.next;
}
@@ -2157,7 +1997,7 @@ config_get_hex16(char *head, char *name, int def)
{
section_t *section;
entry_t *entry;
int value;
unsigned int value;
section = find_section(head);
if (section == NULL)
@@ -2178,7 +2018,7 @@ config_get_hex20(char *head, char *name, int def)
{
section_t *section;
entry_t *entry;
int value;
unsigned int value;
section = find_section(head);
if (section == NULL)
@@ -2199,7 +2039,7 @@ config_get_mac(char *head, char *name, int def)
{
section_t *section;
entry_t *entry;
int val0 = 0, val1 = 0, val2 = 0;
unsigned int val0 = 0, val1 = 0, val2 = 0;
section = find_section(head);
if (section == NULL)

View File

@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
@@ -7,6 +8,7 @@
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -68,122 +70,6 @@ uint32_t *eal_r, *eal_w;
uint16_t *mod1add[2][8];
uint32_t *mod1seg[8];
#if 0
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (cpu_rm == 4)
{
uint8_t sib = rmdat >> 8;
switch (cpu_mod)
{
case 0:
cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
cpu_state.pc++;
break;
case 1:
cpu_state.pc++;
cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
/* pc++; */
break;
case 2:
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
cpu_state.pc += 5;
break;
}
/*SIB byte present*/
if ((sib & 7) == 5 && !cpu_mod)
cpu_state.eaaddr = getlong();
else if ((sib & 6) == 4 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
if (((sib >> 3) & 7) != 4)
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
}
else
{
cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
if (cpu_mod)
{
if (cpu_rm == 5 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
if (cpu_mod == 1)
{
cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
cpu_state.pc++;
}
else
{
cpu_state.eaaddr += getlong();
}
}
else if (cpu_rm == 5)
{
cpu_state.eaaddr = getlong();
}
}
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;
if ( readlookup2[addr >> 12] != -1)
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
}
}
static __inline void fetch_ea_16_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (!cpu_mod && cpu_rm == 6)
{
cpu_state.eaaddr = getword();
}
else
{
switch (cpu_mod)
{
case 0:
cpu_state.eaaddr = 0;
break;
case 1:
cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
break;
case 2:
cpu_state.eaaddr = getword();
break;
}
cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
cpu_state.eaaddr &= 0xFFFF;
}
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;
if ( readlookup2[addr >> 12] != -1)
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
}
}
#endif
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; }
#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0
@@ -222,6 +108,27 @@ extern int dontprint;
break; \
}
#ifdef ENABLE_386_LOG
int x386_do_log = ENABLE_386_LOG;
#endif
static void
x386_log(const char *fmt, ...)
{
#ifdef ENABLE_386_LOG
va_list ap;
if (x386_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
void exec386(int cycs)
{
uint8_t temp;
@@ -240,7 +147,6 @@ void exec386(int cycs)
cycdiff=0;
oldcyc=cycles;
timer_start_period(cycles << TIMER_SHIFT);
/* pclog("%i %02X\n", ins, ram[8]); */
while (cycdiff < cycle_period)
{
/* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX;
@@ -268,10 +174,6 @@ dontprint=0;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
if (output == 3)
{
pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,cpu_state.pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]);
}
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
if (x86_was_reset)
@@ -284,17 +186,6 @@ dontprint=0;
if (cpu_state.abrt)
{
flags_rebuild();
/* pclog("Abort\n"); */
/* if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,cpu_state.abrt); */
/* if (testr[0]!=EAX) pclog("EAX corrupted %08X\n",pc);
if (testr[1]!=EBX) pclog("EBX corrupted %08X\n",pc);
if (testr[2]!=ECX) pclog("ECX corrupted %08X\n",pc);
if (testr[3]!=EDX) pclog("EDX corrupted %08X\n",pc);
if (testr[4]!=ESI) pclog("ESI corrupted %08X\n",pc);
if (testr[5]!=EDI) pclog("EDI corrupted %08X\n",pc);
if (testr[6]!=EBP) pclog("EBP corrupted %08X\n",pc);
if (testr[7]!=ESP) pclog("ESP corrupted %08X\n",pc);*/
/* if (testr[8]!=flags) pclog("FLAGS corrupted %08X\n",pc);*/
tempi = cpu_state.abrt;
cpu_state.abrt = 0;
x86_doabrt(tempi);
@@ -303,14 +194,14 @@ dontprint=0;
cpu_state.abrt = 0;
CS = oldcs;
cpu_state.pc = cpu_state.oldpc;
pclog("Double fault %i\n", ins);
x386_log("Double fault %i\n", ins);
pmodeint(8, 0);
if (cpu_state.abrt)
{
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault - reset\n");
x386_log("Triple fault - reset\n");
}
}
}
@@ -342,7 +233,6 @@ dontprint=0;
{
cpu_state.oldpc = cpu_state.pc;
oldcs = CS;
/* pclog("NMI\n"); */
x86_int(2);
nmi_enable = 0;
if (nmi_auto_clear)
@@ -356,10 +246,6 @@ dontprint=0;
temp=picinterrupt();
if (temp!=0xFF)
{
/* if (temp == 0x54) pclog("Take int 54\n"); */
/* if (output) output=3; */
/* if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc); */
/* if (temp==0x54) output=3; */
flags_rebuild();
if (msw&1)
{
@@ -377,14 +263,11 @@ dontprint=0;
oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
/* if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc); */
}
/* pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); */
}
}
ins++;
insc++;
if (timetolive)
{

View File

@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
@@ -7,6 +8,7 @@
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -69,6 +71,27 @@ uint32_t *eal_r, *eal_w;
uint16_t *mod1add[2][8];
uint32_t *mod1seg[8];
#ifdef ENABLE_386_DYNAREC_LOG
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
#endif
static void
x386_dynarec_log(const char *fmt, ...)
{
#ifdef ENABLE_386_DYNAREC_LOG
va_list ap;
if (x386_dynarec_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
@@ -210,7 +233,7 @@ void x86_int(int num)
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault in real mode - reset\n");
x386_dynarec_log("Triple fault in real mode - reset\n");
}
else
x86_int(8);
@@ -303,9 +326,9 @@ int x86_int_sw_rm(int num)
if (cpu_state.abrt) return 1;
writememw(ss,((SP-2)&0xFFFF),flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; }
writememw(ss,((SP-2)&0xFFFF),flags); if (cpu_state.abrt) {x386_dynarec_log("abrt5\n"); return 1; }
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {pclog("abrt6\n"); return 1; }
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {x386_dynarec_log("abrt6\n"); return 1; }
SP-=6;
eflags &= ~VIF_FLAG;
@@ -428,13 +451,6 @@ int checkio(int port)
int xout=0;
#if 0
#define divexcp() { \
pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \
x86_int(0); \
}
#endif
#define divexcp() { \
x86_int(0); \
}
@@ -592,7 +608,6 @@ void exec386_dynarec(int cycs)
CPU_BLOCK_END();
ins++;
insc++;
/* if ((cs + pc) == 4)
fatal("4\n");*/
@@ -686,9 +701,6 @@ inrecomp=1;
inrecomp=0;
if (!use32) cpu_state.pc &= 0xffff;
cpu_recomp_blocks++;
/* ins += codeblock_ins[index];
insc += codeblock_ins[index];*/
/* pclog("Exit block now %04X:%04X\n", CS, pc);*/
}
else if (valid_block && !cpu_state.abrt)
{
@@ -752,7 +764,6 @@ inrecomp=0;
}
ins++;
insc++;
}
if (!cpu_state.abrt && !x86_was_reset)
@@ -823,7 +834,6 @@ inrecomp=0;
}
ins++;
insc++;
}
if (!cpu_state.abrt && !x86_was_reset)
@@ -848,14 +858,14 @@ inrecomp=0;
cpu_state.abrt = 0;
CS = oldcs;
cpu_state.pc = cpu_state.oldpc;
pclog("Double fault %i\n", ins);
x386_dynarec_log("Double fault %i\n", ins);
pmodeint(8, 0);
if (cpu_state.abrt)
{
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault - reset\n");
x386_dynarec_log("Triple fault - reset\n");
}
}
}
@@ -885,7 +895,6 @@ inrecomp=0;
{
cpu_state.oldpc = cpu_state.pc;
oldcs = CS;
pclog("NMI\n");
x86_int(2);
nmi_enable = 0;
if (nmi_auto_clear)
@@ -903,18 +912,10 @@ inrecomp=0;
flags_rebuild();
if (msw&1)
{
/* if (temp == 0x0E)
{
pclog("Servicing FDC interupt (p)!\n");
} */
pmodeint(temp,0);
}
else
{
/* if (temp == 0x0E)
{
pclog("Servicing FDC interupt (r)!\n");
} */
writememw(ss,(SP-2)&0xFFFF,flags);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -927,10 +928,6 @@ inrecomp=0;
loadcs(readmemw(0,addr+2));
}
}
/* else
{
pclog("Servicing pending interrupt 0xFF (!)!\n");
} */
}
}
timer_end_period(cycles << TIMER_SHIFT);

View File

@@ -1,23 +1,43 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the 86Box distribution.
* This file is part of the VARCem Project.
*
* 286/386+ instruction handlers list.
*
* Version: @(#)386_ops.h 1.0.2 2018/02/18
* Version: @(#)386_ops.h 1.0.3 2018/05/21
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include "x86_ops.h"
@@ -147,11 +167,18 @@ static int ILLEGAL(uint32_t fetchdat)
return 0;
}
#include "x86seg.h"
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#include "x86_ops_amd.h"
#if defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686))
static int internal_illegal(char *s)
{
cpu_state.pc = cpu_state.oldpc;
x86gpf(s, 0);
return cpu_state.abrt;
}
#endif
#include "x86seg.h"
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
# include "x86_ops_amd.h"
#endif
#include "x86_ops_arith.h"
#include "x86_ops_atomic.h"
@@ -167,10 +194,8 @@ static int ILLEGAL(uint32_t fetchdat)
#include "x86_ops_jump.h"
#include "x86_ops_misc.h"
#include "x87_ops.h"
#ifdef DEV_BRANCH
#ifdef USE_I686
#include "x86_ops_i686.h"
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
# include "x86_ops_i686.h"
#endif
#include "x86_ops_mmx.h"
#include "x86_ops_mmx_arith.h"
@@ -195,6 +220,7 @@ static int ILLEGAL(uint32_t fetchdat)
#include "x86_ops_string.h"
#include "x86_ops_xchg.h"
static int op0F_w_a16(uint32_t fetchdat)
{
int opcode = fetchdat & 0xff;
@@ -236,7 +262,8 @@ static int op0F_l_a32(uint32_t fetchdat)
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
}
OpFn OP_TABLE(286_0f)[1024] =
const OpFn OP_TABLE(286_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -327,7 +354,7 @@ OpFn OP_TABLE(286_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(386_0f)[1024] =
const OpFn OP_TABLE(386_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -418,7 +445,7 @@ OpFn OP_TABLE(386_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(486_0f)[1024] =
const OpFn OP_TABLE(486_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -509,7 +536,7 @@ OpFn OP_TABLE(486_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(winchip_0f)[1024] =
const OpFn OP_TABLE(winchip_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -600,7 +627,7 @@ OpFn OP_TABLE(winchip_0f)[1024] =
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
};
OpFn OP_TABLE(pentium_0f)[1024] =
const OpFn OP_TABLE(pentium_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -691,7 +718,7 @@ OpFn OP_TABLE(pentium_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(pentiummmx_0f)[1024] =
const OpFn OP_TABLE(pentiummmx_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -782,9 +809,8 @@ OpFn OP_TABLE(pentiummmx_0f)[1024] =
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
};
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
OpFn OP_TABLE(k6_0f)[1024] =
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
const OpFn OP_TABLE(k6_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -875,9 +901,8 @@ OpFn OP_TABLE(k6_0f)[1024] =
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
};
#endif
#endif
OpFn OP_TABLE(c6x86mx_0f)[1024] =
const OpFn OP_TABLE(c6x86mx_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -970,7 +995,7 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] =
#ifdef DEV_BRANCH
#ifdef USE_I686
OpFn OP_TABLE(pentiumpro_0f)[1024] =
const OpFn OP_TABLE(pentiumpro_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1062,7 +1087,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] =
};
#if 0
OpFn OP_TABLE(pentium2_0f)[1024] =
const OpFn OP_TABLE(pentium2_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1154,7 +1179,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] =
};
#endif
OpFn OP_TABLE(pentium2d_0f)[1024] =
const OpFn OP_TABLE(pentium2d_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1247,7 +1272,7 @@ OpFn OP_TABLE(pentium2d_0f)[1024] =
#endif
#endif
OpFn OP_TABLE(286)[1024] =
const OpFn OP_TABLE(286)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1338,7 +1363,7 @@ OpFn OP_TABLE(286)[1024] =
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
};
OpFn OP_TABLE(386)[1024] =
const OpFn OP_TABLE(386)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1429,7 +1454,7 @@ OpFn OP_TABLE(386)[1024] =
/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32,
};
OpFn OP_TABLE(REPE)[1024] =
const OpFn OP_TABLE(REPE)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1520,7 +1545,7 @@ OpFn OP_TABLE(REPE)[1024] =
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
OpFn OP_TABLE(REPNE)[1024] =
const OpFn OP_TABLE(REPNE)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/

View File

@@ -18,7 +18,7 @@
* 2 clocks - fetch opcode 1 2 clocks - execute
* 2 clocks - fetch opcode 2 etc
*
* Version: @(#)808x.c 1.0.2 2018/03/09
* Version: @(#)808x.c 1.0.5 2018/04/29
*
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
@@ -44,10 +44,12 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -58,9 +60,6 @@
#include "../nmi.h"
#include "../pic.h"
#include "../timer.h"
#include "../device.h" /* for scsi.h */
#include "../keyboard.h" /* its WRONG to have this in here!! --FvK */
#include "../scsi/scsi.h" /* its WRONG to have this in here!! --FvK */
#include "../plat.h"
@@ -84,6 +83,27 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
uint32_t readmemll(uint32_t seg, uint32_t addr);
void writememll(uint32_t seg, uint32_t addr, uint32_t val);
#ifdef ENABLE_808X_LOG
int x808x_do_log = ENABLE_808X_LOG;
#endif
static void
x808x_log(const char *fmt, ...)
{
#ifdef ENABLE_808X_LOG
va_list ap;
if (x808x_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
#undef readmemb
#undef readmemw
uint8_t readmemb(uint32_t a)
@@ -109,7 +129,7 @@ uint16_t readmemw(uint32_t s, uint16_t a)
else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a);
}
void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; }
void refreshread() { FETCHCOMPLETE(); memcycs+=4; }
#undef fetchea
#define fetchea() { rmdat=FETCH(); \
@@ -488,7 +508,7 @@ void makeznptable()
{
znptable8[c]=P_FLAG;
}
if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]);
if (c == 0xb1) x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]);
if (!c) znptable8[c]|=Z_FLAG;
if (c&0x80) znptable8[c]|=N_FLAG;
}
@@ -507,8 +527,8 @@ void makeznptable()
znptable16[c]=0;
else
znptable16[c]=P_FLAG;
if (c == 0xb1) pclog("znp16 b1 = %i %02X\n", d, znptable16[c]);
if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]);
if (c == 0xb1) x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]);
if (c == 0x65b1) x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]);
if (!c) znptable16[c]|=Z_FLAG;
if (c&0x8000) znptable16[c]|=N_FLAG;
}
@@ -541,11 +561,11 @@ void dumpregs(int force)
f=fopen("ram.dmp","wb");
fwrite(ram,mem_size*1024,1,f);
fclose(f);
pclog("Dumping rram.dmp\n");
x808x_log("Dumping rram.dmp\n");
f=fopen("rram.dmp","wb");
for (c=0;c<0x1000000;c++) putc(readmemb(c),f);
fclose(f);
pclog("Dumping rram4.dmp\n");
x808x_log("Dumping rram4.dmp\n");
f=fopen("rram4.dmp","wb");
for (c=0;c<0x0050000;c++)
{
@@ -553,44 +573,44 @@ void dumpregs(int force)
putc(readmemb386l(0,c+0x80000000),f);
}
fclose(f);
pclog("Dumping done\n");
x808x_log("Dumping done\n");
#endif
if (is386)
pclog("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP);
x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP);
else
pclog("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP);
pclog("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,flags);
pclog("%04X:%04X %04X:%04X\n",oldcs,cpu_state.oldpc, oldcs2, oldpc2);
pclog("%i ins\n",ins);
x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP);
x808x_log("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,flags);
x808x_log("%04X:%04X %04X:%04X\n",oldcs,cpu_state.oldpc, oldcs2, oldpc2);
x808x_log("%i ins\n",ins);
if (is386)
pclog("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
x808x_log("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
else
pclog("In %s mode\n",(msw&1)?"protected":"real");
pclog("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high);
pclog("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high);
pclog("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high);
x808x_log("In %s mode\n",(msw&1)?"protected":"real");
x808x_log("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high);
x808x_log("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high);
x808x_log("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high);
if (is386)
{
pclog("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",seg_fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high);
pclog("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high);
x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",seg_fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high);
x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high);
}
pclog("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high);
pclog("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
pclog("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
pclog("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
pclog("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
x808x_log("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high);
x808x_log("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
x808x_log("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
x808x_log("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
if (is386)
{
pclog("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
pclog("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4);
x808x_log("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4);
}
pclog("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
x808x_log("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
for (c=0;c<1024*1024;c++)
{
if (readlookup2[c]!=0xFFFFFFFF) d++;
if (writelookup2[c]!=0xFFFFFFFF) e++;
}
pclog("Entries in readlookup : %i writelookup : %i\n",d,e);
x808x_log("Entries in readlookup : %i writelookup : %i\n",d,e);
x87_dumpregs();
indump = 0;
}
@@ -599,7 +619,7 @@ int resets = 0;
int x86_was_reset = 0;
void resetx86()
{
pclog("x86 reset\n");
x808x_log("x86 reset\n");
resets++;
ins = 0;
use32=0;
@@ -648,7 +668,6 @@ void resetx86()
#endif
x86_was_reset = 1;
port_92_clear_reset();
scsi_card_reset();
}
void softresetx86()
@@ -658,7 +677,12 @@ void softresetx86()
cpu_cur_status = 0;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
msw=0;
cr0=0;
if (is486)
cr0 = 1 << 30;
else
cr0 = 0;
cpu_cache_int_enabled = 0;
cpu_update_waitstates();
cr4 = 0;
eflags=0;
cgate32=0;
@@ -680,7 +704,6 @@ void softresetx86()
x86seg_reset();
x86_was_reset = 1;
port_92_clear_reset();
scsi_card_reset();
}
static void setznp8(uint8_t val)
@@ -1065,7 +1088,7 @@ void execx86(int cycs)
cpu_state.pc--;
if (output)
{
if (!skipnextprint) pclog("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i %p %02X\n",cs,cpu_state.pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ins, ram, ram[0x1a925]);
if (!skipnextprint) x808x_log("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i %p %02X\n",cs,cpu_state.pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ins, ram, ram[0x1a925]);
skipnextprint=0;
}
cpu_state.pc++;
@@ -2974,7 +2997,7 @@ void execx86(int cycs)
}
else
{
pclog("DIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("DIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -2998,7 +3021,7 @@ void execx86(int cycs)
}
else
{
pclog("IDIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("IDIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -3070,7 +3093,7 @@ void execx86(int cycs)
}
else
{
pclog("DIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("DIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -3094,7 +3117,7 @@ void execx86(int cycs)
}
else
{
pclog("IDIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("IDIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -3245,7 +3268,6 @@ void execx86(int cycs)
}
memcycs=0;
insc++;
clockhardware();
if (trap && (flags&T_FLAG) && !noint)

View File

@@ -634,5 +634,12 @@ opFLDimm(L2T, 3.3219280948873623)
opFLDimm(L2E, 1.4426950408889634);
opFLDimm(PI, 3.141592653589793);
opFLDimm(EG2, 0.3010299956639812);
opFLDimm(LN2, 0.693147180559945);
opFLDimm(Z, 0.0)
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
return op_pc;
}

View File

@@ -59,6 +59,7 @@ static uint32_t prev_regmask;
static uint64_t *prev_deps;
static uint32_t prev_fetchdat;
static uint32_t last_regmask_modified;
static uint32_t regmask_modified;
static uint32_t opcode_timings[256] =
@@ -776,7 +777,7 @@ static inline int COUNT(uint32_t c, int op_32)
void codegen_timing_686_block_start()
{
prev_full = decode_delay = 0;
regmask_modified = 0;
regmask_modified = last_regmask_modified = 0;
}
void codegen_timing_686_start()
@@ -787,6 +788,18 @@ void codegen_timing_686_start()
void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
{
if ((prefix & 0xf8) == 0xd8)
{
last_prefix = prefix;
return;
}
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80)
{
/*0fh prefix is 'free' when used on conditional jumps*/
last_prefix = prefix;
return;
}
/*6x86 can decode 1 prefix per instruction per clock with no penalty. If
either instruction has more than one prefix then decode is delayed by
one cycle for each additional prefix*/
@@ -801,7 +814,16 @@ static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_3
if (addr_regmask & IMPL_ESP)
addr_regmask |= (1 << REG_ESP);
return regmask_modified & addr_regmask;
if (regmask_modified & addr_regmask)
{
regmask_modified = 0;
return 2;
}
if (last_regmask_modified & addr_regmask)
return 1;
return 0;
}
void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
@@ -914,6 +936,8 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
}
}
/*One prefix per instruction is free*/
decode_delay--;
if (decode_delay < 0)
decode_delay = 0;
@@ -925,8 +949,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
if (regmask & IMPL_ESP)
regmask |= SRCDEP_ESP | DSTDEP_ESP;
if (check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32))
agi_stall = 2;
agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32);
/*Second instruction in the pair*/
if ((timings[opcode] & PAIR_MASK) == PAIR_NP)
@@ -936,6 +959,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
@@ -946,6 +970,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else if (prev_regmask & regmask)
@@ -955,6 +980,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
prev_full = 0;
last_regmask_modified = regmask_modified;
regmask_modified = prev_regmask;
}
else
@@ -966,12 +992,12 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
if (!t_pair)
fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode);
if (check_agi(deps, opcode, fetchdat, op_32))
agi_stall = 2;
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
codegen_block_cycles += t_pair + agi_stall;
decode_delay = (-t_pair) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask;
prev_full = 0;
return;
@@ -985,12 +1011,12 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
{
/*Instruction not pairable*/
int agi_stall = 0;
if (check_agi(deps, opcode, fetchdat, op_32))
agi_stall = 2;
agi_stall = check_agi(deps, opcode, fetchdat, op_32);
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall;
decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall;
last_regmask_modified = regmask_modified;
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
}
else

View File

@@ -963,7 +963,7 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat)
last_prefix = prefix;
return;
}
if (prefix == 0x0f && (opcode & 0xf0) == 0x80)
if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80)
{
/*On Pentium 0fh prefix is 'free' when used on conditional jumps*/
last_prefix = prefix;

View File

@@ -1,8 +1,10 @@
#ifdef __amd64__
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -94,7 +96,6 @@ void codegen_init()
exit(-1);
}
#endif
// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block);
}
void codegen_reset()
@@ -111,20 +112,6 @@ void codegen_reset()
void dump_block()
{
/* codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n");
while (block)
{
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff);
uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff);
pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next);
if (!block->pc)
fatal("Dead PC=0\n");
block = block->next;
}
pclog("dump_block done\n");*/
}
static void add_to_block_list(codeblock_t *block)
@@ -204,7 +191,6 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
}
else
{
// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2);
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2;
if (block->next_2)
block->next_2->prev_2 = NULL;
@@ -270,11 +256,8 @@ void codegen_block_init(uint32_t phys_addr)
block_current = (block_current + 1) & BLOCK_MASK;
block = &codeblock[block_current];
// if (block->pc == 0xb00b4ff5)
// pclog("Init target block\n");
if (block->valid != 0)
{
// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc);
delete_block(block);
cpu_recomp_reuse++;
}
@@ -374,8 +357,6 @@ void codegen_block_start_recompile(codeblock_t *block)
addbyte(0xBD);
addquad(((uintptr_t)&cpu_state) + 128);
// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num);
last_op32 = -1;
last_ea_seg = NULL;
last_ssegs = -1;
@@ -434,14 +415,10 @@ void codegen_block_generate_end_mask()
end_pc = 0x3ff;
start_pc >>= PAGE_MASK_SHIFT;
end_pc >>= PAGE_MASK_SHIFT;
// pclog("block_end: %08x %08x\n", start_pc, end_pc);
for (; start_pc <= end_pc; start_pc++)
{
block->page_mask |= ((uint64_t)1 << start_pc);
// pclog(" %08x %llx\n", start_pc, block->page_mask);
}
pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask;
block->phys_2 = -1;
@@ -467,7 +444,6 @@ void codegen_block_generate_end_mask()
fatal("!page_mask2\n");
if (block->next_2)
{
// pclog(" next_2->pc=%08x\n", block->next_2->pc);
if (block->next_2->valid == 0)
fatal("block->next_2->valid=0 %p\n", (void *)block->next_2);
}
@@ -476,7 +452,6 @@ void codegen_block_generate_end_mask()
}
}
// pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask);
recomp_page = -1;
}
@@ -542,7 +517,6 @@ void codegen_block_end_recompile(codeblock_t *block)
block->next_2 = block->prev_2 = NULL;
codegen_block_generate_end_mask();
add_to_block_list(block);
// pclog("End block %i\n", block_num);
}
void codegen_flush()
@@ -597,10 +571,6 @@ int opcode_0f_modrm[256] =
void codegen_debug()
{
if (output)
{
pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, cs, cpu_state.pc, SS, ss, ESP, es,EAX, BX,ECX,BP, EDX,EDI);
}
}
static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
@@ -1122,17 +1092,6 @@ generate_call:
addlong(codegen_block_ins);
codegen_block_ins = 0;
}
#if 0
if (codegen_block_full_ins)
{
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)&cpu_recomp_full_ins);
addlong(codegen_block_full_ins);
codegen_block_full_ins = 0;
}
#endif
}
if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32])
@@ -1159,8 +1118,6 @@ generate_call:
}
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
// if (output)
// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]);
if (op_ssegs != last_ssegs)
{
last_ssegs = op_ssegs;
@@ -1169,7 +1126,6 @@ generate_call:
addbyte((uint8_t)cpu_state_offset(ssegs));
addbyte(op_ssegs);
}
//#if 0
if ((!test_modrm ||
(op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) ||
(op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/)
@@ -1195,10 +1151,8 @@ generate_call:
op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset);
op_pc -= pc_off;
}
//#endif
if (op_ea_seg != last_ea_seg)
{
// last_ea_seg = op_ea_seg;
addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/
addbyte(0x45);
addbyte((uint8_t)cpu_state_offset(ea_seg));
@@ -1235,8 +1189,6 @@ generate_call:
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4]));
// call(block, codegen_debug);
codegen_endpc = (cs + cpu_state.pc) + 8;
}

View File

@@ -1,3 +1,41 @@
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Dynamic Recompiler for Intel 32-bit systems.
*
* Version: @(#)codegen_x86.c 1.0.3 2018/05/05
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32
#include <stdio.h>
@@ -956,11 +994,6 @@ static uint32_t gen_MEM_CHECK_WRITE()
return addr;
}
/*static void checkdebug(uint32_t a)
{
pclog("checkdebug %08x\n", a);
}*/
static uint32_t gen_MEM_CHECK_WRITE_W()
{
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@@ -1200,10 +1233,17 @@ void codegen_init()
block_pos = (block_pos + 15) & ~15;
mem_check_write_l = (uint32_t)gen_MEM_CHECK_WRITE_L();
#ifndef _MSC_VER
asm(
"fstcw %0\n"
: "=m" (cpu_state.old_npxc)
);
#else
__asm
{
fstcw cpu_state.old_npxc
}
#endif
}
void codegen_reset()
@@ -1215,20 +1255,6 @@ void codegen_reset()
void dump_block()
{
/* codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n");
while (block)
{
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff);
uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff);
pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next);
if (!block->pc)
fatal("Dead PC=0\n");
block = block->next;
}
pclog("dump_block done\n");*/
}
static void add_to_block_list(codeblock_t *block)
@@ -1657,10 +1683,6 @@ int opcode_0f_modrm[256] =
void codegen_debug()
{
if (output)
{
pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, cs, cpu_state.pc, SS, ss, ESP, es,EAX, BX,ECX,BP, EDX,EDI);
}
}
static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
@@ -1844,7 +1866,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
codeblock_t *block = &codeblock[block_current];
uint32_t op_32 = use32;
uint32_t op_pc = new_pc;
OpFn *op_table = x86_dynarec_opcodes;
const OpFn *op_table = x86_dynarec_opcodes;
RecompOpFn *recomp_op_table = recomp_opcodes;
int opcode_shift = 0;
int opcode_mask = 0x3ff;

View File

@@ -1,22 +1,42 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the 86Box distribution.
* This file is part of the VARCem Project.
*
* CPU type handler.
*
* Version: @(#)cpu.c 1.0.14 2018/03/11
* Version: @(#)cpu.c 1.0.6 2018/05/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdint.h>
@@ -31,58 +51,11 @@
#include "../mem.h"
#include "../pci.h"
#ifdef USE_DYNAREC
#include "codegen.h"
# include "codegen.h"
#endif
int isa_cycles;
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
#ifdef USE_DYNAREC
OpFn *x86_dynarec_opcodes;
OpFn *x86_dynarec_opcodes_0f;
OpFn *x86_dynarec_opcodes_d8_a16;
OpFn *x86_dynarec_opcodes_d8_a32;
OpFn *x86_dynarec_opcodes_d9_a16;
OpFn *x86_dynarec_opcodes_d9_a32;
OpFn *x86_dynarec_opcodes_da_a16;
OpFn *x86_dynarec_opcodes_da_a32;
OpFn *x86_dynarec_opcodes_db_a16;
OpFn *x86_dynarec_opcodes_db_a32;
OpFn *x86_dynarec_opcodes_dc_a16;
OpFn *x86_dynarec_opcodes_dc_a32;
OpFn *x86_dynarec_opcodes_dd_a16;
OpFn *x86_dynarec_opcodes_dd_a32;
OpFn *x86_dynarec_opcodes_de_a16;
OpFn *x86_dynarec_opcodes_de_a32;
OpFn *x86_dynarec_opcodes_df_a16;
OpFn *x86_dynarec_opcodes_df_a32;
OpFn *x86_dynarec_opcodes_REPE;
OpFn *x86_dynarec_opcodes_REPNE;
#endif
OpFn *x86_opcodes;
OpFn *x86_opcodes_0f;
OpFn *x86_opcodes_d8_a16;
OpFn *x86_opcodes_d8_a32;
OpFn *x86_opcodes_d9_a16;
OpFn *x86_opcodes_d9_a32;
OpFn *x86_opcodes_da_a16;
OpFn *x86_opcodes_da_a32;
OpFn *x86_opcodes_db_a16;
OpFn *x86_opcodes_db_a32;
OpFn *x86_opcodes_dc_a16;
OpFn *x86_opcodes_dc_a32;
OpFn *x86_opcodes_dd_a16;
OpFn *x86_opcodes_dd_a32;
OpFn *x86_opcodes_de_a16;
OpFn *x86_opcodes_de_a32;
OpFn *x86_opcodes_df_a16;
OpFn *x86_opcodes_df_a32;
OpFn *x86_opcodes_REPE;
OpFn *x86_opcodes_REPNE;
enum
{
enum {
CPUID_FPU = (1 << 0),
CPUID_VME = (1 << 1),
CPUID_PSE = (1 << 3),
@@ -96,93 +69,145 @@ enum
CPUID_FXSR = (1 << 24)
};
CPU *cpu_s;
int cpu_effective;
int cpu_multi;
int cpu_iscyrix;
int cpu_16bitbus;
int cpu_busspeed;
int cpu_hasrdtsc;
int cpu_hasMMX, cpu_hasMSR;
int cpu_hasCR4;
int cpu_hasVME;
int cpu_cyrix_alignment;
int hasfpu;
int cpuspeed;
uint64_t cpu_CR4_mask;
int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
int cpu_pci_speed;
int is286, is386, is486;
int israpidcad, is_pentium;
uint64_t tsc = 0;
cr0_t CR0;
uint64_t pmc[2] = {0, 0};
uint16_t temp_seg_data[4] = {0, 0, 0, 0};
#ifdef DEV_BRANCH
#ifdef USE_I686
uint16_t cs_msr = 0;
uint32_t esp_msr = 0;
uint32_t eip_msr = 0;
uint64_t apic_base_msr = 0;
uint64_t mtrr_cap_msr = 0;
uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_fix64k_8000_msr = 0;
uint64_t mtrr_fix16k_8000_msr = 0;
uint64_t mtrr_fix16k_a000_msr = 0;
uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t pat_msr = 0;
uint64_t mtrr_deftype_msr = 0;
uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t ecx17_msr = 0;
uint64_t ecx79_msr = 0;
uint64_t ecx8x_msr[4] = {0, 0, 0, 0};
uint64_t ecx116_msr = 0;
uint64_t ecx11x_msr[4] = {0, 0, 0, 0};
uint64_t ecx11e_msr = 0;
uint64_t ecx186_msr = 0;
uint64_t ecx187_msr = 0;
uint64_t ecx1e0_msr = 0;
uint64_t ecx570_msr = 0;
#endif
#ifdef USE_DYNAREC
const OpFn *x86_dynarec_opcodes;
const OpFn *x86_dynarec_opcodes_0f;
const OpFn *x86_dynarec_opcodes_d8_a16;
const OpFn *x86_dynarec_opcodes_d8_a32;
const OpFn *x86_dynarec_opcodes_d9_a16;
const OpFn *x86_dynarec_opcodes_d9_a32;
const OpFn *x86_dynarec_opcodes_da_a16;
const OpFn *x86_dynarec_opcodes_da_a32;
const OpFn *x86_dynarec_opcodes_db_a16;
const OpFn *x86_dynarec_opcodes_db_a32;
const OpFn *x86_dynarec_opcodes_dc_a16;
const OpFn *x86_dynarec_opcodes_dc_a32;
const OpFn *x86_dynarec_opcodes_dd_a16;
const OpFn *x86_dynarec_opcodes_dd_a32;
const OpFn *x86_dynarec_opcodes_de_a16;
const OpFn *x86_dynarec_opcodes_de_a32;
const OpFn *x86_dynarec_opcodes_df_a16;
const OpFn *x86_dynarec_opcodes_df_a32;
const OpFn *x86_dynarec_opcodes_REPE;
const OpFn *x86_dynarec_opcodes_REPNE;
#endif
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
/* AMD K5 and K6 MSR's. */
uint64_t ecx83_msr = 0;
/* These are K6-only. */
uint64_t star = 0;
uint64_t sfmask = 0;
#endif
const OpFn *x86_opcodes;
const OpFn *x86_opcodes_0f;
const OpFn *x86_opcodes_d8_a16;
const OpFn *x86_opcodes_d8_a32;
const OpFn *x86_opcodes_d9_a16;
const OpFn *x86_opcodes_d9_a32;
const OpFn *x86_opcodes_da_a16;
const OpFn *x86_opcodes_da_a32;
const OpFn *x86_opcodes_db_a16;
const OpFn *x86_opcodes_db_a32;
const OpFn *x86_opcodes_dc_a16;
const OpFn *x86_opcodes_dc_a32;
const OpFn *x86_opcodes_dd_a16;
const OpFn *x86_opcodes_dd_a32;
const OpFn *x86_opcodes_de_a16;
const OpFn *x86_opcodes_de_a32;
const OpFn *x86_opcodes_df_a16;
const OpFn *x86_opcodes_df_a32;
const OpFn *x86_opcodes_REPE;
const OpFn *x86_opcodes_REPNE;
CPU *cpu_s;
int cpu_effective;
int cpu_multi;
int cpu_16bitbus;
int cpu_busspeed;
int cpu_cyrix_alignment;
int cpuspeed;
int CPUID;
uint64_t cpu_CR4_mask;
int isa_cycles;
int cpu_cycles_read, cpu_cycles_read_l,
cpu_cycles_write, cpu_cycles_write_l;
int cpu_prefetch_cycles, cpu_prefetch_width,
cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
int cpu_pci_speed;
int is286,
is386,
is486,
cpu_iscyrix,
israpidcad,
is_pentium;
int hasfpu,
cpu_hasrdtsc,
cpu_hasMMX,
cpu_hasMSR,
cpu_hasCR4,
cpu_hasVME;
uint64_t tsc = 0;
msr_t msr;
cr0_t CR0;
uint64_t pmc[2] = {0, 0};
uint16_t temp_seg_data[4] = {0, 0, 0, 0};
#if defined(DEV_BRANCH) && defined(USE_I686)
uint16_t cs_msr = 0;
uint32_t esp_msr = 0;
uint32_t eip_msr = 0;
uint64_t apic_base_msr = 0;
uint64_t mtrr_cap_msr = 0;
uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_fix64k_8000_msr = 0;
uint64_t mtrr_fix16k_8000_msr = 0;
uint64_t mtrr_fix16k_a000_msr = 0;
uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t pat_msr = 0;
uint64_t mtrr_deftype_msr = 0;
uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t ecx17_msr = 0;
uint64_t ecx79_msr = 0;
uint64_t ecx8x_msr[4] = {0, 0, 0, 0};
uint64_t ecx116_msr = 0;
uint64_t ecx11x_msr[4] = {0, 0, 0, 0};
uint64_t ecx11e_msr = 0;
uint64_t ecx186_msr = 0;
uint64_t ecx187_msr = 0;
uint64_t ecx1e0_msr = 0;
uint64_t ecx570_msr = 0;
#endif
int timing_rr;
int timing_mr, timing_mrl;
int timing_rm, timing_rml;
int timing_mm, timing_mml;
int timing_bt, timing_bnt;
int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, timing_int_pm_outer;
int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer;
int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner;
int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
int timing_misaligned;
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */
uint64_t star = 0; /* These are K6-only. */
uint64_t sfmask = 0;
#endif
msr_t msr;
int timing_rr;
int timing_mr, timing_mrl;
int timing_rm, timing_rml;
int timing_mm, timing_mml;
int timing_bt, timing_bnt;
int timing_int, timing_int_rm, timing_int_v86, timing_int_pm,
timing_int_pm_outer;
int timing_iret_rm, timing_iret_v86, timing_iret_pm,
timing_iret_pm_outer;
int timing_call_rm, timing_call_pm, timing_call_pm_gate,
timing_call_pm_gate_inner;
int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
int timing_misaligned;
void cpu_dynamic_switch(int new_cpu)
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
void
cpu_dynamic_switch(int new_cpu)
{
if (cpu_effective == new_cpu)
return;
@@ -194,16 +219,17 @@ void cpu_dynamic_switch(int new_cpu)
cpu = c;
}
void cpu_set_edx()
void
cpu_set_edx(void)
{
EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].edx_reset;
}
void cpu_set()
void
cpu_set(void)
{
CPU *cpu_s;
if (!machines[machine].cpu[cpu_manufacturer].cpus)
{
/*CPU is invalid, set to default*/
@@ -250,7 +276,7 @@ void cpu_set()
cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles;
else
cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000;
if (cpu_s->pci_speed)
{
pci_nonburst_time = 4*cpu_s->rspeed / cpu_s->pci_speed;
@@ -261,16 +287,12 @@ void cpu_set()
pci_nonburst_time = 4;
pci_burst_time = 1;
}
pclog("PCI burst=%i nonburst=%i\n", pci_burst_time, pci_nonburst_time);
if (cpu_iscyrix)
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
else
io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
pclog("hasfpu - %i\n",hasfpu);
pclog("is486 - %i %i\n",is486,cpu_s->cpu_type);
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
#else
@@ -1091,8 +1113,7 @@ void cpu_set()
ccr4 = 0x80;
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
case CPU_5K86:
#ifdef USE_DYNAREC
@@ -1146,10 +1167,8 @@ void cpu_set()
#endif
break;
#endif
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
#if defined(DEV_BRANCH) && defined(USE_I686)
case CPU_PENTIUMPRO:
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f);
@@ -1271,7 +1290,6 @@ void cpu_set()
codegen_timing_set(&codegen_timing_686);
#endif
break;
#endif
#endif
default:
@@ -1294,7 +1312,8 @@ cpu_current_pc(char *bufp)
}
void cpu_CPUID()
void
cpu_CPUID(void)
{
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
{
@@ -1313,7 +1332,7 @@ void cpu_CPUID()
EDX = CPUID_FPU; /*FPU*/
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_iDX4:
@@ -1331,7 +1350,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_Am486SX:
@@ -1348,7 +1367,7 @@ void cpu_CPUID()
EBX = ECX = EDX = 0; /*No FPU*/
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_Am486DX:
@@ -1366,7 +1385,7 @@ void cpu_CPUID()
EDX = CPUID_FPU; /*FPU*/
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_WINCHIP:
@@ -1397,7 +1416,7 @@ void cpu_CPUID()
EDX |= CPUID_MMX;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_PENTIUM:
@@ -1415,11 +1434,10 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
if (!EAX)
{
@@ -1435,7 +1453,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_5K86:
@@ -1487,7 +1505,7 @@ void cpu_CPUID()
EDX = 0x10040120;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_K6:
@@ -1549,9 +1567,8 @@ void cpu_CPUID()
EDX = 0x444D416E;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#endif
#endif
case CPU_PENTIUMMMX:
@@ -1569,7 +1586,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1588,7 +1605,7 @@ void cpu_CPUID()
EDX = CPUID_FPU;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1607,7 +1624,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1626,7 +1643,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1646,7 +1663,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#ifdef DEV_BRANCH
@@ -1669,7 +1686,7 @@ void cpu_CPUID()
{
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
/* case CPU_PENTIUM2:
@@ -1693,7 +1710,7 @@ void cpu_CPUID()
EDX = 0x0C040843;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break; */
case CPU_PENTIUM2D:
@@ -1717,7 +1734,7 @@ void cpu_CPUID()
EDX = 0x0C040844;
}
else
EAX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#endif
#endif
@@ -1759,8 +1776,7 @@ void cpu_RDMSR()
}
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
case CPU_5K86:
case CPU_K6:
@@ -1787,14 +1803,10 @@ void cpu_RDMSR()
EDX = sfmask >> 32;
break;
default:
#ifndef RELEASE_BUILD
pclog("Invalid MSR: %08X\n", ECX);
#endif
x86gpf(NULL, 0);
break;
}
break;
#endif
#endif
case CPU_PENTIUM:
@@ -1941,9 +1953,6 @@ void cpu_RDMSR()
break;
default:
i686_invalid_rdmsr:
#ifndef RELEASE_BUILD
pclog("Invalid MSR: %08X\n", ECX);
#endif
x86gpf(NULL, 0);
break;
}
@@ -1988,8 +1997,8 @@ void cpu_WRMSR()
break;
}
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
case CPU_5K86:
case CPU_K6:
@@ -2012,7 +2021,6 @@ void cpu_WRMSR()
break;
}
break;
#endif
#endif
case CPU_PENTIUM:
@@ -2124,9 +2132,6 @@ void cpu_WRMSR()
break;
default:
i686_invalid_wrmsr:
#ifndef RELEASE_BUILD
pclog("Invalid MSR: %08X\n", ECX);
#endif
x86gpf(NULL, 0);
break;
}
@@ -2202,8 +2207,11 @@ uint8_t cyrix_read(uint16_t addr, void *priv)
return 0xff;
}
void
#ifdef USE_DYNAREC
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f)
x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
const OpFn *dynarec_opcodes, const OpFn *dynarec_opcodes_0f)
{
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
@@ -2211,22 +2219,24 @@ void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn
x86_dynarec_opcodes_0f = dynarec_opcodes_0f;
}
#else
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f)
x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f)
{
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
}
#endif
void cpu_update_waitstates()
void
cpu_update_waitstates(void)
{
cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
if (is486)
cpu_prefetch_width = 16;
else
cpu_prefetch_width = cpu_16bitbus ? 2 : 4;
if (cpu_cache_int_enabled)
{
/* Disable prefetch emulation */
@@ -2260,7 +2270,7 @@ void cpu_update_waitstates()
cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles;
}
if (is486)
cpu_prefetch_cycles *= 4;
cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16;
cpu_mem_prefetch_cycles = cpu_prefetch_cycles;
if (cpu_s->rspeed <= 8000000)
cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles;

View File

@@ -8,7 +8,7 @@
*
* CPU type handler.
*
* Version: @(#)cpu.h 1.0.10 2018/03/11
* Version: @(#)cpu.h 1.0.11 2018/03/28
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,
@@ -258,7 +258,11 @@ struct _cpustate_ {
#ifdef __MSC__
# define COMPILE_TIME_ASSERT(expr) /*nada*/
#else
# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
# ifdef EXTREME_DEBUG
# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];
# else
# define COMPILE_TIME_ASSERT(expr) /*nada*/
# endif
#endif
COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128)

View File

@@ -29,7 +29,7 @@
* 16 = 180 MHz
* 17 = 200 MHz
*
* Version: @(#)cpu_table.c 1.0.4 2018/02/18
* Version: @(#)cpu_table.c 1.0.5 2018/07/17
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,

View File

@@ -1,6 +1,41 @@
/* Copyright holders: Sarah Walker, leilei
see COPYING for more details
*/
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Miscellaneous x86 CPU Instructions.
*
* Version: @(#)x86_ops.h 1.0.2 2018/05/05
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef _X86_OPS_H
#define _X86_OPS_H
@@ -11,194 +46,188 @@
typedef int (*OpFn)(uint32_t fetchdat);
#ifdef USE_DYNAREC
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f);
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
const OpFn *dynarec_opcodes,
const OpFn *dynarec_opcodes_0f);
extern OpFn *x86_dynarec_opcodes;
extern OpFn *x86_dynarec_opcodes_0f;
extern OpFn *x86_dynarec_opcodes_d8_a16;
extern OpFn *x86_dynarec_opcodes_d8_a32;
extern OpFn *x86_dynarec_opcodes_d9_a16;
extern OpFn *x86_dynarec_opcodes_d9_a32;
extern OpFn *x86_dynarec_opcodes_da_a16;
extern OpFn *x86_dynarec_opcodes_da_a32;
extern OpFn *x86_dynarec_opcodes_db_a16;
extern OpFn *x86_dynarec_opcodes_db_a32;
extern OpFn *x86_dynarec_opcodes_dc_a16;
extern OpFn *x86_dynarec_opcodes_dc_a32;
extern OpFn *x86_dynarec_opcodes_dd_a16;
extern OpFn *x86_dynarec_opcodes_dd_a32;
extern OpFn *x86_dynarec_opcodes_de_a16;
extern OpFn *x86_dynarec_opcodes_de_a32;
extern OpFn *x86_dynarec_opcodes_df_a16;
extern OpFn *x86_dynarec_opcodes_df_a32;
extern OpFn *x86_dynarec_opcodes_REPE;
extern OpFn *x86_dynarec_opcodes_REPNE;
extern const OpFn *x86_dynarec_opcodes;
extern const OpFn *x86_dynarec_opcodes_0f;
extern const OpFn *x86_dynarec_opcodes_d8_a16;
extern const OpFn *x86_dynarec_opcodes_d8_a32;
extern const OpFn *x86_dynarec_opcodes_d9_a16;
extern const OpFn *x86_dynarec_opcodes_d9_a32;
extern const OpFn *x86_dynarec_opcodes_da_a16;
extern const OpFn *x86_dynarec_opcodes_da_a32;
extern const OpFn *x86_dynarec_opcodes_db_a16;
extern const OpFn *x86_dynarec_opcodes_db_a32;
extern const OpFn *x86_dynarec_opcodes_dc_a16;
extern const OpFn *x86_dynarec_opcodes_dc_a32;
extern const OpFn *x86_dynarec_opcodes_dd_a16;
extern const OpFn *x86_dynarec_opcodes_dd_a32;
extern const OpFn *x86_dynarec_opcodes_de_a16;
extern const OpFn *x86_dynarec_opcodes_de_a32;
extern const OpFn *x86_dynarec_opcodes_df_a16;
extern const OpFn *x86_dynarec_opcodes_df_a32;
extern const OpFn *x86_dynarec_opcodes_REPE;
extern const OpFn *x86_dynarec_opcodes_REPNE;
extern OpFn dynarec_ops_286[1024];
extern OpFn dynarec_ops_286_0f[1024];
extern const OpFn dynarec_ops_286[1024];
extern const OpFn dynarec_ops_286_0f[1024];
extern OpFn dynarec_ops_386[1024];
extern OpFn dynarec_ops_386_0f[1024];
extern const OpFn dynarec_ops_386[1024];
extern const OpFn dynarec_ops_386_0f[1024];
extern OpFn dynarec_ops_486_0f[1024];
extern const OpFn dynarec_ops_486_0f[1024];
extern OpFn dynarec_ops_winchip_0f[1024];
extern const OpFn dynarec_ops_winchip_0f[1024];
extern OpFn dynarec_ops_pentium_0f[1024];
extern OpFn dynarec_ops_pentiummmx_0f[1024];
extern OpFn dynarec_ops_c6x86mx_0f[1024];
extern const OpFn dynarec_ops_pentium_0f[1024];
extern const OpFn dynarec_ops_pentiummmx_0f[1024];
extern const OpFn dynarec_ops_c6x86mx_0f[1024];
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
extern OpFn dynarec_ops_k6_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
extern const OpFn dynarec_ops_k6_0f[1024];
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
extern OpFn dynarec_ops_pentiumpro_0f[1024];
extern OpFn dynarec_ops_pentium2d_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
extern const OpFn dynarec_ops_pentiumpro_0f[1024];
extern const OpFn dynarec_ops_pentium2d_0f[1024];
#endif
extern OpFn dynarec_ops_fpu_287_d9_a16[256];
extern OpFn dynarec_ops_fpu_287_d9_a32[256];
extern OpFn dynarec_ops_fpu_287_da_a16[256];
extern OpFn dynarec_ops_fpu_287_da_a32[256];
extern OpFn dynarec_ops_fpu_287_db_a16[256];
extern OpFn dynarec_ops_fpu_287_db_a32[256];
extern OpFn dynarec_ops_fpu_287_dc_a16[32];
extern OpFn dynarec_ops_fpu_287_dc_a32[32];
extern OpFn dynarec_ops_fpu_287_dd_a16[256];
extern OpFn dynarec_ops_fpu_287_dd_a32[256];
extern OpFn dynarec_ops_fpu_287_de_a16[256];
extern OpFn dynarec_ops_fpu_287_de_a32[256];
extern OpFn dynarec_ops_fpu_287_df_a16[256];
extern OpFn dynarec_ops_fpu_287_df_a32[256];
extern const OpFn dynarec_ops_fpu_287_d9_a16[256];
extern const OpFn dynarec_ops_fpu_287_d9_a32[256];
extern const OpFn dynarec_ops_fpu_287_da_a16[256];
extern const OpFn dynarec_ops_fpu_287_da_a32[256];
extern const OpFn dynarec_ops_fpu_287_db_a16[256];
extern const OpFn dynarec_ops_fpu_287_db_a32[256];
extern const OpFn dynarec_ops_fpu_287_dc_a16[32];
extern const OpFn dynarec_ops_fpu_287_dc_a32[32];
extern const OpFn dynarec_ops_fpu_287_dd_a16[256];
extern const OpFn dynarec_ops_fpu_287_dd_a32[256];
extern const OpFn dynarec_ops_fpu_287_de_a16[256];
extern const OpFn dynarec_ops_fpu_287_de_a32[256];
extern const OpFn dynarec_ops_fpu_287_df_a16[256];
extern const OpFn dynarec_ops_fpu_287_df_a32[256];
extern OpFn dynarec_ops_fpu_d8_a16[32];
extern OpFn dynarec_ops_fpu_d8_a32[32];
extern OpFn dynarec_ops_fpu_d9_a16[256];
extern OpFn dynarec_ops_fpu_d9_a32[256];
extern OpFn dynarec_ops_fpu_da_a16[256];
extern OpFn dynarec_ops_fpu_da_a32[256];
extern OpFn dynarec_ops_fpu_db_a16[256];
extern OpFn dynarec_ops_fpu_db_a32[256];
extern OpFn dynarec_ops_fpu_dc_a16[32];
extern OpFn dynarec_ops_fpu_dc_a32[32];
extern OpFn dynarec_ops_fpu_dd_a16[256];
extern OpFn dynarec_ops_fpu_dd_a32[256];
extern OpFn dynarec_ops_fpu_de_a16[256];
extern OpFn dynarec_ops_fpu_de_a32[256];
extern OpFn dynarec_ops_fpu_df_a16[256];
extern OpFn dynarec_ops_fpu_df_a32[256];
extern OpFn dynarec_ops_nofpu_a16[256];
extern OpFn dynarec_ops_nofpu_a32[256];
extern const OpFn dynarec_ops_fpu_d8_a16[32];
extern const OpFn dynarec_ops_fpu_d8_a32[32];
extern const OpFn dynarec_ops_fpu_d9_a16[256];
extern const OpFn dynarec_ops_fpu_d9_a32[256];
extern const OpFn dynarec_ops_fpu_da_a16[256];
extern const OpFn dynarec_ops_fpu_da_a32[256];
extern const OpFn dynarec_ops_fpu_db_a16[256];
extern const OpFn dynarec_ops_fpu_db_a32[256];
extern const OpFn dynarec_ops_fpu_dc_a16[32];
extern const OpFn dynarec_ops_fpu_dc_a32[32];
extern const OpFn dynarec_ops_fpu_dd_a16[256];
extern const OpFn dynarec_ops_fpu_dd_a32[256];
extern const OpFn dynarec_ops_fpu_de_a16[256];
extern const OpFn dynarec_ops_fpu_de_a32[256];
extern const OpFn dynarec_ops_fpu_df_a16[256];
extern const OpFn dynarec_ops_fpu_df_a32[256];
extern const OpFn dynarec_ops_nofpu_a16[256];
extern const OpFn dynarec_ops_nofpu_a32[256];
extern OpFn dynarec_ops_fpu_686_da_a16[256];
extern OpFn dynarec_ops_fpu_686_da_a32[256];
extern OpFn dynarec_ops_fpu_686_db_a16[256];
extern OpFn dynarec_ops_fpu_686_db_a32[256];
extern OpFn dynarec_ops_fpu_686_df_a16[256];
extern OpFn dynarec_ops_fpu_686_df_a32[256];
extern const OpFn dynarec_ops_fpu_686_da_a16[256];
extern const OpFn dynarec_ops_fpu_686_da_a32[256];
extern const OpFn dynarec_ops_fpu_686_db_a16[256];
extern const OpFn dynarec_ops_fpu_686_db_a32[256];
extern const OpFn dynarec_ops_fpu_686_df_a16[256];
extern const OpFn dynarec_ops_fpu_686_df_a32[256];
extern OpFn dynarec_ops_REPE[1024];
extern OpFn dynarec_ops_REPNE[1024];
extern const OpFn dynarec_ops_REPE[1024];
extern const OpFn dynarec_ops_REPNE[1024];
#else
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f);
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f);
#endif
extern OpFn *x86_opcodes;
extern OpFn *x86_opcodes_0f;
extern OpFn *x86_opcodes_d8_a16;
extern OpFn *x86_opcodes_d8_a32;
extern OpFn *x86_opcodes_d9_a16;
extern OpFn *x86_opcodes_d9_a32;
extern OpFn *x86_opcodes_da_a16;
extern OpFn *x86_opcodes_da_a32;
extern OpFn *x86_opcodes_db_a16;
extern OpFn *x86_opcodes_db_a32;
extern OpFn *x86_opcodes_dc_a16;
extern OpFn *x86_opcodes_dc_a32;
extern OpFn *x86_opcodes_dd_a16;
extern OpFn *x86_opcodes_dd_a32;
extern OpFn *x86_opcodes_de_a16;
extern OpFn *x86_opcodes_de_a32;
extern OpFn *x86_opcodes_df_a16;
extern OpFn *x86_opcodes_df_a32;
extern OpFn *x86_opcodes_REPE;
extern OpFn *x86_opcodes_REPNE;
extern const OpFn *x86_opcodes;
extern const OpFn *x86_opcodes_0f;
extern const OpFn *x86_opcodes_d8_a16;
extern const OpFn *x86_opcodes_d8_a32;
extern const OpFn *x86_opcodes_d9_a16;
extern const OpFn *x86_opcodes_d9_a32;
extern const OpFn *x86_opcodes_da_a16;
extern const OpFn *x86_opcodes_da_a32;
extern const OpFn *x86_opcodes_db_a16;
extern const OpFn *x86_opcodes_db_a32;
extern const OpFn *x86_opcodes_dc_a16;
extern const OpFn *x86_opcodes_dc_a32;
extern const OpFn *x86_opcodes_dd_a16;
extern const OpFn *x86_opcodes_dd_a32;
extern const OpFn *x86_opcodes_de_a16;
extern const OpFn *x86_opcodes_de_a32;
extern const OpFn *x86_opcodes_df_a16;
extern const OpFn *x86_opcodes_df_a32;
extern const OpFn *x86_opcodes_REPE;
extern const OpFn *x86_opcodes_REPNE;
extern OpFn ops_286[1024];
extern OpFn ops_286_0f[1024];
extern const OpFn ops_286[1024];
extern const OpFn ops_286_0f[1024];
extern OpFn ops_386[1024];
extern OpFn ops_386_0f[1024];
extern const OpFn ops_386[1024];
extern const OpFn ops_386_0f[1024];
extern OpFn ops_486_0f[1024];
extern const OpFn ops_486_0f[1024];
extern OpFn ops_winchip_0f[1024];
extern const OpFn ops_winchip_0f[1024];
extern OpFn ops_pentium_0f[1024];
extern OpFn ops_pentiummmx_0f[1024];
extern const OpFn ops_pentium_0f[1024];
extern const OpFn ops_pentiummmx_0f[1024];
extern OpFn ops_c6x86mx_0f[1024];
extern const OpFn ops_c6x86mx_0f[1024];
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
extern OpFn ops_k6_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
extern const OpFn ops_k6_0f[1024];
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
extern OpFn ops_pentiumpro_0f[1024];
extern OpFn ops_pentium2d_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
extern const OpFn ops_pentiumpro_0f[1024];
extern const OpFn ops_pentium2d_0f[1024];
#endif
extern OpFn ops_fpu_287_d9_a16[256];
extern OpFn ops_fpu_287_d9_a32[256];
extern OpFn ops_fpu_287_da_a16[256];
extern OpFn ops_fpu_287_da_a32[256];
extern OpFn ops_fpu_287_db_a16[256];
extern OpFn ops_fpu_287_db_a32[256];
extern OpFn ops_fpu_287_dc_a16[32];
extern OpFn ops_fpu_287_dc_a32[32];
extern OpFn ops_fpu_287_dd_a16[256];
extern OpFn ops_fpu_287_dd_a32[256];
extern OpFn ops_fpu_287_de_a16[256];
extern OpFn ops_fpu_287_de_a32[256];
extern OpFn ops_fpu_287_df_a16[256];
extern OpFn ops_fpu_287_df_a32[256];
extern const OpFn ops_fpu_287_d9_a16[256];
extern const OpFn ops_fpu_287_d9_a32[256];
extern const OpFn ops_fpu_287_da_a16[256];
extern const OpFn ops_fpu_287_da_a32[256];
extern const OpFn ops_fpu_287_db_a16[256];
extern const OpFn ops_fpu_287_db_a32[256];
extern const OpFn ops_fpu_287_dc_a16[32];
extern const OpFn ops_fpu_287_dc_a32[32];
extern const OpFn ops_fpu_287_dd_a16[256];
extern const OpFn ops_fpu_287_dd_a32[256];
extern const OpFn ops_fpu_287_de_a16[256];
extern const OpFn ops_fpu_287_de_a32[256];
extern const OpFn ops_fpu_287_df_a16[256];
extern const OpFn ops_fpu_287_df_a32[256];
extern OpFn ops_fpu_d8_a16[32];
extern OpFn ops_fpu_d8_a32[32];
extern OpFn ops_fpu_d9_a16[256];
extern OpFn ops_fpu_d9_a32[256];
extern OpFn ops_fpu_da_a16[256];
extern OpFn ops_fpu_da_a32[256];
extern OpFn ops_fpu_db_a16[256];
extern OpFn ops_fpu_db_a32[256];
extern OpFn ops_fpu_dc_a16[32];
extern OpFn ops_fpu_dc_a32[32];
extern OpFn ops_fpu_dd_a16[256];
extern OpFn ops_fpu_dd_a32[256];
extern OpFn ops_fpu_de_a16[256];
extern OpFn ops_fpu_de_a32[256];
extern OpFn ops_fpu_df_a16[256];
extern OpFn ops_fpu_df_a32[256];
extern OpFn ops_nofpu_a16[256];
extern OpFn ops_nofpu_a32[256];
extern const OpFn ops_fpu_d8_a16[32];
extern const OpFn ops_fpu_d8_a32[32];
extern const OpFn ops_fpu_d9_a16[256];
extern const OpFn ops_fpu_d9_a32[256];
extern const OpFn ops_fpu_da_a16[256];
extern const OpFn ops_fpu_da_a32[256];
extern const OpFn ops_fpu_db_a16[256];
extern const OpFn ops_fpu_db_a32[256];
extern const OpFn ops_fpu_dc_a16[32];
extern const OpFn ops_fpu_dc_a32[32];
extern const OpFn ops_fpu_dd_a16[256];
extern const OpFn ops_fpu_dd_a32[256];
extern const OpFn ops_fpu_de_a16[256];
extern const OpFn ops_fpu_de_a32[256];
extern const OpFn ops_fpu_df_a16[256];
extern const OpFn ops_fpu_df_a32[256];
extern const OpFn ops_nofpu_a16[256];
extern const OpFn ops_nofpu_a32[256];
extern OpFn ops_fpu_686_da_a16[256];
extern OpFn ops_fpu_686_da_a32[256];
extern OpFn ops_fpu_686_db_a16[256];
extern OpFn ops_fpu_686_db_a32[256];
extern OpFn ops_fpu_686_df_a16[256];
extern OpFn ops_fpu_686_df_a32[256];
extern const OpFn ops_fpu_686_da_a16[256];
extern const OpFn ops_fpu_686_da_a32[256];
extern const OpFn ops_fpu_686_db_a16[256];
extern const OpFn ops_fpu_686_db_a32[256];
extern const OpFn ops_fpu_686_df_a16[256];
extern const OpFn ops_fpu_686_df_a32[256];
extern OpFn ops_REPE[1024];
extern OpFn ops_REPNE[1024];
extern const OpFn ops_REPE[1024];
extern const OpFn ops_REPNE[1024];
#endif /*_X86_OPS_H*/

View File

@@ -8,19 +8,12 @@
*
* AMD SYSCALL and SYSRET CPU Instructions.
*
* Version: @(#)x86_ops_amd.h 1.0.1 2018/01/01
* Version: @(#)x86_ops_amd.h 1.0.3 2018/04/25
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2018 Miran Grca.
*/
static int internal_illegal(char *s)
{
cpu_state.pc = cpu_state.oldpc;
x86gpf(s, 0);
return cpu_state.abrt;
}
/* 0 = Limit 0-15
1 = Base 0-15
2 = Base 16-23 (bits 0-7), Access rights

View File

@@ -8,7 +8,7 @@
*
* x86 i686 (Pentium Pro/Pentium II) CPU Instructions.
*
* Version: @(#)x86_ops_i686.h 1.0.2 2018/01/01
* Version: @(#)x86_ops_i686.h 1.0.4 2018/04/25
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2018 Miran Grca.

View File

@@ -8,12 +8,12 @@
*
* Miscellaneous x86 CPU Instructions.
*
* Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30
* Version: @(#)x86_ops_misc.h 1.0.1 2018/04/12
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
static int opCBW(uint32_t fetchdat)
@@ -70,6 +70,10 @@ static int opF6_a16(uint32_t fetchdat)
int8_t temps;
fetch_ea_16(fetchdat);
if (cpu_mod != 3)
{
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
}
dst = geteab(); if (cpu_state.abrt) return 1;
switch (rmdat & 0x38)
{
@@ -120,6 +124,7 @@ static int opF6_a16(uint32_t fetchdat)
{
flags_rebuild();
flags |= 0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -127,8 +132,8 @@ static int opF6_a16(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 16 : 14);
PREFETCH_RUN(is486 ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
case 0x38: /*IDIV AL,b*/
tempws = (int)(int16_t)AX;
@@ -142,6 +147,7 @@ static int opF6_a16(uint32_t fetchdat)
{
flags_rebuild();
flags|=0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -217,6 +223,7 @@ static int opF6_a32(uint32_t fetchdat)
{
flags_rebuild();
flags |= 0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -224,8 +231,8 @@ static int opF6_a32(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 16 : 14);
PREFETCH_RUN(is486 ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
case 0x38: /*IDIV AL,b*/
tempws = (int)(int16_t)AX;
@@ -239,6 +246,7 @@ static int opF6_a32(uint32_t fetchdat)
{
flags_rebuild();
flags|=0x8D5; /*Not a Cyrix*/
flags &= ~1;
}
}
else
@@ -323,8 +331,8 @@ static int opF7_w_a16(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 24 : 22);
PREFETCH_RUN(is486 ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
break;
case 0x38: /*IDIV AX,w*/
tempws = (int)((DX << 16)|AX);
@@ -415,8 +423,8 @@ static int opF7_w_a32(uint32_t fetchdat)
x86_int(0);
return 1;
}
CLOCK_CYCLES(is486 ? 24 : 22);
PREFETCH_RUN(is486 ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22);
PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
break;
case 0x38: /*IDIV AX,w*/
tempws = (int)((DX << 16)|AX);

View File

@@ -8,22 +8,25 @@
*
* x86 CPU segment emulation.
*
* Version: @(#)x86seg.c 1.0.6 2017/11/24
* Version: @(#)x86seg.c 1.0.7 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "../device.h"
#include "../machine/machine.h"
#include "../mem.h"
#include "../nvr.h"
@@ -57,7 +60,27 @@ void pmodeint(int num, int soft);
/*NOT PRESENT is INT 0B
GPF is INT 0D*/
FILE *pclogf;
#ifdef ENABLE_X86SEG_LOG
int x86seg_do_log = ENABLE_X86SEG_LOG;
#endif
static void
x86seg_log(const char *fmt, ...)
{
#ifdef ENABLE_X86SEG_LOG
va_list ap;
if (x86seg_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
void x86abort(const char *format, ...)
{
va_list ap;
@@ -377,8 +400,8 @@ void loadseg(uint16_t seg, x86seg *s)
}
else if (s!=&_cs)
{
if (output) pclog("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]);
if (output) pclog("Seg type %03X\n",segdat[2]&0x1F00);
x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]);
x86seg_log("Seg type %03X\n",segdat[2]&0x1F00);
switch ((segdat[2]>>8)&0x1F)
{
case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/
@@ -466,7 +489,7 @@ void loadcs(uint16_t seg)
{
uint16_t segdat[4];
uint32_t addr;
if (output) pclog("Load CS %04X\n",seg);
x86seg_log("Load CS %04X\n",seg);
if (msw&1 && !(eflags&VM_FLAG))
{
if (!(seg&~3))
@@ -600,7 +623,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
segdat[1]=readmemw(0,addr+2);
segdat[2]=readmemw(0,addr+4);
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
if (output) pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]);
x86seg_log("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]);
if (segdat[2]&0x1000) /*Normal code segment*/
{
if (!(segdat[2]&0x400)) /*Not conforming*/
@@ -863,7 +886,7 @@ void loadcscall(uint16_t seg)
if (msw&1 && !(eflags&VM_FLAG))
{
if (csout) pclog("Protected mode CS load! %04X\n",seg);
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
if (!(seg&~3))
{
x86gpf(NULL,0);
@@ -897,7 +920,7 @@ void loadcscall(uint16_t seg)
newpc=segdat[0];
if (type&0x800) newpc|=segdat[3]<<16;
if (csout) pclog("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
if (csout) x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
if (segdat[2]&0x1000)
{
if (!(segdat[2]&0x400)) /*Not conforming*/
@@ -942,18 +965,18 @@ void loadcscall(uint16_t seg)
CS=seg;
do_seg_load(&_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
if (csout) pclog("Complete\n");
if (csout) x86seg_log("Complete\n");
cycles -= timing_call_pm;
}
else
{
type=segdat[2]&0xF00;
if (csout) pclog("Type %03X\n",type);
if (csout) x86seg_log("Type %03X\n",type);
switch (type)
{
case 0x400: /*Call gate*/
case 0xC00: /*386 Call gate*/
if (output) pclog("Callgate %08X\n", cpu_state.pc);
x86seg_log("Callgate %08X\n", cpu_state.pc);
cgate32=(type&0x800);
cgate16=!cgate32;
oldcs=CS;
@@ -970,13 +993,13 @@ void loadcscall(uint16_t seg)
}
if (!(segdat[2]&0x8000))
{
if (output) pclog("Call gate not present %04X\n",seg);
x86seg_log("Call gate not present %04X\n",seg);
x86np("Call gate not present\n", seg & 0xfffc);
return;
}
seg2=segdat[1];
if (output) pclog("New address : %04X:%08X\n", seg2, newpc);
x86seg_log("New address : %04X:%08X\n", seg2, newpc);
if (!(seg2&~3))
{
@@ -1008,7 +1031,7 @@ void loadcscall(uint16_t seg)
segdat[2]=readmemw(0,addr+4);
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
if (output) pclog("Code seg2 call - %04X - %04X %04X %04X\n",seg2,segdat[0],segdat[1],segdat[2]);
x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n",seg2,segdat[0],segdat[1],segdat[2]);
if (DPL > CPL)
{
@@ -1017,7 +1040,7 @@ void loadcscall(uint16_t seg)
}
if (!(segdat[2]&0x8000))
{
if (output) pclog("Call gate CS not present %04X\n",seg2);
x86seg_log("Call gate CS not present %04X\n",seg2);
x86np("Call gate CS not present", seg2 & 0xfffc);
return;
}
@@ -1047,7 +1070,7 @@ void loadcscall(uint16_t seg)
}
cpl_override=0;
if (cpu_state.abrt) return;
if (output) pclog("New stack %04X:%08X\n",newss,newsp);
x86seg_log("New stack %04X:%08X\n",newss,newsp);
if (!(newss&~3))
{
x86ts(NULL,newss&~3);
@@ -1075,12 +1098,12 @@ void loadcscall(uint16_t seg)
addr+=gdt.base;
}
cpl_override=1;
if (output) pclog("Read stack seg\n");
x86seg_log("Read stack seg\n");
segdat2[0]=readmemw(0,addr);
segdat2[1]=readmemw(0,addr+2);
segdat2[2]=readmemw(0,addr+4);
segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
if (output) pclog("Read stack seg done!\n");
x86seg_log("Read stack seg done!\n");
if (((newss & 3) != DPL) || (DPL2 != DPL))
{
x86ts(NULL,newss&~3);
@@ -1104,7 +1127,7 @@ void loadcscall(uint16_t seg)
do_seg_load(&_ss, segdat2);
if (output) pclog("Set access 1\n");
x86seg_log("Set access 1\n");
#ifdef SEL_ACCESSED
cpl_override = 1;
@@ -1118,7 +1141,7 @@ void loadcscall(uint16_t seg)
set_use32(segdat[3]&0x40);
cpu_state.pc=newpc;
if (output) pclog("Set access 2\n");
x86seg_log("Set access 2\n");
#ifdef CS_ACCESSED
cpl_override = 1;
@@ -1126,7 +1149,7 @@ void loadcscall(uint16_t seg)
cpl_override = 0;
#endif
if (output) pclog("Type %04X\n",type);
x86seg_log("Type %04X\n",type);
if (type==0xC00)
{
PUSHL(oldss);
@@ -1154,9 +1177,9 @@ void loadcscall(uint16_t seg)
}
else
{
if (output) pclog("Stack %04X\n",SP);
x86seg_log("Stack %04X\n",SP);
PUSHW(oldss);
if (output) pclog("Write SS to %04X:%04X\n",SS,SP);
x86seg_log("Write SS to %04X:%04X\n",SS,SP);
PUSHW(oldsp2);
if (cpu_state.abrt)
{
@@ -1164,14 +1187,14 @@ void loadcscall(uint16_t seg)
ESP = oldsp2;
return;
}
if (output) pclog("Write SP to %04X:%04X\n",SS,SP);
x86seg_log("Write SP to %04X:%04X\n",SS,SP);
if (count)
{
while (count)
{
count--;
tempw=readmemw(oldssbase,(oldsp&0xFFFF)+(count*2));
if (output) pclog("PUSH %04X\n",tempw);
x86seg_log("PUSH %04X\n",tempw);
PUSHW(tempw);
if (cpu_state.abrt)
{
@@ -1245,7 +1268,7 @@ void pmoderetf(int is32, uint16_t off)
uint32_t addr, oaddr;
uint16_t segdat[4],segdat2[4],seg,newss;
uint32_t oldsp=ESP;
if (output) pclog("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,eflags);
x86seg_log("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,eflags);
if (is32)
{
newpc=POPL();
@@ -1253,12 +1276,12 @@ void pmoderetf(int is32, uint16_t off)
}
else
{
if (output) pclog("PC read from %04X:%04X\n",SS,SP);
x86seg_log("PC read from %04X:%04X\n",SS,SP);
newpc=POPW();
if (output) pclog("CS read from %04X:%04X\n",SS,SP);
x86seg_log("CS read from %04X:%04X\n",SS,SP);
seg=POPW(); if (cpu_state.abrt) return;
}
if (output) pclog("Return to %04X:%08X\n",seg,newpc);
x86seg_log("Return to %04X:%08X\n",seg,newpc);
if ((seg&3)<CPL)
{
ESP=oldsp;
@@ -1296,14 +1319,14 @@ void pmoderetf(int is32, uint16_t off)
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; }
oaddr = addr;
if (output) pclog("CPL %i RPL %i %i\n",CPL,seg&3,is32);
x86seg_log("CPL %i RPL %i %i\n",CPL,seg&3,is32);
if (stack32) ESP+=off;
else SP+=off;
if (CPL==(seg&3))
{
if (output) pclog("RETF CPL = RPL %04X\n", segdat[2]);
x86seg_log("RETF CPL = RPL %04X\n", segdat[2]);
switch (segdat[2]&0x1F00)
{
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
@@ -1361,7 +1384,7 @@ void pmoderetf(int is32, uint16_t off)
x86gpf(NULL,seg&~3);
return;
}
if (output) pclog("RETF non-conforming, %i %i\n",seg&3, DPL);
x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL);
break;
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
if ((seg&3) < DPL)
@@ -1370,7 +1393,7 @@ void pmoderetf(int is32, uint16_t off)
x86gpf(NULL,seg&~3);
return;
}
if (output) pclog("RETF conforming, %i %i\n",seg&3, DPL);
x86seg_log("RETF conforming, %i %i\n",seg&3, DPL);
break;
default:
ESP=oldsp;
@@ -1390,12 +1413,12 @@ void pmoderetf(int is32, uint16_t off)
}
else
{
if (output) pclog("SP read from %04X:%04X\n",SS,SP);
x86seg_log("SP read from %04X:%04X\n",SS,SP);
newsp=POPW();
if (output) pclog("SS read from %04X:%04X\n",SS,SP);
x86seg_log("SS read from %04X:%04X\n",SS,SP);
newss=POPW(); if (cpu_state.abrt) return;
}
if (output) pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base);
x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base);
if (!(newss&~3))
{
ESP=oldsp;
@@ -1428,7 +1451,7 @@ void pmoderetf(int is32, uint16_t off)
segdat2[1]=readmemw(0,addr+2);
segdat2[2]=readmemw(0,addr+4);
segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; }
if (output) pclog("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]);
x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]);
if ((newss & 3) != (seg & 3))
{
ESP=oldsp;
@@ -1507,7 +1530,7 @@ void pmodeint(int num, int soft)
if (eflags&VM_FLAG && IOPL!=3 && soft)
{
if (output) pclog("V86 banned int\n");
x86seg_log("V86 banned int\n");
x86gpf(NULL,0);
return;
}
@@ -1528,7 +1551,7 @@ void pmodeint(int num, int soft)
{
x86gpf(NULL,(num*8)+2+((soft)?0:1));
}
if (output) pclog("addr >= IDT.limit\n");
x86seg_log("addr >= IDT.limit\n");
return;
}
addr+=idt.base;
@@ -1536,10 +1559,10 @@ void pmodeint(int num, int soft)
segdat[0]=readmemw(0,addr);
segdat[1]=readmemw(2,addr);
segdat[2]=readmemw(4,addr);
segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* pclog("Abrt reading from %08X\n",addr); */ return; }
segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* x86seg_log("Abrt reading from %08X\n",addr); */ return; }
oaddr = addr;
if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
x86seg_log("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
if (!(segdat[2]&0x1F00))
{
x86gpf(NULL,(num*8)+2);
@@ -1682,7 +1705,7 @@ void pmodeint(int num, int soft)
cpl_override = 0;
#endif
if (output) pclog("New stack %04X:%08X\n",SS,ESP);
x86seg_log("New stack %04X:%08X\n",SS,ESP);
cpl_override=1;
if (type>=0x800)
{
@@ -1867,7 +1890,7 @@ void pmodeiret(int is32)
addr=seg&~7;
if (seg&4)
{
pclog("TS LDT %04X %04X IRET\n",seg,gdt.limit);
x86seg_log("TS LDT %04X %04X IRET\n",seg,gdt.limit);
x86ts(NULL,seg&~3);
return;
}
@@ -2031,7 +2054,7 @@ void pmodeiret(int is32)
else /*Return to outer level*/
{
oaddr = addr;
if (output) pclog("Outer level\n");
x86seg_log("Outer level\n");
if (is32)
{
newsp=POPL();
@@ -2043,7 +2066,7 @@ void pmodeiret(int is32)
newss=POPW(); if (cpu_state.abrt) { ESP = oldsp; return; }
}
if (output) pclog("IRET load stack %04X:%04X\n",newss,newsp);
x86seg_log("IRET load stack %04X:%04X\n",newss,newsp);
if (!(newss&~3))
{

View File

@@ -1,25 +1,48 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the 86Box distribution.
* This file is part of the VARCem Project.
*
* x87 FPU instructions core.
*
* Version: @(#)x87_ops.h 1.0.1 2017/10/28
* Version: @(#)x87_ops.h 1.0.5 2018/05/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 leilei.
* Copyright 2016,2017 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include <math.h>
#include <fenv.h>
#ifdef _MSC_VER
# include <intrin.h>
#endif
#define fplog 0
@@ -80,6 +103,21 @@ static __inline void x87_push(double i)
cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0;
}
static inline void x87_push_u64(uint64_t i)
{
union
{
double d;
uint64_t ll;
} td;
td.ll = i;
cpu_state.TOP=(cpu_state.TOP-1)&7;
cpu_state.ST[cpu_state.TOP] = td.d;
cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0;
}
static __inline double x87_pop()
{
double t = cpu_state.ST[cpu_state.TOP];
@@ -193,7 +231,7 @@ static __inline void x87_st80(double d)
test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final;
test.eind.ll = mant80final;
writememl(easeg,cpu_state.eaaddr,test.eind.ll);
writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff);
writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32);
writememw(easeg,cpu_state.eaaddr+8,test.begin);
}
@@ -245,14 +283,14 @@ static __inline void x87_stmmx(MMX_REG r)
static __inline uint16_t x87_compare(double a, double b)
{
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32
uint32_t out;
uint32_t result;
if (!is386)
{
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
{
/* pclog("Comparing infinity\n"); */
#ifndef _MSC_VER
__asm volatile ("" : : : "memory");
__asm(
@@ -261,14 +299,26 @@ static __inline uint16_t x87_compare(double a, double b)
"fclex\n"
"fcompp\n"
"fnstsw %0\n"
: "=m" (out)
: "=m" (result)
: "m" (a), "m" (a)
);
#else
_ReadWriteBarrier();
__asm
{
fld a
fld a
fclex
fcompp
fnstsw result
}
#endif
return out & (C0|C2|C3);
return result & (C0|C2|C3);
}
}
#ifndef _MSC_VER
/* Memory barrier, to force GCC to write to the input parameters
* before the compare rather than after */
__asm volatile ("" : : : "memory");
@@ -279,11 +329,22 @@ static __inline uint16_t x87_compare(double a, double b)
"fclex\n"
"fcompp\n"
"fnstsw %0\n"
: "=m" (out)
: "=m" (result)
: "m" (a), "m" (b)
);
#else
_ReadWriteBarrier();
_asm
{
fld b
fld a
fclex
fcompp
fnstsw result
}
#endif
return out & (C0|C2|C3);
return result & (C0|C2|C3);
#else
/* Generic C version is known to give incorrect results in some
* situations, eg comparison of infinity (Unreal) */
@@ -293,32 +354,33 @@ static __inline uint16_t x87_compare(double a, double b)
{
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
{
out |= C3;
return out;
result |= C3;
return result;
}
if (a == b)
out |= C3;
result |= C3;
else if (a < b)
out |= C0;
result |= C0;
}
else
{
if (a == b)
out |= C3;
result |= C3;
else if (a < b)
out |= C0;
result |= C0;
}
return out;
return result;
#endif
}
static __inline uint16_t x87_ucompare(double a, double b)
{
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32
uint32_t out;
uint32_t result;
#ifndef _MSC_VER
/* Memory barrier, to force GCC to write to the input parameters
* before the compare rather than after */
__asm volatile ("" : : : "memory");
@@ -329,22 +391,33 @@ static __inline uint16_t x87_ucompare(double a, double b)
"fclex\n"
"fucompp\n"
"fnstsw %0\n"
: "=m" (out)
: "=m" (result)
: "m" (a), "m" (b)
);
#else
_ReadWriteBarrier();
_asm
{
fld b
fld a
fclex
fcompp
fnstsw result
}
#endif
return out & (C0|C2|C3);
return result & (C0|C2|C3);
#else
/* Generic C version is known to give incorrect results in some
* situations, eg comparison of infinity (Unreal) */
uint32_t out = 0;
uint32_t result = 0;
if (a == b)
out |= C3;
result |= C3;
else if (a < b)
out |= C0;
result |= C0;
return out;
return result;
#endif
}
@@ -420,14 +493,14 @@ static int FPU_ILLEGAL_a32(uint32_t fetchdat)
#define ILLEGAL_a16 FPU_ILLEGAL_a16
#define ILLEGAL_a32 FPU_ILLEGAL_a32
OpFn OP_TABLE(fpu_d8_a16)[32] =
const OpFn OP_TABLE(fpu_d8_a16)[32] =
{
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR
};
OpFn OP_TABLE(fpu_d8_a32)[32] =
const OpFn OP_TABLE(fpu_d8_a32)[32] =
{
opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32,
opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32,
@@ -435,7 +508,7 @@ OpFn OP_TABLE(fpu_d8_a32)[32] =
opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR
};
OpFn OP_TABLE(fpu_287_d9_a16)[256] =
const OpFn OP_TABLE(fpu_287_d9_a16)[256] =
{
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -474,7 +547,7 @@ OpFn OP_TABLE(fpu_287_d9_a16)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_287_d9_a32)[256] =
const OpFn OP_TABLE(fpu_287_d9_a32)[256] =
{
opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -513,7 +586,7 @@ OpFn OP_TABLE(fpu_287_d9_a32)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_d9_a16)[256] =
const OpFn OP_TABLE(fpu_d9_a16)[256] =
{
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -552,7 +625,7 @@ OpFn OP_TABLE(fpu_d9_a16)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_d9_a32)[256] =
const OpFn OP_TABLE(fpu_d9_a32)[256] =
{
opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -591,7 +664,7 @@ OpFn OP_TABLE(fpu_d9_a32)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_287_da_a16)[256] =
const OpFn OP_TABLE(fpu_287_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
@@ -629,7 +702,7 @@ OpFn OP_TABLE(fpu_287_da_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_da_a32)[256] =
const OpFn OP_TABLE(fpu_287_da_a32)[256] =
{
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
@@ -668,7 +741,7 @@ OpFn OP_TABLE(fpu_287_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_da_a16)[256] =
const OpFn OP_TABLE(fpu_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
@@ -706,7 +779,7 @@ OpFn OP_TABLE(fpu_da_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_da_a32)[256] =
const OpFn OP_TABLE(fpu_da_a32)[256] =
{
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
@@ -745,7 +818,7 @@ OpFn OP_TABLE(fpu_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_686_da_a16)[256] =
const OpFn OP_TABLE(fpu_686_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
@@ -783,7 +856,7 @@ OpFn OP_TABLE(fpu_686_da_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_686_da_a32)[256] =
const OpFn OP_TABLE(fpu_686_da_a32)[256] =
{
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
@@ -822,7 +895,7 @@ OpFn OP_TABLE(fpu_686_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_287_db_a16)[256] =
const OpFn OP_TABLE(fpu_287_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -860,7 +933,7 @@ OpFn OP_TABLE(fpu_287_db_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_db_a32)[256] =
const OpFn OP_TABLE(fpu_287_db_a32)[256] =
{
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -899,7 +972,7 @@ OpFn OP_TABLE(fpu_287_db_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_db_a16)[256] =
const OpFn OP_TABLE(fpu_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -937,7 +1010,7 @@ OpFn OP_TABLE(fpu_db_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_db_a32)[256] =
const OpFn OP_TABLE(fpu_db_a32)[256] =
{
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -976,7 +1049,7 @@ OpFn OP_TABLE(fpu_db_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_686_db_a16)[256] =
const OpFn OP_TABLE(fpu_686_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1014,7 +1087,7 @@ OpFn OP_TABLE(fpu_686_db_a16)[256] =
opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_686_db_a32)[256] =
const OpFn OP_TABLE(fpu_686_db_a32)[256] =
{
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1053,14 +1126,14 @@ OpFn OP_TABLE(fpu_686_db_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_287_dc_a16)[32] =
const OpFn OP_TABLE(fpu_287_dc_a16)[32] =
{
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_287_dc_a32)[32] =
const OpFn OP_TABLE(fpu_287_dc_a32)[32] =
{
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
@@ -1068,14 +1141,14 @@ OpFn OP_TABLE(fpu_287_dc_a32)[32] =
opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_dc_a16)[32] =
const OpFn OP_TABLE(fpu_dc_a16)[32] =
{
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_dc_a32)[32] =
const OpFn OP_TABLE(fpu_dc_a32)[32] =
{
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
@@ -1083,7 +1156,7 @@ OpFn OP_TABLE(fpu_dc_a32)[32] =
opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_287_dd_a16)[256] =
const OpFn OP_TABLE(fpu_287_dd_a16)[256] =
{
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1121,7 +1194,7 @@ OpFn OP_TABLE(fpu_287_dd_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_dd_a32)[256] =
const OpFn OP_TABLE(fpu_287_dd_a32)[256] =
{
opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1160,7 +1233,7 @@ OpFn OP_TABLE(fpu_287_dd_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_dd_a16)[256] =
const OpFn OP_TABLE(fpu_dd_a16)[256] =
{
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1198,7 +1271,7 @@ OpFn OP_TABLE(fpu_dd_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_dd_a32)[256] =
const OpFn OP_TABLE(fpu_dd_a32)[256] =
{
opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1237,7 +1310,7 @@ OpFn OP_TABLE(fpu_dd_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_287_de_a16)[256] =
const OpFn OP_TABLE(fpu_287_de_a16)[256] =
{
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
@@ -1276,7 +1349,7 @@ OpFn OP_TABLE(fpu_287_de_a16)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_287_de_a32)[256] =
const OpFn OP_TABLE(fpu_287_de_a32)[256] =
{
opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32,
opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32,
@@ -1315,7 +1388,7 @@ OpFn OP_TABLE(fpu_287_de_a32)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_de_a16)[256] =
const OpFn OP_TABLE(fpu_de_a16)[256] =
{
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
@@ -1354,7 +1427,7 @@ OpFn OP_TABLE(fpu_de_a16)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_de_a32)[256] =
const OpFn OP_TABLE(fpu_de_a32)[256] =
{
opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32,
opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32,
@@ -1393,7 +1466,7 @@ OpFn OP_TABLE(fpu_de_a32)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_287_df_a16)[256] =
const OpFn OP_TABLE(fpu_287_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1431,7 +1504,7 @@ OpFn OP_TABLE(fpu_287_df_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_df_a32)[256] =
const OpFn OP_TABLE(fpu_287_df_a32)[256] =
{
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1470,7 +1543,7 @@ OpFn OP_TABLE(fpu_287_df_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_df_a16)[256] =
const OpFn OP_TABLE(fpu_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1508,7 +1581,7 @@ OpFn OP_TABLE(fpu_df_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_df_a32)[256] =
const OpFn OP_TABLE(fpu_df_a32)[256] =
{
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1547,7 +1620,7 @@ OpFn OP_TABLE(fpu_df_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_686_df_a16)[256] =
const OpFn OP_TABLE(fpu_686_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1585,7 +1658,7 @@ OpFn OP_TABLE(fpu_686_df_a16)[256] =
opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_686_df_a32)[256] =
const OpFn OP_TABLE(fpu_686_df_a32)[256] =
{
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1624,7 +1697,7 @@ OpFn OP_TABLE(fpu_686_df_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(nofpu_a16)[256] =
const OpFn OP_TABLE(nofpu_a16)[256] =
{
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
@@ -1662,7 +1735,7 @@ OpFn OP_TABLE(nofpu_a16)[256] =
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
};
OpFn OP_TABLE(nofpu_a32)[256] =
const OpFn OP_TABLE(nofpu_a32)[256] =
{
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,

View File

@@ -478,7 +478,7 @@ static int opFLDLN2(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
if (fplog) pclog("FLDLN2\n");
x87_push(0.693147180559945);
x87_push_u64(0x3fe62e42fefa39f0ull);
CLOCK_CYCLES(8);
return 0;
}

View File

@@ -9,7 +9,7 @@
* Implementation of the generic device interface to handle
* all devices attached to the emulator.
*
* Version: @(#)device.c 1.0.5 2018/03/18
* Version: @(#)device.c 1.0.8 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -37,10 +37,12 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "86box.h"
#include "cpu/cpu.h"
#include "config.h"
@@ -57,6 +59,26 @@ static device_t *devices[DEVICE_MAX];
static device_t *device_current;
#ifdef ENABLE_DEVICE_LOG
int device_do_log = ENABLE_DEVICE_LOG;
#endif
static void
device_log(const char *format, ...)
{
#ifdef ENABLE_DEVICE_LOG
va_list ap;
if (device_do_log) {
va_start(ap, format);
pclog_ex(format, ap);
va_end(ap);
}
#endif
}
void
device_init(void)
{
@@ -72,7 +94,7 @@ device_add(const device_t *d)
for (c=0; c<256; c++) {
if (devices[c] == (device_t *)d) {
pclog("DEVICE: device already exists!\n");
device_log("DEVICE: device already exists!\n");
return(NULL);
}
if (devices[c] == NULL) break;
@@ -82,18 +104,22 @@ device_add(const device_t *d)
device_current = (device_t *)d;
devices[c] = (device_t *)d;
if (d->init != NULL) {
priv = d->init(d);
if (priv == NULL) {
if (d->name)
pclog("DEVICE: device '%s' init failed\n", d->name);
else
pclog("DEVICE: device init failed\n");
device_log("DEVICE: device '%s' init failed\n", d->name);
else
device_log("DEVICE: device init failed\n");
device_priv[c] = NULL;
return(NULL);
}
}
devices[c] = (device_t *)d;
device_priv[c] = priv;
return(priv);
@@ -152,6 +178,21 @@ device_reset_all(void)
}
/* Reset all attached PCI devices - needed for PCI turbo reset control. */
void
device_reset_all_pci(void)
{
int c;
for (c=0; c<DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if ((devices[c]->reset != NULL) && (devices[c]->flags & DEVICE_PCI))
devices[c]->reset(device_priv[c]);
}
}
}
void *
device_get_priv(const device_t *d)
{
@@ -211,20 +252,6 @@ device_force_redraw(void)
}
void
device_add_status_info(char *s, int max_len)
{
int c;
for (c=0; c<DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if (devices[c]->add_status_info != NULL)
devices[c]->add_status_info(s, max_len, device_priv[c]);
}
}
}
char *
device_get_config_string(char *s)
{

View File

@@ -8,7 +8,7 @@
*
* Definitions for the device handler.
*
* Version: @(#)device.h 1.0.3 2018/03/15
* Version: @(#)device.h 1.0.5 2018/04/26
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -104,7 +104,6 @@ typedef struct _device_ {
int (*available)(/*void*/);
void (*speed_changed)(void *p);
void (*force_redraw)(void *p);
void (*add_status_info)(char *s, int max_len, void *p);
const device_config_t *config;
} device_t;
@@ -119,11 +118,11 @@ extern void *device_add(const device_t *d);
extern void device_add_ex(const device_t *d, void *priv);
extern void device_close_all(void);
extern void device_reset_all(void);
extern void device_reset_all_pci(void);
extern void *device_get_priv(const device_t *d);
extern int device_available(const device_t *d);
extern void device_speed_changed(void);
extern void device_force_redraw(void);
extern void device_add_status_info(char *s, int max_len);
extern int device_get_config_int(char *name);
extern int device_get_config_int_ex(char *s, int default_int);

View File

@@ -8,7 +8,7 @@
*
* Common code to handle all sorts of disk controllers.
*
* Version: @(#)hdc.c 1.0.12 2018/03/19
* Version: @(#)hdc.c 1.0.15 2018/04/29
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -16,21 +16,44 @@
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../machine/machine.h"
#include "../device.h"
#include "hdc.h"
#include "hdc_ide.h"
#include "hdd.h"
char *hdc_name; /* configured HDC name */
int hdc_current;
#ifdef ENABLE_HDC_LOG
int hdc_do_log = ENABLE_HDC_LOG;
#endif
static void
hdc_log(const char *fmt, ...)
{
#ifdef ENABLE_HDC_LOG
va_list ap;
if (hdc_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static void *
null_init(const device_t *info)
{
@@ -47,7 +70,7 @@ null_close(void *priv)
static const device_t null_device = {
"Null HDC", 0, 0,
null_init, null_close, NULL,
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
};
@@ -67,7 +90,7 @@ inthdc_close(void *priv)
static const device_t inthdc_device = {
"Internal Controller", 0, 0,
inthdc_init, inthdc_close, NULL,
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
};
@@ -106,6 +129,9 @@ static const struct {
{ "[ISA] [IDE] PS/2 AT XTIDE (1.1.5)", "xtide_at_ps2",
&xtide_at_ps2_device },
{ "[ISA] [IDE] WDXT-150 IDE (XTA) Adapter", "xta_wdxt150",
&xta_wdxt150_device },
{ "[ISA] [XT IDE] Acculogic XT IDE", "xtide_acculogic",
&xtide_acculogic_device },
@@ -138,7 +164,7 @@ hdc_init(char *name)
{
int c;
pclog("HDC: initializing..\n");
hdc_log("HDC: initializing..\n");
for (c = 0; controllers[c].device; c++) {
if (! strcmp(name, (char *) controllers[c].internal_name)) {
@@ -146,6 +172,9 @@ hdc_init(char *name)
break;
}
}
/* Zero all the hard disk image arrays. */
hdd_image_init();
}
@@ -153,21 +182,18 @@ hdc_init(char *name)
void
hdc_reset(void)
{
pclog("HDC: reset(current=%d, internal=%d)\n",
hdc_current, (machines[machine].flags & MACHINE_HDC)?1:0);
hdc_log("HDC: reset(current=%d, internal=%d)\n",
hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0);
/* If we have a valid controller, add its device. */
if (hdc_current > 1)
device_add(controllers[hdc_current].device);
/* Reconfire and reset the IDE layer. */
ide_ter_disable();
ide_qua_disable();
if (ide_enable[2])
ide_ter_init();
if (ide_enable[3])
ide_qua_init();
ide_reset_hard();
/* Now, add the tertiary and/or quaternary IDE controllers. */
if (ide_ter_enabled)
device_add(&ide_ter_device);
if (ide_qua_enabled)
device_add(&ide_qua_device);
}
@@ -185,6 +211,22 @@ hdc_get_internal_name(int hdc)
}
int
hdc_get_from_internal_name(char *s)
{
int c = 0;
while (strlen((char *) controllers[c].internal_name))
{
if (!strcmp((char *) controllers[c].internal_name, s))
return c;
c++;
}
return 0;
}
const device_t *
hdc_get_device(int hdc)
{
@@ -192,6 +234,19 @@ hdc_get_device(int hdc)
}
int
hdc_has_config(int hdc)
{
const device_t *dev = hdc_get_device(hdc);
if (dev == NULL) return(0);
if (dev->config == NULL) return(0);
return(1);
}
int
hdc_get_flags(int hdc)
{

View File

@@ -8,7 +8,7 @@
*
* Definitions for the common disk controller handler.
*
* Version: @(#)hdc.h 1.0.7 2018/03/19
* Version: @(#)hdc.h 1.0.8 2018/04/05
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -22,7 +22,7 @@
#define MFM_NUM 2 /* 2 drives per controller supported */
#define ESDI_NUM 2 /* 2 drives per controller supported */
#define XTIDE_NUM 2 /* 2 drives per controller supported */
#define XTA_NUM 2 /* 2 drives per controller supported */
#define IDE_NUM 8
#define SCSI_NUM 16 /* theoretically the controller can have at
* least 7 devices, with each device being
@@ -47,6 +47,12 @@ extern const device_t ide_vlb_2ch_device; /* vlb_ide_2ch */
extern const device_t ide_pci_device; /* pci_ide */
extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */
extern const device_t ide_ter_device;
extern const device_t ide_qua_device;
extern const device_t xta_wdxt150_device; /* xta_wdxt150 */
extern const device_t xta_hd20_device; /* EuroPC internal */
extern const device_t xtide_device; /* xtide_xt */
extern const device_t xtide_at_device; /* xtide_at */
extern const device_t xtide_acculogic_device; /* xtide_ps2 */
@@ -58,6 +64,8 @@ extern void hdc_reset(void);
extern char *hdc_get_name(int hdc);
extern char *hdc_get_internal_name(int hdc);
extern int hdc_get_from_internal_name(char *s);
extern int hdc_has_config(int hdc);
extern const device_t *hdc_get_device(int hdc);
extern int hdc_get_flags(int hdc);
extern int hdc_available(int hdc);

View File

@@ -8,7 +8,7 @@
*
* Driver for the ESDI controller (WD1007-vse1) for PC/AT.
*
* Version: @(#)hdc_esdi_at.c 1.0.9 2018/03/18
* Version: @(#)hdc_esdi_at.c 1.0.13 2018/05/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -21,11 +21,13 @@
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _GNU_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../device.h"
#include "../io.h"
@@ -104,33 +106,43 @@ typedef struct {
} esdi_t;
static __inline void irq_raise(esdi_t *esdi)
{
/* If not already pending.. */
if (! esdi->irqstat) {
/* If enabled in the control register.. */
if (! (esdi->fdisk & 0x02)) {
/* .. raise IRQ14. */
picint(1<<14);
}
#ifdef ENABLE_ESDI_AT_LOG
int esdi_at_do_log = ENABLE_ESDI_AT_LOG;
#endif
/* Remember this. */
esdi->irqstat = 1;
static void
esdi_at_log(const char *fmt, ...)
{
#ifdef ENABLE_ESDI_AT_LOG
va_list ap;
if (esdi_at_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static __inline void irq_lower(esdi_t *esdi)
static inline void
irq_raise(esdi_t *esdi)
{
/* If raised.. */
if (esdi->irqstat) {
/* If enabled in the control register.. */
if (! (esdi->fdisk & 0x02)) {
/* .. drop IRQ14. */
picintc(1<<14);
}
if (!(esdi->fdisk & 2))
picint(1 << 14);
esdi->irqstat = 1;
}
static inline void
irq_lower(esdi_t *esdi)
{
if (esdi->irqstat) {
if (!(esdi->fdisk & 2))
picintc(1 << 14);
/* Remember this. */
esdi->irqstat = 0;
}
}
@@ -146,12 +158,12 @@ get_sector(esdi_t *esdi, off64_t *addr)
int c, h, s;
if (esdi->head > heads) {
pclog("esdi_get_sector: past end of configured heads\n");
esdi_at_log("esdi_get_sector: past end of configured heads\n");
return(1);
}
if (esdi->sector >= sectors+1) {
pclog("esdi_get_sector: past end of configured sectors\n");
esdi_at_log("esdi_get_sector: past end of configured sectors\n");
return(1);
}
@@ -209,7 +221,8 @@ esdi_writew(uint16_t port, uint16_t val, void *priv)
esdi->pos = 0;
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 6LL*HDC_TIME;
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
esdi->callback = (3125LL * TIMER_USEC) / 8LL;
timer_update_outstanding();
}
}
@@ -220,9 +233,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
{
esdi_t *esdi = (esdi_t *)priv;
#ifdef ENABLE_HDD_LOG
pclog("WD1007 write(%04x, %02x)\n", port, val);
#endif
esdi_at_log("WD1007 write(%04x, %02x)\n", port, val);
switch (port) {
case 0x1f0: /* data */
@@ -264,9 +275,8 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
esdi->command = val;
esdi->error = 0;
#ifdef ENABLE_HDD_LOG
pclog("WD1007: command %02x\n", val & 0xf0);
#endif
esdi_at_log("WD1007: command %02x\n", val & 0xf0);
switch (val & 0xf0) {
case CMD_RESTORE:
esdi->command &= ~0x0f; /*mask off step rate*/
@@ -356,7 +366,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
break;
default:
pclog("WD1007: bad command %02X\n", val);
esdi_at_log("WD1007: bad command %02X\n", val);
case 0xe8: /*???*/
esdi->status = STAT_BUSY;
timer_clock();
@@ -384,6 +394,9 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
esdi->status = STAT_BUSY;
}
esdi->fdisk = val;
/* Lower IRQ on IRQ disable. */
if ((val & 2) && !(esdi->fdisk & 0x02))
picintc(1 << 14);
break;
}
}
@@ -407,7 +420,8 @@ esdi_readw(uint16_t port, void *priv)
next_sector(esdi);
esdi->status = STAT_BUSY;
timer_clock();
esdi->callback = 6LL*HDC_TIME;
/* 390.625 us per sector at 10 Mbit/s = 1280 kB/s. */
esdi->callback = (3125LL * TIMER_USEC) / 8LL;
timer_update_outstanding();
} else {
ui_sb_update_icon(SB_HDD|HDD_BUS_ESDI, 0);
@@ -460,9 +474,7 @@ esdi_read(uint16_t port, void *priv)
break;
}
#ifdef ENABLE_HDD_LOG
pclog("WD1007 read(%04x) = %02x\n", port, temp);
#endif
esdi_at_log("WD1007 read(%04x) = %02x\n", port, temp);
return(temp);
}
@@ -490,9 +502,7 @@ esdi_callback(void *priv)
return;
}
#ifdef ENABLE_HDD_LOG
pclog("WD1007: command %02x\n", esdi->command);
#endif
esdi_at_log("WD1007: command %02x\n", esdi->command);
switch (esdi->command) {
case CMD_RESTORE:
@@ -638,9 +648,9 @@ esdi_callback(void *priv)
drive->cfg_spt = esdi->secount;
drive->cfg_hpc = esdi->head+1;
#ifdef ENABLE_HDD_LOG
pclog("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
#endif
esdi_at_log("WD1007: parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc);
if (! esdi->secount)
fatal("WD1007: secount=0\n");
esdi->status = STAT_READY|STAT_DSC;
@@ -679,7 +689,7 @@ esdi_callback(void *priv)
break;
default:
pclog("WD1007: bad read config %02x\n",
esdi_at_log("WD1007: bad read config %02x\n",
esdi->cylinder >> 8);
}
esdi->status = STAT_READY|STAT_DSC;
@@ -736,7 +746,7 @@ esdi_callback(void *priv)
break;
default:
pclog("WD1007: callback on unknown command %02x\n", esdi->command);
esdi_at_log("WD1007: callback on unknown command %02x\n", esdi->command);
/*FALLTHROUGH*/
case 0xe8:
@@ -756,7 +766,7 @@ loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn)
drive_t *drive = &esdi->drives[hdd_num];
if (! hdd_image_load(d)) {
pclog("WD1007: drive %d not present!\n", d);
esdi_at_log("WD1007: drive %d not present!\n", d);
drive->present = 0;
return;
}
@@ -841,6 +851,6 @@ const device_t esdi_at_wd1007vse1_device = {
0,
wd1007vse1_init, wd1007vse1_close, NULL,
wd1007vse1_available,
NULL, NULL, NULL,
NULL, NULL,
NULL
};

View File

@@ -52,7 +52,7 @@
* however, are auto-configured by the system software as
* shown above.
*
* Version: @(#)hdc_esdi_mca.c 1.0.9 2018/03/18
* Version: @(#)hdc_esdi_mca.c 1.0.13 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -60,11 +60,13 @@
* Copyright 2008-2018 Sarah Walker.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../device.h"
#include "../dma.h"
@@ -101,8 +103,6 @@ typedef struct esdi_drive {
} drive_t;
typedef struct esdi {
uint16_t base;
int8_t irq;
int8_t dma;
uint32_t bios;
@@ -190,21 +190,42 @@ typedef struct esdi {
#define CMD_GET_POS_INFO 0x0a
#define STATUS_LEN(x) ((x) << 8)
#define STATUS_DEVICE(x) ((x) << 5)
#define STATUS_DEVICE_HOST_ADAPTER (7 << 5)
#ifdef ENABLE_ESDI_MCA_LOG
int esdi_mca_do_log = ENABLE_ESDI_MCA_LOG;
#endif
static void
esdi_mca_log(const char *fmt, ...)
{
#ifdef ENABLE_ESDI_MCA_LOG
va_list ap;
if (esdi_mca_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static __inline void
set_irq(esdi_t *dev)
{
if (dev->basic_ctrl & CTRL_IRQ_ENA)
picint(1 << dev->irq);
picint(1 << 14);
}
static __inline void
clear_irq(esdi_t *dev)
{
picintc(1 << dev->irq);
picintc(1 << 14);
}
@@ -250,23 +271,42 @@ device_not_present(esdi_t *dev)
set_irq(dev);
}
static void rba_out_of_range(esdi_t *dev)
{
dev->status_len = 9;
dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev;
dev->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/
dev->status_data[2] = 0x0007; /*RBA out of range*/
dev->status_data[3] = 0;
dev->status_data[4] = 0;
dev->status_data[5] = 0;
dev->status_data[6] = 0;
dev->status_data[7] = 0;
dev->status_data[8] = 0;
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE;
dev->irq_in_progress = 1;
set_irq(dev);
static void
rba_out_of_range(esdi_t *dev)
{
dev->status_len = 9;
dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev;
dev->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/
dev->status_data[2] = 0x0007; /*RBA out of range*/
dev->status_data[3] = 0;
dev->status_data[4] = 0;
dev->status_data[5] = 0;
dev->status_data[6] = 0;
dev->status_data[7] = 0;
dev->status_data[8] = 0;
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE;
dev->irq_in_progress = 1;
set_irq(dev);
}
static void
complete_command_status(esdi_t *dev)
{
dev->status_len = 7;
if (dev->cmd_dev == ATTN_DEVICE_0)
dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0);
else
dev->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1);
dev->status_data[1] = 0x0000; /*Error bits*/
dev->status_data[2] = 0x1900; /*Device status*/
dev->status_data[3] = 0; /*Number of blocks left to do*/
dev->status_data[4] = (dev->rba-1) & 0xffff; /*Last RBA processed*/
dev->status_data[5] = (dev->rba-1) >> 8;
dev->status_data[6] = 0; /*Number of blocks requiring error recovery*/
}
#define ESDI_ADAPTER_ONLY() do \
@@ -377,7 +417,8 @@ esdi_callback(void *priv)
break;
case 2:
dev->status = STATUS_IRQ;
complete_command_status(dev);
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->irq_in_progress = 1;
set_irq(dev);
@@ -438,11 +479,11 @@ esdi_callback(void *priv)
hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *)dev->data);
dev->rba++;
dev->sector_pos++;
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI,
dev->cmd_dev == ATTN_DEVICE_0 ? 0 : 1);
dev->data_pos = 0;
}
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
dev->status = STATUS_CMD_IN_PROGRESS;
dev->cmd_state = 2;
@@ -450,7 +491,8 @@ esdi_callback(void *priv)
break;
case 2:
dev->status = STATUS_IRQ;
complete_command_status(dev);
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->irq_in_progress = 1;
set_irq(dev);
@@ -471,7 +513,9 @@ esdi_callback(void *priv)
return;
}
dev->status = STATUS_IRQ;
dev->rba += dev->sector_count;
complete_command_status(dev);
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->irq_in_progress = 1;
set_irq(dev);
@@ -485,7 +529,8 @@ esdi_callback(void *priv)
return;
}
dev->status = STATUS_IRQ;
complete_command_status(dev);
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->irq_in_progress = 1;
set_irq(dev);
@@ -499,8 +544,6 @@ esdi_callback(void *priv)
return;
}
if (dev->status_pos)
fatal("Status send in progress\n");
if ((dev->status & STATUS_IRQ) || dev->irq_in_progress)
fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress);
@@ -529,8 +572,6 @@ esdi_callback(void *priv)
return;
}
if (dev->status_pos)
fatal("Status send in progress\n");
if ((dev->status & STATUS_IRQ) || dev->irq_in_progress)
fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress);
@@ -542,13 +583,12 @@ esdi_callback(void *priv)
dev->status_data[4] = drive->tracks;
dev->status_data[5] = drive->hpc | (drive->spt << 16);
#if 0
pclog("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n",
esdi_mca_log("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n",
drive->sectors,
dev->status_data[0], dev->status_data[1],
dev->status_data[2], dev->status_data[3],
dev->status_data[4], dev->status_data[5]);
#endif
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->irq_in_progress = 1;
@@ -557,8 +597,7 @@ esdi_callback(void *priv)
case CMD_GET_POS_INFO:
ESDI_ADAPTER_ONLY();
if (dev->status_pos)
fatal("Status send in progress\n");
if ((dev->status & STATUS_IRQ) || dev->irq_in_progress)
fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress);
@@ -567,8 +606,8 @@ esdi_callback(void *priv)
dev->status_data[1] = 0xffdd; /*MCA ID*/
dev->status_data[2] = dev->pos_regs[3] |
(dev->pos_regs[2] << 8);
dev->status_data[3] = 0xffff;
dev->status_data[4] = 0xffff;
dev->status_data[3] = 0xff;
dev->status_data[4] = 0xff;
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS;
@@ -688,8 +727,6 @@ esdi_callback(void *priv)
case 0x12:
ESDI_ADAPTER_ONLY();
if (dev->status_pos)
fatal("Status send in progress\n");
if ((dev->status & STATUS_IRQ) || dev->irq_in_progress)
fatal("IRQ in progress %02x %i\n", dev->status, dev->irq_in_progress);
@@ -715,7 +752,7 @@ esdi_read(uint16_t port, void *priv)
esdi_t *dev = (esdi_t *)priv;
uint8_t ret = 0xff;
switch (port-dev->base) {
switch (port & 7) {
case 2: /*Basic status register*/
ret = dev->status;
break;
@@ -738,10 +775,9 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
{
esdi_t *dev = (esdi_t *)priv;
#if 0
pclog("ESDI: wr(%04x, %02x)\n", port-dev->base, val);
#endif
switch (port-dev->base) {
esdi_mca_log("ESDI: wr(%04x, %02x)\n", port & 7, val);
switch (port & 7) {
case 2: /*Basic control register*/
if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) {
dev->in_reset = 1;
@@ -751,7 +787,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
dev->basic_ctrl = val;
if (! (dev->basic_ctrl & CTRL_IRQ_ENA))
picintc(1 << dev->irq);
picintc(1 << 14);
break;
case 3: /*Attention register*/
@@ -765,6 +801,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
dev->cmd_dev = ATTN_HOST_ADAPTER;
dev->status |= STATUS_BUSY;
dev->cmd_pos = 0;
dev->status_pos = 0;
break;
case ATTN_EOI:
@@ -793,6 +830,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
dev->cmd_dev = ATTN_DEVICE_0;
dev->status |= STATUS_BUSY;
dev->cmd_pos = 0;
dev->status_pos = 0;
break;
case ATTN_EOI:
@@ -815,6 +853,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
dev->cmd_dev = ATTN_DEVICE_1;
dev->status |= STATUS_BUSY;
dev->cmd_pos = 0;
dev->status_pos = 0;
break;
case ATTN_EOI:
@@ -845,12 +884,11 @@ esdi_readw(uint16_t port, void *priv)
esdi_t *dev = (esdi_t *)priv;
uint16_t ret = 0xffff;
switch (port-dev->base) {
switch (port & 7) {
case 0: /*Status Interface Register*/
if (dev->status_pos >= dev->status_len)
return(0);
ret = dev->status_data[dev->status_pos++];
if (dev->status_pos >= dev->status_len) {
ret = dev->status_data[dev->status_pos++]; if (dev->status_pos >= dev->status_len) {
dev->status &= ~STATUS_STATUS_OUT_FULL;
dev->status_pos = dev->status_len = 0;
}
@@ -869,10 +907,9 @@ esdi_writew(uint16_t port, uint16_t val, void *priv)
{
esdi_t *dev = (esdi_t *)priv;
#if 0
pclog("ESDI: wrw(%04x, %04x)\n", port-dev->base, val);
#endif
switch (port-dev->base) {
esdi_mca_log("ESDI: wrw(%04x, %04x)\n", port & 7, val);
switch (port & 7) {
case 0: /*Command Interface Register*/
if (dev->cmd_pos >= 4)
fatal("CIR pos 4\n");
@@ -903,9 +940,8 @@ esdi_mca_read(int port, void *priv)
{
esdi_t *dev = (esdi_t *)priv;
#if 0
pclog("ESDI: mcard(%04x)\n", port);
#endif
esdi_mca_log("ESDI: mcard(%04x)\n", port);
return(dev->pos_regs[port & 7]);
}
@@ -915,127 +951,58 @@ esdi_mca_write(int port, uint8_t val, void *priv)
{
esdi_t *dev = (esdi_t *)priv;
#if 0
pclog("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n",
esdi_mca_log("ESDI: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n",
port, val, dev->pos_regs[2], dev->pos_regs[3]);
#endif
if (port < 0x102) return;
/*
* The PS/2 Model 80 BIOS always enables a card if it finds one,
* even if no resources were assigned yet (because we only added
* the card, but have not run AutoConfig yet...)
*
* So, remove current address, if any.
*
* Note by Kotori: Moved this to the beginning of esdi_mca_write,
* so the *old* base is removed rather than the
* new base.
*/
io_removehandler(dev->base, 8,
esdi_read, esdi_readw, NULL,
esdi_write, esdi_writew, NULL, dev);
mem_mapping_disable(&dev->bios_rom.mapping);
if (port < 0x102)
return;
/* Save the new value. */
dev->pos_regs[port & 7] = val;
/* Extract the new I/O base. */
switch(dev->pos_regs[2] & 0x02) {
case 0x00: /* PRIMARY [0]=XXxx xx0X 0x3510 */
dev->base = ESDI_IOADDR_PRI;
break;
io_removehandler(ESDI_IOADDR_PRI, 8,
esdi_read, esdi_readw, NULL,
esdi_write, esdi_writew, NULL, dev);
mem_mapping_disable(&dev->bios_rom.mapping);
case 0x02: /* SECONDARY [0]=XXxx xx1X 0x3518 */
dev->base = ESDI_IOADDR_SEC;
break;
}
/* Extract the new DMA channel. */
switch(dev->pos_regs[2] & 0x3c) {
case 0x14: /* DMA 5 [0]=XX01 01XX */
case 0x14:
dev->dma = 5;
break;
case 0x18: /* DMA 6 [0]=XX01 10XX */
case 0x18:
dev->dma = 6;
break;
case 0x1c: /* DMA 7 [0]=XX01 11XX */
case 0x1c:
dev->dma = 7;
break;
case 0x00: /* DMA 0 [0]=XX00 00XX */
case 0x00:
dev->dma = 0;
break;
case 0x01: /* DMA 1 [0]=XX00 01XX */
case 0x04:
dev->dma = 1;
break;
case 0x04: /* DMA 3 [0]=XX00 11XX */
case 0x0c:
dev->dma = 3;
break;
case 0x10: /* DMA 4 [0]=XX01 00XX */
case 0x10:
dev->dma = 4;
break;
}
/* Extract the new BIOS address. */
if (! (dev->pos_regs[3] & 0x08)) switch(dev->pos_regs[3] & 0x0f) {
case 0: /* ROM C000 [1]=XXXX 0000 */
dev->bios = 0xC0000;
break;
case 1: /* ROM C400 [1]=XXXX 0001 */
dev->bios = 0xC4000;
break;
case 2: /* ROM C800 [1]=XXXX 0010 */
dev->bios = 0xC8000;
break;
case 3: /* ROM CC00 [1]=XXXX 0011 */
dev->bios = 0xCC000;
break;
case 4: /* ROM D000 [1]=XXXX 0100 */
dev->bios = 0xD0000;
break;
case 5: /* ROM D400 [1]=XXXX 0101 */
dev->bios = 0xD4000;
break;
case 6: /* ROM D800 [1]=XXXX 0110 */
dev->bios = 0xD8000;
break;
case 7: /* ROM DC00 [1]=XXXX 0111 */
dev->bios = 0xDC000;
break;
} else {
/* BIOS ROM disabled. */
dev->bios = 0x000000;
}
if (dev->pos_regs[2] & 0x01) {
/* Card enabled; register (new) I/O handler. */
io_sethandler(dev->base, 8,
if (dev->pos_regs[2] & 1) {
io_sethandler(ESDI_IOADDR_PRI, 8,
esdi_read, esdi_readw, NULL,
esdi_write, esdi_writew, NULL, dev);
/* Enable or disable the BIOS ROM. */
if (dev->bios != 0x000000) {
if (!(dev->pos_regs[3] & 8)) {
mem_mapping_enable(&dev->bios_rom.mapping);
mem_mapping_set_addr(&dev->bios_rom.mapping,
dev->bios, 0x4000);
((dev->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000);
}
/* Say hello. */
pclog("ESDI: I/O=%04x, IRQ=%d, DMA=%d, BIOS @%05X\n",
dev->base, dev->irq, dev->dma, dev->bios);
esdi_mca_log("ESDI: I/O=3510, IRQ=14, DMA=%d, BIOS @%05X\n",
dev->dma, dev->bios);
}
}
@@ -1054,9 +1021,6 @@ esdi_init(const device_t *info)
/* Mark as unconfigured. */
dev->irq_status = 0xff;
/* This is hardwired. */
dev->irq = ESDI_IRQCHAN;
rom_init_interleaved(&dev->bios_rom,
BIOS_FILE_H, BIOS_FILE_L,
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
@@ -1080,7 +1044,7 @@ esdi_init(const device_t *info)
drive->spt = hdd[i].spt;
drive->hpc = hdd[i].hpc;
drive->tracks = hdd[i].tracks;
drive->sectors = hdd[i].spt*hdd[i].hpc*hdd[i].tracks;
drive->sectors = hdd_image_get_last_sector(i) + 1;
drive->hdd_num = i;
/* Mark drive as present. */
@@ -1139,5 +1103,5 @@ const device_t esdi_ps2_device = {
"IBM ESDI Fixed Disk Adapter (MCA)",
DEVICE_MCA, 0,
esdi_init, esdi_close, NULL,
esdi_available, NULL, NULL, NULL, NULL
esdi_available, NULL, NULL, NULL
};

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
* Implementation of the IDE emulation for hard disks and ATAPI
* CD-ROM devices.
*
* Version: @(#)hdd_ide.h 1.0.8 2018/03/20
* Version: @(#)hdd_ide.h 1.0.10 2018/05/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -21,59 +21,52 @@
typedef struct {
int type;
int board;
uint8_t atastat;
uint8_t error;
int secount,sector,cylinder,head,drive,cylprecomp;
uint8_t command;
uint8_t fdisk;
int pos;
int packlen;
int spt,hpc;
int t_spt,t_hpc;
int tracks;
int packetstatus;
uint8_t asc;
int reset;
uint8_t atastat, error,
command, fdisk;
int type, board,
irqstat, service,
blocksize, blockcount,
hdd_num, channel,
pos, sector_pos,
lba, skip512,
reset, tracks,
spt, hpc,
mdma_mode, do_initial_read;
uint32_t secount, sector,
cylinder, head,
drive, cylprecomp,
cfg_spt, cfg_hpc,
lba_addr;
uint16_t *buffer;
int irqstat;
int service;
int lba;
int channel;
uint32_t lba_addr;
int skip512;
int blocksize, blockcount;
uint16_t dma_identify_data[3];
int hdi,base;
int hdd_num;
uint8_t specify_success;
int mdma_mode;
uint8_t *sector_buffer;
int do_initial_read;
int sector_pos;
} IDE;
} ide_t;
extern int ideboard;
extern int ide_ter_enabled, ide_qua_enabled;
extern int ide_enable[5];
extern int ide_irq[5];
extern IDE ide_drives[IDE_NUM + XTIDE_NUM];
extern ide_t *ide_drives[IDE_NUM];
extern int64_t idecallback[5];
extern void ide_irq_raise(IDE *ide);
extern void ide_irq_lower(IDE *ide);
extern void ide_irq_raise(ide_t *ide);
extern void ide_irq_lower(ide_t *ide);
extern void writeide(int ide_board, uint16_t addr, uint8_t val);
extern void writeidew(int ide_board, uint16_t val);
extern uint8_t readide(int ide_board, uint16_t addr);
extern uint16_t readidew(int ide_board);
extern void callbackide(int ide_board);
extern void * ide_xtide_init(void);
extern void ide_xtide_close(void);
extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel));
extern void ide_writew(uint16_t addr, uint16_t val, void *priv);
extern void ide_write_devctl(uint16_t addr, uint8_t val, void *priv);
extern void ide_writeb(uint16_t addr, uint8_t val, void *priv);
extern uint8_t ide_readb(uint16_t addr, void *priv);
extern uint8_t ide_read_alt_status(uint16_t addr, void *priv);
extern uint16_t ide_readw(uint16_t addr, void *priv);
extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length, void *priv),
int (*write)(int channel, uint8_t *data, int transfer_length, void *priv),
void (*set_irq)(int channel, void *priv),
void *priv0, void *priv1);
extern void win_cdrom_eject(uint8_t id);
extern void win_cdrom_reload(uint8_t id);
@@ -81,36 +74,20 @@ extern void win_cdrom_reload(uint8_t id);
extern void ide_set_base(int controller, uint16_t port);
extern void ide_set_side(int controller, uint16_t port);
extern void ide_init_first(void);
extern void ide_reset(void);
extern void ide_reset_hard(void);
extern void ide_set_all_signatures(void);
extern void ide_xtide_init(void);
extern void ide_pri_enable(void);
extern void ide_pri_enable_ex(void);
extern void ide_pri_disable(void);
extern void ide_sec_enable(void);
extern void ide_sec_disable(void);
extern void ide_ter_enable(void);
extern void ide_ter_disable(void);
extern void ide_ter_init(void);
extern void ide_qua_enable(void);
extern void ide_qua_disable(void);
extern void ide_qua_init(void);
extern void ide_set_callback(uint8_t channel, int64_t callback);
extern void secondary_ide_check(void);
extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src);
extern void ide_destroy_buffers(void);
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length);
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length);
extern void (*ide_bus_master_set_irq)(int channel);
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv);
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
extern void *ide_bus_master_priv[2];
#endif /*EMU_IDE_H*/

View File

@@ -12,7 +12,7 @@
* based design. Most cards were WD1003-WA2 or -WAH, where the
* -WA2 cards had a floppy controller as well (to save space.)
*
* Version: @(#)hdc_mfm_at.c 1.0.13 2018/03/18
* Version: @(#)hdc_mfm_at.c 1.0.17 2018/05/02
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -23,11 +23,13 @@
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../device.h"
#include "../io.h"
@@ -110,33 +112,43 @@ typedef struct {
} mfm_t;
static __inline void irq_raise(mfm_t *mfm)
{
/* If not already pending.. */
if (! mfm->irqstat) {
/* If enabled in the control register.. */
if (! (mfm->fdisk&0x02)) {
/* .. raise IRQ14. */
picint(1<<14);
}
#ifdef ENABLE_MFM_AT_LOG
int mfm_at_do_log = ENABLE_MFM_AT_LOG;
#endif
/* Remember this. */
mfm->irqstat = 1;
static void
mfm_at_log(const char *fmt, ...)
{
#ifdef ENABLE_MFM_AT_LOG
va_list ap;
if (mfm_at_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static __inline void irq_lower(mfm_t *mfm)
static inline void
irq_raise(mfm_t *mfm)
{
/* If raised.. */
if (mfm->irqstat) {
/* If enabled in the control register.. */
if (! (mfm->fdisk&0x02)) {
/* .. drop IRQ14. */
picintc(1<<14);
}
if (!(mfm->fdisk & 2))
picint(1 << 14);
mfm->irqstat = 1;
}
static inline void
irq_lower(mfm_t *mfm)
{
if (mfm->irqstat) {
if (!(mfm->fdisk & 2))
picintc(1 << 14);
/* Remember this. */
mfm->irqstat = 0;
}
}
@@ -160,18 +172,18 @@ get_sector(mfm_t *mfm, off64_t *addr)
drive_t *drive = &mfm->drives[mfm->drvsel];
if (drive->curcyl != mfm->cylinder) {
pclog("WD1003(%d) sector: wrong cylinder\n");
mfm_at_log("WD1003(%d) sector: wrong cylinder\n");
return(1);
}
if (mfm->head > drive->cfg_hpc) {
pclog("WD1003(%d) get_sector: past end of configured heads\n",
mfm_at_log("WD1003(%d) get_sector: past end of configured heads\n",
mfm->drvsel);
return(1);
}
if (mfm->sector >= drive->cfg_spt+1) {
pclog("WD1003(%d) get_sector: past end of configured sectors\n",
mfm_at_log("WD1003(%d) get_sector: past end of configured sectors\n",
mfm->drvsel);
return(1);
}
@@ -179,12 +191,12 @@ get_sector(mfm_t *mfm, off64_t *addr)
#if 1
/* We should check this in the SET_DRIVE_PARAMETERS command! --FvK */
if (mfm->head > drive->hpc) {
pclog("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel);
mfm_at_log("WD1003(%d) get_sector: past end of heads\n", mfm->drvsel);
return(1);
}
if (mfm->sector >= drive->spt+1) {
pclog("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel);
mfm_at_log("WD1003(%d) get_sector: past end of sectors\n", mfm->drvsel);
return(1);
}
#endif
@@ -221,7 +233,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
if (! drive->present) {
/* This happens if sofware polls all drives. */
pclog("WD1003(%d) command %02x on non-present drive\n",
mfm_at_log("WD1003(%d) command %02x on non-present drive\n",
mfm->drvsel, val);
mfm->command = 0xff;
mfm->status = STAT_BUSY;
@@ -233,24 +245,23 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
}
irq_lower(mfm);
mfm->command = val;
mfm->error = 0;
switch (val & 0xf0) {
case CMD_RESTORE:
drive->steprate = (val & 0x0f);
#if ENABLE_HDC_LOG
pclog("WD1003(%d) restore, step=%d\n",
mfm_at_log("WD1003(%d) restore, step=%d\n",
mfm->drvsel, drive->steprate);
#endif
drive->curcyl = 0;
mfm->status = STAT_READY|STAT_DSC;
mfm->command = 0x00;
mfm->command &= 0xf0;
irq_raise(mfm);
break;
case CMD_SEEK:
drive->steprate = (val & 0x0f);
mfm->command = (val & 0xf0);
mfm->command &= 0xf0;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200LL*MFM_TIME;
@@ -258,16 +269,15 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
break;
default:
mfm->command = val;
switch (val) {
case CMD_READ:
case CMD_READ+1:
case CMD_READ+2:
case CMD_READ+3:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) read, opt=%d\n",
mfm_at_log("WD1003(%d) read, opt=%d\n",
mfm->drvsel, val&0x03);
#endif
mfm->command = (val & 0xf0);
mfm->command &= 0xfc;
if (val & 2)
fatal("WD1003: READ with ECC\n");
mfm->status = STAT_BUSY;
@@ -280,11 +290,9 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
case CMD_WRITE+1:
case CMD_WRITE+2:
case CMD_WRITE+3:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) write, opt=%d\n",
mfm_at_log("WD1003(%d) write, opt=%d\n",
mfm->drvsel, val & 0x03);
#endif
mfm->command = (val & 0xf0);
mfm->command &= 0xfc;
if (val & 2)
fatal("WD1003: WRITE with ECC\n");
mfm->status = STAT_DRQ|STAT_DSC;
@@ -293,7 +301,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
case CMD_VERIFY:
case CMD_VERIFY+1:
mfm->command = (val & 0xfe);
mfm->command &= 0xfe;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200LL*MFM_TIME;
@@ -301,13 +309,11 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
break;
case CMD_FORMAT:
mfm->command = val;
mfm->status = STAT_DRQ|STAT_BUSY;
mfm->pos = 0;
break;
case CMD_DIAGNOSE:
mfm->command = val;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200LL*MFM_TIME;
@@ -335,11 +341,11 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
/* Only accept after RESET or DIAG. */
drive->cfg_spt = mfm->secount;
drive->cfg_hpc = mfm->head+1;
pclog("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n",
mfm_at_log("WD1003(%d) parameters: tracks=%d, spt=%i, hpc=%i\n",
mfm->drvsel, drive->tracks,
drive->cfg_spt, drive->cfg_hpc);
} else {
pclog("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n",
mfm_at_log("WD1003(%d) parameters: tracks=%d,spt=%i,hpc=%i (IGNORED)\n",
mfm->drvsel, drive->tracks,
drive->cfg_spt, drive->cfg_hpc);
}
@@ -350,7 +356,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
break;
default:
pclog("WD1003: bad command %02X\n", val);
mfm_at_log("WD1003: bad command %02X\n", val);
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 200LL*MFM_TIME;
@@ -373,7 +379,9 @@ mfm_writew(uint16_t port, uint16_t val, void *priv)
mfm->pos = 0;
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 6LL*MFM_TIME;
/* 781.25 us per sector at 5 Mbit/s = 640 kB/s. */
mfm->callback = ((3125LL * TIMER_USEC) / 4LL);
/* mfm->callback = 10LL * MFM_TIME; */
timer_update_outstanding();
}
}
@@ -384,9 +392,8 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
{
mfm_t *mfm = (mfm_t *)priv;
#if ENABLE_HDC_LOG > 1
pclog("WD1003 write(%04x, %02x)\n", port, val);
#endif
mfm_at_log("WD1003 write(%04x, %02x)\n", port, val);
switch (port) {
case 0x01f0: /* data */
mfm_writew(port, val | (val << 8), priv);
@@ -417,7 +424,7 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
mfm->drvsel = (val & 0x10) ? 1 : 0;
if (mfm->drives[mfm->drvsel].present)
mfm->status = STAT_READY|STAT_DSC;
else
else
mfm->status = 0;
return;
@@ -428,21 +435,24 @@ mfm_write(uint16_t port, uint8_t val, void *priv)
case 0x03f6: /* device control */
val &= 0x0f;
if ((mfm->fdisk & 0x04) && !(val & 0x04)) {
mfm->status = STAT_BUSY;
mfm->reset = 1;
timer_clock();
mfm->callback = 500LL*MFM_TIME;
timer_update_outstanding();
mfm->reset = 1;
mfm->status = STAT_BUSY;
}
if (val & 0x04) {
/* Drive held in reset. */
mfm->status = STAT_BUSY;
mfm->callback = 0LL;
timer_clock();
mfm->callback = 0LL;
timer_update_outstanding();
mfm->status = STAT_BUSY;
}
mfm->fdisk = val;
/* Lower IRQ on IRQ disable. */
if ((val & 2) && !(mfm->fdisk & 0x02))
picintc(1 << 14);
break;
}
}
@@ -465,7 +475,9 @@ mfm_readw(uint16_t port, void *priv)
next_sector(mfm);
mfm->status = STAT_BUSY;
timer_clock();
mfm->callback = 6LL*MFM_TIME;
/* 781.25 us per sector at 5 Mbit/s = 640 kB/s. */
mfm->callback = ((3125LL * TIMER_USEC) / 4LL);
/* mfm->callback = 10LL * MFM_TIME; */
timer_update_outstanding();
} else {
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
@@ -520,9 +532,8 @@ mfm_read(uint16_t port, void *priv)
default:
break;
}
#if ENABLE_HDC_LOG > 1
pclog("WD1003 read(%04x) = %02x\n", port, ret);
#endif
mfm_at_log("WD1003 read(%04x) = %02x\n", port, ret);
return(ret);
}
@@ -533,10 +544,9 @@ do_seek(mfm_t *mfm)
{
drive_t *drive = &mfm->drives[mfm->drvsel];
#if ENABLE_HDC_LOG
pclog("WD1003(%d) seek(%d) max=%d\n",
mfm_at_log("WD1003(%d) seek(%d) max=%d\n",
mfm->drvsel,mfm->cylinder,drive->tracks);
#endif
if (mfm->cylinder < drive->tracks)
drive->curcyl = mfm->cylinder;
else
@@ -553,9 +563,8 @@ do_callback(void *priv)
mfm->callback = 0LL;
if (mfm->reset) {
#if ENABLE_HDC_LOG
pclog("WD1003(%d) reset\n", mfm->drvsel);
#endif
mfm_at_log("WD1003(%d) reset\n", mfm->drvsel);
mfm->status = STAT_READY|STAT_DSC;
mfm->error = 1;
mfm->secount = 1;
@@ -575,20 +584,16 @@ do_callback(void *priv)
switch (mfm->command) {
case CMD_SEEK:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) seek, step=%d\n",
mfm_at_log("WD1003(%d) seek, step=%d\n",
mfm->drvsel, drive->steprate);
#endif
do_seek(mfm);
mfm->status = STAT_READY|STAT_DSC;
irq_raise(mfm);
break;
case CMD_READ:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) read(%d,%d,%d)\n",
mfm_at_log("WD1003(%d) read(%d,%d,%d)\n",
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
#endif
do_seek(mfm);
if (get_sector(mfm, &addr)) {
mfm->error = ERR_ID_NOT_FOUND;
@@ -606,10 +611,8 @@ do_callback(void *priv)
break;
case CMD_WRITE:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) write(%d,%d,%d)\n",
mfm_at_log("WD1003(%d) write(%d,%d,%d)\n",
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
#endif
do_seek(mfm);
if (get_sector(mfm, &addr)) {
mfm->error = ERR_ID_NOT_FOUND;
@@ -619,26 +622,23 @@ do_callback(void *priv)
}
hdd_image_write(drive->hdd_num, addr, 1,(uint8_t *)mfm->buffer);
irq_raise(mfm);
mfm->secount = (mfm->secount - 1) & 0xff;
mfm->status = STAT_READY|STAT_DSC;
mfm->secount = (mfm->secount - 1) & 0xff;
if (mfm->secount) {
/* More sectors to do.. */
mfm->status |= STAT_DRQ;
mfm->pos = 0;
next_sector(mfm);
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
} else {
} else
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
}
irq_raise(mfm);
break;
case CMD_VERIFY:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) verify(%d,%d,%d)\n",
mfm_at_log("WD1003(%d) verify(%d,%d,%d)\n",
mfm->drvsel, mfm->cylinder, mfm->head, mfm->sector);
#endif
do_seek(mfm);
mfm->pos = 0;
mfm->status = STAT_READY|STAT_DSC;
@@ -647,10 +647,8 @@ do_callback(void *priv)
break;
case CMD_FORMAT:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) format(%d,%d)\n",
mfm_at_log("WD1003(%d) format(%d,%d)\n",
mfm->drvsel, mfm->cylinder, mfm->head);
#endif
do_seek(mfm);
if (get_sector(mfm, &addr)) {
mfm->error = ERR_ID_NOT_FOUND;
@@ -667,9 +665,7 @@ do_callback(void *priv)
break;
case CMD_DIAGNOSE:
#if ENABLE_HDC_LOG
pclog("WD1003(%d) diag\n", mfm->drvsel);
#endif
mfm_at_log("WD1003(%d) diag\n", mfm->drvsel);
drive->steprate = 0x0f;
mfm->error = 1;
mfm->status = STAT_READY|STAT_DSC;
@@ -677,7 +673,7 @@ do_callback(void *priv)
break;
default:
pclog("WD1003(%d) callback on unknown command %02x\n",
mfm_at_log("WD1003(%d) callback on unknown command %02x\n",
mfm->drvsel, mfm->command);
mfm->status = STAT_READY|STAT_ERR|STAT_DSC;
mfm->error = ERR_ABRT;
@@ -712,7 +708,7 @@ mfm_init(const device_t *info)
mfm_t *mfm;
int c, d;
pclog("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n");
mfm_at_log("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n");
mfm = malloc(sizeof(mfm_t));
memset(mfm, 0x00, sizeof(mfm_t));
@@ -721,7 +717,7 @@ mfm_init(const device_t *info)
if ((hdd[d].bus == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) {
loadhd(mfm, hdd[d].mfm_channel, d, hdd[d].fn);
pclog("WD1003(%d): (%ls) geometry %d/%d/%d\n", c, hdd[d].fn,
mfm_at_log("WD1003(%d): (%ls) geometry %d/%d/%d\n", c, hdd[d].fn,
(int)hdd[d].tracks, (int)hdd[d].hpc, (int)hdd[d].spt);
if (++c >= MFM_NUM) break;
@@ -769,5 +765,5 @@ const device_t mfm_at_wd1003_device = {
DEVICE_ISA | DEVICE_AT,
0,
mfm_init, mfm_close, NULL,
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
};

View File

@@ -41,7 +41,7 @@
* Since all controllers (including the ones made by DTC) use
* (mostly) the same API, we keep them all in this module.
*
* Version: @(#)hdc_mfm_xt.c 1.0.14 2018/03/18
* Version: @(#)hdc_mfm_xt.c 1.0.17 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Fred N. van Kempen, <decwiz@yahoo.com>
@@ -52,11 +52,13 @@
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../device.h"
#include "../dma.h"
@@ -71,7 +73,8 @@
#include "hdd.h"
#define MFM_TIME (2000LL*TIMER_USEC)
// #define MFM_TIME (2000LL*TIMER_USEC)
#define MFM_TIME (50LL*TIMER_USEC)
#define XEBEC_BIOS_FILE L"roms/hdd/mfm_xebec/ibm_xebec_62x0822_1985.bin"
#define DTC_BIOS_FILE L"roms/hdd/mfm_xebec/dtc_cxd21a.bin"
@@ -152,6 +155,26 @@ typedef struct {
#define ERR_ILLEGAL_SECTOR_ADDRESS 0x21
#ifdef ENABLE_MFM_XT_LOG
int mfm_xt_do_log = ENABLE_MFM_XT_LOG;
#endif
static void
mfm_xt_log(const char *fmt, ...)
{
#ifdef ENABLE_MFM_XT_LOG
va_list ap;
if (mfm_xt_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static uint8_t
mfm_read(uint16_t port, void *priv)
{
@@ -278,7 +301,7 @@ mfm_error(mfm_t *mfm, uint8_t error)
mfm->completion_byte |= 0x02;
mfm->error = error;
pclog("mfm_error - %02x\n", mfm->error);
mfm_xt_log("mfm_error - %02x\n", mfm->error);
}
@@ -289,22 +312,22 @@ get_sector(mfm_t *mfm, off64_t *addr)
int heads = drive->cfg_hpc;
if (drive->current_cylinder != mfm->cylinder) {
pclog("mfm_get_sector: wrong cylinder\n");
mfm_xt_log("mfm_get_sector: wrong cylinder\n");
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
return(1);
}
if (mfm->head > heads) {
pclog("mfm_get_sector: past end of configured heads\n");
mfm_xt_log("mfm_get_sector: past end of configured heads\n");
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
return(1);
}
if (mfm->head > drive->hpc) {
pclog("mfm_get_sector: past end of heads\n");
mfm_xt_log("mfm_get_sector: past end of heads\n");
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
return(1);
}
if (mfm->sector >= 17) {
pclog("mfm_get_sector: past end of sectors\n");
mfm_xt_log("mfm_get_sector: past end of sectors\n");
mfm->error = ERR_ILLEGAL_SECTOR_ADDRESS;
return(1);
}
@@ -395,7 +418,7 @@ mfm_callback(void *priv)
mfm->sector_count = mfm->command[4];
do {
if (get_sector(mfm, &addr)) {
pclog("get_sector failed\n");
mfm_xt_log("get_sector failed\n");
mfm_error(mfm, mfm->error);
mfm_complete(mfm);
return;
@@ -422,14 +445,14 @@ mfm_callback(void *priv)
mfm->head = mfm->command[1] & 0x1f;
if (get_sector(mfm, &addr)) {
pclog("get_sector failed\n");
mfm_xt_log("get_sector failed\n");
mfm_error(mfm, mfm->error);
mfm_complete(mfm);
return;
}
hdd_image_zero(drive->hdd_num, addr, 17);
mfm_complete(mfm);
break;
@@ -470,7 +493,7 @@ mfm_callback(void *priv)
int val = dma_channel_write(3, mfm->sector_buf[mfm->data_pos]);
if (val == DMA_NODATA) {
pclog("CMD_READ_SECTORS out of data!\n");
mfm_xt_log("CMD_READ_SECTORS out of data!\n");
mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
mfm->callback = MFM_TIME;
return;
@@ -543,7 +566,7 @@ mfm_callback(void *priv)
int val = dma_channel_read(3);
if (val == DMA_NODATA) {
pclog("CMD_WRITE_SECTORS out of data!\n");
mfm_xt_log("CMD_WRITE_SECTORS out of data!\n");
mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
mfm->callback = MFM_TIME;
return;
@@ -618,7 +641,7 @@ mfm_callback(void *priv)
case STATE_RECEIVED_DATA:
drive->cfg_cyl = mfm->data[1] | (mfm->data[0] << 8);
drive->cfg_hpc = mfm->data[2];
pclog("Drive %i: cylinders=%i, heads=%i\n", mfm->drive_sel, drive->cfg_cyl, drive->cfg_hpc);
mfm_xt_log("Drive %i: cylinders=%i, heads=%i\n", mfm->drive_sel, drive->cfg_cyl, drive->cfg_hpc);
mfm_complete(mfm);
break;
@@ -647,7 +670,7 @@ mfm_callback(void *priv)
int val = dma_channel_read(3);
if (val == DMA_NODATA) {
pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n");
mfm_xt_log("CMD_WRITE_SECTOR_BUFFER out of data!\n");
mfm->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ;
mfm->callback = MFM_TIME;
return;
@@ -696,7 +719,7 @@ mfm_callback(void *priv)
mfm->data[0] = drive->tracks & 0xff;
mfm->data[1] = 17 | ((drive->tracks >> 2) & 0xc0);
mfm->data[2] = drive->hpc-1;
pclog("Get drive params %02x %02x %02x %i\n", mfm->data[0], mfm->data[1], mfm->data[2], drive->tracks);
mfm_xt_log("Get drive params %02x %02x %02x %i\n", mfm->data[0], mfm->data[1], mfm->data[2], drive->tracks);
break;
case STATE_SENT_DATA:
@@ -757,7 +780,7 @@ loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn)
{
drive_t *drive = &mfm->drives[d];
if (! hdd_image_load(d)) {
if (! hdd_image_load(c)) {
drive->present = 0;
return;
}
@@ -802,7 +825,7 @@ mfm_set_switches(mfm_t *mfm)
}
if (c == 4)
pclog("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C');
mfm_xt_log("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C');
}
}
@@ -815,16 +838,16 @@ xebec_init(const device_t *info)
mfm_t *xebec = malloc(sizeof(mfm_t));
memset(xebec, 0x00, sizeof(mfm_t));
pclog("MFM: looking for disks..\n");
mfm_xt_log("MFM: looking for disks..\n");
for (i=0; i<HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
pclog("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
mfm_xt_log("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
loadhd(xebec, i, hdd[i].mfm_channel, hdd[i].fn);
if (++c > MFM_NUM) break;
}
}
pclog("MFM: %d disks loaded.\n", c);
mfm_xt_log("MFM: %d disks loaded.\n", c);
mfm_set_switches(xebec);
@@ -859,7 +882,7 @@ mfm_close(void *priv)
static int
xebec_available(void)
{
return(rom_present(XEBEC_BIOS_FILE));
return(rom_present(XEBEC_BIOS_FILE));
}
@@ -868,8 +891,7 @@ const device_t mfm_xt_xebec_device = {
DEVICE_ISA,
0,
xebec_init, mfm_close, NULL,
xebec_available, NULL, NULL, NULL,
NULL
xebec_available, NULL, NULL, NULL
};
@@ -881,16 +903,16 @@ dtc5150x_init(const device_t *info)
mfm_t *dtc = malloc(sizeof(mfm_t));
memset(dtc, 0x00, sizeof(mfm_t));
pclog("MFM: looking for disks..\n");
mfm_xt_log("MFM: looking for disks..\n");
for (i=0; i<HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
pclog("Found MFM hard disk on channel %i\n", hdd[i].mfm_channel);
mfm_xt_log("Found MFM hard disk on channel %i (%ls)\n", hdd[i].mfm_channel, hdd[i].fn);
loadhd(dtc, i, hdd[i].mfm_channel, hdd[i].fn);
if (++c > MFM_NUM) break;
}
}
pclog("MFM: %d disks loaded.\n", c);
mfm_xt_log("MFM: %d disks loaded.\n", c);
dtc->switches = 0xff;
@@ -923,6 +945,5 @@ const device_t mfm_xt_dtc5150x_device = {
DEVICE_ISA,
0,
dtc5150x_init, mfm_close, NULL,
dtc5150x_available, NULL, NULL, NULL,
NULL
dtc5150x_available, NULL, NULL, NULL
};

1161
src/disk/hdc_xta.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
* already on their way out, the newer IDE standard based on the
* PC/AT controller and 16b design became the IDE we now know.
*
* Version: @(#)hdc_xtide.c 1.0.11 2018/03/18
* Version: @(#)hdc_xtide.c 1.0.13 2018/04/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -52,6 +52,7 @@
typedef struct {
void *ide_board;
uint8_t data_high;
rom_t bios_rom;
} xtide_t;
@@ -64,7 +65,7 @@ xtide_write(uint16_t port, uint8_t val, void *priv)
switch (port & 0xf) {
case 0x0:
writeidew(4, val | (xtide->data_high << 8));
ide_writew(0x0, val | (xtide->data_high << 8), xtide->ide_board);
return;
case 0x1:
@@ -74,7 +75,7 @@ xtide_write(uint16_t port, uint8_t val, void *priv)
case 0x5:
case 0x6:
case 0x7:
writeide(4, (port & 0xf) | 0x1f0, val);
ide_writeb((port & 0xf), val, xtide->ide_board);
return;
case 0x8:
@@ -82,7 +83,7 @@ xtide_write(uint16_t port, uint8_t val, void *priv)
return;
case 0xe:
writeide(4, 0x3f6, val);
ide_write_devctl(0x0, val, xtide->ide_board);
return;
}
}
@@ -96,7 +97,7 @@ xtide_read(uint16_t port, void *priv)
switch (port & 0xf) {
case 0x0:
tempw = readidew(4);
tempw = ide_readw(0x0, xtide->ide_board);
xtide->data_high = tempw >> 8;
break;
@@ -107,7 +108,7 @@ xtide_read(uint16_t port, void *priv)
case 0x5:
case 0x6:
case 0x7:
tempw = readide(4, (port & 0xf) | 0x1f0);
tempw = ide_readb((port & 0xf), xtide->ide_board);
break;
case 0x8:
@@ -115,7 +116,7 @@ xtide_read(uint16_t port, void *priv)
break;
case 0xe:
tempw = readide(4, 0x3f6);
tempw = ide_read_alt_status(0x0, xtide->ide_board);
break;
default:
@@ -136,7 +137,7 @@ xtide_init(const device_t *info)
rom_init(&xtide->bios_rom, ROM_PATH_XT,
0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
ide_xtide_init();
xtide->ide_board = ide_xtide_init();
io_sethandler(0x0300, 16,
xtide_read, NULL, NULL,
@@ -186,7 +187,7 @@ xtide_acculogic_init(const device_t *info)
rom_init(&xtide->bios_rom, ROM_PATH_PS2,
0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
ide_xtide_init();
xtide->ide_board = ide_xtide_init();
io_sethandler(0x0360, 16,
xtide_read, NULL, NULL,
@@ -203,6 +204,17 @@ xtide_acculogic_available(void)
}
static void
xtide_close(void *priv)
{
xtide_t *xtide = (xtide_t *)priv;
free(xtide);
ide_xtide_close();
}
static void *
xtide_at_ps2_init(const device_t *info)
{
@@ -227,7 +239,7 @@ xtide_at_ps2_available(void)
static void
xtide_close(void *priv)
xtide_at_close(void *priv)
{
xtide_t *xtide = (xtide_t *)priv;
@@ -240,7 +252,7 @@ const device_t xtide_device = {
DEVICE_ISA,
0,
xtide_init, xtide_close, NULL,
xtide_available, NULL, NULL, NULL,
xtide_available, NULL, NULL,
NULL
};
@@ -248,8 +260,8 @@ const device_t xtide_at_device = {
"XTIDE (AT)",
DEVICE_ISA | DEVICE_AT,
0,
xtide_at_init, xtide_close, NULL,
xtide_at_available, NULL, NULL, NULL,
xtide_at_init, xtide_at_close, NULL,
xtide_at_available, NULL, NULL,
NULL
};
@@ -258,7 +270,7 @@ const device_t xtide_acculogic_device = {
DEVICE_ISA,
0,
xtide_acculogic_init, xtide_close, NULL,
xtide_acculogic_available, NULL, NULL, NULL,
xtide_acculogic_available, NULL, NULL,
NULL
};
@@ -266,7 +278,7 @@ const device_t xtide_at_ps2_device = {
"XTIDE (AT) (1.1.5)",
DEVICE_ISA | DEVICE_PS2,
0,
xtide_at_ps2_init, xtide_close, NULL,
xtide_at_ps2_available, NULL, NULL, NULL,
xtide_at_ps2_init, xtide_at_close, NULL,
xtide_at_ps2_available, NULL, NULL,
NULL
};

View File

@@ -8,13 +8,13 @@
*
* Common code to handle all sorts of hard disk images.
*
* Version: @(#)hdd.c 1.0.7 2017/11/18
* Version: @(#)hdd.c 1.0.9 2018/05/25
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -48,7 +48,7 @@ hdd_string_to_bus(char *str, int cdrom)
if (! strcmp(str, "mfm")) {
if (cdrom) {
no_cdrom:
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4114);
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4099);
return(0);
}
@@ -63,53 +63,35 @@ no_cdrom:
}
if (! strcmp(str, "ide_pio_only"))
return(HDD_BUS_IDE_PIO_ONLY);
return(HDD_BUS_IDE);
if (! strcmp(str, "ide"))
return(HDD_BUS_IDE_PIO_ONLY);
return(HDD_BUS_IDE);
if (! strcmp(str, "atapi_pio_only"))
return(HDD_BUS_IDE_PIO_ONLY);
return(HDD_BUS_IDE);
if (! strcmp(str, "atapi"))
return(HDD_BUS_IDE_PIO_ONLY);
return(HDD_BUS_IDE);
if (! strcmp(str, "eide"))
return(HDD_BUS_IDE_PIO_ONLY);
return(HDD_BUS_IDE);
if (! strcmp(str, "xtide"))
return(HDD_BUS_XTIDE);
if (! strcmp(str, "xta"))
return(HDD_BUS_XTA);
if (! strcmp(str, "atide"))
return(HDD_BUS_IDE_PIO_ONLY);
return(HDD_BUS_IDE);
if (! strcmp(str, "ide_pio_and_dma"))
return(HDD_BUS_IDE_PIO_AND_DMA);
return(HDD_BUS_IDE);
if (! strcmp(str, "atapi_pio_and_dma"))
return(HDD_BUS_IDE_PIO_AND_DMA);
return(HDD_BUS_IDE);
if (! strcmp(str, "scsi"))
return(HDD_BUS_SCSI);
if (! strcmp(str, "removable")) {
if (cdrom) goto no_cdrom;
return(HDD_BUS_SCSI_REMOVABLE);
}
if (! strcmp(str, "scsi_removable")) {
if (cdrom) goto no_cdrom;
return(HDD_BUS_SCSI_REMOVABLE);
}
if (! strcmp(str, "removable_scsi")) {
if (cdrom) goto no_cdrom;
return(HDD_BUS_SCSI_REMOVABLE);
}
if (! strcmp(str, "usb"))
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4110);
@@ -131,29 +113,21 @@ hdd_bus_to_string(int bus, int cdrom)
s = "mfm";
break;
case HDD_BUS_XTIDE:
s = "xtide";
case HDD_BUS_XTA:
s = "xta";
break;
case HDD_BUS_ESDI:
s = "esdi";
break;
case HDD_BUS_IDE_PIO_ONLY:
s = cdrom ? "atapi_pio_only" : "ide_pio_only";
break;
case HDD_BUS_IDE_PIO_AND_DMA:
s = cdrom ? "atapi_pio_and_dma" : "ide_pio_and_dma";
case HDD_BUS_IDE:
s = cdrom ? "atapi" : "ide";
break;
case HDD_BUS_SCSI:
s = "scsi";
break;
case HDD_BUS_SCSI_REMOVABLE:
s = "scsi_removable";
break;
}
return(s);
@@ -163,12 +137,14 @@ hdd_bus_to_string(int bus, int cdrom)
int
hdd_is_valid(int c)
{
if (hdd[c].bus == HDD_BUS_DISABLED) return(0);
if (hdd[c].bus == HDD_BUS_DISABLED)
return(0);
if ((wcslen(hdd[c].fn) == 0) &&
(hdd[c].bus != HDD_BUS_SCSI_REMOVABLE)) return(0);
if (wcslen(hdd[c].fn) == 0)
return(0);
if ((hdd[c].tracks==0) || (hdd[c].hpc==0) || (hdd[c].spt==0)) return(0);
if ((hdd[c].tracks==0) || (hdd[c].hpc==0) || (hdd[c].spt==0))
return(0);
return(1);
}

View File

@@ -8,12 +8,12 @@
*
* Definitions for the hard disk image handler.
*
* Version: @(#)hdd.h 1.0.3 2017/10/05
* Version: @(#)hdd.h 1.0.6 2018/06/09
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#ifndef EMU_HDD_H
# define EMU_HDD_H
@@ -23,17 +23,53 @@
/* Hard Disk bus types. */
#if 0
/* Bit 4 = DMA supported (0 = no, 1 yes) - used for IDE and ATAPI only;
Bit 5 = Removable (0 = no, 1 yes). */
enum {
BUS_DISABLED = 0x00,
BUS_MFM = 0x01, /* These four are for hard disk only. */
BUS_XIDE = 0x02,
BUS_XTA = 0x03,
BUS_ESDI = 0x04,
BUS_PANASONIC = 0x21, / These four are for CD-ROM only. */
BUS_PHILIPS = 0x22,
BUS_SONY = 0x23,
BUS_MITSUMI = 0x24,
BUS_IDE_PIO_ONLY = 0x05,
BUS_IDE_PIO_AND_DMA = 0x15,
BUS_IDE_R_PIO_ONLY = 0x25,
BUS_IDE_R_PIO_AND_DMA = 0x35,
BUS_ATAPI_PIO_ONLY = 0x06,
BUS_ATAPI_PIO_AND_DMA = 0x16,
BUS_ATAPI_R_PIO_ONLY = 0x26,
BUS_ATAPI_R_PIO_AND_DMA = 0x36,
BUS_SASI = 0x07,
BUS_SASI_R = 0x27,
BUS_SCSI = 0x08,
BUS_SCSI_R = 0x28,
BUS_USB = 0x09,
BUS_USB_R = 0x29
};
#else
enum {
HDD_BUS_DISABLED = 0,
HDD_BUS_MFM,
HDD_BUS_XTIDE,
HDD_BUS_XTA,
HDD_BUS_ESDI,
HDD_BUS_IDE_PIO_ONLY,
HDD_BUS_IDE_PIO_AND_DMA,
HDD_BUS_IDE,
HDD_BUS_SCSI,
HDD_BUS_SCSI_REMOVABLE,
HDD_BUS_USB
};
#endif
/* Define the virtual Hard Disk. */
@@ -45,18 +81,15 @@ typedef struct {
uint8_t mfm_channel; /* should rename and/or unionize */
uint8_t esdi_channel;
uint8_t xtide_channel;
uint8_t xta_channel;
uint8_t ide_channel;
uint8_t scsi_id;
uint8_t scsi_lun;
uint32_t base;
uint64_t spt,
uint32_t base,
spt,
hpc, /* physical geometry parameters */
tracks;
uint64_t at_spt, /* [Translation] parameters */
tracks,
at_spt, /* [Translation] parameters */
at_hpc;
FILE *f; /* current file handle to image */
@@ -67,7 +100,32 @@ typedef struct {
extern hard_disk_t hdd[HDD_NUM];
extern uint64_t hdd_table[128][3];
extern unsigned int hdd_table[128][3];
typedef struct vhd_footer_t
{
uint8_t cookie[8];
uint32_t features;
uint32_t version;
uint64_t offset;
uint32_t timestamp;
uint8_t creator[4];
uint32_t creator_vers;
uint8_t creator_host_os[4];
uint64_t orig_size;
uint64_t curr_size;
struct {
uint16_t cyl;
uint8_t heads;
uint8_t spt;
} geom;
uint32_t type;
uint32_t checksum;
uint8_t uuid[16];
uint8_t saved_state;
uint8_t reserved[427];
} vhd_footer_t;
extern int hdd_init(void);
@@ -75,6 +133,7 @@ extern int hdd_string_to_bus(char *str, int cdrom);
extern char *hdd_bus_to_string(int bus, int cdrom);
extern int hdd_is_valid(int c);
extern void hdd_image_init(void);
extern int hdd_image_load(int id);
extern void hdd_image_seek(uint8_t id, uint32_t sector);
extern void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer);
@@ -84,13 +143,21 @@ extern int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8
extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count);
extern int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count);
extern uint32_t hdd_image_get_last_sector(uint8_t id);
extern uint32_t hdd_image_get_pos(uint8_t id);
extern uint8_t hdd_image_get_type(uint8_t id);
extern void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt);
extern void hdd_image_unload(uint8_t id, int fn_preserve);
extern void hdd_image_close(uint8_t id);
extern void hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size);
extern void vhd_footer_from_bytes(vhd_footer_t *vhd, uint8_t *bytes);
extern void vhd_footer_to_bytes(uint8_t *bytes, vhd_footer_t *vhd);
extern void new_vhd_footer(vhd_footer_t **vhd);
extern void generate_vhd_checksum(vhd_footer_t *vhd);
extern int image_is_hdi(const wchar_t *s);
extern int image_is_hdx(const wchar_t *s, int check_signature);
extern int image_is_vhd(const wchar_t *s, int check_signature);
#endif /*EMU_HDD_H*/

File diff suppressed because it is too large Load Diff

View File

@@ -9,13 +9,13 @@
* Implementation of the IDE emulation for hard disks and ATAPI
* CD-ROM devices.
*
* Version: @(#)hdd_table.c 1.0.5 2017/11/01
* Version: @(#)hdd_table.c 1.0.5 2018/04/08
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2016,2017 Miran Grca.
* Copyright 2017 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
@@ -26,7 +26,7 @@
#include "hdd.h"
uint64_t hdd_table[128][3] = {
unsigned int hdd_table[128][3] = {
{ 306, 4, 17 }, /* 0 - 7 */
{ 615, 2, 17 },
{ 306, 4, 26 },

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
* Implementation of the Iomega ZIP drive with SCSI(-like)
* commands, for both ATAPI and SCSI usage.
*
* Version: @(#)zip.h 1.0.4 2018/03/20
* Version: @(#)zip.h 1.0.6 2018/04/30
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
@@ -19,20 +19,19 @@
#define EMU_ZIP_H
#define ZIP_NUM 4
#define ZIP_NUM 4
#define ZIP_PHASE_IDLE 0
#define ZIP_PHASE_COMMAND 1
#define ZIP_PHASE_COMPLETE 2
#define ZIP_PHASE_DATA_IN 3
#define ZIP_PHASE_DATA_IN_DMA 4
#define ZIP_PHASE_DATA_OUT 5
#define ZIP_PHASE_DATA_OUT_DMA 6
#define ZIP_PHASE_IDLE 0x00
#define ZIP_PHASE_COMMAND 0x01
#define ZIP_PHASE_COMPLETE 0x02
#define ZIP_PHASE_DATA_IN 0x03
#define ZIP_PHASE_DATA_IN_DMA 0x04
#define ZIP_PHASE_DATA_OUT 0x05
#define ZIP_PHASE_DATA_OUT_DMA 0x06
#define ZIP_PHASE_ERROR 0x80
#define BUF_SIZE 32768
#define IDE_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
#define ZIP_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
#define ZIP_SECTORS (96*2048)
@@ -42,165 +41,111 @@
enum {
ZIP_BUS_DISABLED = 0,
ZIP_BUS_ATAPI_PIO_ONLY = 4,
ZIP_BUS_ATAPI_PIO_AND_DMA,
ZIP_BUS_ATAPI = 4,
ZIP_BUS_SCSI,
ZIP_BUS_USB = 8
ZIP_BUS_USB
};
typedef struct {
uint8_t previous_command;
unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t ide_channel,
bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
int toctimes;
int media_status;
unsigned int scsi_device_id, is_250;
int is_dma;
wchar_t image_path[1024],
prev_image_path[1024];
int requested_blocks; /* This will be set to something other than 1 when block reads are implemented. */
int read_only, ui_writeprot;
uint64_t current_page_code;
int current_page_len;
uint32_t medium_size, base;
int current_page_pos;
int mode_select_phase;
int total_length;
int written_length;
int do_page_save;
uint8_t error;
uint8_t features;
uint16_t request_length;
uint16_t max_transfer_len;
uint8_t status;
uint8_t phase;
uint32_t sector_pos;
uint32_t sector_len;
uint32_t packet_len;
int packet_status;
uint8_t atapi_cdb[16];
uint8_t current_cdb[16];
uint32_t pos;
int callback;
int data_pos;
int cdb_len_setting;
int cdb_len;
int cd_status;
int prev_status;
int unit_attention;
uint8_t sense[256];
int request_pos;
uint8_t *buffer;
int times;
uint32_t seek_pos;
int total_read;
int block_total;
int all_blocks_total;
int old_len;
int block_descriptor_len;
int init_length;
} zip_t;
typedef struct {
int host_drive;
int prev_host_drive;
unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */
uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */
uint8_t ide_channel;
unsigned int scsi_device_id;
unsigned int scsi_device_lun;
unsigned int is_250;
unsigned int atapi_dma;
wchar_t image_path[1024];
wchar_t prev_image_path[1024];
uint32_t medium_size;
int read_only;
int ui_writeprot;
uint32_t base;
FILE *f;
FILE *f;
} zip_drive_t;
typedef struct {
mode_sense_pages_t ms_pages_saved;
extern zip_t zip[ZIP_NUM];
zip_drive_t *drv;
uint8_t previous_command,
error, features,
status, phase,
id, *buffer,
atapi_cdb[16],
current_cdb[16],
sense[256];
uint16_t request_length, max_transfer_len;
int toctimes, media_status,
is_dma, requested_blocks,
current_page_len, current_page_pos,
total_length, written_length,
mode_select_phase, do_page_save,
callback, data_pos,
packet_status, unit_attention,
cdb_len_setting, cdb_len,
request_pos, total_read,
block_total, all_blocks_total,
old_len, block_descriptor_len,
init_length;
uint32_t sector_pos, sector_len,
packet_len, pos,
seek_pos;
uint64_t current_page_code;
} zip_t;
extern zip_t *zip[ZIP_NUM];
extern zip_drive_t zip_drives[ZIP_NUM];
extern uint8_t atapi_zip_drives[8];
extern uint8_t scsi_zip_drives[16][8];
extern uint8_t scsi_zip_drives[16];
#define zip_sense_error zip[id].sense[0]
#define zip_sense_key zip[id].sense[2]
#define zip_asc zip[id].sense[12]
#define zip_ascq zip[id].sense[13]
#define zip_drive zip_drives[id].host_drive
#define zip_sense_error dev->sense[0]
#define zip_sense_key dev->sense[2]
#define zip_asc dev->sense[12]
#define zip_ascq dev->sense[13]
#ifdef __cplusplus
extern "C" {
#endif
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length);
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length);
extern void (*ide_bus_master_set_irq)(int channel);
extern void ioctl_close(uint8_t id);
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv);
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
extern void *ide_bus_master_priv[2];
extern uint32_t zip_mode_sense_get_channel(uint8_t id, int channel);
extern uint32_t zip_mode_sense_get_volume(uint8_t id, int channel);
extern void build_atapi_zip_map(void);
extern void build_scsi_zip_map(void);
extern int zip_ZIP_PHASE_to_scsi(uint8_t id);
extern int zip_atapi_phase_to_scsi(uint8_t id);
extern void zip_command(uint8_t id, uint8_t *cdb);
extern void zip_phase_callback(uint8_t id);
extern int zip_ZIP_PHASE_to_scsi(zip_t *dev);
extern int zip_atapi_phase_to_scsi(zip_t *dev);
extern void zip_command(zip_t *dev, uint8_t *cdb);
extern void zip_phase_callback(zip_t *dev);
extern uint32_t zip_read(uint8_t channel, int length);
extern void zip_write(uint8_t channel, uint32_t val, int length);
extern int zip_lba_to_msf_accurate(int lba);
extern void zip_close(uint8_t id);
extern void zip_disk_reload(uint8_t id);
extern void zip_reset(uint8_t id);
extern void zip_set_signature(int id);
extern void zip_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length);
extern void zip_disk_close(zip_t *dev);
extern void zip_disk_reload(zip_t *dev);
extern void zip_reset(zip_t *dev);
extern void zip_set_signature(zip_t *dev);
extern void zip_request_sense_for_scsi(zip_t *dev, uint8_t *buffer, uint8_t alloc_length);
extern void zip_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks);
extern void zip_insert(uint8_t id);
extern void zip_insert(zip_t *dev);
extern int find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun);
extern int zip_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
extern int find_zip_for_scsi_id(uint8_t scsi_id);
extern int zip_read_capacity(zip_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
extern void zip_global_init(void);
extern void zip_hard_reset(void);
extern int zip_load(uint8_t id, wchar_t *fn);
extern void zip_close(uint8_t id);
extern int zip_load(zip_t *dev, wchar_t *fn);
extern void zip_close();
#ifdef __cplusplus
}

1666
src/dma.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,40 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the 86Box distribution.
* This file is part of the VARCem Project.
*
* Implementation of the Intel DMA controllers.
* Definitions for the Intel DMA controller.
*
* Version: @(#)dma.h 1.0.5 2018/03/11
* Version: @(#)dma.h 1.0.2 2018/03/12
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef EMU_DMA_H
# define EMU_DMA_H
@@ -25,25 +45,25 @@
#define DMA_VERIFY 0x20000
/*DMA*/
typedef struct dma_t
{
uint32_t ab, ac;
uint16_t cb;
int cc;
int wp;
uint8_t m, mode;
uint8_t page;
uint8_t stat, stat_rq;
uint8_t command;
int size;
uint8_t ps2_mode;
uint8_t arb_level;
uint16_t io_addr;
typedef struct {
uint32_t ab, ac;
uint16_t cb;
int cc;
int wp;
uint8_t m, mode;
uint8_t page;
uint8_t stat, stat_rq;
uint8_t command;
int size;
uint8_t ps2_mode;
uint8_t arb_level;
uint16_t io_addr;
} dma_t;
extern dma_t dma[8];
extern dma_t dma[8];
extern void dma_init(void);
extern void dma16_init(void);

View File

@@ -9,7 +9,7 @@
* Implementation of the NEC uPD-765 and compatible floppy disk
* controller.
*
* Version: @(#)fdc.c 1.0.5 2018/03/16
* Version: @(#)fdc.c 1.0.9 2018/06/12
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
@@ -133,10 +133,14 @@ fdc_log(const char *fmt, ...)
uint8_t
fdc_ps1_525(void)
{
if ((romset == ROM_IBMPS1_2011) && fdd_is_525(current_drive))
return 0x40;
else
return 0;
switch (romset) {
case ROM_IBMPS1_2011:
case ROM_IBMPS1_2121:
case ROM_IBMPS1_2121_ISA:
return fdd_is_525(current_drive) ? 0x40 : 0x00;
default:
return 0x00;
}
}
@@ -151,6 +155,7 @@ fdc_ctrl_reset(void *p)
fdc->lock = 0;
fdc->head = 0;
fdc->abort = 0;
fdc->step = 0;
if (!(fdc->flags & FDC_FLAG_AT))
fdc->rate = 2;
}
@@ -214,7 +219,7 @@ static void fdc_rate(fdc_t *fdc, int drive);
int
fdc_get_perp(fdc_t *fdc)
{
if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR) || (fdc->flags & FDC_FLAG_PS1))
if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR))
return 0;
return fdc->perp;
@@ -226,7 +231,7 @@ fdc_get_gap2(fdc_t *fdc, int drive)
{
int auto_gap2 = 22;
if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR) || (fdc->flags & FDC_FLAG_PS1))
if (!(fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_PCJR))
return 22;
if (fdc->perp & 3)
@@ -608,7 +613,7 @@ void
fdc_seek(fdc_t *fdc, int drive, int params)
{
fdd_seek(real_drive(fdc, drive), params);
fdc->time = 5000 * TIMER_SHIFT;
fdc->time = 5000LL * (1 << TIMER_SHIFT);
fdc->stat |= (1 << fdc->drive);
}
@@ -715,7 +720,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
case 1:
return;
case 2: /*DOR*/
if ((fdc->flags & FDC_FLAG_PCJR)) {
if (fdc->flags & FDC_FLAG_PCJR) {
if ((fdc->dor & 0x40) && !(val & 0x40)) {
fdc->watchdog_timer = 1000LL * TIMER_USEC;
fdc->watchdog_count = 1000LL;
@@ -728,6 +733,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc->interrupt = -1;
ui_sb_update_icon(SB_FLOPPY | 0, 0);
fdc_ctrl_reset(fdc);
fdd_changed[0] = 1;
fdd_changed[1] = 1;
fdd_changed[2] = 1;
fdd_changed[3] = 1;
}
if (!fdd_get_flags(0))
val &= 0xfe;
@@ -793,6 +802,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc->perp &= 0xfc;
fdc_ctrl_reset(fdc);
}
/* if (fdc->flags & FDC_FLAG_PS1)
fdc->rate = val & 0x03; */
return;
case 5: /*Command register*/
if ((fdc->stat & 0xf0) == 0xb0) {
@@ -935,7 +946,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc_callback(fdc);
break;
case 0x12: /*Set perpendicular mode*/
if ((fdc->flags & FDC_FLAG_AT) && !(fdc->flags & FDC_FLAG_PCJR) && !(fdc->flags & FDC_FLAG_PS1)) {
if ((fdc->flags & FDC_FLAG_AT) && !(fdc->flags & FDC_FLAG_PCJR)) {
fdc->pnum=0;
fdc->ptot=1;
fdc->stat |= 0x90;
@@ -981,6 +992,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
fdc->read_track_sector.id.h = fdc->params[2];
fdc->read_track_sector.id.r = 1;
fdc->read_track_sector.id.n = fdc->params[4];
if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) {
fdc_noidam(fdc);
return;
}
fdd_readsector(real_drive(fdc, fdc->drive), SECTOR_FIRST, fdc->params[1], fdc->head, fdc->rate, fdc->params[4]);
break;
case 3: /*Specify*/
@@ -1006,12 +1021,20 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
case 5: /*Write data*/
case 9: /*Write deleted data*/
fdc_io_command_phase1(fdc, 1);
if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) {
fdc_noidam(fdc);
return;
}
fdd_writesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->params[1], fdc->head, fdc->rate, fdc->params[4]);
break;
case 0x11: /*Scan equal*/
case 0x19: /*Scan low or equal*/
case 0x1D: /*Scan high or equal*/
fdc_io_command_phase1(fdc, 1);
if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) {
fdc_noidam(fdc);
return;
}
fdd_comparesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->params[1], fdc->head, fdc->rate, fdc->params[4]);
break;
case 0x16: /*Verify*/
@@ -1021,6 +1044,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
case 0xC: /*Read deleted data*/
fdc_io_command_phase1(fdc, 0);
fdc_log("Reading sector (drive %i) (%i) (%i %i %i %i) (%i %i %i)\n", fdc->drive, fdc->params[0], fdc->params[1], fdc->params[2], fdc->params[3], fdc->params[4], fdc->params[5], fdc->params[6], fdc->params[7]);
if ((fdc->head & 0x01) && !fdd_is_double_sided(real_drive(fdc, fdc->drive))) {
fdc_noidam(fdc);
return;
}
if (((dma_mode(2) & 0x0C) == 0x00) && !(fdc->flags & FDC_FLAG_PCJR) && fdc->dma) {
/* DMA is in verify mode, treat this like a VERIFY command. */
fdc_log("Verify-mode read!\n");
@@ -1054,7 +1081,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
if ((real_drive(fdc, fdc->drive) != 1) || fdc->drv2en)
fdc_seek(fdc, fdc->drive, -fdc->max_track);
fdc_log("Recalibrating...\n");
fdc->time = 5000LL;
fdc->time = 5000LL * (1 << TIMER_SHIFT);
fdc->step = fdc->seek_dir = 1;
break;
case 0x0d: /*Format*/
fdc_rate(fdc, fdc->drive);
@@ -1098,14 +1126,17 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
if (fdc->params[1]) {
if (fdc->command & 0x40) {
/* Relative seek inwards. */
fdc->seek_dir = 0;
fdc_seek(fdc, fdc->drive, fdc->params[1]);
fdc->pcn[fdc->params[0] & 3] += fdc->params[1];
} else {
/* Relative seek outwards. */
fdc->seek_dir = 1;
fdc_seek(fdc, fdc->drive, -fdc->params[1]);
fdc->pcn[fdc->params[0] & 3] -= fdc->params[1];
}
fdc->time = 5000LL;
fdc->time = 5000LL * (1 << TIMER_SHIFT);
fdc->step = 1;
} else {
fdc->st0 = 0x20 | (fdc->params[0] & 7);
fdc->interrupt = -3;
@@ -1125,9 +1156,14 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
timer_update_outstanding();
break;
}
if (fdc->params[1] > fdc->pcn[fdc->params[0] & 3])
fdc->seek_dir = 0;
else
fdc->seek_dir = 1;
fdc_seek(fdc, fdc->drive, fdc->params[1] - fdc->pcn[fdc->params[0] & 3]);
fdc->pcn[fdc->params[0] & 3] = fdc->params[1];
fdc->time = 5000LL;
fdc->time = 5000LL * (1 << TIMER_SHIFT);
fdc->step = 1;
fdc_log("fdc->time = %i\n", fdc->time);
}
break;
@@ -1154,7 +1190,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
case 7:
if (!(fdc->flags & FDC_FLAG_AT))
return;
fdc->rate=val&3;
fdc->rate = val & 0x03;
if (fdc->flags & FDC_FLAG_PS1)
fdc->noprec = !!(val & 0x04);
return;
}
}
@@ -1171,24 +1209,58 @@ fdc_read(uint16_t addr, void *priv)
switch (addr&7) {
case 0: /* STA */
ret = 0xff;
if (fdc->flags & FDC_FLAG_PS1) {
drive = real_drive(fdc, fdc->dor & 3);
ret = 0x00;
/* TODO:
Bit 2: INDEX (best return always 0 as it goes by very fast)
Bit 6: DRQ
*/
if (writeprot[drive]) /* WRITEPROT */
ret |= 0x01;
if (fdc->seek_dir) /* nDIRECTION */
ret |= 0x02;
if (!fdd_get_head(drive)) /* nHDSEL */
ret |= 0x08;
if (fdd_track0(drive)) /* TRK0 */
ret |= 0x10;
if (fdc->step) /* STEP */
ret |= 0x20;
if (fdc->fintr || fdc->reset_stat) /* INTR */
ret |= 0x80;
} else
ret = 0xff;
break;
case 1: /* STB */
if (is486)
return 0xff;
drive = real_drive(fdc, fdc->dor & 3);
if (!fdc->enable_3f1)
ret = 0xff;
ret = 0x70;
if (drive)
ret &= ~0x40;
else
ret &= ~0x20;
if (fdc->flags & FDC_FLAG_PS1) {
drive = real_drive(fdc, fdc->dor & 3);
ret = 0x00;
/* -Drive 2 Installed */
if (!fdd_get_type(1))
ret |= 80;
/* -Drive Select 1,0 */
if (drive)
ret |= 0x20;
else
ret |= 0x40;
} else {
if (is486)
return 0xff;
drive = real_drive(fdc, fdc->dor & 3);
if (!fdc->enable_3f1)
ret = 0xff;
if (fdc->dor & 0x10)
ret |= 1;
if (fdc->dor & 0x20)
ret |= 2;
ret = 0x70;
if (drive)
ret &= ~0x40;
else
ret &= ~0x20;
if (fdc->dor & 0x10)
ret |= 1;
if (fdc->dor & 0x20)
ret |= 2;
}
break;
case 2:
ret = fdc->dor;
@@ -1252,13 +1324,27 @@ fdc_read(uint16_t addr, void *priv)
break;
case 7: /*Disk change*/
drive = real_drive(fdc, fdc->dor & 3);
if (fdc->dor & (0x10 << drive))
ret = (fdd_changed[drive] || drive_empty[drive])?0x80:0;
else
ret = 0;
if (fdc->flags & FDC_FLAG_DISKCHG_ACTLOW) /*PC2086/3086 seem to reverse this bit*/
ret ^= 0x80;
ret |= 0x01;
if (fdc->flags & FDC_FLAG_PS1) {
if (fdc->dor & (0x10 << drive)) {
ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x00 : 0x80;
ret |= (fdc->dor & 0x08);
ret |= (fdc->noprec << 2);
ret |= (fdc->rate & 0x03);
} else
ret = 0x00;
} else {
if (fdc->dor & (0x10 << drive))
ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x80 : 0x00;
else
ret = 0x00;
if (fdc->flags & FDC_FLAG_DISKCHG_ACTLOW) /*PC2086/3086 seem to reverse this bit*/
ret ^= 0x80;
ret |= 0x01;
}
fdc->step = 0;
break;
default:
ret = 0xFF;
@@ -1271,7 +1357,8 @@ static void
fdc_poll_common_finish(fdc_t *fdc, int compare, int st5)
{
fdc_int(fdc);
fdc->fintr = 0;
if (!(fdc->flags & FDC_FLAG_PS1))
fdc->fintr = 0;
fdc->stat = 0xD0;
fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive;
fdc->res[5] = st5;
@@ -1376,7 +1463,9 @@ fdc_callback(void *priv)
fdc->inread = 1;
return;
case 4: /*Sense drive status*/
fdc->res[10] = (fdc->params[0] & 7) | 0x28;
fdc->res[10] = (fdc->params[0] & 7) | 0x20;
if (fdd_is_double_sided(real_drive(fdc, fdc->drive)))
fdc->res[10] |= 0x08;
if ((real_drive(fdc, fdc->drive) != 1) || fdc->drv2en) {
if (fdd_track0(real_drive(fdc, fdc->drive)))
fdc->res[10] |= 0x10;
@@ -1468,10 +1557,14 @@ fdc_callback(void *priv)
fdc_poll_readwrite_finish(fdc, compare);
return;
}
if ((fdc->command & 0x80) && (fdd_get_head(real_drive(fdc, fdc->drive)) == 0)) {
if ((fdd_get_head(real_drive(fdc, fdc->drive)) == 0)) {
fdc->sector = 1;
fdc->head |= 1;
fdd_set_head(real_drive(fdc, fdc->drive), 1);
if (!fdd_is_double_sided(real_drive(fdc, fdc->drive))) {
fdc_noidam(fdc);
return;
}
}
} else if (fdc->sector < fdc->params[5])
fdc->sector++;
@@ -1530,7 +1623,8 @@ fdc_callback(void *priv)
} else {
fdc->interrupt = -2;
fdc_int(fdc);
fdc->fintr = 0;
if (!(fdc->flags & FDC_FLAG_PS1))
fdc->fintr = 0;
fdc->stat = 0xD0;
fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->drive;
fdc->res[5] = fdc->res[6] = 0;
@@ -1612,9 +1706,12 @@ fdc_error(fdc_t *fdc, int st5, int st6)
fdc->time = 0LL;
fdc_int(fdc);
fdc->fintr = 0;
if (!(fdc->flags & FDC_FLAG_PS1))
fdc->fintr = 0;
fdc->stat = 0xD0;
fdc->st0 = fdc->res[4] = 0x40 | (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive;
if (fdc->head && !fdd_is_double_sided(real_drive(fdc, fdc->drive)))
fdc->st0 |= 0x08;
fdc->res[5] = st5;
fdc->res[6] = st6;
fdc_log("FDC Error: %02X %02X %02X\n", fdc->res[4], fdc->res[5], fdc->res[6]);
@@ -1977,7 +2074,10 @@ fdc_reset(void *priv)
fdc_update_is_nsc(fdc, 0);
fdc_update_enh_mode(fdc, 0);
fdc_update_densel_polarity(fdc, 1);
if (fdc->flags & FDC_FLAG_PS1)
fdc_update_densel_polarity(fdc, 0);
else
fdc_update_densel_polarity(fdc, 1);
fdc_update_densel_force(fdc, 0);
fdc_update_rwc(fdc, 0, default_rwc);
fdc_update_rwc(fdc, 1, default_rwc);
@@ -1992,7 +2092,7 @@ fdc_reset(void *priv)
fdc->fifo = 0;
fdc->tfifo = 1;
if ((fdc->flags & FDC_FLAG_PCJR)) {
if (fdc->flags & FDC_FLAG_PCJR) {
fdc->dma = 0;
fdc->specify[1] = 1;
} else {
@@ -2082,7 +2182,7 @@ const device_t fdc_xt_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t fdc_pcjr_device = {
@@ -2092,7 +2192,7 @@ const device_t fdc_pcjr_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t fdc_at_device = {
@@ -2102,7 +2202,7 @@ const device_t fdc_at_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t fdc_at_actlow_device = {
@@ -2112,7 +2212,7 @@ const device_t fdc_at_actlow_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t fdc_at_ps1_device = {
@@ -2122,7 +2222,7 @@ const device_t fdc_at_ps1_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t fdc_at_smc_device = {
@@ -2132,7 +2232,7 @@ const device_t fdc_at_smc_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t fdc_at_winbond_device = {
@@ -2142,7 +2242,7 @@ const device_t fdc_at_winbond_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t fdc_at_nsc_device = {
@@ -2152,5 +2252,5 @@ const device_t fdc_at_nsc_device = {
fdc_init,
fdc_close,
fdc_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};

View File

@@ -9,7 +9,7 @@
* Implementation of the NEC uPD-765 and compatible floppy disk
* controller.
*
* Version: @(#)fdc.h 1.0.3 2018/03/17
* Version: @(#)fdc.h 1.0.4 2018/04/12
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -70,6 +70,8 @@ typedef struct {
int abort;
int format_state, format_n;
int tc, written;
int step, seek_dir;
int noprec;
int data_ready, inread;
int bitcell_period, enh_mode;

View File

@@ -8,7 +8,7 @@
*
* Implementation of the floppy drive emulation.
*
* Version: @(#)fdd.c 1.0.5 2018/03/16
* Version: @(#)fdd.c 1.0.9 2018/05/13
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -36,10 +36,12 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../machine/machine.h"
#include "../mem.h"
@@ -114,6 +116,7 @@ static const struct
{L"BIN", img_load, img_close, -1},
{L"CQ", img_load, img_close, -1},
{L"CQM", img_load, img_close, -1},
{L"DDI", img_load, img_close, -1},
{L"DSK", img_load, img_close, -1},
{L"FDI", fdi_load, fdi_close, -1},
{L"FDF", img_load, img_close, -1},
@@ -226,6 +229,27 @@ static const struct
}
};
#ifdef ENABLE_FDD_LOG
int fdd_do_log = ENABLE_FDD_LOG;
#endif
static void
fdd_log(const char *fmt, ...)
{
#ifdef ENABLE_FDD_LOG
va_list ap;
if (fdd_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
char *fdd_getname(int type)
{
return (char *)drive_types[type].name;
@@ -357,7 +381,7 @@ int fdd_can_read_medium(int drive)
{
int hole = fdd_hole(drive);
hole = 1 << (hole + 3);
hole = 1 << (hole + 4);
return (drive_types[fdd[drive].type].flags & hole) ? 1 : 0;
}
@@ -409,11 +433,16 @@ int fdd_is_double_sided(int drive)
void fdd_set_head(int drive, int head)
{
fdd[drive].head = head;
if (head && !fdd_is_double_sided(drive))
fdd[drive].head = 0;
else
fdd[drive].head = head;
}
int fdd_get_head(int drive)
{
if (!fdd_is_double_sided(drive))
return 0;
return fdd[drive].head;
}
@@ -455,7 +484,7 @@ void fdd_load(int drive, wchar_t *fn)
wchar_t *p;
FILE *f;
pclog("FDD: loading drive %d with '%ls'\n", drive, fn);
fdd_log("FDD: loading drive %d with '%ls'\n", drive, fn);
if (!fn) return;
p = plat_get_extension(fn);
@@ -480,7 +509,7 @@ void fdd_load(int drive, wchar_t *fn)
}
c++;
}
pclog("FDD: could not load '%ls' %s\n",fn,p);
fdd_log("FDD: could not load '%ls' %s\n",fn,p);
drive_empty[drive] = 1;
fdd_set_head(drive, 0);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
@@ -489,13 +518,12 @@ void fdd_load(int drive, wchar_t *fn)
void fdd_close(int drive)
{
pclog("FDD: closing drive %d\n", drive);
fdd_log("FDD: closing drive %d\n", drive);
if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive);
drive_empty[drive] = 1;
fdd_set_head(drive, 0);
floppyfns[drive][0] = 0;
d86f_destroy(drive);
drives[drive].hole = NULL;
drives[drive].poll = NULL;
drives[drive].seek = NULL;
@@ -506,6 +534,7 @@ void fdd_close(int drive)
drives[drive].format = NULL;
drives[drive].byteperiod = NULL;
drives[drive].stop = NULL;
d86f_destroy(drive);
ui_sb_update_icon_state(drive, 1);
}

View File

@@ -8,7 +8,7 @@
*
* Definitions for the floppy drive emulation.
*
* Version: @(#)fdd.h 1.0.3 2018/03/17
* Version: @(#)fdd.h 1.0.4 2018/04/12
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -135,7 +135,6 @@ extern void fdd_format(int drive, int side, int density, uint8_t fill);
extern int fdd_hole(int drive);
extern double fdd_byteperiod(int drive);
extern void fdd_stop(int drive);
extern int fdd_empty(int drive);
extern void fdd_set_rate(int drive, int drvden, int rate);
extern int motorspin;

View File

@@ -10,7 +10,7 @@
* data in the form of FM/MFM-encoded transitions) which also
* forms the core of the emulator's floppy disk emulation.
*
* Version: @(#)fdd_86f.c 1.0.7 2018/03/19
* Version: @(#)fdd_86f.c 1.0.10 2018/06/12
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -46,6 +46,7 @@
#define HAVE_STDARG_H
#include "../86box.h"
#include "../config.h"
#include "../device.h"
#include "../dma.h"
#include "../nvr.h"
#include "../random.h"
@@ -54,7 +55,9 @@
#include "fdd.h"
#include "fdc.h"
#include "fdd_86f.h"
#ifdef D86F_COMPRESS
#include "lzf/lzf.h"
#endif
/*
@@ -225,7 +228,9 @@ typedef struct {
uint16_t current_bit[2];
int cur_track;
uint32_t error_condition;
#ifdef D86F_COMPRESS
int is_compressed;
#endif
int id_found;
wchar_t original_file_name[2048];
uint8_t *filebuf;
@@ -1430,9 +1435,9 @@ d86f_read_sector_id(int drive, int side, int match)
dev->state = STATE_IDLE;
fdc_finishread(d86f_fdc);
fdc_headercrcerror(d86f_fdc);
} else if (dev->state == STATE_0A_READ_ID) {
} else if (dev->state == STATE_0A_READ_ID)
dev->state--;
} else {
else {
dev->error_condition |= 1; /* Mark that there was an ID CRC error. */
dev->state++;
}
@@ -1544,6 +1549,7 @@ d86f_read_sector_data(int drive, int side)
if (dev->data_find.bits_obtained) {
if (!(dev->data_find.bits_obtained & 15)) {
/* We've got a byte. */
d86f_log("86F: We've got a byte.\n");
if (dev->data_find.bytes_obtained < sector_len) {
data = decodefm(drive, dev->last_word[side]);
if (dev->state == STATE_11_SCAN_DATA) {
@@ -1554,33 +1560,18 @@ d86f_read_sector_data(int drive, int side)
if (dev->data_find.bytes_obtained < d86f_get_data_len(drive)) {
if (dev->state != STATE_16_VERIFY_DATA) {
read_status = fdc_data(d86f_fdc, data);
if (read_status == -1) {
if (read_status == -1)
dev->dma_over++;
}
}
}
}
fdd_calccrc(data, &(dev->calc_crc));
} else if (dev->data_find.bytes_obtained < crc_pos) {
} else if (dev->data_find.bytes_obtained < crc_pos)
dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = decodefm(drive, dev->last_word[side]);
}
dev->data_find.bytes_obtained++;
if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) {
/* We've got the data. */
if (dev->dma_over > 1) {
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
dev->error_condition = 0;
dev->state = STATE_IDLE;
fdc_finishread(d86f_fdc);
fdc_overrun(d86f_fdc);
d86f_get_bit(drive, side);
dev->data_find.bits_obtained++;
return;
}
if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) {
d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword);
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
@@ -1595,15 +1586,14 @@ d86f_read_sector_data(int drive, int side)
fdc_track_finishread(d86f_fdc, dev->error_condition);
} else {
/* CRC is valid. */
d86f_log("86F: Data CRC OK: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword);
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
dev->error_condition = 0;
if (dev->state == STATE_11_SCAN_DATA) {
dev->state = STATE_IDLE;
dev->state = STATE_IDLE;
if (dev->state == STATE_11_SCAN_DATA)
fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0);
} else {
dev->state = STATE_IDLE;
else
fdc_sector_finishread(d86f_fdc);
}
}
}
}
@@ -1699,17 +1689,6 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
dev->data_find.bytes_obtained++;
if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) {
if (dev->dma_over > 1) {
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
dev->error_condition = 0;
dev->state = STATE_IDLE;
fdc_finishread(d86f_fdc);
fdc_overrun(d86f_fdc);
dev->data_find.bits_obtained++;
return;
}
/* We've written the data. */
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
dev->error_condition = 0;
@@ -2138,15 +2117,6 @@ d86f_turbo_read(int drive, int side)
}
}
if (dev->dma_over > 1) {
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
dev->error_condition = 0;
dev->state = STATE_IDLE;
fdc_finishread(d86f_fdc);
fdc_overrun(d86f_fdc);
return;
}
if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) {
/* CRC is valid. */
dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0;
@@ -2568,7 +2538,8 @@ d86f_poll(int drive)
fdc_wrongcylinder(d86f_fdc);
else
fdc_nosector(d86f_fdc);
}
} else
fdc_nosector(d86f_fdc);
} else {
fdc_noidam(d86f_fdc);
}
@@ -3084,9 +3055,11 @@ d86f_writeback(int drive)
d86f_t *dev = d86f[drive];
uint8_t header[32];
int header_size;
#ifdef D86F_COMPRESS
uint32_t len;
int ret = 0;
FILE *cf;
#endif
header_size = d86f_header_size(drive);
if (! dev->f) return;
@@ -3100,6 +3073,7 @@ d86f_writeback(int drive)
d86f_write_tracks(drive, &dev->f, NULL);
#ifdef D86F_COMPRESS
if (dev->is_compressed) {
/* The image is compressed. */
@@ -3128,6 +3102,7 @@ d86f_writeback(int drive)
free(dev->outbuf);
free(dev->filebuf);
}
#endif
}
@@ -3182,7 +3157,8 @@ d86f_readsector(int drive, int sector, int track, int side, int rate, int sector
int ret = 0;
ret = d86f_common_command(drive, sector, track, side, rate, sector_size);
if (! ret) return;
if (! ret)
return;
if (sector == SECTOR_FIRST)
dev->state = STATE_02_SPIN_TO_INDEX;
@@ -3450,13 +3426,15 @@ d86f_export(int drive, wchar_t *fn)
void
d86f_load(int drive, wchar_t *fn)
{
wchar_t temp_file_name[2048];
d86f_t *dev = d86f[drive];
uint32_t magic = 0;
uint32_t len = 0;
uint16_t temp = 0;
int i = 0, j = 0;
#ifdef D86F_COMPRESS
wchar_t temp_file_name[2048];
uint16_t temp = 0;
FILE *tf;
#endif
d86f_unregister(drive);
@@ -3533,8 +3511,12 @@ d86f_load(int drive, wchar_t *fn)
}
}
#ifdef D86F_COMPRESS
dev->is_compressed = (magic == 0x66623638) ? 1 : 0;
if ((len < 51052) && !dev->is_compressed) {
#else
if (len < 51052) {
#endif
/* File too small, abort. */
fclose(dev->f);
dev->f = NULL;
@@ -3567,6 +3549,7 @@ d86f_load(int drive, wchar_t *fn)
}
#endif
#ifdef D86F_COMPRESS
if (dev->is_compressed) {
memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 256);
memcpy(dev->original_file_name, fn, (wcslen(fn) << 1) + 2);
@@ -3613,15 +3596,17 @@ d86f_load(int drive, wchar_t *fn)
dev->f = plat_fopen(temp_file_name, L"rb+");
}
#endif
if (dev->disk_flags & 0x100) {
/* Zoned disk. */
d86f_log("86F: Disk is zoned (Apple or Sony)\n");
fclose(dev->f);
dev->f = NULL;
if (dev->is_compressed) {
#ifdef D86F_COMPRESS
if (dev->is_compressed)
plat_remove(temp_file_name);
}
#endif
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
free(dev);
return;
@@ -3632,8 +3617,10 @@ d86f_load(int drive, wchar_t *fn)
d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n");
fclose(dev->f);
dev->f = NULL;
#ifdef D86F_COMPRESS
if (dev->is_compressed)
plat_remove(temp_file_name);
#endif
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
free(dev);
return;
@@ -3648,9 +3635,11 @@ d86f_load(int drive, wchar_t *fn)
fclose(dev->f);
dev->f = NULL;
#ifdef D86F_COMPRESS
if (dev->is_compressed)
dev->f = plat_fopen(temp_file_name, L"rb");
else
else
#endif
dev->f = plat_fopen(fn, L"rb");
}
@@ -3735,9 +3724,14 @@ d86f_load(int drive, wchar_t *fn)
d86f_common_handlers(drive);
drives[drive].format = d86f_format;
#ifdef D86F_COMPRESS
d86f_log("86F: Disk is %scompressed and does%s have surface description data\n",
dev->is_compressed ? "" : "not ",
d86f_has_surface_desc(drive) ? "" : " not");
#else
d86f_log("86F: Disk does%s have surface description data\n",
d86f_has_surface_desc(drive) ? "" : " not");
#endif
}
@@ -3795,8 +3789,10 @@ d86f_close(int drive)
fclose(dev->f);
dev->f = NULL;
}
#ifdef D86F_COMPRESS
if (dev->is_compressed)
plat_remove(temp_file_name);
#endif
}

View File

@@ -9,7 +9,7 @@
* Implementation of the FDI floppy stream image format
* interface to the FDI2RAW module.
*
* Version: @(#)fdd_fdi.c 1.0.2 2018/03/17
* Version: @(#)fdd_fdi.c 1.0.3 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -37,11 +37,13 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../plat.h"
#include "fdd.h"
@@ -71,6 +73,27 @@ static fdi_t *fdi[FDD_NUM];
static fdc_t *fdi_fdc;
#ifdef ENABLE_FDI_LOG
int fdi_do_log = ENABLE_FDI_LOG;
#endif
static void
fdi_log(const char *fmt, ...)
{
#ifdef ENABLE_FDI_LOG
va_list ap;
if (fdi_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static uint16_t
disk_flags(int drive)
{
@@ -339,7 +362,7 @@ fdi_load(int drive, wchar_t *fn)
header[25] = 0;
if (strcmp(header, "Formatted Disk Image file") != 0) {
/* This is a Japanese FDI file. */
pclog("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n");
fdi_log("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n");
fclose(dev->f);
free(dev);
img_load(drive, fn);
@@ -372,7 +395,7 @@ fdi_load(int drive, wchar_t *fn)
drives[drive].seek = fdi_seek;
pclog("Loaded as FDI\n");
fdi_log("Loaded as FDI\n");
}

View File

@@ -8,7 +8,7 @@
*
* Implementation of the IMD floppy image format.
*
* Version: @(#)fdd_imd.c 1.0.6 2018/03/19
* Version: @(#)fdd_imd.c 1.0.7 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -34,11 +34,13 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../plat.h"
#include "fdd.h"
@@ -82,6 +84,27 @@ static imd_t *imd[FDD_NUM];
static fdc_t *imd_fdc;
#ifdef ENABLE_IMD_LOG
int imd_do_log = ENABLE_IMD_LOG;
#endif
static void
imd_log(const char *fmt, ...)
{
#ifdef ENABLE_IMD_LOG
va_list ap;
if (imd_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static uint32_t
get_raw_tsize(int side_flags, int slower_rpm)
{
@@ -617,13 +640,13 @@ imd_load(int drive, wchar_t *fn)
fseek(dev->f, 0, SEEK_SET);
fread(&magic, 1, 4, dev->f);
if (magic != 0x20444D49) {
pclog("IMD: Not a valid ImageDisk image\n");
imd_log("IMD: Not a valid ImageDisk image\n");
fclose(dev->f);
free(dev);;
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
return;
} else {
pclog("IMD: Valid ImageDisk image\n");
imd_log("IMD: Valid ImageDisk image\n");
}
fseek(dev->f, 0, SEEK_END);
@@ -635,24 +658,24 @@ imd_load(int drive, wchar_t *fn)
buffer2 = strchr(buffer, 0x1A);
if (buffer2 == NULL) {
pclog("IMD: No ASCII EOF character\n");
imd_log("IMD: No ASCII EOF character\n");
fclose(dev->f);
free(dev);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
return;
} else {
pclog("IMD: ASCII EOF character found at offset %08X\n", buffer2 - buffer);
imd_log("IMD: ASCII EOF character found at offset %08X\n", buffer2 - buffer);
}
buffer2++;
if ((buffer2 - buffer) == fsize) {
pclog("IMD: File ends after ASCII EOF character\n");
imd_log("IMD: File ends after ASCII EOF character\n");
fclose(dev->f);
free(dev);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
return;
} else {
pclog("IMD: File continues after ASCII EOF character\n");
imd_log("IMD: File continues after ASCII EOF character\n");
}
dev->start_offs = (buffer2 - buffer);
@@ -691,7 +714,7 @@ imd_load(int drive, wchar_t *fn)
dev->tracks[track][side].side_flags |= 0x20;
if ((dev->tracks[track][side].side_flags & 7) == 1)
dev->tracks[track][side].side_flags |= 0x20;
/* pclog("Side flags for (%02i)(%01i): %02X\n", track, side, dev->tracks[track][side].side_flags); */
/* imd_log("Side flags for (%02i)(%01i): %02X\n", track, side, dev->tracks[track][side].side_flags); */
dev->tracks[track][side].is_present = 1;
dev->tracks[track][side].file_offs = (buffer2 - buffer);
memcpy(dev->tracks[track][side].params, buffer2, 5);
@@ -766,7 +789,7 @@ imd_load(int drive, wchar_t *fn)
dev->disk_flags |= (3 << 5);
if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) {
/* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */
pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt);
imd_log("IMD: Unable to fit the %i sectors in a track\n", track_spt);
fclose(dev->f);
free(dev);
imd[drive] = NULL;
@@ -779,7 +802,7 @@ imd_load(int drive, wchar_t *fn)
} else if (gap3_sizes[converted_rate][sector_size][track_spt] != 0x00)
dev->tracks[track][side].gap3_len = gap3_sizes[converted_rate][sector_size][track_spt];
/* pclog("GAP3 length for (%02i)(%01i): %i bytes\n", track, side, dev->tracks[track][side].gap3_len); */
/* imd_log("GAP3 length for (%02i)(%01i): %i bytes\n", track, side, dev->tracks[track][side].gap3_len); */
if (track > dev->track_count)
dev->track_count = track;
@@ -797,7 +820,7 @@ imd_load(int drive, wchar_t *fn)
if (dev->sides == 2)
dev->disk_flags |= 8;
/* pclog("%i tracks, %i sides\n", dev->track_count, dev->sides); */
/* imd_log("%i tracks, %i sides\n", dev->track_count, dev->sides); */
/* Attach this format to the D86F engine. */
d86f_handler[drive].disk_flags = disk_flags;

View File

@@ -13,7 +13,7 @@
* re-merged with the other files. Much of it is generic to
* all formats.
*
* Version: @(#)fdd_img.c 1.0.5 2018/03/17
* Version: @(#)fdd_img.c 1.0.8 2018/05/09
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -41,11 +41,13 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../config.h"
#include "../plat.h"
@@ -297,6 +299,27 @@ const int gap3_sizes[5][8][48] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } };
#ifdef ENABLE_IMG_LOG
int img_do_log = ENABLE_IMG_LOG;
#endif
static void
img_log(const char *fmt, ...)
{
#ifdef ENABLE_IMG_LOG
va_list ap;
if (img_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
/* Generic */
static int
sector_size_code(int sector_size)
@@ -605,7 +628,7 @@ img_load(int drive, wchar_t *fn)
uint8_t bpb_mid; /* Media type ID. */
uint8_t bpb_sectors;
uint8_t bpb_sides;
uint8_t fdi, cqm, fdf;
uint8_t cqm, ddi, fdf, fdi;
uint16_t comment_len = 0;
int16_t block_len = 0;
uint32_t cur_pos = 0;
@@ -646,13 +669,19 @@ img_load(int drive, wchar_t *fn)
writeprot[drive] = 1;
fwriteprot[drive] = writeprot[drive];
fdi = cqm = 0;
cqm = ddi = fdf = fdi = 0;
dev->interleave = dev->skew = 0;
if (! wcscasecmp(ext, L"DDI")) {
ddi = 1;
dev->base = 0x2400;
} else
dev->base = 0;
if (! wcscasecmp(ext, L"FDI")) {
/* This is a Japanese FDI image, so let's read the header */
pclog("img_load(): File is a Japanese FDI image...\n");
img_log("img_load(): File is a Japanese FDI image...\n");
fseek(dev->f, 0x10, SEEK_SET);
(void)fread(&bpb_bps, 1, 2, dev->f);
fseek(dev->f, 0x0C, SEEK_SET);
@@ -689,7 +718,7 @@ img_load(int drive, wchar_t *fn)
if ((first_byte == 0x1A) && (second_byte == 'F') &&
(third_byte == 'D') && (fourth_byte == 'F')) {
/* This is a FDF image. */
pclog("img_load(): File is a FDF image...\n");
img_log("img_load(): File is a FDF image...\n");
fwriteprot[drive] = writeprot[drive] = 1;
fclose(dev->f);
dev->f = plat_fopen(fn, L"rb");
@@ -711,10 +740,10 @@ img_load(int drive, wchar_t *fn)
/* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */
first_byte = fgetc(dev->f);
fread(&track_bytes, 1, 2, dev->f);
pclog("Block header: %02X %04X ", first_byte, track_bytes);
img_log("Block header: %02X %04X ", first_byte, track_bytes);
/* Read the length of encoded data block. */
fread(&track_bytes, 1, 2, dev->f);
pclog("%04X\n", track_bytes);
img_log("%04X\n", track_bytes);
}
if (feof(dev->f)) break;
@@ -765,10 +794,10 @@ img_load(int drive, wchar_t *fn)
/* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */
first_byte = fgetc(dev->f);
fread(&track_bytes, 1, 2, dev->f);
pclog("Block header: %02X %04X ", first_byte, track_bytes);
img_log("Block header: %02X %04X ", first_byte, track_bytes);
/* Read the length of encoded data block. */
fread(&track_bytes, 1, 2, dev->f);
pclog("%04X\n", track_bytes);
img_log("%04X\n", track_bytes);
}
if (feof(dev->f)) break;
@@ -829,7 +858,7 @@ img_load(int drive, wchar_t *fn)
if (((first_byte == 'C') && (second_byte == 'Q')) ||
((first_byte == 'c') && (second_byte == 'q'))) {
pclog("img_load(): File is a CopyQM image...\n");
img_log("img_load(): File is a CopyQM image...\n");
fwriteprot[drive] = writeprot[drive] = 1;
fclose(dev->f);
dev->f = plat_fopen(fn, L"rb");
@@ -894,7 +923,7 @@ img_load(int drive, wchar_t *fn)
}
}
}
pclog("Finished reading CopyQM image data\n");
img_log("Finished reading CopyQM image data\n");
cqm = 1;
dev->disk_at_once = 1;
@@ -903,16 +932,20 @@ img_load(int drive, wchar_t *fn)
} else {
dev->disk_at_once = 0;
/* Read the BPB */
pclog("img_load(): File is a raw image...\n");
fseek(dev->f, 0x0B, SEEK_SET);
if (ddi) {
img_log("img_load(): File is a DDI image...\n");
fwriteprot[drive] = writeprot[drive] = 1;
} else
img_log("img_load(): File is a raw image...\n");
fseek(dev->f, dev->base + 0x0B, SEEK_SET);
fread(&bpb_bps, 1, 2, dev->f);
fseek(dev->f, 0x13, SEEK_SET);
fseek(dev->f, dev->base + 0x13, SEEK_SET);
fread(&bpb_total, 1, 2, dev->f);
fseek(dev->f, 0x15, SEEK_SET);
fseek(dev->f, dev->base + 0x15, SEEK_SET);
bpb_mid = fgetc(dev->f);
fseek(dev->f, 0x18, SEEK_SET);
fseek(dev->f, dev->base + 0x18, SEEK_SET);
bpb_sectors = fgetc(dev->f);
fseek(dev->f, 0x1A, SEEK_SET);
fseek(dev->f, dev->base + 0x1A, SEEK_SET);
bpb_sides = fgetc(dev->f);
cqm = 0;
@@ -920,16 +953,19 @@ img_load(int drive, wchar_t *fn)
fseek(dev->f, -1, SEEK_END);
size = ftell(dev->f) + 1;
if (ddi)
size -= 0x2400;
jump_if_fdf:
dev->base = 0;
if (!ddi)
dev->base = 0;
fdi = 0;
}
dev->sides = 2;
dev->sector_size = 2;
pclog("BPB reports %i sides and %i bytes per sector (%i sectors total)\n",
img_log("BPB reports %i sides and %i bytes per sector (%i sectors total)\n",
bpb_sides, bpb_bps, bpb_total);
guess = (bpb_sides < 1);
@@ -1056,7 +1092,7 @@ jump_if_fdf:
dev->sectors = 42;
dev->tracks = 86;
} else {
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
img_log("Image is bigger than can fit on an ED floppy, ejecting...\n");
fclose(dev->f);
free(dev);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
@@ -1106,13 +1142,13 @@ jump_if_fdf:
dev->dmf = 0;
}
pclog("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type);
img_log("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type);
break;
}
}
if (temp_rate == 0xFF) {
pclog("Image is bigger than can fit on an ED floppy, ejecting...\n");
img_log("Image is bigger than can fit on an ED floppy, ejecting...\n");
fclose(dev->f);
free(dev);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
@@ -1125,7 +1161,7 @@ jump_if_fdf:
else
dev->gap3_size = gap3_sizes[temp_rate][dev->sector_size][dev->sectors];
if (! dev->gap3_size) {
pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41);
img_log("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41);
fclose(dev->f);
free(dev);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
@@ -1149,7 +1185,7 @@ jump_if_fdf:
dev->is_cqm = cqm;
pclog("Disk flags: %i, track flags: %i\n",
img_log("Disk flags: %i, track flags: %i\n",
dev->disk_flags, dev->track_flags);
/* Set up the drive unit. */

View File

@@ -8,7 +8,7 @@
*
* Implementation of the PCjs JSON floppy image format.
*
* Version: @(#)fdd_json.c 1.0.4 2018/03/17
* Version: @(#)fdd_json.c 1.0.5 2018/04/29
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -44,11 +44,13 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../plat.h"
#include "fdd.h"
@@ -104,6 +106,27 @@ typedef struct {
static json_t *images[FDD_NUM];
#ifdef ENABLE_JSON_LOG
int json_do_log = ENABLE_JSON_LOG;
#endif
static void
json_log(const char *fmt, ...)
{
#ifdef ENABLE_JSON_LOG
va_list ap;
if (json_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static void
handle(json_t *dev, char *name, char *str)
{
@@ -182,7 +205,7 @@ handle(json_t *dev, char *name, char *str)
static int
unexpect(int c, int state, int level)
{
pclog("JSON: Unexpected '%c' in state %d/%d.\n", c, state, level);
json_log("JSON: Unexpected '%c' in state %d/%d.\n", c, state, level);
return(-1);
}
@@ -196,7 +219,7 @@ load_image(json_t *dev)
char *ptr;
if (dev->f == NULL) {
pclog("JSON: no file loaded!\n");
json_log("JSON: no file loaded!\n");
return(0);
}
@@ -373,7 +396,7 @@ json_seek(int drive, int track)
int interleave_type;
if (dev->f == NULL) {
pclog("JSON: seek: no file loaded!\n");
json_log("JSON: seek: no file loaded!\n");
return;
}
@@ -536,7 +559,7 @@ json_load(int drive, wchar_t *fn)
/* Load all sectors from the image file. */
if (! load_image(dev)) {
pclog("JSON: failed to initialize\n");
json_log("JSON: failed to initialize\n");
(void)fclose(dev->f);
free(dev);
images[drive] = NULL;
@@ -544,7 +567,7 @@ json_load(int drive, wchar_t *fn)
return;
}
pclog("JSON(%d): %ls (%i tracks, %i sides, %i sectors)\n",
json_log("JSON(%d): %ls (%i tracks, %i sides, %i sectors)\n",
drive, fn, dev->tracks, dev->sides, dev->spt[0][0]);
/*
@@ -601,7 +624,7 @@ json_load(int drive, wchar_t *fn)
}
if (temp_rate == 0xff) {
pclog("JSON: invalid image (temp_rate=0xff)\n");
json_log("JSON: invalid image (temp_rate=0xff)\n");
(void)fclose(dev->f);
dev->f = NULL;
free(dev);
@@ -622,7 +645,7 @@ json_load(int drive, wchar_t *fn)
dev->gap3_len = fdd_get_gap3_size(temp_rate,sec->size,dev->spt[0][0]);
if (! dev->gap3_len) {
pclog("JSON: image of unknown format was inserted into drive %c:!\n",
json_log("JSON: image of unknown format was inserted into drive %c:!\n",
'C'+drive);
(void)fclose(dev->f);
dev->f = NULL;
@@ -636,9 +659,9 @@ json_load(int drive, wchar_t *fn)
if (temp_rate & 0x04)
dev->track_flags |= 0x20; /* RPM */
pclog(" disk_flags: 0x%02x, track_flags: 0x%02x, GAP3 length: %i\n",
json_log(" disk_flags: 0x%02x, track_flags: 0x%02x, GAP3 length: %i\n",
dev->disk_flags, dev->track_flags, dev->gap3_len);
pclog(" bit rate 300: %.2f, temporary rate: %i, hole: %i, DMF: %i\n",
json_log(" bit rate 300: %.2f, temporary rate: %i, hole: %i, DMF: %i\n",
bit_rate, temp_rate, (dev->disk_flags >> 1), dev->dmf);
/* Set up handlers for 86F layer. */

View File

@@ -8,7 +8,7 @@
*
* Implementation of the Teledisk floppy image format.
*
* Version: @(#)fdd_td0.c 1.0.5 2018/03/19
* Version: @(#)fdd_td0.c 1.0.6 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -46,11 +46,13 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../plat.h"
#include "fdd.h"
@@ -218,6 +220,27 @@ static const uint8_t d_len[256] = {
static td0_t *td0[FDD_NUM];
#ifdef ENABLE_TD0_LOG
int td0_do_log = ENABLE_TD0_LOG;
#endif
static void
td0_log(const char *fmt, ...)
{
#ifdef ENABLE_TD0_LOG
va_list ap;
if (td0_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static void
fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len)
{
@@ -611,7 +634,7 @@ td0_initialize(int drive)
int i, j, k;
if (dev->f == NULL) {
pclog("TD0: Attempted to initialize without loading a file first\n");
td0_log("TD0: Attempted to initialize without loading a file first\n");
return(0);
}
@@ -619,12 +642,12 @@ td0_initialize(int drive)
file_size = ftell(dev->f);
if (file_size < 12) {
pclog("TD0: File is too small to even contain the header\n");
td0_log("TD0: File is too small to even contain the header\n");
return(0);
}
if (file_size > TD0_MAX_BUFSZ) {
pclog("TD0: File exceeds the maximum size\n");
td0_log("TD0: File exceeds the maximum size\n");
return(0);
}
@@ -633,13 +656,13 @@ td0_initialize(int drive)
head_count = header[9];
if (header[0] == 't') {
pclog("TD0: File is compressed\n");
td0_log("TD0: File is compressed\n");
disk_decode.fdd_file = dev->f;
state_init_Decode(&disk_decode);
disk_decode.fdd_file_offset = 12;
state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ);
} else {
pclog("TD0: File is uncompressed\n");
td0_log("TD0: File is uncompressed\n");
fseek(dev->f, 12, SEEK_SET);
fread(dev->imagebuf, 1, file_size - 12, dev->f);
}
@@ -650,14 +673,14 @@ td0_initialize(int drive)
track_spt = dev->imagebuf[offset];
if (track_spt == 255) {
/* Empty file? */
pclog("TD0: File has no tracks\n");
td0_log("TD0: File has no tracks\n");
return(0);
}
density = (header[5] >> 1) & 3;
if (density == 3) {
pclog("TD0: Unknown density\n");
td0_log("TD0: Unknown density\n");
return(0);
}
@@ -725,7 +748,7 @@ td0_initialize(int drive)
size = 128 << hs[3];
if ((total_size + size) >= TD0_MAX_BUFSZ) {
pclog("TD0: Processed buffer overflow\n");
td0_log("TD0: Processed buffer overflow\n");
return(0);
}
@@ -735,7 +758,7 @@ td0_initialize(int drive)
offset += 3;
switch (hs[8]) {
default:
pclog("TD0: Image uses an unsupported sector data encoding\n");
td0_log("TD0: Image uses an unsupported sector data encoding\n");
return(0);
case 0:
@@ -803,7 +826,7 @@ td0_initialize(int drive)
dev->disk_flags |= (3 << 5);
if ((raw_tsize - track_size + (fm ? 73 : 146)) < (minimum_gap3 + minimum_gap4)) {
/* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */
pclog("TD0: Unable to fit the %i sectors in a track\n", track_spt);
td0_log("TD0: Unable to fit the %i sectors in a track\n", track_spt);
return 0;
}
}
@@ -814,7 +837,7 @@ td0_initialize(int drive)
}
if ((dev->disk_flags & 0x60) == 0x60)
pclog("TD0: Disk will rotate 2% below perfect RPM\n");
td0_log("TD0: Disk will rotate 2% below perfect RPM\n");
dev->tracks = track_count + 1;
@@ -836,7 +859,7 @@ td0_initialize(int drive)
dev->current_side_flags[0] = dev->side_flags[0][0];
dev->current_side_flags[1] = dev->side_flags[0][1];
pclog("TD0: File loaded: %i tracks, %i sides, disk flags: %02X, side flags: %02X, %02X, GAP3 length: %02X\n", dev->tracks, dev->sides, dev->disk_flags, dev->current_side_flags[0], dev->current_side_flags[1], dev->gap3_len);
td0_log("TD0: File loaded: %i tracks, %i sides, disk flags: %02X, side flags: %02X, %02X, GAP3 length: %02X\n", dev->tracks, dev->sides, dev->disk_flags, dev->current_side_flags[0], dev->current_side_flags[1], dev->gap3_len);
return(1);
}
@@ -1136,13 +1159,13 @@ td0_load(int drive, wchar_t *fn)
fwriteprot[drive] = writeprot[drive];
if (! dsk_identify(drive)) {
pclog("TD0: Not a valid Teledisk image\n");
td0_log("TD0: Not a valid Teledisk image\n");
fclose(dev->f);
dev->f = NULL;
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
return;
} else {
pclog("TD0: Valid Teledisk image\n");
td0_log("TD0: Valid Teledisk image\n");
}
/* Allocate the processing buffers. */
@@ -1153,14 +1176,14 @@ td0_load(int drive, wchar_t *fn)
memset(dev->processed_buf, 0x00, i);
if (! td0_initialize(drive)) {
pclog("TD0: Failed to initialize\n");
td0_log("TD0: Failed to initialize\n");
fclose(dev->f);
free(dev->imagebuf);
free(dev->processed_buf);
memset(floppyfns[drive], 0, sizeof(floppyfns[drive]));
return;
} else {
pclog("TD0: Initialized successfully\n");
td0_log("TD0: Initialized successfully\n");
}
/* Attach this format to the D86F engine. */

View File

@@ -12,7 +12,7 @@
* addition of get_last_head and C++ callability by Thomas
* Harte.
*
* Version: @(#)fdi2raw.c 1.0.2 2018/03/12
* Version: @(#)fdi2raw.c 1.0.3 2018/04/29
*
* Authors: Toni Wilen, <twilen@arabuusimiehet.com>
* and Vincent Joguin,
@@ -41,8 +41,9 @@
* USA.
*/
#define STATIC_INLINE
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
@@ -53,6 +54,7 @@
#include "zfile.h"*/
/* ELSE */
#define xmalloc malloc
#define HAVE_STDARG_H
#include "../86box.h"
#include "fdi2raw.h"
@@ -62,6 +64,27 @@
#undef VERBOSE
#ifdef ENABLE_FDI2RAW_LOG
int fdi2raw_do_log = ENABLE_FDI2RAW_LOG;
#endif
static void
fdi2raw_log(const char *fmt, ...)
{
#ifdef ENABLE_FDI2RAW_LOG
va_list ap;
if (fdi2raw_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
#ifdef DEBUG
static char *datalog(uae_u8 *src, int len)
{
@@ -86,9 +109,6 @@ static char *datalog(uae_u8 *src, int len)
static char *datalog(uae_u8 *src, int len) { return ""; }
#endif
#define outlog pclog
#define debuglog pclog
static int fdi_allocated;
#ifdef DEBUG
static void fdi_free (void *p)
@@ -333,13 +353,13 @@ static int decode_raw_track (FDI *fdi)
/* unknown track */
static void zxx (FDI *fdi)
{
outlog ("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
fdi2raw_log("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
}
/* unsupported track */
#if 0
static void zyy (FDI *fdi)
{
outlog ("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
fdi2raw_log("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type);
}
#endif
/* empty track */
@@ -351,17 +371,9 @@ static void track_empty (FDI *fdi)
/* unknown sector described type */
static void dxx (FDI *fdi)
{
outlog ("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type);
fdi2raw_log("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type);
fdi->err = 1;
}
/* unsupported sector described type */
#if 0
static void dyy (FDI *fdi)
{
outlog ("\ntrack %d: unsupported sector described 0x%02.2X\n", fdi->current_track, fdi->track_type);
fdi->err = 1;
}
#endif
/* add position of mfm sync bit */
static void add_mfm_sync_bit (FDI *fdi)
{
@@ -371,12 +383,12 @@ static void add_mfm_sync_bit (FDI *fdi)
}
fdi->mfmsync_buffer[fdi->mfmsync_offset++] = fdi->out;
if (fdi->out == 0) {
outlog ("illegal position for mfm sync bit, offset=%d\n",fdi->out);
fdi2raw_log("illegal position for mfm sync bit, offset=%d\n",fdi->out);
fdi->err = 1;
}
if (fdi->mfmsync_offset >= MAX_MFM_SYNC_BUFFER) {
fdi->mfmsync_offset = 0;
outlog ("mfmsync buffer overflow\n");
fdi2raw_log("mfmsync buffer overflow\n");
fdi->err = 1;
}
fdi->out++;
@@ -397,7 +409,7 @@ static void bit_add (FDI *fdi, int bit)
fdi->track_dst[BIT_BYTEOFFSET] |= (1 << BIT_BITOFFSET);
fdi->out++;
if (fdi->out >= MAX_DST_BUFFER * 8) {
outlog ("destination buffer overflow\n");
fdi2raw_log("destination buffer overflow\n");
fdi->err = 1;
fdi->out = 1;
}
@@ -412,13 +424,13 @@ static void bit_mfm_add (FDI *fdi, int bit)
static void bit_drop_next (FDI *fdi)
{
if (fdi->nextdrop > 0) {
outlog("multiple bit_drop_next() called");
fdi2raw_log("multiple bit_drop_next() called");
} else if (fdi->nextdrop < 0) {
fdi->nextdrop = 0;
debuglog(":DNN:");
fdi2raw_log(":DNN:");
return;
}
debuglog(":DN:");
fdi2raw_log(":DN:");
fdi->nextdrop = 1;
}
@@ -426,10 +438,10 @@ static void bit_drop_next (FDI *fdi)
static void bit_dedrop (FDI *fdi)
{
if (fdi->nextdrop) {
outlog("bit_drop_next called before bit_dedrop");
fdi2raw_log("bit_drop_next called before bit_dedrop");
}
fdi->nextdrop = -1;
debuglog(":BDD:");
fdi2raw_log(":BDD:");
}
/* add one byte */
@@ -482,7 +494,7 @@ static void s08(FDI *fdi)
int bytes = *fdi->track_src++;
uae_u8 byte = *fdi->track_src++;
if (bytes == 0) bytes = 256;
debuglog ("s08:len=%d,data=%02.2X",bytes,byte);
fdi2raw_log("s08:len=%d,data=%02.2X",bytes,byte);
while(bytes--) byte_add (fdi, byte);
}
/* RLE MFM-decoded data */
@@ -492,7 +504,7 @@ static void s09(FDI *fdi)
uae_u8 byte = *fdi->track_src++;
if (bytes == 0) bytes = 256;
bit_drop_next (fdi);
debuglog ("s09:len=%d,data=%02.2X",bytes,byte);
fdi2raw_log("s09:len=%d,data=%02.2X",bytes,byte);
while(bytes--) byte_mfm_add (fdi, byte);
}
/* MFM-encoded data */
@@ -501,7 +513,7 @@ static void s0a(FDI *fdi)
int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1];
uae_u8 b;
fdi->track_src += 2;
debuglog ("s0a:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
fdi2raw_log("s0a:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
while (bits >= 8) {
byte_add (fdi, *fdi->track_src++);
bits -= 8;
@@ -521,7 +533,7 @@ static void s0b(FDI *fdi)
int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536;
uae_u8 b;
fdi->track_src += 2;
debuglog ("s0b:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
fdi2raw_log("s0b:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
while (bits >= 8) {
byte_add (fdi, *fdi->track_src++);
bits -= 8;
@@ -542,7 +554,7 @@ static void s0c(FDI *fdi)
uae_u8 b;
fdi->track_src += 2;
bit_drop_next (fdi);
debuglog ("s0c:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
fdi2raw_log("s0c:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
while (bits >= 8) {
byte_mfm_add (fdi, *fdi->track_src++);
bits -= 8;
@@ -563,7 +575,7 @@ static void s0d(FDI *fdi)
uae_u8 b;
fdi->track_src += 2;
bit_drop_next (fdi);
debuglog ("s0d:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
fdi2raw_log("s0d:bits=%d,data=%s", bits, datalog(fdi->track_src, (bits + 7) / 8));
while (bits >= 8) {
byte_mfm_add (fdi, *fdi->track_src++);
bits -= 8;
@@ -692,13 +704,13 @@ static int amiga_check_track (FDI *fdi)
trackoffs = (id & 0xff00) >> 8;
if (trackoffs + 1 > drvsec) {
outlog("illegal sector offset %d\n",trackoffs);
fdi2raw_log("illegal sector offset %d\n",trackoffs);
ok = 0;
mbuf = mbuf2;
continue;
}
if ((id >> 24) != 0xff) {
outlog ("sector %d format type %02.2X?\n", trackoffs, id >> 24);
fdi2raw_log("sector %d format type %02.2X?\n", trackoffs, id >> 24);
ok = 0;
}
chksum = odd ^ even;
@@ -717,14 +729,14 @@ static int amiga_check_track (FDI *fdi)
even = getmfmlong (mbuf + 2 * 2);
mbuf += 4 * 2;
if (((odd << 1) | even) != chksum) {
outlog("sector %d header crc error\n", trackoffs);
fdi2raw_log("sector %d header crc error\n", trackoffs);
ok = 0;
mbuf = mbuf2;
continue;
}
outlog("sector %d header crc ok\n", trackoffs);
fdi2raw_log("sector %d header crc ok\n", trackoffs);
if (((id & 0x00ff0000) >> 16) != (uae_u32)fdi->current_track) {
outlog("illegal track number %d <> %d\n",fdi->current_track,(id & 0x00ff0000) >> 16);
fdi2raw_log("illegal track number %d <> %d\n",fdi->current_track,(id & 0x00ff0000) >> 16);
ok++;
mbuf = mbuf2;
continue;
@@ -747,14 +759,14 @@ static int amiga_check_track (FDI *fdi)
}
mbuf += 256 * 2;
if (chksum) {
outlog("sector %d data checksum error\n",trackoffs);
fdi2raw_log("sector %d data checksum error\n",trackoffs);
ok = 0;
} else if (sectable[trackoffs]) {
outlog("sector %d already found?\n", trackoffs);
fdi2raw_log("sector %d already found?\n", trackoffs);
mbuf = mbuf2;
} else {
outlog("sector %d ok\n",trackoffs);
if (slabel) outlog("(non-empty sector header)\n");
fdi2raw_log("sector %d ok\n",trackoffs);
if (slabel) fdi2raw_log("(non-empty sector header)\n");
sectable[trackoffs] = 1;
secwritten++;
if (trackoffs == 9)
@@ -763,7 +775,7 @@ static int amiga_check_track (FDI *fdi)
}
for (i = 0; i < drvsec; i++) {
if (!sectable[i]) {
outlog ("sector %d missing\n", i);
fdi2raw_log("sector %d missing\n", i);
ok = 0;
}
}
@@ -884,7 +896,7 @@ static void amiga_sector_header (FDI *fdi, uae_u8 *header, uae_u8 *data, int sec
static void s20(FDI *fdi)
{
bit_drop_next (fdi);
debuglog ("s20:header=%s,data=%s", datalog(fdi->track_src, 4), datalog(fdi->track_src + 4, 16));
fdi2raw_log("s20:header=%s,data=%s", datalog(fdi->track_src, 4), datalog(fdi->track_src + 4, 16));
amiga_sector_header (fdi, fdi->track_src, fdi->track_src + 4, 0, 0);
fdi->track_src += 4 + 16;
}
@@ -892,7 +904,7 @@ static void s20(FDI *fdi)
static void s21(FDI *fdi)
{
bit_drop_next (fdi);
debuglog ("s21:header=%s", datalog(fdi->track_src, 4));
fdi2raw_log("s21:header=%s", datalog(fdi->track_src, 4));
amiga_sector_header (fdi, fdi->track_src, 0, 0, 0);
fdi->track_src += 4;
}
@@ -900,14 +912,14 @@ static void s21(FDI *fdi)
static void s22(FDI *fdi)
{
bit_drop_next (fdi);
debuglog("s22:sector=%d,untilgap=%d", fdi->track_src[0], fdi->track_src[1]);
fdi2raw_log("s22:sector=%d,untilgap=%d", fdi->track_src[0], fdi->track_src[1]);
amiga_sector_header (fdi, 0, 0, fdi->track_src[0], fdi->track_src[1]);
fdi->track_src += 2;
}
/* standard 512-byte, CRC-correct Amiga data */
static void s23(FDI *fdi)
{
debuglog("s23:data=%s", datalog (fdi->track_src, 512));
fdi2raw_log("s23:data=%s", datalog (fdi->track_src, 512));
amiga_data (fdi, fdi->track_src);
fdi->track_src += 512;
}
@@ -915,7 +927,7 @@ static void s23(FDI *fdi)
static void s24(FDI *fdi)
{
int shift = *fdi->track_src++;
debuglog("s24:shift=%d,data=%s", shift, datalog (fdi->track_src, 128 << shift));
fdi2raw_log("s24:shift=%d,data=%s", shift, datalog (fdi->track_src, 128 << shift));
amiga_data_raw (fdi, fdi->track_src, 0, 128 << shift);
fdi->track_src += 128 << shift;
}
@@ -923,7 +935,7 @@ static void s24(FDI *fdi)
static void s25(FDI *fdi)
{
int shift = *fdi->track_src++;
debuglog("s25:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 128 << shift));
fdi2raw_log("s25:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 128 << shift));
amiga_data_raw (fdi, fdi->track_src + 4, fdi->track_src, 128 << shift);
fdi->track_src += 4 + (128 << shift);
}
@@ -931,7 +943,7 @@ static void s25(FDI *fdi)
static void s26(FDI *fdi)
{
s21 (fdi);
debuglog("s26:data=%s", datalog (fdi->track_src, 512));
fdi2raw_log("s26:data=%s", datalog (fdi->track_src, 512));
amiga_data (fdi, fdi->track_src);
fdi->track_src += 512;
}
@@ -939,7 +951,7 @@ static void s26(FDI *fdi)
static void s27(FDI *fdi)
{
s22 (fdi);
debuglog("s27:data=%s", datalog (fdi->track_src, 512));
fdi2raw_log("s27:data=%s", datalog (fdi->track_src, 512));
amiga_data (fdi, fdi->track_src);
fdi->track_src += 512;
}
@@ -1060,14 +1072,14 @@ static void s12(FDI *fdi)
static void s13(FDI *fdi)
{
bit_drop_next (fdi);
debuglog ("s13:header=%s", datalog (fdi->track_src, 4));
fdi2raw_log("s13:header=%s", datalog (fdi->track_src, 4));
ibm_sector_header (fdi, fdi->track_src, 0, -1, 1);
fdi->track_src += 4;
}
/* standard mini-extended IBM sector header */
static void s14(FDI *fdi)
{
debuglog ("s14:header=%s", datalog (fdi->track_src, 4));
fdi2raw_log("s14:header=%s", datalog (fdi->track_src, 4));
ibm_sector_header (fdi, fdi->track_src, 0, -1, 0);
fdi->track_src += 4;
}
@@ -1075,33 +1087,33 @@ static void s14(FDI *fdi)
static void s15(FDI *fdi)
{
bit_drop_next (fdi);
debuglog ("s15:sector=%d", *fdi->track_src);
fdi2raw_log("s15:sector=%d", *fdi->track_src);
ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 1);
}
/* standard mini-short IBM sector header */
static void s16(FDI *fdi)
{
debuglog ("s16:track=%d", *fdi->track_src);
fdi2raw_log("s16:track=%d", *fdi->track_src);
ibm_sector_header (fdi, 0, 0, *fdi->track_src++, 0);
}
/* standard CRC-incorrect mini-extended IBM sector header */
static void s17(FDI *fdi)
{
debuglog ("s17:header=%s,crc=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 2));
fdi2raw_log("s17:header=%s,crc=%s", datalog (fdi->track_src, 4), datalog (fdi->track_src + 4, 2));
ibm_sector_header (fdi, fdi->track_src, fdi->track_src + 4, -1, 0);
fdi->track_src += 4 + 2;
}
/* standard CRC-incorrect mini-short IBM sector header */
static void s18(FDI *fdi)
{
debuglog ("s18:sector=%d,header=%s", *fdi->track_src, datalog (fdi->track_src + 1, 4));
fdi2raw_log("s18:sector=%d,header=%s", *fdi->track_src, datalog (fdi->track_src + 1, 4));
ibm_sector_header (fdi, 0, fdi->track_src + 1, *fdi->track_src, 0);
fdi->track_src += 1 + 4;
}
/* standard 512-byte CRC-correct IBM data */
static void s19(FDI *fdi)
{
debuglog ("s19:data=%s", datalog (fdi->track_src , 512));
fdi2raw_log("s19:data=%s", datalog (fdi->track_src , 512));
ibm_data (fdi, fdi->track_src, 0, 512);
fdi->track_src += 512;
}
@@ -1109,7 +1121,7 @@ static void s19(FDI *fdi)
static void s1a(FDI *fdi)
{
int shift = *fdi->track_src++;
debuglog ("s1a:shift=%d,data=%s", shift, datalog (fdi->track_src , 128 << shift));
fdi2raw_log("s1a:shift=%d,data=%s", shift, datalog (fdi->track_src , 128 << shift));
ibm_data (fdi, fdi->track_src, 0, 128 << shift);
fdi->track_src += 128 << shift;
}
@@ -1117,7 +1129,7 @@ static void s1a(FDI *fdi)
static void s1b(FDI *fdi)
{
int shift = *fdi->track_src++;
debuglog ("s1b:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src + (128 << shift), 2), datalog (fdi->track_src , 128 << shift));
fdi2raw_log("s1b:shift=%d,crc=%s,data=%s", shift, datalog (fdi->track_src + (128 << shift), 2), datalog (fdi->track_src , 128 << shift));
ibm_data (fdi, fdi->track_src, fdi->track_src + (128 << shift), 128 << shift);
fdi->track_src += (128 << shift) + 2;
}
@@ -1323,25 +1335,25 @@ static int handle_sectors_described_track (FDI *fdi)
fdi->index_offset = get_u32(fdi->track_src);
fdi->index_offset >>= 8;
fdi->track_src += 3;
outlog ("sectors_described, index offset: %d\n",fdi->index_offset);
fdi2raw_log("sectors_described, index offset: %d\n",fdi->index_offset);
do {
fdi->track_type = *fdi->track_src++;
outlog ("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type);
fdi2raw_log("%06.6X %06.6X %02.2X:",fdi->track_src - start_src + 0x200, fdi->out/8, fdi->track_type);
oldout = fdi->out;
decode_sectors_described_track[fdi->track_type](fdi);
outlog(" %d\n", fdi->out - oldout);
fdi2raw_log(" %d\n", fdi->out - oldout);
oldout = fdi->out;
if (fdi->out < 0 || fdi->err) {
outlog ("\nin %d bytes, out %d bits\n", fdi->track_src - fdi->track_src_buffer, fdi->out);
fdi2raw_log("\nin %d bytes, out %d bits\n", fdi->track_src - fdi->track_src_buffer, fdi->out);
return -1;
}
if (fdi->track_src - fdi->track_src_buffer >= fdi->track_src_len) {
outlog ("source buffer overrun, previous type: %02.2X\n", fdi->track_type);
fdi2raw_log("source buffer overrun, previous type: %02.2X\n", fdi->track_type);
return -1;
}
} while (fdi->track_type != 0xff);
outlog("\n");
fdi2raw_log("\n");
fix_mfm_sync (fdi);
return fdi->out;
}
@@ -1445,7 +1457,7 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi
|| (avgp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) )
i++;
if (i == pulses) {
outlog ("No stable and long-enough pulse in track.\n");
fdi2raw_log("No stable and long-enough pulse in track.\n");
return;
}
i--;
@@ -1572,7 +1584,7 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi
|| (minp[i] < (standard_MFM_2_bit_cell_size - (standard_MFM_2_bit_cell_size / 4))) ) )
i++;
if (i == pulses) {
outlog ("FDI: No stable and long-enough pulse in track.\n");
fdi2raw_log("FDI: No stable and long-enough pulse in track.\n");
return;
}
nexti = i;
@@ -1649,12 +1661,12 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi
}
avg_pulse += jitter;
if ((avg_pulse < min_pulse) || (avg_pulse > max_pulse)) {
outlog ("FDI: avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, max_pulse);
outlog ("FDI: avgp=%u (%u) minp=%u (%u) maxp=%u (%u) jitter=%d i=%d ni=%d\n",
fdi2raw_log("FDI: avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, max_pulse);
fdi2raw_log("FDI: avgp=%u (%u) minp=%u (%u) maxp=%u (%u) jitter=%d i=%d ni=%d\n",
avgp[i], avgp[nexti], minp[i], minp[nexti], maxp[i], maxp[nexti], jitter, i, nexti);
}
if (avg_pulse < ref_pulse)
outlog ("FDI: avg_pulse < ref_pulse! (%u < %u)\n", avg_pulse, ref_pulse);
fdi2raw_log("FDI: avg_pulse < ref_pulse! (%u < %u)\n", avg_pulse, ref_pulse);
pulse += avg_pulse - ref_pulse;
ref_pulse = 0;
if (i == eodat)
@@ -1927,7 +1939,7 @@ static int decode_lowlevel_track (FDI *fdi, int track, struct fdi_cache *cache)
idxp[i] = sum;
}
len = totalavg / 100000;
/* outlog("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n",
/* fdi2raw_log("totalavg=%u index=%d (%d) maxidx=%d weakbits=%d len=%d\n",
totalavg, indexoffset, maxidx, weakbits, len); */
cache->avgp = avgp;
cache->idxp = idxp;
@@ -1970,7 +1982,7 @@ void fdi2raw_header_free (FDI *fdi)
fdi_free (c->maxp);
}
fdi_free (fdi);
debuglog ("FREE: memory allocated %d\n", fdi_allocated);
fdi2raw_log("FREE: memory allocated %d\n", fdi_allocated);
}
int fdi2raw_get_last_track (FDI *fdi)
@@ -2021,7 +2033,7 @@ FDI *fdi2raw_header(FILE *f)
uae_u8 type, size;
FDI *fdi;
debuglog ("ALLOC: memory allocated %d\n", fdi_allocated);
fdi2raw_log("ALLOC: memory allocated %d\n", fdi_allocated);
fdi = fdi_malloc(sizeof(FDI));
memset (fdi, 0, sizeof (FDI));
fdi->file = f;
@@ -2051,8 +2063,8 @@ FDI *fdi2raw_header(FILE *f)
fdi->disk_type = fdi->header[145];
fdi->rotation_speed = fdi->header[146] + 128;
fdi->write_protect = fdi->header[147] & 1;
outlog ("FDI version %d.%d\n", fdi->header[140], fdi->header[141]);
outlog ("last_track=%d rotation_speed=%d\n",fdi->last_track,fdi->rotation_speed);
fdi2raw_log("FDI version %d.%d\n", fdi->header[140], fdi->header[141]);
fdi2raw_log("last_track=%d rotation_speed=%d\n",fdi->last_track,fdi->rotation_speed);
offset = 512;
i = fdi->last_track;
@@ -2091,7 +2103,7 @@ int fdi2raw_loadrevolution_2 (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, i
fdi2_decode (fdi, cache->totalavg,
cache->avgp, cache->minp, cache->maxp, cache->idxp,
cache->maxidx, &idx, cache->pulses, mfm);
/* outlog("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n",
/* fdi2raw_log("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n",
track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits, cache->indexoffset); */
len = fdi->out;
if (cache->weakbits >= 10 && multirev)
@@ -2144,7 +2156,7 @@ int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int trac
else
fdi->bit_rate = 250;
/* outlog ("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n",
/* fdi2raw_log("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n",
fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate); */
if ((fdi->track_type & 0xc0) == 0x80) {

View File

@@ -8,7 +8,7 @@
*
* Implementation of a generic Game Port.
*
* Version: @(#)gameport.c 1.0.4 2018/03/19
* Version: @(#)gameport.c 1.0.6 2018/04/29
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
@@ -177,7 +177,6 @@ gameport_write(uint16_t addr, uint8_t val, void *priv)
timer_clock();
p->state |= 0x0f;
pclog("gameport_write : joysticks_present=%i\n", joysticks_present);
p->axis[0].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 0));
p->axis[1].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 1));
@@ -321,7 +320,7 @@ const device_t gameport_device = {
0, 0,
gameport_init,
gameport_close,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL
};
@@ -330,6 +329,6 @@ const device_t gameport_201_device = {
0, 0,
gameport_201_init,
gameport_close,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL
};

View File

@@ -8,7 +8,7 @@
*
* Implementation of the Intel 1 Mbit 8-bit flash devices.
*
* Version: @(#)intel_flash.c 1.0.14 2018/03/18
* Version: @(#)intel_flash.c 1.0.16 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -185,8 +185,6 @@ void *intel_flash_init(uint8_t type)
wcscpy(flash_path, flash_name);
/* pclog("Flash path: %ls\n", flash_name); */
flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94;
flash->invert_high_pin = (type & FLASH_INVERT);
@@ -295,7 +293,7 @@ const device_t intel_flash_bxt_ami_device =
intel_flash_bxt_ami_init,
intel_flash_close,
NULL,
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
};
const device_t intel_flash_bxb_ami_device =
@@ -305,7 +303,7 @@ const device_t intel_flash_bxb_ami_device =
intel_flash_bxb_ami_init,
intel_flash_close,
NULL,
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
};
const device_t intel_flash_bxt_device =
@@ -315,7 +313,7 @@ const device_t intel_flash_bxt_device =
intel_flash_bxt_init,
intel_flash_close,
NULL,
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
};
const device_t intel_flash_bxb_device =
@@ -325,5 +323,5 @@ const device_t intel_flash_bxb_device =
intel_flash_bxb_init,
intel_flash_close,
NULL,
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
};

File diff suppressed because it is too large Load Diff

View File

@@ -6,18 +6,20 @@
*
* Emulation of Intel System I/O PCI chip.
*
* Version: @(#)intel_sio.c 1.0.7 2017/11/04
* Version: @(#)intel_sio.c 1.0.8 2018/04/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "device.h"
#include "cpu/cpu.h"
#include "io.h"
#include "dma.h"
@@ -26,144 +28,180 @@
#include "intel_sio.h"
static uint8_t card_sio[256];
static void sio_write(int func, int addr, uint8_t val, void *priv)
typedef struct
{
if (func > 0)
return;
if (addr >= 0x0f && addr < 0x4c)
uint8_t regs[256];
} sio_t;
static void
sio_write(int func, int addr, uint8_t val, void *priv)
{
sio_t *dev = (sio_t *) priv;
if (func > 0)
return;
if (addr >= 0x0f && addr < 0x4c)
return;
switch (addr) {
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0e:
return;
switch (addr)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0e:
return;
case 0x04: /*Command register*/
val &= 0x08;
val |= 0x07;
break;
case 0x05:
val = 0;
break;
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
val = 0x02;
break;
case 0x40:
if (!((val ^ card_sio[addr]) & 0x40))
{
return;
}
if (val & 0x40)
{
dma_alias_remove();
}
else
{
dma_alias_set();
}
case 0x04: /*Command register*/
val &= 0x08;
val |= 0x07;
break;
case 0x05:
val = 0;
break;
case 0x4f:
if (!((val ^ card_sio[addr]) & 0x40))
{
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
val = 0x02;
break;
case 0x40:
if (!((val ^ dev->regs[addr]) & 0x40))
return;
}
if (val & 0x40)
{
port_92_add();
}
dma_alias_remove();
else
dma_alias_set();
break;
case 0x4f:
if (!((val ^ dev->regs[addr]) & 0x40))
return;
if (val & 0x40)
port_92_add();
else
{
port_92_remove();
}
case 0x60:
if (val & 0x80)
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA, val & 0xf);
break;
case 0x61:
if (val & 0x80)
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTC, val & 0xf);
break;
case 0x62:
if (val & 0x80)
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTB, val & 0xf);
break;
case 0x63:
if (val & 0x80)
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTD, val & 0xf);
break;
}
card_sio[addr] = val;
case 0x60:
if (val & 0x80)
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA, val & 0xf);
break;
case 0x61:
if (val & 0x80)
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTC, val & 0xf);
break;
case 0x62:
if (val & 0x80)
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTB, val & 0xf);
break;
case 0x63:
if (val & 0x80)
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTD, val & 0xf);
break;
}
dev->regs[addr] = val;
}
static uint8_t sio_read(int func, int addr, void *priv)
static uint8_t
sio_read(int func, int addr, void *priv)
{
if (func > 0)
return 0xff;
sio_t *dev = (sio_t *) priv;
uint8_t ret;
return card_sio[addr];
ret = 0xff;
if (func == 0)
ret = dev->regs[addr];
return ret;
}
static void sio_reset(void)
static void
sio_reset(void *priv)
{
memset(card_sio, 0, 256);
card_sio[0x00] = 0x86; card_sio[0x01] = 0x80; /*Intel*/
card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378IB (SIO)*/
card_sio[0x04] = 0x07; card_sio[0x05] = 0x00;
card_sio[0x06] = 0x00; card_sio[0x07] = 0x02;
card_sio[0x08] = 0x03; /*A0 stepping*/
sio_t *dev = (sio_t *) priv;
card_sio[0x40] = 0x20; card_sio[0x41] = 0x00;
card_sio[0x42] = 0x04; card_sio[0x43] = 0x00;
card_sio[0x44] = 0x20; card_sio[0x45] = 0x10;
card_sio[0x46] = 0x0f; card_sio[0x47] = 0x00;
card_sio[0x48] = 0x01; card_sio[0x49] = 0x10;
card_sio[0x4a] = 0x10; card_sio[0x4b] = 0x0f;
card_sio[0x4c] = 0x56; card_sio[0x4d] = 0x40;
card_sio[0x4e] = 0x07; card_sio[0x4f] = 0x4f;
card_sio[0x54] = 0x00; card_sio[0x55] = 0x00; card_sio[0x56] = 0x00;
card_sio[0x60] = 0x80; card_sio[0x61] = 0x80; card_sio[0x62] = 0x80; card_sio[0x63] = 0x80;
card_sio[0x80] = 0x78; card_sio[0x81] = 0x00;
card_sio[0xa0] = 0x08;
card_sio[0xa8] = 0x0f;
memset(dev->regs, 0, 256);
dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/
dev->regs[0x02] = 0x84; dev->regs[0x03] = 0x04; /*82378IB (SIO)*/
dev->regs[0x04] = 0x07; dev->regs[0x05] = 0x00;
dev->regs[0x06] = 0x00; dev->regs[0x07] = 0x02;
dev->regs[0x08] = 0x03; /*A0 stepping*/
dev->regs[0x40] = 0x20; dev->regs[0x41] = 0x00;
dev->regs[0x42] = 0x04; dev->regs[0x43] = 0x00;
dev->regs[0x44] = 0x20; dev->regs[0x45] = 0x10;
dev->regs[0x46] = 0x0f; dev->regs[0x47] = 0x00;
dev->regs[0x48] = 0x01; dev->regs[0x49] = 0x10;
dev->regs[0x4a] = 0x10; dev->regs[0x4b] = 0x0f;
dev->regs[0x4c] = 0x56; dev->regs[0x4d] = 0x40;
dev->regs[0x4e] = 0x07; dev->regs[0x4f] = 0x4f;
dev->regs[0x54] = 0x00; dev->regs[0x55] = 0x00; dev->regs[0x56] = 0x00;
dev->regs[0x60] = 0x80; dev->regs[0x61] = 0x80; dev->regs[0x62] = 0x80; dev->regs[0x63] = 0x80;
dev->regs[0x80] = 0x78; dev->regs[0x81] = 0x00;
dev->regs[0xa0] = 0x08;
dev->regs[0xa8] = 0x0f;
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
}
void sio_init(int card)
static void
sio_close(void *p)
{
pci_add_card(card, sio_read, sio_write, NULL);
sio_t *sio = (sio_t *)p;
free(sio);
}
static void
*sio_init(const device_t *info)
{
sio_t *sio = (sio_t *) malloc(sizeof(sio_t));
memset(sio, 0, sizeof(sio_t));
pci_add_card(2, sio_read, sio_write, sio);
sio_reset();
sio_reset(sio);
port_92_reset();
port_92_reset();
port_92_add();
port_92_add();
dma_alias_set();
dma_alias_set();
pci_reset_handler.pci_set_reset = sio_reset;
return sio;
}
const device_t sio_device =
{
"Intel 82378IB (SIO)",
DEVICE_PCI,
0,
sio_init,
sio_close,
NULL,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -6,12 +6,12 @@
*
* Emulation of Intel System I/O PCI chip.
*
* Version: @(#)sio.h 1.0.2 2017/08/23
* Version: @(#)sio.h 1.0.3 2018/03/26
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
void sio_init(int card);
extern const device_t sio_device;

View File

@@ -8,7 +8,7 @@
*
* Implement I/O ports and their operations.
*
* Version: @(#)io.c 1.0.3 2018/02/02
* Version: @(#)io.c 1.0.4 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -17,11 +17,13 @@
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "86box.h"
#include "io.h"
#include "cpu/cpu.h"
@@ -48,13 +50,35 @@ int initialized = 0;
io_t *io[NPORTS], *io_last[NPORTS];
#ifdef IO_CATCH
static uint8_t null_inb(uint16_t addr, void *priv) { pclog("IO: read(%04x)\n"); return(0xff); }
static uint16_t null_inw(uint16_t addr, void *priv) { pclog("IO: readw(%04x)\n"); return(0xffff); }
static uint32_t null_inl(uint16_t addr, void *priv) { pclog("IO: readl(%04x)\n"); return(0xffffffff); }
static void null_outb(uint16_t addr, uint8_t val, void *priv) { pclog("IO: write(%04x, %02x)\n", val); }
static void null_outw(uint16_t addr, uint16_t val, void *priv) { pclog("IO: writew(%04x, %04x)\n", val); }
static void null_outl(uint16_t addr, uint32_t val, void *priv) { pclog("IO: writel(%04x, %08lx)\n", val); }
#ifdef ENABLE_IO_LOG
int io_do_log = ENABLE_IO_LOG;
#endif
#ifdef ENABLE_IO_LOG
static void
io_log(const char *format, ...)
{
#ifdef ENABLE_IO_LOG
va_list ap;
if (io_do_log) {
va_start(ap, format);
pclog_ex(format, ap);
va_end(ap);
}
#endif
}
#endif
#ifdef ENABLE_IO_LOG
static uint8_t null_inb(uint16_t addr, void *priv) { io_log("IO: read(%04x)\n"); return(0xff); }
static uint16_t null_inw(uint16_t addr, void *priv) { io_log("IO: readw(%04x)\n"); return(0xffff); }
static uint32_t null_inl(uint16_t addr, void *priv) { io_log("IO: readl(%04x)\n"); return(0xffffffff); }
static void null_outb(uint16_t addr, uint8_t val, void *priv) { io_log("IO: write(%04x, %02x)\n", val); }
static void null_outw(uint16_t addr, uint16_t val, void *priv) { io_log("IO: writew(%04x, %04x)\n", val); }
static void null_outl(uint16_t addr, uint32_t val, void *priv) { io_log("IO: writel(%04x, %08lx)\n", val); }
#endif
@@ -83,7 +107,7 @@ io_init(void)
p = NULL;
}
#ifdef IO_CATCH
#ifdef ENABLE_IO_LOG
/* io[c] should be the only handler, pointing at the NULL catch handler. */
p = (io_t *) malloc(sizeof(io_t));
memset(p, 0, sizeof(io_t));
@@ -278,9 +302,9 @@ inb(uint16_t port)
}
}
#ifdef IO_TRACE
#ifdef ENABLE_IO_LOG
if (CS == IO_TRACE)
pclog("IOTRACE(%04X): inb(%04x)=%02x\n", IO_TRACE, port, r);
io_log("IOTRACE(%04X): inb(%04x)=%02x\n", IO_TRACE, port, r);
#endif
return(r);
@@ -301,9 +325,9 @@ outb(uint16_t port, uint8_t val)
}
}
#ifdef IO_TRACE
#ifdef ENABLE_IO_LOG
if (CS == IO_TRACE)
pclog("IOTRACE(%04X): outb(%04x,%02x)\n", IO_TRACE, port, val);
io_log("IOTRACE(%04X): outb(%04x,%02x)\n", IO_TRACE, port, val);
#endif
return;
}

View File

@@ -8,7 +8,7 @@
*
* Definitions for the keyboard interface.
*
* Version: @(#)keyboard.h 1.0.14 2018/03/22
* Version: @(#)keyboard.h 1.0.15 2018/03/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -70,6 +70,8 @@ extern const device_t keyboard_ps2_ami_device;
extern const device_t keyboard_ps2_mca_device;
extern const device_t keyboard_ps2_mca_2_device;
extern const device_t keyboard_ps2_quadtel_device;
extern const device_t keyboard_ps2_pci_device;
extern const device_t keyboard_ps2_ami_pci_device;
#endif
extern void keyboard_init(void);
@@ -87,7 +89,6 @@ extern int keyboard_recv(uint16_t key);
extern int keyboard_isfsexit(void);
extern int keyboard_ismsexit(void);
extern void keyboard_at_reset(void);
extern void keyboard_at_adddata_keyboard_raw(uint8_t val);
extern void keyboard_at_adddata_mouse(uint8_t val);
extern void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val,void *), void *);

View File

@@ -8,7 +8,7 @@
*
* Intel 8042 (AT keyboard controller) emulation.
*
* Version: @(#)keyboard_at.c 1.0.33 2018/03/22
* Version: @(#)keyboard_at.c 1.0.37 2018/05/25
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -44,6 +44,7 @@
#include "sound/snd_speaker.h"
#include "video/video.h"
#include "keyboard.h"
#include "mouse.h"
#define STAT_PARITY 0x80
@@ -121,6 +122,8 @@ typedef struct {
uint8_t (*write60_ven)(void *p, uint8_t val);
uint8_t (*write64_ven)(void *p, uint8_t val);
int64_t timeout;
} atkbd_t;
@@ -1001,6 +1004,20 @@ kbd_pulse_poll(void *p)
}
static void
kbd_timeout_poll(void *p)
{
atkbd_t *kbd = (atkbd_t *) p;
kbd->key_wantdata = 0;
kbd->want60 = 0;
if (mouse_p)
mouse_clear_data(mouse_p);
kbd->timeout = 0LL;
}
static void
kbd_keyboard_set(atkbd_t *kbd, uint8_t enable)
{
@@ -1074,6 +1091,7 @@ kbd_write64_generic(void *p, uint8_t val)
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
kbdlog("ATkbd: write mouse output buffer\n");
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
return 0;
}
break;
@@ -1081,6 +1099,7 @@ kbd_write64_generic(void *p, uint8_t val)
if ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
kbdlog("ATkbd: write to mouse\n");
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
return 0;
}
break;
@@ -1122,6 +1141,7 @@ kbd_write60_ami(void *p, uint8_t val)
if (kbd->secr_phase == 1) {
kbd->mem_addr = val;
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
kbd->secr_phase = 2;
} else if (kbd->secr_phase == 2) {
kbd->mem[kbd->mem_addr] = val;
@@ -1164,6 +1184,7 @@ kbd_write64_ami(void *p, uint8_t val)
case 0x5c: case 0x5d: case 0x5e: case 0x5f:
kbdlog("AMI - alias write to register %08X\n", kbd->command);
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
return 0;
case 0xa1: /*AMI - get controller version*/
kbdlog("AMI - get controller version\n");
@@ -1229,6 +1250,7 @@ kbd_write64_ami(void *p, uint8_t val)
case 0xaf: /*Set extended controller RAM*/
kbdlog("ATkbd: set extended controller RAM\n");
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
kbd->secr_phase = 1;
return 0;
case 0xb0: case 0xb1: case 0xb2: case 0xb3:
@@ -1245,9 +1267,10 @@ kbd_write64_ami(void *p, uint8_t val)
return 0;
case 0xb8: case 0xb9: case 0xba: case 0xbb:
/*Set keyboard controller line P10-P13 (input port bits 0-3) high*/
if (!PCI || (val > 0xb9))
if (!PCI || (val > 0xb9)) {
kbd->input_port |= (1 << (val & 0x03));
kbd_adddata(0x00);
kbd_adddata(0x00);
}
return 0;
case 0xbc: case 0xbd:
/*Set keyboard controller line P22-P23 (output port bits 2-3) high*/
@@ -1274,6 +1297,7 @@ kbd_write64_ami(void *p, uint8_t val)
case 0xcb: /*AMI - set keyboard mode*/
kbdlog("AMI - set keyboard mode\n");
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
return 0;
case 0xef: /*??? - sent by AMI486*/
kbdlog("??? - sent by AMI486\n");
@@ -1343,6 +1367,7 @@ kbd_write64_quadtel(void *p, uint8_t val)
case 0xcf: /*??? - sent by MegaPC BIOS*/
kbdlog("??? - sent by MegaPC BIOS\n");
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
return 0;
}
@@ -1394,6 +1419,7 @@ kbd_write64_toshiba(void *p, uint8_t val)
return 0;
case 0xb6: /* T3100e: Set colour / mono byte */
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
return 0;
case 0xb7: /* T3100e: Emulate PS/2 keyboard - not implemented */
case 0xb8: /* T3100e: Emulate AT keyboard - not implemented */
@@ -1482,10 +1508,8 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
kbd_mouse_set(kbd, 1);
if (mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1))
mouse_write(val, mouse_p);
else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1)) {
pclog("Adding 0xFF to queue\n");
else if (!mouse_write && ((kbd->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1))
keyboard_at_adddata_mouse(0xff);
}
break;
default:
@@ -1549,6 +1573,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0xed: /*Set/reset LEDs*/
kbdlog("ATkbd: set/reset leds\n");
kbd->key_wantdata = 1;
kbd->timeout = 25000LL * TIMER_USEC;
kbd_adddata_keyboard(0xfa);
break;
@@ -1564,6 +1589,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0xf0: /*Get/set scan code set*/
kbdlog("ATkbd: scan code set\n");
kbd->key_wantdata = 1;
kbd->timeout = 25000LL * TIMER_USEC;
kbd_adddata_keyboard(0xfa);
break;
@@ -1578,6 +1604,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0xf3: /*Set typematic rate/delay*/
kbdlog("ATkbd: set typematic rate/delay\n");
kbd->key_wantdata = 1;
kbd->timeout = 25000LL * TIMER_USEC;
kbd_adddata_keyboard(0xfa);
break;
@@ -1698,6 +1725,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0x78: case 0x79: case 0x7a: case 0x7b:
case 0x7c: case 0x7d: case 0x7e: case 0x7f:
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
break;
case 0xaa: /*Self-test*/
@@ -1755,11 +1783,13 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
case 0xd1: /*Write output port*/
// kbdlog("ATkbd: write output port\n");
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
break;
case 0xd2: /*Write keyboard output buffer*/
kbdlog("ATkbd: write keyboard output buffer\n");
kbd->want60 = 1;
kbd->timeout = 25000LL * TIMER_USEC;
break;
case 0xdd: /* Disable A20 Address Line */
@@ -1866,6 +1896,7 @@ kbd_reset(void *priv)
kbd->last_irq = 0;
kbd->secr_phase = 0;
kbd->key_wantdata = 0;
kbd->timeout = 0LL;
keyboard_mode = 0x02 | kbd->dtrans;
@@ -1911,6 +1942,9 @@ kbd_init(const device_t *info)
timer_add(kbd_pulse_poll,
&kbd->pulse_cb, &kbd->pulse_cb, kbd);
timer_add(kbd_timeout_poll,
&kbd->timeout, &kbd->timeout, kbd);
kbd->write60_ven = NULL;
kbd->write64_ven = NULL;
@@ -1971,7 +2005,7 @@ const device_t keyboard_at_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_at_ami_device = {
@@ -1981,7 +2015,7 @@ const device_t keyboard_at_ami_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_at_toshiba_device = {
@@ -1991,7 +2025,7 @@ const device_t keyboard_at_toshiba_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_ps2_device = {
@@ -2001,7 +2035,7 @@ const device_t keyboard_ps2_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_ps2_ami_device = {
@@ -2011,7 +2045,7 @@ const device_t keyboard_ps2_ami_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_ps2_mca_device = {
@@ -2021,7 +2055,7 @@ const device_t keyboard_ps2_mca_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_ps2_mca_2_device = {
@@ -2031,7 +2065,7 @@ const device_t keyboard_ps2_mca_2_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_ps2_quadtel_device = {
@@ -2041,18 +2075,28 @@ const device_t keyboard_ps2_quadtel_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_ps2_pci_device = {
"PS/2 Keyboard",
DEVICE_PCI,
KBC_TYPE_PS2_1 | KBC_VEN_GENERIC,
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL
};
void
keyboard_at_reset(void)
{
atkbd_t *kbd = CurrentKbd;
if (kbd != NULL)
kbd_reset(kbd);
}
const device_t keyboard_ps2_ami_pci_device = {
"PS/2 Keyboard (AMI)",
DEVICE_PCI,
KBC_TYPE_PS2_1 | KBC_VEN_AMI,
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL
};
void

View File

@@ -8,7 +8,7 @@
*
* Implementation of the XT-style keyboard.
*
* Version: @(#)keyboard_xt.c 1.0.11 2018/03/19
* Version: @(#)keyboard_xt.c 1.0.12 2018/04/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -581,7 +581,7 @@ const device_t keyboard_xt_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};
const device_t keyboard_tandy_device = {
@@ -591,5 +591,5 @@ const device_t keyboard_tandy_device = {
kbd_init,
kbd_close,
kbd_reset,
NULL, NULL, NULL, NULL
NULL, NULL, NULL
};

View File

@@ -10,7 +10,7 @@
*
* NOTE: FIXME: Strings 2176 and 2193 are same.
*
* Version: @(#)language.h 1.0.7 2018/03/07
* Version: @(#)language.h 1.0.8 2018/05/25
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -25,17 +25,17 @@
#define IDS_2049 2049 // "86Box Error"
#define IDS_2050 2050 // "86Box Fatal Error"
#define IDS_2051 2051 // "This will reset 86Box.."
#define IDS_2052 2052 // "DirectDraw Screenshot Error"
#define IDS_2053 2053 // "Invalid number of sectors.."
#define IDS_2054 2054 // "Invalid number of heads.."
#define IDS_2055 2055 // "Invalid number of cylinders.."
#define IDS_2052 2052 // "Use CTRL+ALT+PAGE DOWN.."
#define IDS_2053 2053 // "Speed"
#define IDS_2054 2054 // "ZIP %i (%03i): %ls"
#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..."
#define IDS_2056 2056 // "No usable ROM images found!"
#define IDS_2057 2057 // "(empty)"
#define IDS_2058 2058 // "(host drive %c:)"
#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..."
#define IDS_2059 2059 // "(Turbo)"
#define IDS_2060 2060 // "On"
#define IDS_2061 2061 // "Off"
#define IDS_2062 2062 // "86Box was unable to find any.."
#define IDS_2062 2062 // "All floppy images (*.DSK..."
#define IDS_2063 2063 // "Configured ROM set not avai.."
#define IDS_2064 2064 // "Configured video BIOS not.."
#define IDS_2065 2065 // "Machine"
@@ -49,114 +49,54 @@
#define IDS_2073 2073 // "Floppy drives"
#define IDS_2074 2074 // "Other removable devices"
#define IDS_2075 2075 // "CD-ROM images (*.ISO;*.CU.."
#define IDS_2076 2076 // "Host CD/DVD Drive (%c:)"
#define IDS_2076 2076 // "Surface-based images (*.8.."
#define IDS_2077 2077 // "Click to capture mouse"
#define IDS_2078 2078 // "Press F12-F8 to release mouse"
#define IDS_2079 2079 // "Press F12-F8 or middle button.."
#define IDS_2080 2080 // "Drive"
#define IDS_2081 2081 // "Location"
#define IDS_2080 2080 // "E&xport to 86F..."
#define IDS_2081 2081 // "Unable to initialize Flui.."
#define IDS_2082 2082 // "Bus"
#define IDS_2083 2083 // "File"
#define IDS_2084 2084 // "C"
#define IDS_2085 2085 // "H"
#define IDS_2086 2086 // "S"
#define IDS_2087 2087 // "MB"
#define IDS_2088 2088 // "Unable to create bitmap file: %s"
#define IDS_2089 2089 // "Enabled"
#define IDS_2090 2090 // "Mute"
#define IDS_2091 2091 // "Type"
#define IDS_2092 2092 // "Bus"
#define IDS_2093 2093 // "DMA"
#define IDS_2088 2088 // "Check BPB"
#define IDS_2089 2089 // "&Image..."
#define IDS_2090 2090 // "&Reload previous image"
#define IDS_2091 2091 // "E&mpty"
#define IDS_2092 2092 // "&Mute"
#define IDS_2093 2093 // "E&ject"
#define IDS_2094 2094 // "KB"
#define IDS_2095 2095 // "Neither DirectDraw nor Dire.."
#define IDS_2096 2096 // "Slave"
#define IDS_2097 2097 // "SCSI (ID %s, LUN %s)"
#define IDS_2098 2098 // "Adapter Type"
#define IDS_2099 2099 // "Base Address"
#define IDS_2100 2100 // "IRQ"
#define IDS_2101 2101 // "8-bit DMA"
#define IDS_2102 2102 // "16-bit DMA"
#define IDS_2103 2103 // "BIOS"
#define IDS_2104 2104 // "Network Type"
#define IDS_2105 2105 // "Surround Module"
#define IDS_2106 2106 // "MPU-401 Base Address"
#define IDS_2107 2107 // "Use CTRL+ALT+PAGE DOWN.."
#define IDS_2108 2108 // "On-board RAM"
#define IDS_2109 2109 // "Memory Size"
#define IDS_2110 2110 // "Display Type"
#define IDS_2111 2111 // "RGB"
#define IDS_2112 2112 // "Composite"
#define IDS_2113 2113 // "Composite Type"
#define IDS_2114 2114 // "Old"
#define IDS_2115 2115 // "New"
#define IDS_2116 2116 // "RGB Type"
#define IDS_2117 2117 // "Color"
#define IDS_2118 2118 // "Monochrome (Green)"
#define IDS_2119 2119 // "Monochrome (Amber)"
#define IDS_2120 2120 // "Monochrome (Gray)"
#define IDS_2121 2121 // "Color (no brown)"
#define IDS_2122 2122 // "Monochrome (Default)"
#define IDS_2123 2123 // "Snow Emulation"
#define IDS_2124 2124 // "Bilinear Filtering"
#define IDS_2125 2125 // "Dithering"
#define IDS_2126 2126 // "Framebuffer Memory Size"
#define IDS_2127 2127 // "Texture Memory Size"
#define IDS_2128 2128 // "Screen Filter"
#define IDS_2129 2129 // "Render Threads"
#define IDS_2130 2130 // "Recompiler"
#define IDS_2131 2131 // "System Default"
#define IDS_2132 2132 // "%i Wait state(s)"
#define IDS_2133 2133 // "8-bit"
#define IDS_2134 2134 // "Slow 16-bit"
#define IDS_2135 2135 // "Fast 16-bit"
#define IDS_2136 2136 // "Slow VLB/PCI"
#define IDS_2137 2137 // "Mid VLB/PCI"
#define IDS_2138 2138 // "Fast VLB/PCI"
#define IDS_2139 2139 // "PCap failed to set up.."
#define IDS_2140 2140 // "No PCap devices found"
#define IDS_2141 2141 // "Invalid PCap device"
#define IDS_2142 2142 // "&Notify disk change"
#define IDS_2143 2143 // "Type"
#define IDS_2144 2144 // "Standard 2-button joystick(s)"
#define IDS_2145 2145 // "Standard 4-button joystick"
#define IDS_2146 2146 // "Standard 6-button joystick"
#define IDS_2147 2147 // "Standard 8-button joystick"
#define IDS_2148 2148 // "CH Flightstick Pro"
#define IDS_2149 2149 // "Microsoft SideWinder Pad"
#define IDS_2150 2150 // "Thrustmaster Flight Cont.."
#define IDS_2151 2151 // "Disabled"
#define IDS_2152 2152 // "None"
#define IDS_2153 2153 // "Unable to load Accelerators"
#define IDS_2154 2154 // "Unable to register Raw Input"
#define IDS_2155 2155 // "IRQ %i"
#define IDS_2156 2156 // "%" PRIu64
#define IDS_2157 2157 // "%" PRIu64 " MB (CHS: %".."
#define IDS_2158 2158 // "Floppy %i (%s): %ls"
#define IDS_2159 2159 // "All floppy images (*.0??;*.."
#define IDS_2160 2160 // "Configuration files (*.CF.."
#define IDS_2161 2161 // "&New image..."
#define IDS_2162 2162 // "&Existing image..."
#define IDS_2163 2163 // "Existing image (&Write-pr..."
#define IDS_2164 2164 // "E&ject"
#define IDS_2165 2165 // "&Mute"
#define IDS_2166 2166 // "E&mpty"
#define IDS_2167 2167 // "&Reload previous image"
#define IDS_2168 2168 // "&Image..."
#define IDS_2169 2169 // "Image (&Write-protected)..."
#define IDS_2170 2170 // "Check BPB"
#define IDS_2171 2171 // "Unable to initialize Flui.."
#define IDS_2172 2172 // "E&xport to 86F..."
#define IDS_2173 2173 // "Surface-based images (*.8.."
#define IDS_2174 2174 // "All floppy images (*.DSK..."
#define IDS_2175 2175 // "ZIP images (*.IM?)\0*.IM..."
#define IDS_2176 2176 // "ZIP images (*.IM?)\0*.IM..."
#define IDS_2177 2177 // "ZIP %i (%03i): %ls"
#define IDS_2178 2178 // "Speed"
#define IDS_2096 2096 // "&New image..."
#define IDS_2097 2097 // "&Existing image..."
#define IDS_2098 2098 // "Existing image (&Write-pr..."
#define IDS_2099 2099 // "Default"
#define IDS_2100 2100 // "%i Wait state(s)"
#define IDS_2101 2101 // "Type"
#define IDS_2102 2102 // "PCap failed to set up.."
#define IDS_2103 2103 // "No PCap devices found"
#define IDS_2104 2104 // "Invalid PCap device"
#define IDS_2105 2105 // "Standard 2-button joystick(s)"
#define IDS_2106 2106 // "Standard 4-button joystick"
#define IDS_2107 2107 // "Standard 6-button joystick"
#define IDS_2108 2108 // "Standard 8-button joystick"
#define IDS_2109 2109 // "CH Flightstick Pro"
#define IDS_2110 2110 // "Microsoft SideWinder Pad"
#define IDS_2111 2111 // "Thrustmaster Flight Cont.."
#define IDS_2112 2112 // "None"
#define IDS_2113 2113 // "Unable to load Accelerators"
#define IDS_2114 2114 // "Unable to register Raw Input"
#define IDS_2115 2115 // "%u"
#define IDS_2116 2116 // "%u MB (CHS: %i, %i, %i)"
#define IDS_2117 2117 // "Floppy %i (%s): %ls"
#define IDS_2118 2118 // "All floppy images (*.0??;*.."
#define IDS_4096 4096 // "Hard disk (%s)"
#define IDS_4097 4097 // "%01i:%01i"
#define IDS_4098 4098 // "%i"
#define IDS_4099 4099 // "Disabled"
#define IDS_4099 4099 // "MFM/RLL or ESDI CD-ROM driv.."
#define IDS_4100 4100 // "Custom..."
#define IDS_4101 4101 // "Custom (large)..."
#define IDS_4102 4102 // "Add New Hard Disk"
@@ -171,8 +111,6 @@
#define IDS_4111 4111 // "This image exists and will be.."
#define IDS_4112 4112 // "Please enter a valid file name"
#define IDS_4113 4113 // "Remember to partition and fo.."
#define IDS_4114 4114 // "MFM/RLL or ESDI CD-ROM driv.."
#define IDS_4115 4115 // "Removable disk %i (SCSI): %ls"
#define IDS_4352 4352 // "MFM/RLL"
#define IDS_4353 4353 // "XT IDE"
@@ -193,17 +131,17 @@
#define IDS_5120 5120 // "CD-ROM %i (%s): %s"
#define IDS_5376 5376 // "Disabled"
#define IDS_5377 5377 // "<Reserved>"
#define IDS_5378 5378 // "<Reserved>"
#define IDS_5379 5379 // "<Reserved>"
#define IDS_5377 5377 // <Reserved>
#define IDS_5378 5378 // <Reserved>
#define IDS_5379 5379 // <Reserved>
#define IDS_5380 5380 // "ATAPI (PIO-only)"
#define IDS_5381 5381 // "ATAPI (PIO and DMA)"
#define IDS_5382 5382 // "SCSI"
#define IDS_5632 5632 // "Disabled"
#define IDS_5633 5633 // "<Reserved>"
#define IDS_5634 5634 // "<Reserved>"
#define IDS_5635 5635 // "<Reserved>"
#define IDS_5633 5633 // <Reserved>
#define IDS_5634 5634 // <Reserved>
#define IDS_5635 5635 // <Reserved>
#define IDS_5636 5636 // "ATAPI (PIO-only) (%01i:%01i)"
#define IDS_5637 5637 // "ATAPI (PIO and DMA) (%01i:%01i)"
#define IDS_5638 5638 // "SCSI (%02i:%02i)"
@@ -232,9 +170,9 @@
#define IDS_LANG_ENUS IDS_7168
#define STR_NUM_2048 131
#define STR_NUM_2048 71
#define STR_NUM_3072 11
#define STR_NUM_4096 20
#define STR_NUM_4096 18
#define STR_NUM_4352 7
#define STR_NUM_4608 7
#define STR_NUM_5120 1

View File

@@ -32,7 +32,7 @@
* in alpha mode, but in highres ("ECD350") mode, it displays
* some semi-random junk. Video-memory pointer maybe?
*
* Version: @(#)m_amstrad.c 1.0.11 2018/03/18
* Version: @(#)m_amstrad.c 1.0.14 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -42,11 +42,13 @@
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../cpu/cpu.h"
#include "../io.h"
@@ -150,6 +152,27 @@ static uint8_t crtc_mask[32] = {
};
#ifdef ENABLE_AMSTRAD_LOG
int amstrad_do_log = ENABLE_AMSTRAD_LOG;
#endif
static void
amstrad_log(const char *fmt, ...)
{
#ifdef ENABLE_AMSTRAD_LOG
va_list ap;
if (amstrad_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static void
recalc_timings_1512(amsvid_t *vid)
{
@@ -563,7 +586,6 @@ static const device_t vid_1512_device = {
NULL, vid_close_1512, NULL,
NULL,
vid_speed_change_1512,
NULL,
NULL
};
@@ -727,7 +749,6 @@ static const device_t vid_1640_device = {
NULL, vid_close_1640, NULL,
NULL,
vid_speed_changed_1640,
NULL,
NULL
};
@@ -862,7 +883,6 @@ static const device_t vid_200_device = {
NULL, vid_close_200, NULL,
NULL,
vid_speed_changed_200,
NULL,
NULL
};
@@ -918,10 +938,8 @@ static void
kbd_adddata(uint16_t val)
{
key_queue[key_queue_end] = val;
#if ENABLE_KEYBOARD_LOG
pclog("keyboard_amstrad : %02X added to key queue at %i\n",
amstrad_log("keyboard_amstrad : %02X added to key queue at %i\n",
val, key_queue_end);
#endif
key_queue_end = (key_queue_end + 1) & 0xf;
}
@@ -937,13 +955,8 @@ static void
kbd_write(uint16_t port, uint8_t val, void *priv)
{
amstrad_t *ams = (amstrad_t *)priv;
#ifdef WALTJE
int i = 0;
#endif
#if ENABLE_KEYBOARD_LOG
pclog("keyboard_amstrad : write %04X %02X %02X\n", port, val, ams->pb);
#endif
amstrad_log("keyboard_amstrad : write %04X %02X %02X\n", port, val, ams->pb);
switch (port) {
case 0x61:
@@ -961,13 +974,9 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
*
* This register is controlled by BIOS and/or ROS.
*/
#if ENABLE_KEYBOARD_LOG
pclog("AMSkb: write PB %02x (%02x)\n", val, ams->pb);
#endif
amstrad_log("AMSkb: write PB %02x (%02x)\n", val, ams->pb);
if (!(ams->pb & 0x40) && (val & 0x40)) { /*Reset keyboard*/
#if ENABLE_KEYBOARD_LOG
pclog("AMSkb: reset keyboard\n");
#endif
amstrad_log("AMSkb: reset keyboard\n");
kbd_adddata(0xaa);
}
ams->pb = val;
@@ -993,30 +1002,19 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
break;
case 0x64:
#ifdef WALTJE
pclog("AMSkb: STAT1 = %02x (%02x)\n", val, ams->stat1);
#endif
ams->stat1 = val;
break;
case 0x65:
#ifdef WALTJE
pclog("AMSkb: STAT2 = %02x (%02x)\n", val, ams->stat2);
i = 512 + (((val & 0x1f) - 0x0e) * 32);
pclog("AMSkb: %d KB RAM installed.\n", i);
#endif
ams->stat2 = val;
break;
case 0x66:
#ifdef WALTJE
pclog("AMSkb: RESET REQUESTED !\n");
#endif
pc_reset(1);
break;
default:
pclog("AMSkb: bad keyboard write %04X %02X\n", port, val);
amstrad_log("AMSkb: bad keyboard write %04X %02X\n", port, val);
}
}
@@ -1105,7 +1103,7 @@ kbd_read(uint16_t port, void *priv)
break;
default:
pclog("AMDkb: bad keyboard read %04X\n", port);
amstrad_log("AMDkb: bad keyboard read %04X\n", port);
}
return(ret);
@@ -1123,17 +1121,13 @@ kbd_poll(void *priv)
{
ams->wantirq = 0;
ams->pa = ams->key_waiting;
picint(2);
#if ENABLE_KEYBOARD_LOG
pclog("keyboard_amstrad : take IRQ\n");
picint(2);
amstrad_log("keyboard_amstrad : take IRQ\n");
}
if (key_queue_start != key_queue_end && !ams->pa) {
ams->key_waiting = key_queue[key_queue_start];
#if ENABLE_KEYBOARD_LOG
ams->key_waiting = key_queue[key_queue_start];
amstrad_log("Reading %02X from the key queue at %i\n",
ams->key_waiting, key_queue_start);
ams->key_waiting, key_queue_start);
key_queue_start = (key_queue_start + 1) & 0xf;
ams->wantirq = 1;
@@ -1205,7 +1199,7 @@ machine_amstrad_init(const machine_t *model)
ams = (amstrad_t *)malloc(sizeof(amstrad_t));
memset(ams, 0x00, sizeof(amstrad_t));
device_add(&amstrad_nvr_device);
machine_common_init(model);

View File

@@ -30,7 +30,7 @@ machine_at_common_init(const machine_t *model)
if (lpt_enabled)
lpt2_remove();
nvr_at_init(8);
device_add(&at_nvr_device);
if (joystick_type != 7)
device_add(&gameport_device);

View File

@@ -1,345 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel 430FX PCISet chip.
*
* Version: @(#)m_at_430fx.c 1.0.14 2018/03/18
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016,2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../mem.h"
#include "../memregs.h"
#include "../rom.h"
#include "../pci.h"
#include "../device.h"
#include "../keyboard.h"
#include "../piix.h"
#include "../intel_flash.h"
#include "../sio.h"
#include "../video/video.h"
#include "../video/vid_cl54xx.h"
#include "../video/vid_s3.h"
#include "machine.h"
static uint8_t card_i430fx[256];
static void i430fx_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3)
{
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
}
static void i430fx_write(int func, int addr, uint8_t val, void *priv)
{
if (func)
return;
if (addr >= 0x10 && addr < 0x4f)
return;
switch (addr)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0e:
return;
case 0x04: /*Command register*/
val &= 0x02;
val |= 0x04;
break;
case 0x05:
val = 0;
break;
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
val = 0x02;
break;
case 0x59: /*PAM0*/
if ((card_i430fx[0x59] ^ val) & 0xf0)
{
i430fx_map(0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
pclog("i430fx_write : PAM0 write %02X\n", val);
break;
case 0x5a: /*PAM1*/
if ((card_i430fx[0x5a] ^ val) & 0x0f)
i430fx_map(0xc0000, 0x04000, val & 0xf);
if ((card_i430fx[0x5a] ^ val) & 0xf0)
i430fx_map(0xc4000, 0x04000, val >> 4);
break;
case 0x5b: /*PAM2*/
if ((card_i430fx[0x5b] ^ val) & 0x0f)
i430fx_map(0xc8000, 0x04000, val & 0xf);
if ((card_i430fx[0x5b] ^ val) & 0xf0)
i430fx_map(0xcc000, 0x04000, val >> 4);
break;
case 0x5c: /*PAM3*/
if ((card_i430fx[0x5c] ^ val) & 0x0f)
i430fx_map(0xd0000, 0x04000, val & 0xf);
if ((card_i430fx[0x5c] ^ val) & 0xf0)
i430fx_map(0xd4000, 0x04000, val >> 4);
break;
case 0x5d: /*PAM4*/
if ((card_i430fx[0x5d] ^ val) & 0x0f)
i430fx_map(0xd8000, 0x04000, val & 0xf);
if ((card_i430fx[0x5d] ^ val) & 0xf0)
i430fx_map(0xdc000, 0x04000, val >> 4);
break;
case 0x5e: /*PAM5*/
if ((card_i430fx[0x5e] ^ val) & 0x0f)
i430fx_map(0xe0000, 0x04000, val & 0xf);
if ((card_i430fx[0x5e] ^ val) & 0xf0)
i430fx_map(0xe4000, 0x04000, val >> 4);
pclog("i430fx_write : PAM5 write %02X\n", val);
break;
case 0x5f: /*PAM6*/
if ((card_i430fx[0x5f] ^ val) & 0x0f)
i430fx_map(0xe8000, 0x04000, val & 0xf);
if ((card_i430fx[0x5f] ^ val) & 0xf0)
i430fx_map(0xec000, 0x04000, val >> 4);
pclog("i430fx_write : PAM6 write %02X\n", val);
break;
case 0x72: /*SMRAM*/
if ((card_i430fx[0x72] ^ val) & 0x48)
i430fx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
break;
}
card_i430fx[addr] = val;
}
static uint8_t i430fx_read(int func, int addr, void *priv)
{
if (func)
return 0xff;
return card_i430fx[addr];
}
static void i430fx_reset(void)
{
memset(card_i430fx, 0, 256);
card_i430fx[0x00] = 0x86; card_i430fx[0x01] = 0x80; /*Intel*/
card_i430fx[0x02] = 0x2d; card_i430fx[0x03] = 0x16; /*SB82437FX-66*/
card_i430fx[0x04] = 0x06; card_i430fx[0x05] = 0x00;
card_i430fx[0x06] = 0x00; card_i430fx[0x07] = 0x82;
if (romset == ROM_MB500N) card_i430fx[0x07] = 0x02;
card_i430fx[0x08] = 0x00; /*A0 stepping*/
card_i430fx[0x09] = 0x00; card_i430fx[0x0a] = 0x00; card_i430fx[0x0b] = 0x06;
card_i430fx[0x52] = 0x40; /*256kb PLB cache*/
if (romset == ROM_MB500N)
{
card_i430fx[0x52] = 0x42;
card_i430fx[0x53] = 0x14;
card_i430fx[0x56] = 0x52; /*DRAM control*/
}
card_i430fx[0x57] = 0x01;
card_i430fx[0x60] = card_i430fx[0x61] = card_i430fx[0x62] = card_i430fx[0x63] = card_i430fx[0x64] = 0x02;
if (romset == ROM_MB500N)
{
card_i430fx[0x67] = 0x11;
card_i430fx[0x69] = 0x03;
card_i430fx[0x70] = 0x20;
}
card_i430fx[0x72] = 0x02;
if (romset == ROM_MB500N)
{
card_i430fx[0x74] = 0x0e;
card_i430fx[0x78] = 0x23;
}
}
static void i430fx_pci_reset(void)
{
i430fx_write(0, 0x59, 0x00, NULL);
i430fx_write(0, 0x72, 0x02, NULL);
}
static void i430fx_init(void)
{
pci_add_card(0, i430fx_read, i430fx_write, NULL);
i430fx_reset();
pci_reset_handler.pci_master_reset = i430fx_pci_reset;
}
void
machine_at_p54tp4xe_init(const machine_t *model)
{
machine_at_ps2_init(model);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix3_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_endeavor_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
if (gfxcard == GFX_INTERNAL)
device_add(&s3_phoenix_trio64_onboard_pci_device);
}
const device_t *
at_endeavor_get_device(void)
{
return &s3_phoenix_trio64_onboard_pci_device;
}
void
machine_at_zappa_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
}
void
machine_at_mb500n_init(const machine_t *model)
{
machine_at_ps2_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_president_init(const machine_t *model)
{
machine_at_ps2_init(model);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_thor_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430fx_init();
piix_init(7);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
}

View File

@@ -1,329 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel 430HX PCISet chip.
*
* Version: @(#)m_at_430hx.c 1.0.11 2018/03/18
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../io.h"
#include "../mem.h"
#include "../memregs.h"
#include "../pci.h"
#include "../device.h"
#include "../keyboard.h"
#include "../piix.h"
#include "../intel_flash.h"
#include "../sio.h"
#include "machine.h"
static uint8_t card_i430hx[256];
static void i430hx_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3)
{
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
}
static void i430hx_write(int func, int addr, uint8_t val, void *priv)
{
if (func)
return;
if ((addr >= 0x10) && (addr < 0x4f))
return;
switch (addr)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0e:
return;
case 0x04: /*Command register*/
val &= 0x02;
val |= 0x04;
break;
case 0x05:
val = 0;
break;
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
val &= 0x80;
val |= 0x02;
break;
case 0x59: /*PAM0*/
if ((card_i430hx[0x59] ^ val) & 0xf0)
{
i430hx_map(0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
break;
case 0x5a: /*PAM1*/
if ((card_i430hx[0x5a] ^ val) & 0x0f)
i430hx_map(0xc0000, 0x04000, val & 0xf);
if ((card_i430hx[0x5a] ^ val) & 0xf0)
i430hx_map(0xc4000, 0x04000, val >> 4);
break;
case 0x5b: /*PAM2*/
if ((card_i430hx[0x5b] ^ val) & 0x0f)
i430hx_map(0xc8000, 0x04000, val & 0xf);
if ((card_i430hx[0x5b] ^ val) & 0xf0)
i430hx_map(0xcc000, 0x04000, val >> 4);
break;
case 0x5c: /*PAM3*/
if ((card_i430hx[0x5c] ^ val) & 0x0f)
i430hx_map(0xd0000, 0x04000, val & 0xf);
if ((card_i430hx[0x5c] ^ val) & 0xf0)
i430hx_map(0xd4000, 0x04000, val >> 4);
break;
case 0x5d: /*PAM4*/
if ((card_i430hx[0x5d] ^ val) & 0x0f)
i430hx_map(0xd8000, 0x04000, val & 0xf);
if ((card_i430hx[0x5d] ^ val) & 0xf0)
i430hx_map(0xdc000, 0x04000, val >> 4);
break;
case 0x5e: /*PAM5*/
if ((card_i430hx[0x5e] ^ val) & 0x0f)
i430hx_map(0xe0000, 0x04000, val & 0xf);
if ((card_i430hx[0x5e] ^ val) & 0xf0)
i430hx_map(0xe4000, 0x04000, val >> 4);
break;
case 0x5f: /*PAM6*/
if ((card_i430hx[0x5f] ^ val) & 0x0f)
i430hx_map(0xe8000, 0x04000, val & 0xf);
if ((card_i430hx[0x5f] ^ val) & 0xf0)
i430hx_map(0xec000, 0x04000, val >> 4);
break;
case 0x72: /*SMRAM*/
if ((card_i430hx[0x72] ^ val) & 0x48)
i430hx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
break;
}
card_i430hx[addr] = val;
}
static uint8_t i430hx_read(int func, int addr, void *priv)
{
if (func)
return 0xff;
return card_i430hx[addr];
}
static void i430hx_reset(void)
{
memset(card_i430hx, 0, 256);
card_i430hx[0x00] = 0x86; card_i430hx[0x01] = 0x80; /*Intel*/
card_i430hx[0x02] = 0x50; card_i430hx[0x03] = 0x12; /*82439HX*/
card_i430hx[0x04] = 0x06; card_i430hx[0x05] = 0x00;
card_i430hx[0x06] = 0x00; card_i430hx[0x07] = 0x02;
card_i430hx[0x08] = 0x00; /*A0 stepping*/
card_i430hx[0x09] = 0x00; card_i430hx[0x0a] = 0x00; card_i430hx[0x0b] = 0x06;
card_i430hx[0x51] = 0x20;
card_i430hx[0x52] = 0xB5; /*512kb cache*/
card_i430hx[0x59] = 0x40;
card_i430hx[0x5A] = card_i430hx[0x5B] = card_i430hx[0x5C] = card_i430hx[0x5D] = card_i430hx[0x5E] = card_i430hx[0x5F] = 0x44;
card_i430hx[0x56] = 0x52; /*DRAM control*/
card_i430hx[0x57] = 0x01;
card_i430hx[0x60] = card_i430hx[0x61] = card_i430hx[0x62] = card_i430hx[0x63] = card_i430hx[0x64] = card_i430hx[0x65] = card_i430hx[0x66] = card_i430hx[0x67] = 0x02;
card_i430hx[0x68] = 0x11;
card_i430hx[0x72] = 0x02;
}
static void i430hx_pci_reset(void)
{
i430hx_write(0, 0x59, 0x00, NULL);
i430hx_write(0, 0x72, 0x02, NULL);
}
static void i430hx_init(void)
{
pci_add_card(0, i430hx_read, i430hx_write, NULL);
i430hx_reset();
pci_reset_handler.pci_master_reset = i430hx_pci_reset;
}
static int acerm3a_index;
static void
acerm3a_out(uint16_t port, uint8_t val, void *p)
{
if (port == 0xea)
acerm3a_index = val;
}
static uint8_t
acerm3a_in(uint16_t port, void *p)
{
if (port == 0xeb)
{
switch (acerm3a_index)
{
case 2:
return 0xfd;
}
}
return 0xff;
}
void
machine_at_acerm3a_init(const machine_t *model)
{
machine_at_ps2_init(model);
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x1F, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x10, PCI_CARD_ONBOARD, 4, 0, 0, 0);
i430hx_init();
piix3_init(7);
fdc37c932fr_init();
io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, NULL);
device_add(&intel_flash_bxb_device);
}
void
machine_at_acerv35n_init(const machine_t *model)
{
machine_at_ps2_init(model);
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
i430hx_init();
piix3_init(7);
fdc37c932fr_init();
io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, NULL);
device_add(&intel_flash_bxb_device);
}
void
machine_at_ap53_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_device);
memregs_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4);
i430hx_init();
piix3_init(7);
fdc37c669_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_p55t2p4_init(const machine_t *model)
{
machine_at_ps2_init(model);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430hx_init();
piix3_init(7);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_p55t2s_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_device);
memregs_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430hx_init();
piix3_init(7);
pc87306_init();
device_add(&intel_flash_bxt_device);
}

View File

@@ -1,250 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel 430LX and 430NX PCISet chips.
*
* Version: @(#)m_at_430lx_nx.c 1.0.10 2018/03/18
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../mem.h"
#include "../memregs.h"
#include "../rom.h"
#include "../pci.h"
#include "../device.h"
#include "../keyboard.h"
#include "../intel.h"
#include "../intel_flash.h"
#include "../intel_sio.h"
#include "../sio.h"
#include "machine.h"
static uint8_t card_i430_lx_nx[256];
static void i430lx_nx_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3)
{
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
}
static void i430lx_nx_write(int func, int addr, uint8_t val, void *priv)
{
if (func)
return;
if ((addr >= 0x10) && (addr < 0x4f))
return;
switch (addr)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0e:
return;
case 0x04: /*Command register*/
val &= 0x42;
val |= 0x04;
break;
case 0x05:
val &= 0x01;
break;
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
val = 0x02;
break;
case 0x59: /*PAM0*/
if ((card_i430_lx_nx[0x59] ^ val) & 0xf0)
{
i430lx_nx_map(0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
pclog("i430lx_write : PAM0 write %02X\n", val);
break;
case 0x5a: /*PAM1*/
if ((card_i430_lx_nx[0x5a] ^ val) & 0x0f)
i430lx_nx_map(0xc0000, 0x04000, val & 0xf);
if ((card_i430_lx_nx[0x5a] ^ val) & 0xf0)
i430lx_nx_map(0xc4000, 0x04000, val >> 4);
break;
case 0x5b: /*PAM2*/
if (romset == ROM_REVENGE)
{
if ((card_i430_lx_nx[0x5b] ^ val) & 0x0f)
i430lx_nx_map(0xc8000, 0x04000, val & 0xf);
if ((card_i430_lx_nx[0x5b] ^ val) & 0xf0)
i430lx_nx_map(0xcc000, 0x04000, val >> 4);
}
break;
case 0x5c: /*PAM3*/
if ((card_i430_lx_nx[0x5c] ^ val) & 0x0f)
i430lx_nx_map(0xd0000, 0x04000, val & 0xf);
if ((card_i430_lx_nx[0x5c] ^ val) & 0xf0)
i430lx_nx_map(0xd4000, 0x04000, val >> 4);
break;
case 0x5d: /*PAM4*/
if ((card_i430_lx_nx[0x5d] ^ val) & 0x0f)
i430lx_nx_map(0xd8000, 0x04000, val & 0xf);
if ((card_i430_lx_nx[0x5d] ^ val) & 0xf0)
i430lx_nx_map(0xdc000, 0x04000, val >> 4);
break;
case 0x5e: /*PAM5*/
if ((card_i430_lx_nx[0x5e] ^ val) & 0x0f)
i430lx_nx_map(0xe0000, 0x04000, val & 0xf);
if ((card_i430_lx_nx[0x5e] ^ val) & 0xf0)
i430lx_nx_map(0xe4000, 0x04000, val >> 4);
pclog("i430lx_write : PAM5 write %02X\n", val);
break;
case 0x5f: /*PAM6*/
if ((card_i430_lx_nx[0x5f] ^ val) & 0x0f)
i430lx_nx_map(0xe8000, 0x04000, val & 0xf);
if ((card_i430_lx_nx[0x5f] ^ val) & 0xf0)
i430lx_nx_map(0xec000, 0x04000, val >> 4);
pclog("i430lx_write : PAM6 write %02X\n", val);
break;
}
card_i430_lx_nx[addr] = val;
}
static uint8_t i430lx_nx_read(int func, int addr, void *priv)
{
if (func)
return 0xff;
return card_i430_lx_nx[addr];
}
static void i430lx_nx_reset_common(void)
{
memset(card_i430_lx_nx, 0, 256);
card_i430_lx_nx[0x00] = 0x86; card_i430_lx_nx[0x01] = 0x80; /*Intel*/
card_i430_lx_nx[0x02] = 0xa3; card_i430_lx_nx[0x03] = 0x04; /*82434LX/NX*/
card_i430_lx_nx[0x04] = 0x06; card_i430_lx_nx[0x05] = 0x00;
card_i430_lx_nx[0x06] = 0x00; card_i430_lx_nx[0x07] = 0x02;
card_i430_lx_nx[0x09] = 0x00; card_i430_lx_nx[0x0a] = 0x00; card_i430_lx_nx[0x0b] = 0x06;
card_i430_lx_nx[0x57] = 0x31;
card_i430_lx_nx[0x60] = card_i430_lx_nx[0x61] = card_i430_lx_nx[0x62] = card_i430_lx_nx[0x63] = card_i430_lx_nx[0x64] = 0x02;
}
static void i430lx_reset(void)
{
i430lx_nx_reset_common();
card_i430_lx_nx[0x08] = 0x03; /*A3 stepping*/
card_i430_lx_nx[0x50] = 0x80;
card_i430_lx_nx[0x52] = 0x40; /*256kb PLB cache*/
}
static void i430nx_reset(void)
{
i430lx_nx_reset_common();
card_i430_lx_nx[0x08] = 0x10; /*A0 stepping*/
card_i430_lx_nx[0x50] = 0xA0;
card_i430_lx_nx[0x52] = 0x44; /*256kb PLB cache*/
card_i430_lx_nx[0x66] = card_i430_lx_nx[0x67] = 0x02;
}
static void i430lx_nx_pci_reset(void)
{
i430lx_nx_write(0, 0x59, 0x00, NULL);
}
static void i430lx_init(void)
{
pci_add_card(0, i430lx_nx_read, i430lx_nx_write, NULL);
i430lx_reset();
pci_reset_handler.pci_master_reset = i430lx_nx_pci_reset;
}
static void i430nx_init(void)
{
pci_add_card(0, i430lx_nx_read, i430lx_nx_write, NULL);
i430nx_reset();
pci_reset_handler.pci_master_reset = i430lx_nx_pci_reset;
}
static void
machine_at_premiere_common_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_2);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0);
sio_init(2);
fdc37c665_init();
intel_batman_init();
device_add(&intel_flash_bxt_ami_device);
}
void
machine_at_batman_init(const machine_t *model)
{
machine_at_premiere_common_init(model);
i430lx_init();
}
void
machine_at_plato_init(const machine_t *model)
{
machine_at_premiere_common_init(model);
i430nx_init();
}

View File

@@ -1,254 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel 430VX PCISet chip.
*
* Version: @(#)m_at_430vx.c 1.0.11 2018/03/18
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../io.h"
#include "../pci.h"
#include "../mem.h"
#include "../memregs.h"
#include "../device.h"
#include "../piix.h"
#include "../intel_flash.h"
#include "../sio.h"
#include "machine.h"
static uint8_t card_i430vx[256];
static void i430vx_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3)
{
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
}
static void i430vx_write(int func, int addr, uint8_t val, void *priv)
{
if (func)
return;
if ((addr >= 0x10) && (addr < 0x4f))
return;
switch (addr)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0e:
return;
case 0x04: /*Command register*/
val &= 0x02;
val |= 0x04;
break;
case 0x05:
val = 0;
break;
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
val &= 0x80;
val |= 0x02;
break;
case 0x59: /*PAM0*/
if ((card_i430vx[0x59] ^ val) & 0xf0)
{
i430vx_map(0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
/* pclog("i430vx_write : PAM0 write %02X\n", val); */
break;
case 0x5a: /*PAM1*/
if ((card_i430vx[0x5a] ^ val) & 0x0f)
i430vx_map(0xc0000, 0x04000, val & 0xf);
if ((card_i430vx[0x5a] ^ val) & 0xf0)
i430vx_map(0xc4000, 0x04000, val >> 4);
break;
case 0x5b: /*PAM2*/
if ((card_i430vx[0x5b] ^ val) & 0x0f)
i430vx_map(0xc8000, 0x04000, val & 0xf);
if ((card_i430vx[0x5b] ^ val) & 0xf0)
i430vx_map(0xcc000, 0x04000, val >> 4);
break;
case 0x5c: /*PAM3*/
if ((card_i430vx[0x5c] ^ val) & 0x0f)
i430vx_map(0xd0000, 0x04000, val & 0xf);
if ((card_i430vx[0x5c] ^ val) & 0xf0)
i430vx_map(0xd4000, 0x04000, val >> 4);
break;
case 0x5d: /*PAM4*/
if ((card_i430vx[0x5d] ^ val) & 0x0f)
i430vx_map(0xd8000, 0x04000, val & 0xf);
if ((card_i430vx[0x5d] ^ val) & 0xf0)
i430vx_map(0xdc000, 0x04000, val >> 4);
break;
case 0x5e: /*PAM5*/
if ((card_i430vx[0x5e] ^ val) & 0x0f)
i430vx_map(0xe0000, 0x04000, val & 0xf);
if ((card_i430vx[0x5e] ^ val) & 0xf0)
i430vx_map(0xe4000, 0x04000, val >> 4);
/* pclog("i430vx_write : PAM5 write %02X\n", val); */
break;
case 0x5f: /*PAM6*/
if ((card_i430vx[0x5f] ^ val) & 0x0f)
i430vx_map(0xe8000, 0x04000, val & 0xf);
if ((card_i430vx[0x5f] ^ val) & 0xf0)
i430vx_map(0xec000, 0x04000, val >> 4);
/* pclog("i430vx_write : PAM6 write %02X\n", val); */
break;
case 0x72: /*SMRAM*/
if ((card_i430vx[0x72] ^ val) & 0x48)
i430vx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
break;
}
card_i430vx[addr] = val;
}
static uint8_t i430vx_read(int func, int addr, void *priv)
{
if (func)
return 0xff;
return card_i430vx[addr];
}
static void i430vx_reset(void)
{
memset(card_i430vx, 0, 256);
card_i430vx[0x00] = 0x86; card_i430vx[0x01] = 0x80; /*Intel*/
card_i430vx[0x02] = 0x30; card_i430vx[0x03] = 0x70; /*82437VX*/
card_i430vx[0x04] = 0x06; card_i430vx[0x05] = 0x00;
card_i430vx[0x06] = 0x00; card_i430vx[0x07] = 0x02;
card_i430vx[0x08] = 0x00; /*A0 stepping*/
card_i430vx[0x09] = 0x00; card_i430vx[0x0a] = 0x00; card_i430vx[0x0b] = 0x06;
card_i430vx[0x52] = 0x42; /*256kb PLB cache*/
card_i430vx[0x53] = 0x14;
card_i430vx[0x56] = 0x52; /*DRAM control*/
card_i430vx[0x57] = 0x01;
card_i430vx[0x60] = card_i430vx[0x61] = card_i430vx[0x62] = card_i430vx[0x63] = card_i430vx[0x64] = 0x02;
card_i430vx[0x67] = 0x11;
card_i430vx[0x69] = 0x03;
card_i430vx[0x70] = 0x20;
card_i430vx[0x72] = 0x02;
card_i430vx[0x74] = 0x0e;
card_i430vx[0x78] = 0x23;
}
static void i430vx_pci_reset(void)
{
i430vx_write(0, 0x59, 0x00, NULL);
i430vx_write(0, 0x72, 0x02, NULL);
}
void i430vx_init(void)
{
pci_add_card(0, i430vx_read, i430vx_write, NULL);
i430vx_reset();
pci_reset_handler.pci_master_reset = i430vx_pci_reset;
}
void
machine_at_p55tvp4_init(const machine_t *model)
{
machine_at_ps2_init(model);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430vx_init();
piix3_init(7);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_i430vx_init(const machine_t *model)
{
machine_at_ps2_init(model);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430vx_init();
piix3_init(7);
um8669f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_p55va_init(const machine_t *model)
{
machine_at_ps2_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i430vx_init();
piix3_init(7);
fdc37c932fr_init();
device_add(&intel_flash_bxt_device);
}

View File

@@ -1,239 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel 440FX PCISet chip.
*
* Version: @(#)m_at_440fx.c 1.0.11 2018/03/18
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../io.h"
#include "../pci.h"
#include "../mem.h"
#include "../memregs.h"
#include "../device.h"
#include "../keyboard.h"
#include "../piix.h"
#include "../intel_flash.h"
#include "../sio.h"
#include "machine.h"
static uint8_t card_i440fx[256];
static void i440fx_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3)
{
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
}
static void i440fx_write(int func, int addr, uint8_t val, void *priv)
{
if (func)
return;
if ((addr >= 0x10) && (addr < 0x4f))
return;
switch (addr)
{
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0e:
return;
case 0x04: /*Command register*/
val &= 0x02;
val |= 0x04;
break;
case 0x05:
val = 0;
break;
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
val &= 0x80;
val |= 0x02;
break;
case 0x59: /*PAM0*/
if ((card_i440fx[0x59] ^ val) & 0xf0)
{
i440fx_map(0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
break;
case 0x5a: /*PAM1*/
if ((card_i440fx[0x5a] ^ val) & 0x0f)
i440fx_map(0xc0000, 0x04000, val & 0xf);
if ((card_i440fx[0x5a] ^ val) & 0xf0)
i440fx_map(0xc4000, 0x04000, val >> 4);
break;
case 0x5b: /*PAM2*/
if ((card_i440fx[0x5b] ^ val) & 0x0f)
i440fx_map(0xc8000, 0x04000, val & 0xf);
if ((card_i440fx[0x5b] ^ val) & 0xf0)
i440fx_map(0xcc000, 0x04000, val >> 4);
break;
case 0x5c: /*PAM3*/
if ((card_i440fx[0x5c] ^ val) & 0x0f)
i440fx_map(0xd0000, 0x04000, val & 0xf);
if ((card_i440fx[0x5c] ^ val) & 0xf0)
i440fx_map(0xd4000, 0x04000, val >> 4);
break;
case 0x5d: /*PAM4*/
if ((card_i440fx[0x5d] ^ val) & 0x0f)
i440fx_map(0xd8000, 0x04000, val & 0xf);
if ((card_i440fx[0x5d] ^ val) & 0xf0)
i440fx_map(0xdc000, 0x04000, val >> 4);
break;
case 0x5e: /*PAM5*/
if ((card_i440fx[0x5e] ^ val) & 0x0f)
i440fx_map(0xe0000, 0x04000, val & 0xf);
if ((card_i440fx[0x5e] ^ val) & 0xf0)
i440fx_map(0xe4000, 0x04000, val >> 4);
break;
case 0x5f: /*PAM6*/
if ((card_i440fx[0x5f] ^ val) & 0x0f)
i440fx_map(0xe8000, 0x04000, val & 0xf);
if ((card_i440fx[0x5f] ^ val) & 0xf0)
i440fx_map(0xec000, 0x04000, val >> 4);
break;
case 0x72: /*SMRAM*/
if ((card_i440fx[0x72] ^ val) & 0x48)
i440fx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
break;
}
card_i440fx[addr] = val;
}
static uint8_t i440fx_read(int func, int addr, void *priv)
{
if (func)
return 0xff;
return card_i440fx[addr];
}
static void i440fx_reset(void)
{
memset(card_i440fx, 0, 256);
card_i440fx[0x00] = 0x86; card_i440fx[0x01] = 0x80; /*Intel*/
card_i440fx[0x02] = 0x37; card_i440fx[0x03] = 0x12; /*82441FX*/
card_i440fx[0x04] = 0x03; card_i440fx[0x05] = 0x01;
card_i440fx[0x06] = 0x80; card_i440fx[0x07] = 0x00;
card_i440fx[0x08] = 0x02; /*A0 stepping*/
card_i440fx[0x09] = 0x00; card_i440fx[0x0a] = 0x00; card_i440fx[0x0b] = 0x06;
card_i440fx[0x0d] = 0x00;
card_i440fx[0x0f] = 0x00;
card_i440fx[0x2c] = 0xf4;
card_i440fx[0x2d] = 0x1a;
card_i440fx[0x2e] = 0x00;
card_i440fx[0x2f] = 0x11;
card_i440fx[0x50] = 0x00;
card_i440fx[0x51] = 0x01;
card_i440fx[0x52] = card_i440fx[0x54] = card_i440fx[0x55] = card_i440fx[0x56] = 0x00;
card_i440fx[0x53] = 0x80;
card_i440fx[0x57] = 0x01;
card_i440fx[0x58] = 0x10;
card_i440fx[0x5a] = card_i440fx[0x5b] = card_i440fx[0x5c] = card_i440fx[0x5d] = card_i440fx[0x5e] = 0x11;
card_i440fx[0x5f] = 0x31;
card_i440fx[0x72] = 0x02;
}
static void i440fx_pci_reset(void)
{
i440fx_write(0, 0x59, 0x00, NULL);
i440fx_write(0, 0x72, 0x02, NULL);
}
static void i440fx_init(void)
{
pci_add_card(0, i440fx_read, i440fx_write, NULL);
i440fx_reset();
pci_reset_handler.pci_master_reset = i440fx_pci_reset;
}
void
machine_at_i440fx_init(const machine_t *model)
{
machine_at_ps2_init(model);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
i440fx_init();
piix3_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_s1668_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4);
i440fx_init();
piix3_init(7);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}

View File

@@ -1,153 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation for C&T 82C206/82c597 based 4GLX3 board.
*
* NOTE: The NEAT 82c206 code should be moved into a 82c206 module,
* so it can be re-used by other boards.
*
* Version: @(#)m_4gpv31.c 1.0.5 2018/03/18
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../io.h"
#include "../device.h"
#include "../keyboard.h"
#include "../floppy/fdd.h"
#include "../floppy/fdc.h"
#include "machine.h"
typedef struct {
uint8_t regs[256];
int indx;
int emspg[4];
} neat_t;
#if NOT_USED
static void
neat_wrems(uint32_t addr, uint8_t val, void *priv)
{
neat_t *dev = (neat_t *)priv;
ram[(dev->emspg[(addr >> 14) & 3] << 14) + (addr & 0x3fff)] = val;
}
static uint8_t
neat_rdems(uint32_t addr, void *priv)
{
neat_t *dev = (neat_t *)priv;
return(ram[(dev->emspg[(addr >> 14) & 3] << 14) + (addr & 0x3fff)]);
}
#endif
static void
neat_write(uint16_t port, uint8_t val, void *priv)
{
neat_t *dev = (neat_t *)priv;
pclog("NEAT: write(%04x, %02x)\n", port, val);
switch (port) {
case 0x22:
dev->indx = val;
break;
case 0x23:
dev->regs[dev->indx] = val;
switch (dev->indx) {
case 0x6e: /* EMS page extension */
dev->emspg[3] = (dev->emspg[3] & 0x7F) | (( val & 3) << 7);
dev->emspg[2] = (dev->emspg[2] & 0x7F) | (((val >> 2) & 3) << 7);
dev->emspg[1] = (dev->emspg[1] & 0x7F) | (((val >> 4) & 3) << 7);
dev->emspg[0] = (dev->emspg[0] & 0x7F) | (((val >> 6) & 3) << 7);
break;
}
break;
case 0x0208:
case 0x0209:
case 0x4208:
case 0x4209:
case 0x8208:
case 0x8209:
case 0xc208:
case 0xc209:
dev->emspg[port >> 14] = (dev->emspg[port >> 14] & 0x180) | (val & 0x7F);
break;
}
}
static uint8_t
neat_read(uint16_t port, void *priv)
{
neat_t *dev = (neat_t *)priv;
uint8_t ret = 0xff;
switch (port) {
case 0x22:
ret = dev->indx;
break;
case 0x23:
ret = dev->regs[dev->indx];
break;
}
pclog("NEAT: read(%04x) = %02x\n", port, ret);
return(ret);
}
static void
neat_init(void)
{
neat_t *dev;
dev = (neat_t *)malloc(sizeof(neat_t));
memset(dev, 0x00, sizeof(neat_t));
io_sethandler(0x0022, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0x0208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0x4208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0x8208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
io_sethandler(0xc208, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
}
void
machine_at_4gpv31_init(const machine_t *model)
{
machine_at_common_ide_init(model);
device_add(&keyboard_at_ami_device);
device_add(&fdc_at_device);
neat_init();
}

919
src/machine/m_at_4x0.c Normal file
View File

@@ -0,0 +1,919 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the Intel PCISet chips from 430LX to 440FX.
*
* Version: @(#)m_at_430lx_nx.c 1.0.0 2018/05/09
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../mem.h"
#include "../memregs.h"
#include "../io.h"
#include "../rom.h"
#include "../pci.h"
#include "../device.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "../keyboard.h"
#include "../intel.h"
#include "../intel_flash.h"
#include "../intel_sio.h"
#include "../piix.h"
#include "../sio.h"
#include "../video/video.h"
#include "../video/vid_cl54xx.h"
#include "../video/vid_s3.h"
#include "machine.h"
enum
{
INTEL_430LX,
INTEL_430NX,
INTEL_430FX,
INTEL_430HX,
#if defined(DEV_BRANCH) && defined(USE_I686)
INTEL_430VX,
INTEL_440FX
#else
INTEL_430VX
#endif
};
typedef struct
{
uint8_t regs[256];
int type;
} i4x0_t;
typedef struct
{
int index;
} acerm3a_t;
static void
i4x0_map(uint32_t addr, uint32_t size, int state)
{
switch (state & 3) {
case 0:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 1:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
}
flushmmucache_nopc();
}
static void
i4x0_write(int func, int addr, uint8_t val, void *priv)
{
i4x0_t *dev = (i4x0_t *) priv;
if (func)
return;
if ((addr >= 0x10) && (addr < 0x4f))
return;
switch (addr) {
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0e:
return;
case 0x04: /*Command register*/
if (dev->type >= INTEL_430FX) {
if (romset == ROM_PB640)
val &= 0x06;
else
val &= 0x02;
} else
val &= 0x42;
val |= 0x04;
break;
case 0x05:
if (dev->type >= INTEL_430FX)
val = 0;
else
val &= 0x01;
break;
case 0x06: /*Status*/
val = 0;
break;
case 0x07:
if (dev->type >= INTEL_430HX) {
val &= 0x80;
val |= 0x02;
} else {
val = 0x02;
if (romset == ROM_PB640)
val |= 0x20;
}
break;
case 0x59: /*PAM0*/
if ((dev->regs[0x59] ^ val) & 0xf0) {
i4x0_map(0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
break;
case 0x5a: /*PAM1*/
if ((dev->regs[0x5a] ^ val) & 0x0f)
i4x0_map(0xc0000, 0x04000, val & 0xf);
if ((dev->regs[0x5a] ^ val) & 0xf0)
i4x0_map(0xc4000, 0x04000, val >> 4);
break;
case 0x5b: /*PAM2*/
if ((dev->regs[0x5b] ^ val) & 0x0f)
i4x0_map(0xc8000, 0x04000, val & 0xf);
if ((dev->regs[0x5b] ^ val) & 0xf0)
i4x0_map(0xcc000, 0x04000, val >> 4);
break;
case 0x5c: /*PAM3*/
if ((dev->regs[0x5c] ^ val) & 0x0f)
i4x0_map(0xd0000, 0x04000, val & 0xf);
if ((dev->regs[0x5c] ^ val) & 0xf0)
i4x0_map(0xd4000, 0x04000, val >> 4);
break;
case 0x5d: /*PAM4*/
if ((dev->regs[0x5d] ^ val) & 0x0f)
i4x0_map(0xd8000, 0x04000, val & 0xf);
if ((dev->regs[0x5d] ^ val) & 0xf0)
i4x0_map(0xdc000, 0x04000, val >> 4);
break;
case 0x5e: /*PAM5*/
if ((dev->regs[0x5e] ^ val) & 0x0f)
i4x0_map(0xe0000, 0x04000, val & 0xf);
if ((dev->regs[0x5e] ^ val) & 0xf0)
i4x0_map(0xe4000, 0x04000, val >> 4);
break;
case 0x5f: /*PAM6*/
if ((dev->regs[0x5f] ^ val) & 0x0f)
i4x0_map(0xe8000, 0x04000, val & 0xf);
if ((dev->regs[0x5f] ^ val) & 0xf0)
i4x0_map(0xec000, 0x04000, val >> 4);
break;
case 0x72: /*SMRAM*/
if ((dev->type >= INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x48))
i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
break;
}
dev->regs[addr] = val;
}
static uint8_t
i4x0_read(int func, int addr, void *priv)
{
i4x0_t *dev = (i4x0_t *) priv;
if (func)
return 0xff;
return dev->regs[addr];
}
static void
i4x0_reset(void *priv)
{
i4x0_t *i4x0 = (i4x0_t *)priv;
i4x0_write(0, 0x59, 0x00, priv);
if (i4x0->type >= INTEL_430FX)
i4x0_write(0, 0x72, 0x02, priv);
}
static void
i4x0_close(void *p)
{
i4x0_t *i4x0 = (i4x0_t *)p;
free(i4x0);
}
static void
*i4x0_init(const device_t *info)
{
i4x0_t *i4x0 = (i4x0_t *) malloc(sizeof(i4x0_t));
memset(i4x0, 0, sizeof(i4x0_t));
i4x0->type = info->local;
i4x0->regs[0x00] = 0x86; i4x0->regs[0x01] = 0x80; /*Intel*/
switch(i4x0->type) {
case INTEL_430LX:
i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/
i4x0->regs[0x08] = 0x03; /*A3 stepping*/
i4x0->regs[0x50] = 0x80;
i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/
break;
case INTEL_430NX:
i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/
i4x0->regs[0x08] = 0x10; /*A0 stepping*/
i4x0->regs[0x50] = 0xA0;
i4x0->regs[0x52] = 0x44; /*256kb PLB cache*/
i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02;
break;
case INTEL_430FX:
i4x0->regs[0x02] = 0x2d; i4x0->regs[0x03] = 0x12; /*SB82437FX-66*/
if (romset == ROM_PB640)
i4x0->regs[0x08] = 0x02; /*???? stepping*/
else
i4x0->regs[0x08] = 0x00; /*A0 stepping*/
i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/
break;
case INTEL_430HX:
i4x0->regs[0x02] = 0x50; i4x0->regs[0x03] = 0x12; /*82439HX*/
i4x0->regs[0x08] = 0x00; /*A0 stepping*/
i4x0->regs[0x51] = 0x20;
i4x0->regs[0x52] = 0xB5; /*512kb cache*/
i4x0->regs[0x56] = 0x52; /*DRAM control*/
i4x0->regs[0x59] = 0x40;
i4x0->regs[0x5A] = i4x0->regs[0x5B] = i4x0->regs[0x5C] = i4x0->regs[0x5D] = 0x44;
i4x0->regs[0x5E] = i4x0->regs[0x5F] = 0x44;
i4x0->regs[0x65] = i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02;
i4x0->regs[0x68] = 0x11;
break;
case INTEL_430VX:
i4x0->regs[0x02] = 0x30; i4x0->regs[0x03] = 0x70; /*82437VX*/
i4x0->regs[0x08] = 0x00; /*A0 stepping*/
i4x0->regs[0x52] = 0x42; /*256kb PLB cache*/
i4x0->regs[0x53] = 0x14;
i4x0->regs[0x56] = 0x52; /*DRAM control*/
i4x0->regs[0x67] = 0x11;
i4x0->regs[0x69] = 0x03;
i4x0->regs[0x70] = 0x20;
i4x0->regs[0x74] = 0x0e;
i4x0->regs[0x78] = 0x23;
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440FX:
i4x0->regs[0x02] = 0x37; i4x0->regs[0x03] = 0x12; /*82441FX*/
i4x0->regs[0x08] = 0x02; /*A0 stepping*/
i4x0->regs[0x2c] = 0xf4;
i4x0->regs[0x2d] = 0x1a;
i4x0->regs[0x2f] = 0x11;
i4x0->regs[0x51] = 0x01;
i4x0->regs[0x53] = 0x80;
i4x0->regs[0x58] = 0x10;
i4x0->regs[0x5a] = i4x0->regs[0x5b] = i4x0->regs[0x5c] = i4x0->regs[0x5d] = 0x11;
i4x0->regs[0x5e] = 0x11;
i4x0->regs[0x5f] = 0x31;
break;
#endif
}
i4x0->regs[0x04] = 0x06; i4x0->regs[0x05] = 0x00;
#if defined(DEV_BRANCH) && defined(USE_I686)
if (i4x0->type == INTEL_440FX)
i4x0->regs[0x06] = 0x80;
#endif
if ((i4x0->type == INTEL_430FX) && (romset != ROM_PB640))
i4x0->regs[0x07] = 0x82;
#if defined(DEV_BRANCH) && defined(USE_I686)
else if (i4x0->type != INTEL_440FX)
#else
else
#endif
i4x0->regs[0x07] = 0x02;
i4x0->regs[0x0b] = 0x06;
if (i4x0->type >= INTEL_430FX)
i4x0->regs[0x57] = 0x01;
else
i4x0->regs[0x57] = 0x31;
i4x0->regs[0x60] = i4x0->regs[0x61] = i4x0->regs[0x62] = i4x0->regs[0x63] = 0x02;
i4x0->regs[0x64] = 0x02;
if (i4x0->type >= INTEL_430FX)
i4x0->regs[0x72] = 0x02;
pci_add_card(0, i4x0_read, i4x0_write, i4x0);
return i4x0;
}
const device_t i430lx_device =
{
"Intel 82434LX",
DEVICE_PCI,
INTEL_430LX,
i4x0_init,
i4x0_close,
i4x0_reset,
NULL,
NULL,
NULL,
NULL
};
const device_t i430nx_device =
{
"Intel 82434NX",
DEVICE_PCI,
INTEL_430NX,
i4x0_init,
i4x0_close,
i4x0_reset,
NULL,
NULL,
NULL,
NULL
};
const device_t i430fx_device =
{
"Intel SB82437FX-66",
DEVICE_PCI,
INTEL_430FX,
i4x0_init,
i4x0_close,
i4x0_reset,
NULL,
NULL,
NULL,
NULL
};
const device_t i430hx_device =
{
"Intel 82439HX",
DEVICE_PCI,
INTEL_430HX,
i4x0_init,
i4x0_close,
i4x0_reset,
NULL,
NULL,
NULL,
NULL
};
const device_t i430vx_device =
{
"Intel 82437VX",
DEVICE_PCI,
INTEL_430VX,
i4x0_init,
i4x0_close,
i4x0_reset,
NULL,
NULL,
NULL,
NULL
};
#if defined(DEV_BRANCH) && defined(USE_I686)
const device_t i440fx_device =
{
"Intel 82441FX",
DEVICE_PCI,
INTEL_440FX,
i4x0_init,
i4x0_close,
i4x0_reset,
NULL,
NULL,
NULL,
NULL
};
#endif
static void
acerm3a_out(uint16_t port, uint8_t val, void *p)
{
acerm3a_t *dev = (acerm3a_t *) p;
if (port == 0xea)
dev->index = val;
}
static uint8_t
acerm3a_in(uint16_t port, void *p)
{
acerm3a_t *dev = (acerm3a_t *) p;
if (port == 0xeb) {
switch (dev->index) {
case 2:
return 0xfd;
}
}
return 0xff;
}
static void
acerm3a_close(void *p)
{
acerm3a_t *dev = (acerm3a_t *)p;
free(dev);
}
static void
*acerm3a_init(const device_t *info)
{
acerm3a_t *acerm3a = (acerm3a_t *) malloc(sizeof(acerm3a_t));
memset(acerm3a, 0, sizeof(acerm3a_t));
io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, acerm3a);
return acerm3a;
}
const device_t acerm3a_device =
{
"Acer M3A Register",
0,
0,
acerm3a_init,
acerm3a_close,
NULL,
NULL,
NULL,
NULL,
NULL
};
static void
machine_at_premiere_common_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&ide_pci_2ch_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_2);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x01, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 2, 1, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4);
pci_register_slot(0x02, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&sio_device);
fdc37c665_init();
intel_batman_init();
device_add(&intel_flash_bxt_ami_device);
}
void
machine_at_batman_init(const machine_t *model)
{
machine_at_premiere_common_init(model);
device_add(&i430lx_device);
}
void
machine_at_plato_init(const machine_t *model)
{
machine_at_premiere_common_init(model);
device_add(&i430nx_device);
}
void
machine_at_p54tp4xe_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_device);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_endeavor_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_device);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
if (gfxcard == GFX_INTERNAL)
device_add(&s3_phoenix_trio64_onboard_pci_device);
}
const device_t *
at_endeavor_get_device(void)
{
return &s3_phoenix_trio64_onboard_pci_device;
}
void
machine_at_zappa_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_device);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
}
void
machine_at_mb500n_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_device);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_president_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_device);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_thor_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 2, 1);
pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 3, 2, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_device);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
}
void
machine_at_pb640_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 2, 1, 4);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_pb640_device);
pc87306_init();
device_add(&intel_flash_bxt_ami_device);
if (gfxcard == GFX_INTERNAL)
device_add(&gd5440_onboard_pci_device);
}
const device_t *
at_pb640_get_device(void)
{
return &gd5440_onboard_pci_device;
}
void
machine_at_acerm3a_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x1F, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x10, PCI_CARD_ONBOARD, 4, 0, 0, 0);
device_add(&i430hx_device);
device_add(&piix3_device);
fdc37c932fr_init();
device_add(&acerm3a_device);
device_add(&intel_flash_bxb_device);
}
void
machine_at_acerv35n_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&i430hx_device);
device_add(&piix3_device);
fdc37c932fr_init();
device_add(&acerm3a_device);
device_add(&intel_flash_bxb_device);
}
void
machine_at_ap53_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
memregs_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_ONBOARD, 1, 2, 3, 4);
device_add(&i430hx_device);
device_add(&piix3_device);
fdc37c669_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_p55t2p4_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430hx_device);
device_add(&piix3_device);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_p55t2s_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
memregs_init();
powermate_memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430hx_device);
device_add(&piix3_device);
pc87306_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_p55tvp4_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
w83877f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_i430vx_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
um8669f_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_p55va_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
fdc37c932fr_init();
device_add(&intel_flash_bxt_device);
}
#if defined(DEV_BRANCH) && defined(USE_I686)
void
machine_at_i440fx_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
device_add(&i440fx_device);
device_add(&piix3_device);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
void
machine_at_s1668_init(const machine_t *model)
{
machine_at_common_init(model);
device_add(&keyboard_ps2_ami_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&i440fx_device);
device_add(&piix3_device);
fdc37c665_init();
device_add(&intel_flash_bxt_device);
}
#endif

View File

@@ -251,10 +251,12 @@ Note: the block address is forced to be a multiple of the block size by
ignoring the appropriate number of the least-significant bits
SeeAlso: #P0178,#P0187
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../cpu/cpu.h"
#include "../io.h"
@@ -278,7 +280,6 @@ static void opti495_write(uint16_t addr, uint8_t val, void *p)
optireg=val;
break;
case 0x24:
pclog("OPTI: writing reg %02X %02X\n",optireg,val);
if (optireg>=0x20 && optireg<=0x2C)
{
optiregs[optireg-0x20]=val;

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,30 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the SiS 85c496/85c497 chip.
*
* Version: @(#)m_at_sis_85c496.c 1.0.1 2018/04/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../cpu/cpu.h"
#include "../device.h"
#include "../keyboard.h"
#include "../io.h"
#include "../pci.h"
#include "../mem.h"
@@ -20,169 +36,195 @@
typedef struct sis_85c496_t
{
uint8_t pci_conf[256];
uint8_t pci_conf[256];
} sis_85c496_t;
sis_85c496_t sis496;
static void sis_85c496_recalcmapping(void)
static void
sis_85c496_recalcmapping(sis_85c496_t *dev)
{
int c;
for (c = 0; c < 8; c++)
{
uint32_t base = 0xc0000 + (c << 15);
if (sis496.pci_conf[0x44] & (1 << c))
{
switch (sis496.pci_conf[0x45] & 3)
{
case 0:
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 1:
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
}
}
else
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
int c;
uint32_t base;
flushmmucache();
shadowbios = (sis496.pci_conf[0x44] & 0xf0);
for (c = 0; c < 8; c++) {
base = 0xc0000 + (c << 15);
if (dev->pci_conf[0x44] & (1 << c)) {
switch (dev->pci_conf[0x45] & 3) {
case 0:
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
break;
case 1:
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
break;
case 2:
mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
break;
}
} else
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
}
flushmmucache();
shadowbios = (dev->pci_conf[0x44] & 0xf0);
}
static void sis_85c496_write(int func, int addr, uint8_t val, void *p)
static void
sis_85c496_write(int func, int addr, uint8_t val, void *p)
{
switch (addr)
{
case 0x44: /*Shadow configure*/
if ((sis496.pci_conf[0x44] & val) ^ 0xf0)
{
sis496.pci_conf[0x44] = val;
sis_85c496_recalcmapping();
}
break;
case 0x45: /*Shadow configure*/
if ((sis496.pci_conf[0x45] & val) ^ 0x01)
{
sis496.pci_conf[0x45] = val;
sis_85c496_recalcmapping();
}
break;
case 0xc0:
if (val & 0x80)
pci_set_irq_routing(PCI_INTA, val & 0xf);
else
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
break;
case 0xc1:
if (val & 0x80)
pci_set_irq_routing(PCI_INTB, val & 0xf);
else
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
break;
case 0xc2:
if (val & 0x80)
pci_set_irq_routing(PCI_INTC, val & 0xf);
else
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
break;
case 0xc3:// pclog("IRQ routing %02x %02x\n", addr, val);
if (val & 0x80)
pci_set_irq_routing(PCI_INTD, val & 0xf);
else
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
break;
}
sis_85c496_t *dev = (sis_85c496_t *) p;
switch (addr) {
case 0x44: /*Shadow configure*/
if ((dev->pci_conf[0x44] & val) ^ 0xf0) {
dev->pci_conf[0x44] = val;
sis_85c496_recalcmapping(dev);
}
break;
case 0x45: /*Shadow configure*/
if ((dev->pci_conf[0x45] & val) ^ 0x01) {
dev->pci_conf[0x45] = val;
sis_85c496_recalcmapping(dev);
}
break;
case 0xc0:
if (val & 0x80)
pci_set_irq_routing(PCI_INTA, val & 0xf);
else
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
break;
case 0xc1:
if (val & 0x80)
pci_set_irq_routing(PCI_INTB, val & 0xf);
else
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
break;
case 0xc2:
if (val & 0x80)
pci_set_irq_routing(PCI_INTC, val & 0xf);
else
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
break;
case 0xc3:
if (val & 0x80)
pci_set_irq_routing(PCI_INTD, val & 0xf);
else
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
break;
}
if ((addr >= 4 && addr < 8) || addr >= 0x40)
sis496.pci_conf[addr] = val;
if ((addr >= 4 && addr < 8) || addr >= 0x40)
dev->pci_conf[addr] = val;
}
static uint8_t sis_85c496_read(int func, int addr, void *p)
static uint8_t
sis_85c496_read(int func, int addr, void *p)
{
return sis496.pci_conf[addr];
sis_85c496_t *dev = (sis_85c496_t *) p;
return dev->pci_conf[addr];
}
static void sis_85c496_reset(void)
static void
sis_85c496_reset(void *priv)
{
memset(&sis496, 0, sizeof(sis_85c496_t));
sis496.pci_conf[0x00] = 0x39; /*SiS*/
sis496.pci_conf[0x01] = 0x10;
sis496.pci_conf[0x02] = 0x96; /*496/497*/
sis496.pci_conf[0x03] = 0x04;
uint8_t val = 0;
sis496.pci_conf[0x04] = 7;
sis496.pci_conf[0x05] = 0;
sis496.pci_conf[0x06] = 0x80;
sis496.pci_conf[0x07] = 0x02;
sis496.pci_conf[0x08] = 2; /*Device revision*/
sis496.pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/
sis496.pci_conf[0x0a] = 0x00;
sis496.pci_conf[0x0b] = 0x06;
sis496.pci_conf[0x0e] = 0x00; /*Single function device*/
val = sis_85c496_read(0, 0x44, priv); /* Read current value of 0x44. */
sis_85c496_write(0, 0x44, val & 0xf, priv); /* Turn off shadow BIOS but keep the lower 4 bits. */
}
static void sis_85c496_pci_reset(void)
static void
sis_85c496_close(void *p)
{
uint8_t val = 0;
sis_85c496_t *sis_85c496 = (sis_85c496_t *)p;
val = sis_85c496_read(0, 0x44, NULL); /* Read current value of 0x44. */
sis_85c496_write(0, 0x44, val & 0xf, NULL); /* Turn off shadow BIOS but keep the lower 4 bits. */
free(sis_85c496);
}
static void sis_85c496_init(void)
static void
*sis_85c496_init(const device_t *info)
{
pci_add_card(5, sis_85c496_read, sis_85c496_write, NULL);
sis_85c496_t *sis496 = malloc(sizeof(sis_85c496_t));
memset(sis496, 0, sizeof(sis_85c496_t));
sis_85c496_reset();
sis496->pci_conf[0x00] = 0x39; /*SiS*/
sis496->pci_conf[0x01] = 0x10;
sis496->pci_conf[0x02] = 0x96; /*496/497*/
sis496->pci_conf[0x03] = 0x04;
pci_reset_handler.pci_master_reset = sis_85c496_pci_reset;
sis496->pci_conf[0x04] = 7;
sis496->pci_conf[0x05] = 0;
sis496->pci_conf[0x06] = 0x80;
sis496->pci_conf[0x07] = 0x02;
sis496->pci_conf[0x08] = 2; /*Device revision*/
sis496->pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/
sis496->pci_conf[0x0a] = 0x00;
sis496->pci_conf[0x0b] = 0x06;
sis496->pci_conf[0x0e] = 0x00; /*Single function device*/
pci_add_card(5, sis_85c496_read, sis_85c496_write, sis496);
return sis496;
}
const device_t sis_85c496_device =
{
"SiS 85c496/85c497",
DEVICE_PCI,
0,
sis_85c496_init,
sis_85c496_close,
sis_85c496_reset,
NULL,
NULL,
NULL,
NULL
};
static void
machine_at_sis_85c496_common_init(const machine_t *model)
{
machine_at_ps2_init(model);
device_add(&ide_pci_device);
machine_at_common_init(model);
device_add(&keyboard_ps2_pci_device);
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x05, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
device_add(&ide_pci_device);
sis_85c496_init();
memregs_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x05, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
device_add(&sis_85c496_device);
}
void
machine_at_r418_init(const machine_t *model)
{
machine_at_sis_85c496_common_init(model);
machine_at_sis_85c496_common_init(model);
fdc37c665_init();
fdc37c665_init();
}

View File

@@ -6,14 +6,14 @@
*
* Emulation of the SiS 50x PCI chips.
*
* Version: @(#)m_at_sis_85c50x.c 1.0.6 2018/03/18
* Version: @(#)m_at_sis_85c50x.c 1.0.7 2018/04/29
*
* Author: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2015-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
@@ -87,7 +87,6 @@ static void sis_85c501_recalcmapping(void)
static void sis_85c501_write(int func, int addr, uint8_t val, void *p)
{
/* pclog("sis_85c501_write : addr=%02x val=%02x\n", addr, val); */
if (func)
return;
@@ -131,8 +130,6 @@ static void sis_85c501_write(int func, int addr, uint8_t val, void *p)
static void sis_85c503_write(int func, int addr, uint8_t val, void *p)
{
/* pclog("sis_85c503_write : addr=%02x val=%02x\n", addr, val); */
if (func > 0)
return;
@@ -162,28 +159,24 @@ static void sis_85c503_write(int func, int addr, uint8_t val, void *p)
break;
case 0x41:
pclog("Set IRQ routing: INT A -> %02X\n", val);
if (val & 0x80)
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTA, val & 0xf);
break;
case 0x42:
pclog("Set IRQ routing: INT B -> %02X\n", val);
if (val & 0x80)
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTC, val & 0xf);
break;
case 0x43:
pclog("Set IRQ routing: INT C -> %02X\n", val);
if (val & 0x80)
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
else
pci_set_irq_routing(PCI_INTB, val & 0xf);
break;
case 0x44:
pclog("Set IRQ routing: INT D -> %02X\n", val);
if (val & 0x80)
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
else

View File

@@ -117,7 +117,7 @@
* bit 2 set for single-pixel LCD font
* bits 0,1 for display font
*
* Version: @(#)m_at_t3100e.c 1.0.4 2018/03/18
* Version: @(#)m_at_t3100e.c 1.0.5 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -145,11 +145,13 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../io.h"
#include "../mouse.h"
@@ -168,9 +170,6 @@ extern uint8_t *ram; /* Physical RAM */
void at_init();
static const int t3100e_log = 0;
/* The T3100e motherboard can (and does) dynamically reassign RAM between
* conventional, XMS and EMS. This translates to monkeying with the mappings.
*/
@@ -214,6 +213,27 @@ struct t3100e_ems_regs
void t3100e_ems_out(uint16_t addr, uint8_t val, void *p);
#ifdef ENABLE_T3100E_LOG
int t3100e_do_log = ENABLE_T3100E_LOG;
#endif
static void
t3100e_log(const char *fmt, ...)
{
#ifdef ENABLE_T3100E_LOG
va_list ap;
if (t3100e_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
/* Given a memory address (which ought to be in the page frame at 0xD0000),
* which page does it relate to? */
static int addr_to_page(uint32_t addr)
@@ -329,7 +349,7 @@ void dump_mappings()
offset = t3100e_ems.page_exec[3];
}
pclog(" %p | base=%05x size=%05x %c @ %06x %s\n", mm,
t3100e_log(" %p | base=%05x size=%05x %c @ %06x %s\n", mm,
mm->base, mm->size, mm->enable ? 'Y' : 'N',
offset, name);
@@ -342,16 +362,14 @@ void t3100e_map_ram(uint8_t val)
int n;
int32_t upper_len;
if (t3100e_log)
{
pclog("OUT 0x8084, %02x [ set memory mapping :", val | 0x40);
if (val & 1) pclog("ENABLE_EMS ");
if (val & 2) pclog("ENABLE_XMS ");
if (val & 4) pclog("640K ");
if (val & 8) pclog("X8X ");
if (val & 16) pclog("UPPER_IS_XMS ");
pclog("\n");
}
t3100e_log("OUT 0x8084, %02x [ set memory mapping :", val | 0x40);
if (val & 1) t3100e_log("ENABLE_EMS ");
if (val & 2) t3100e_log("ENABLE_XMS ");
if (val & 4) t3100e_log("640K ");
if (val & 8) t3100e_log("X8X ");
if (val & 16) t3100e_log("UPPER_IS_XMS ");
t3100e_log("\n");
/* Bit 2 controls size of conventional memory */
if (val & 4)
{
@@ -441,7 +459,7 @@ uint8_t t3100e_sys_in(uint16_t addr, void *p)
/* The low 4 bits always seem to be 0x0C. The high 4 are a
* notification sent by the keyboard controller when it detects
* an [Fn] key combination */
if (t3100e_log) pclog("IN 0x8084\n");
t3100e_log("IN 0x8084\n");
return 0x0C | (regs->notify << 4);
}
@@ -455,7 +473,7 @@ void t3100e_sys_out(uint16_t addr, uint8_t val, void *p)
switch (val & 0xE0)
{
case 0x00: /* Set serial port IRQs. Not implemented */
if (t3100e_log) pclog("OUT 0x8084, %02x [ set serial port IRQs]\n", val);
t3100e_log("OUT 0x8084, %02x [ set serial port IRQs]\n", val);
break;
case 0x40: /* Set RAM mappings. */
t3100e_map_ram(val & 0x1F);
@@ -465,7 +483,7 @@ void t3100e_sys_out(uint16_t addr, uint8_t val, void *p)
t3100e_video_options_set(val & 0x1F); break;
/* Other options not implemented. */
default: if (t3100e_log) pclog("OUT 0x8084, %02x\n", val); break;
default: t3100e_log("OUT 0x8084, %02x\n", val); break;
}
}
@@ -562,7 +580,7 @@ void t3100e_ems_out(uint16_t addr, uint8_t val, void *p)
int pg = port_to_page(addr);
regs->page_exec[pg & 3] = t3100e_ems_execaddr(regs, pg, val);
if (t3100e_log) pclog("EMS: page %d %02x -> %02x [%06x]\n",
t3100e_log("EMS: page %d %02x -> %02x [%06x]\n",
pg, regs->page[pg], val, regs->page_exec[pg & 3]);
regs->page[pg] = val;
@@ -570,14 +588,14 @@ void t3100e_ems_out(uint16_t addr, uint8_t val, void *p)
/* Bit 7 set if page is enabled, reset if page is disabled */
if (regs->page_exec[pg])
{
if (t3100e_log) pclog("Enabling EMS RAM at %05x\n",
t3100e_log("Enabling EMS RAM at %05x\n",
page_to_addr(pg));
mem_mapping_enable(&regs->mapping[pg]);
mem_mapping_set_exec(&regs->mapping[pg], ram + regs->page_exec[pg]);
}
else
{
if (t3100e_log) pclog("Disabling EMS RAM at %05x\n",
t3100e_log("Disabling EMS RAM at %05x\n",
page_to_addr(pg));
mem_mapping_disable(&regs->mapping[pg]);
}
@@ -604,9 +622,9 @@ static uint16_t ems_read_ramw(uint32_t addr, void *priv)
int pg = addr_to_page(addr);
if (pg < 0) return 0xFF;
//pclog("ems_read_ramw addr=%05x ", addr);
//t3100e_log("ems_read_ramw addr=%05x ", addr);
addr = regs->page_exec[pg] + (addr & 0x3FFF);
//pclog("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]);
//t3100e_log("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]);
return *(uint16_t *)&ram[addr];
}
@@ -639,9 +657,9 @@ static void ems_write_ramw(uint32_t addr, uint16_t val, void *priv)
int pg = addr_to_page(addr);
if (pg < 0) return;
//pclog("ems_write_ramw addr=%05x ", addr);
//t3100e_log("ems_write_ramw addr=%05x ", addr);
addr = regs->page_exec[pg] + (addr & 0x3FFF);
//pclog("-> %06x val=%04x\n", addr, val);
//t3100e_log("-> %06x val=%04x\n", addr, val);
*(uint16_t *)&ram[addr] = val;
}
@@ -743,7 +761,7 @@ void machine_at_t3100e_init(const machine_t *model)
/* Map the EMS page frame */
for (pg = 0; pg < 4; pg++)
{
if (t3100e_log) pclog("Adding memory map at %x for page %d\n", page_to_addr(pg), pg);
t3100e_log("Adding memory map at %x for page %d\n", page_to_addr(pg), pg);
mem_mapping_add(&t3100e_ems.mapping[pg],
page_to_addr(pg), 16384,
ems_read_ram, ems_read_ramw, ems_read_raml,

View File

@@ -22,7 +22,7 @@
* 61 50 52 0F 19 06 19 19 02 0D 0B 0C MONO
* 2D 28 22 0A 67 00 64 67 02 03 06 07 640x400
*
* Version: @(#)m_at_t3100e_vid.c 1.0.4 2018/03/18
* Version: @(#)m_at_t3100e_vid.c 1.0.6 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -50,11 +50,13 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../device.h"
#include "../io.h"
@@ -196,7 +198,6 @@ void t3100e_write(uint32_t addr, uint8_t val, void *p)
t3100e_t *t3100e = (t3100e_t *)p;
egawrites++;
// pclog("CGA_WRITE %04X %02X\n", addr, val);
t3100e->vram[addr & 0x7fff] = val;
cycles -= 4;
}
@@ -209,7 +210,6 @@ uint8_t t3100e_read(uint32_t addr, void *p)
egareads++;
cycles -= 4;
// pclog("CGA_READ %04X\n", addr);
return t3100e->vram[addr & 0x7fff];
}
@@ -758,6 +758,5 @@ const device_t t3100e_device =
NULL,
NULL,
t3100e_speed_changed,
NULL,
NULL
};

View File

@@ -1,8 +1,8 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
@@ -50,7 +50,6 @@ wd76c10_read(uint16_t port, void *priv)
static void
wd76c10_write(uint16_t port, uint16_t val, void *priv)
{
pclog("WD76C10 write %04X %04X\n", port, val);
switch (port)
{
case 0x0092:

View File

@@ -68,7 +68,7 @@
*
* WARNING THIS IS A WORK-IN-PROGRESS MODULE. USE AT OWN RISK.
*
* Version: @(#)europc.c 1.0.3 2018/03/18
* Version: @(#)europc.c 1.0.6 2018/04/29
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -109,19 +109,21 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <time.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../io.h"
#include "../nmi.h"
#include "../mem.h"
#include "../rom.h"
#include "../nvr.h"
#include "../device.h"
#include "../nvr.h"
#include "../keyboard.h"
#include "../mouse.h"
#include "../game/gameport.h"
@@ -167,6 +169,27 @@ typedef struct {
static europc_t europc;
#ifdef ENABLE_EUROPC_LOG
int europc_do_log = ENABLE_EUROPC_LOG;
#endif
static void
europc_log(const char *fmt, ...)
{
#ifdef ENABLE_EUROPC_LOG
va_list ap;
if (europc_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
/*
* This is called every second through the NVR/RTC hook.
*
@@ -180,7 +203,7 @@ static europc_t europc;
* FIXME: should we mark NVR as dirty?
*/
static void
rtc_tick(nvr_t *nvr)
europc_rtc_tick(nvr_t *nvr)
{
uint8_t *regs;
int mon, yr;
@@ -388,7 +411,7 @@ jim_set(europc_t *sys, uint8_t reg, uint8_t val)
case 0x1f: /* 0001 1111 */
case 0x0b: /* 0000 1011 */
//europc_jim.mode=AGA_MONO;
pclog("EuroPC: AGA Monochrome mode!\n");
europc_log("EuroPC: AGA Monochrome mode!\n");
break;
case 0x18: /* 0001 1000 */
@@ -398,12 +421,12 @@ jim_set(europc_t *sys, uint8_t reg, uint8_t val)
case 0x0e: /* 0000 1100 */
/*80 columns? */
pclog("EuroPC: AGA 80-column mode!\n");
europc_log("EuroPC: AGA 80-column mode!\n");
break;
case 0x0d: /* 0000 1011 */
/*40 columns? */
pclog("EuroPC: AGA 40-column mode!\n");
europc_log("EuroPC: AGA 40-column mode!\n");
break;
default:
@@ -444,7 +467,7 @@ jim_write(uint16_t addr, uint8_t val, void *priv)
uint8_t b;
#if EUROPC_DEBUG > 1
pclog("EuroPC: jim_wr(%04x, %02x)\n", addr, val);
europc_log("EuroPC: jim_wr(%04x, %02x)\n", addr, val);
#endif
switch (addr & 0x000f) {
@@ -485,7 +508,7 @@ jim_write(uint16_t addr, uint8_t val, void *priv)
break;
default:
pclog("EuroPC: invalid JIM write %02x, val %02x\n", addr, val);
europc_log("EuroPC: invalid JIM write %02x, val %02x\n", addr, val);
break;
}
}
@@ -532,12 +555,12 @@ jim_read(uint16_t addr, void *priv)
break;
default:
pclog("EuroPC: invalid JIM read %02x\n", addr);
europc_log("EuroPC: invalid JIM read %02x\n", addr);
break;
}
#if EUROPC_DEBUG > 1
pclog("EuroPC: jim_rd(%04x): %02x\n", addr, r);
europc_log("EuroPC: jim_rd(%04x): %02x\n", addr, r);
#endif
return(r);
@@ -552,10 +575,10 @@ europc_boot(const device_t *info)
uint8_t b;
#if EUROPC_DEBUG
pclog("EuroPC: booting mainboard..\n");
europc_log("EuroPC: booting mainboard..\n");
#endif
pclog("EuroPC: NVR=[ %02x %02x %02x %02x %02x ] %sVALID\n",
europc_log("EuroPC: NVR=[ %02x %02x %02x %02x %02x ] %sVALID\n",
sys->nvr.regs[MRTC_CONF_A], sys->nvr.regs[MRTC_CONF_B],
sys->nvr.regs[MRTC_CONF_C], sys->nvr.regs[MRTC_CONF_D],
sys->nvr.regs[MRTC_CONF_E],
@@ -652,13 +675,16 @@ europc_boot(const device_t *info)
/* Only after JIM has been initialized. */
(void)device_add(&keyboard_xt_device);
/*
/* Enable and set up the FDC. */
(void)device_add(&fdc_xt_device);
/*
* Set up and enable the HD20 disk controller.
*
* We only do this if we have not configured another one.
*/
if (hdc_current == 1)
(void)device_add(&europc_hdc_device);
(void)device_add(&xta_hd20_device);
return(sys);
}
@@ -699,7 +725,7 @@ const device_t europc_device = {
"EuroPC System Board",
0, 0,
europc_boot, europc_close, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
europc_config
};
@@ -715,12 +741,13 @@ const device_t europc_device = {
void
machine_europc_init(const machine_t *model)
{
machine_common_init(model);
nmi_init();
/* Clear the machine state. */
memset(&europc, 0x00, sizeof(europc_t));
europc.jim = 0x0250;
machine_common_init(model);
nmi_init();
mem_add_bios();
/* This is machine specific. */
@@ -730,14 +757,11 @@ machine_europc_init(const machine_t *model)
/* Set up any local handlers here. */
europc.nvr.reset = rtc_reset;
europc.nvr.start = rtc_start;
europc.nvr.tick = rtc_tick;
europc.nvr.tick = europc_rtc_tick;
/* Initialize the actual NVR. */
nvr_init(&europc.nvr);
/* Enable and set up the FDC. */
(void)device_add(&fdc_xt_device);
/* Enable and set up the mainboard device. */
device_add(&europc_device);
}

View File

@@ -1,987 +0,0 @@
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Implementation of the EuroPC HD20 internal controller.
*
* The HD20 was an externally-connected drive, very often a
* 8425XT (20MB, 615/4/17) from Miniscribe. These drives used
* an 8-bit version of IDE called X-IDE, also known as XTA.
* Some older units had a 8225XT drive (20MB, 771/2/17.)
*
* To access the HD disk formatter, enter the "debug" program
* in DOS, and type "g=f000:a000" to start that utility, which
* is hidden in the PC's ROM BIOS.
*
* This driver is based on the information found in the IBM-PC
* Technical Reference manual, pp 187 and on.
*
* Based on the original "xebec.c" from Sarah Walker.
*
* Version: @(#)m_europc_hdc.c 1.0.3 2018/03/18
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2008-2017 Sarah Walker.
*
* Redistribution and use in source and binary forms, with
* or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the entire
* above notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include "../86box.h"
#include "../io.h"
#include "../dma.h"
#include "../pic.h"
#include "../device.h"
#include "../timer.h"
#include "../disk/hdc.h"
#include "../disk/hdd.h"
#include "../plat.h"
#include "../ui.h"
#include "machine.h"
#define HDC_DEBUG 0
#define HDC_NEWPARAMS 1 /* use NEW parameter block */
#define HDD_IOADDR 0x0320
#define HDD_IRQCHAN 5
#define HDD_DMACHAN 3
#define HDC_TIME (200*TIMER_USEC)
enum {
STATE_IDLE,
STATE_CMD,
STATE_RUN,
STATE_RXDTA,
STATE_RDATA,
STATE_TXDTA,
STATE_TDATA,
STATE_COMPL
};
/* Command values. */
#define CMD_TEST_DRV_RDY 0x00
#define CMD_RECALIBRATE 0x01
/* unused 0x02 */
#define CMD_READ_SENSE 0x03
#define CMD_FORMAT_DRIVE 0x04
#define CMD_READY_VERIFY 0x05
#define CMD_FORMAT_TRACK 0x06
#define CMD_FORMAT_BAD_TRACK 0x07
#define CMD_READ_SECTORS 0x08
/* unused 0x09 */
#define CMD_WRITE_SECTORS 0x0a
#define CMD_SEEK 0x0b
#define CMD_SET_DRIVE_PARAMS 0x0c
#define CMD_READ_ECC_BURST 0x0d
#define CMD_READ_SECTOR_BUFFER 0x0e
#define CMD_WRITE_SECTOR_BUFFER 0x0f
#define CMD_RAM_DIAGS 0xe0
/* unused 0xe1 */
/* unused 0xe2 */
#define CMD_DRIVE_DIAGS 0xe3
#define CMD_CTRL_DIAGS 0xe4
#define CMD_READ_LONG 0xe5
#define CMD_WRITE_LONG 0xe6
/* STATUS register values. */
#define STAT_REQ 0x01
#define STAT_IO 0x02
#define STAT_CD 0x04
#define STAT_BSY 0x08
#define STAT_DRQ 0x10
#define STAT_IRQ 0x20
/* Sense Error codes. */
#define ERR_NOERROR 0x00 /* no error detected */
#define ERR_NOINDEX 0x01 /* drive did not detect IDX pulse */
#define ERR_NOSEEK 0x02 /* drive did not complete SEEK */
#define ERR_WRFAULT 0x03 /* write fault during last cmd */
#define ERR_NOTRDY 0x04 /* drive did not go READY after cmd */
#define ERR_NOTRK000 0x06 /* drive did not see TRK0 signal */
#define ERR_LONGSEEK 0x08 /* long seek in progress */
#define ERR_IDREAD 0x10 /* ECC error during ID field */
#define ERR_DATA 0x11 /* uncorrectable ECC err in data */
#define ERR_NOMARK 0x12 /* no address mark detected */
#define ERR_NOSECT 0x14 /* sector not found */
#define ERR_SEEK 0x15 /* seek error */
#define ERR_ECCDATA 0x18 /* ECC corrected data */
#define ERR_BADTRK 0x19 /* bad track detected */
#define ERR_ILLCMD 0x20 /* invalid command received */
#define ERR_ILLADDR 0x21 /* invalid disk address received */
#define ERR_BADRAM 0x30 /* bad RAM in sector data buffer */
#define ERR_BADROM 0x31 /* bad checksum in ROM test */
#define ERR_BADECC 0x32 /* ECC polynomial generator bad */
/* Completion Byte fields. */
#define COMP_DRIVE 0x20
#define COMP_ERR 0x02
#define IRQ_ENA 0x02
#define DMA_ENA 0x01
/* The device control block (6 bytes) */
#pragma pack(push,1)
struct dcb {
uint8_t cmd; /* [7:5] class, [4:0] opcode */
uint8_t head:5, /* [4:0] head number */
drvsel:1, /* [5] drive select */
unused:2; /* [7:6] unused MBZ */
uint8_t sector:6, /* [5:0] sector number 0-63 */
cylh:2; /* [7:6] cylinder [9:8] bits */
uint8_t cyl; /* [7:0] cylinder [7:0] bits */
uint8_t count; /* [7:0] blk count / interleave */
uint8_t ctrl; /* [7:0] control field */
};
#pragma pack(pop)
/*
* The (configured) Drive Parameters.
*
* Although the IBM specification calls for a total of 8 bytes
* in the Paramater Block, the EuroPC uses a 16-byte block. It
* looks like it has extended (translated?) information there,
* as well as the actual data we need.
*
* [ 03 ac 04 01 f4 02 67 0b 11 04 67 02 00 00 01 00]
*
* is what was sent for a standard 615/4/17 disk with rdwrcyl
* set to 500, and precomp to 615.
*
* For now, we will just look at the rest of the data.
*/
#pragma pack(push,1)
struct dprm {
#if HDC_NEWPARAMS
uint16_t tracks; /* total number of sectors on drive */
uint8_t heads; /* number of heads per cylinder */
uint16_t rwcurrent; /* (MSB) reduced write current cylinder */
uint16_t wprecomp; /* (MSB) write precompensation cylinder */
uint8_t maxecc; /* max ECC data burst length */
#else
uint16_t tracks; /* (MSB) max number of cylinders */
uint8_t heads; /* number of heads per cylinder */
uint16_t rwcurrent; /* (MSB) reduced write current cylinder */
uint16_t wprecomp; /* (MSB) write precompensation cylinder */
uint8_t maxecc; /* max ECC data burst length */
#endif
};
typedef struct {
uint8_t spt,
hpc;
uint16_t tracks;
struct dprm params;
uint8_t cfg_spt,
cfg_hpc;
uint16_t cfg_tracks;
uint16_t cur_cyl;
int8_t present,
hdd_num;
} drive_t;
#pragma pack(pop)
typedef struct {
uint16_t base;
int8_t irq;
int8_t dma;
uint8_t mask;
int8_t state;
int64_t callback;
uint8_t sense; /* current SENSE ERROR value */
uint8_t status; /* current operational status */
/* Current operation parameters. */
int16_t buf_idx, /* command buffer index and pointer */
buf_len;
uint8_t *buf_ptr;
uint16_t track; /* requested track# */
uint8_t head, /* requested head# */
sector, /* requested sector# */
comp; /* operation completion byte */
int count; /* requested sector count */
struct dcb dcb; /* device control block */
drive_t drives[MFM_NUM];
uint8_t data[512]; /* data buffer */
uint8_t sector_buf[512];
} hd20_t;
static void
hd20_intr(hd20_t *dev)
{
dev->status = STAT_REQ|STAT_CD|STAT_IO|STAT_BSY;
dev->state = STATE_COMPL;
if (dev->mask & IRQ_ENA) {
dev->status |= STAT_IRQ;
picint(1<<dev->irq);
}
}
static int
get_sector(hd20_t *dev, drive_t *drive, off64_t *addr)
{
int heads = drive->cfg_hpc;
if (drive->cur_cyl != dev->track) {
pclog("HD20: get_sector: wrong cylinder %d/%d\n",
drive->cur_cyl, dev->track);
dev->sense = ERR_ILLADDR;
return(1);
}
if (dev->head > heads) {
pclog("HD20: get_sector: past end of configured heads\n");
dev->sense = ERR_ILLADDR;
return(1);
}
if (dev->head > drive->hpc) {
pclog("HD20: get_sector: past end of heads\n");
dev->sense = ERR_ILLADDR;
return(1);
}
if (dev->sector >= 17) {
pclog("HD20: get_sector: past end of sectors\n");
dev->sense = ERR_ILLADDR;
return(1);
}
*addr = ((((off64_t) dev->track*heads) + dev->head)*17) + dev->sector;
return(0);
}
static void
next_sector(hd20_t *dev, drive_t *drive)
{
if (++dev->sector >= 17) {
dev->sector = 0;
if (++dev->head >= drive->cfg_hpc) {
dev->head = 0;
dev->track++;
drive->cur_cyl++;
if (drive->cur_cyl >= drive->cfg_tracks)
drive->cur_cyl = drive->cfg_tracks-1;
}
}
}
/* Execute the DCB we just received. */
static void
hd20_callback(void *priv)
{
hd20_t *dev = (hd20_t *)priv;
struct dcb *dcb = &dev->dcb;
drive_t *drive;
off64_t addr;
int val;
dev->callback = 0;
drive = &dev->drives[dcb->drvsel];
dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00;
switch (dcb->cmd) {
case CMD_TEST_DRV_RDY:
#if HDC_DEBUG
if (dcb->drvsel == 0)
pclog("HD20: test_rdy(%d) ready=%d\n",
dcb->drvsel, drive->present);
#endif
if (! drive->present) {
dev->comp |= COMP_ERR;
dev->sense = ERR_NOTRDY;
}
hd20_intr(dev);
break;
case CMD_RECALIBRATE:
#if HDC_DEBUG
if (dcb->drvsel == 0)
pclog("HD20: recalibrate(%d) ready=%d\n",
dcb->drvsel, drive->present);
#endif
if (! drive->present) {
dev->comp |= COMP_ERR;
dev->sense = ERR_NOTRDY;
} else {
dev->track = drive->cur_cyl = 0;
}
hd20_intr(dev);
break;
case CMD_READ_SENSE:
if (dev->state == STATE_RUN) {
#if HDC_DEBUG
if (dcb->drvsel == 0)
pclog("HD20: sense(%d)\n", dcb->drvsel);
#endif
dev->buf_idx = 0;
dev->buf_len = 4;
dev->buf_ptr = dev->data;
dev->data[0] = dev->sense;
dev->data[1] = dcb->drvsel ? 0x20 : 0x00;
dev->data[2] = dev->data[3] = 0x00;
dev->sense = ERR_NOERROR;
dev->status = STAT_BSY|STAT_IO|STAT_REQ;
dev->state = STATE_TXDTA;
} else if (dev->state == STATE_TDATA) {
hd20_intr(dev);
}
break;
case CMD_READY_VERIFY:
if (dev->state == STATE_RUN) {
/* Seek to cylinder. */
dev->track = dcb->cyl | (dcb->cylh<<2);
if (dev->track >= drive->cfg_tracks)
drive->cur_cyl = drive->cfg_tracks-1;
else
drive->cur_cyl = dev->track;
dev->head = dcb->head;
dev->sector = dcb->sector;
#if HDC_DEBUG
pclog("HD20: verify_sector(%d) %d,%d,%d\n",
dcb->drvsel, dev->track, dev->head,dev->sector);
#endif
/* Get sector count; count=0 means 256. */
dev->count = (int)dcb->count;
if (dev->count == 0) dev->count = 256;
while (dev->count-- > 0) {
if (get_sector(dev, drive, &addr)) {
pclog("HD20: get_sector failed\n");
dev->comp |= COMP_ERR;
hd20_intr(dev);
return;
}
next_sector(dev, drive);
}
hd20_intr(dev);
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
}
break;
case CMD_FORMAT_DRIVE:
#if HDC_DEBUG
pclog("HD20: format_drive(%d)\n", dcb->drvsel);
#endif
for (dev->track=0; dev->track<drive->tracks; dev->track++) {
drive->cur_cyl = dev->track;
for (dev->head=0; dev->head<drive->hpc; dev->head++) {
dev->sector = 0;
if (get_sector(dev, drive, &addr)) {
pclog("HD20: get_sector failed\n");
dev->comp |= COMP_ERR;
hd20_intr(dev);
return;
}
hdd_image_zero(drive->hdd_num,addr,drive->spt);
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
}
}
hd20_intr(dev);
break;
case CMD_FORMAT_TRACK:
/* Seek to cylinder. */
dev->track = dcb->cyl | (dcb->cylh<<2);
if (dev->track >= drive->cfg_tracks)
drive->cur_cyl = drive->cfg_tracks-1;
else
drive->cur_cyl = dev->track;
dev->head = dcb->head;
dev->sector = 0;
#if HDC_DEBUG
pclog("HD20: format_track(%d) %d,%d\n",
dcb->drvsel, dev->track, dev->head);
#endif
if (get_sector(dev, drive, &addr)) {
pclog("HD20: get_sector failed\n");
dev->comp |= COMP_ERR;
hd20_intr(dev);
return;
}
hdd_image_zero(drive->hdd_num, addr, drive->spt);
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
hd20_intr(dev);
break;
case CMD_READ_SECTORS:
switch (dev->state) {
case STATE_RUN:
/* Seek to cylinder. */
dev->track = dcb->cyl | (dcb->cylh<<2);
if (dev->track >= drive->cfg_tracks)
drive->cur_cyl = drive->cfg_tracks-1;
else
drive->cur_cyl = dev->track;
dev->head = dcb->head;
dev->sector = dcb->sector;
/* Get sector count; count=0 means 256. */
dev->count = (int)dcb->count;
if (dev->count == 0) dev->count = 256;
#if HDC_DEBUG
pclog("HD20: read_sector(%d) %d,%d,%d cnt=%d\n",
dcb->drvsel, dev->track, dev->head,
dev->sector, dev->count);
#endif
if (get_sector(dev, drive, &addr)) {
dev->comp |= COMP_ERR;
hd20_intr(dev);
return;
}
hdd_image_read(drive->hdd_num, addr, 1,
(uint8_t *)dev->sector_buf);
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
/* Ready to transfer the data out. */
dev->buf_idx = 0;
dev->buf_len = 512;
dev->state = STATE_TXDTA;
if (! (dev->mask & DMA_ENA)) {
memcpy(dev->data, dev->sector_buf, 512);
dev->buf_ptr = dev->data;
dev->status = STAT_BSY|STAT_IO|STAT_REQ;
} else {
dev->callback = HDC_TIME;
dev->buf_ptr = dev->sector_buf;
}
break;
case STATE_TXDTA:
dev->status = STAT_BSY;
while (dev->buf_idx < dev->buf_len) {
val = dma_channel_write(dev->dma,
*dev->buf_ptr++);
if (val == DMA_NODATA) {
pclog("CMD_READ_SECTORS out of data!\n");
dev->status = STAT_BSY|STAT_CD|STAT_IO|STAT_REQ;
dev->callback = HDC_TIME;
return;
}
dev->buf_idx++;
}
dev->state = STATE_TDATA;
dev->callback = HDC_TIME;
break;
case STATE_TDATA:
next_sector(dev, drive);
dev->buf_idx = 0;
if (--dev->count == 0) {
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
hd20_intr(dev);
return;
}
if (get_sector(dev, drive, &addr)) {
dev->comp |= COMP_ERR;
hd20_intr(dev);
return;
}
hdd_image_read(drive->hdd_num, addr, 1,
(uint8_t *)dev->sector_buf);
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
dev->state = STATE_TXDTA;
if (! (dev->mask & DMA_ENA)) {
memcpy(dev->data, dev->sector_buf, 512);
dev->buf_ptr = dev->data;
dev->status = STAT_BSY|STAT_IO|STAT_REQ;
} else {
dev->buf_ptr = dev->sector_buf;
dev->callback = HDC_TIME;
}
break;
}
break;
case CMD_WRITE_SECTORS:
switch (dev->state) {
case STATE_RUN:
/* Seek to cylinder. */
dev->track = dcb->cyl | (dcb->cylh<<2);
if (dev->track >= drive->cfg_tracks)
drive->cur_cyl = drive->cfg_tracks-1;
else
drive->cur_cyl = dev->track;
dev->head = dcb->head;
dev->sector = dcb->sector;
/* Get sector count; count=0 means 256. */
dev->count = (int)dev->dcb.count;
if (dev->count == 0) dev->count = 256;
#if HDC_DEBUG
pclog("HD20: write_sector(%d) %d,%d,%d cnt=%d\n",
dcb->drvsel, dev->track, dev->head,
dev->sector, dev->count);
#endif
dev->buf_idx = 0;
dev->buf_len = 512;
dev->state = STATE_RXDTA;
if (! (dev->mask & DMA_ENA)) {
dev->buf_ptr = dev->data;
dev->status = STAT_BSY|STAT_REQ;
} else {
dev->buf_ptr = dev->sector_buf;
dev->callback = HDC_TIME;
}
break;
case STATE_RXDTA:
dev->status = STAT_BSY;
while (dev->buf_idx < dev->buf_len) {
val = dma_channel_read(dev->dma);
if (val == DMA_NODATA) {
pclog("CMD_WRITE_SECTORS out of data!\n");
dev->status = STAT_BSY|STAT_CD|STAT_IO|STAT_REQ;
dev->callback = HDC_TIME;
return;
}
*dev->buf_ptr++ = (val & 0xff);
dev->buf_idx++;
}
dev->state = STATE_RDATA;
dev->callback = HDC_TIME;
break;
case STATE_RDATA:
#if 0
/* If I enable this, we get data corruption.. ??? -FvK */
if (! (dev->mask & DMA_ENA))
memcpy(dev->sector_buf, dev->data, 512);
#endif
if (get_sector(dev, drive, &addr)) {
dev->comp |= COMP_ERR;
hd20_intr(dev);
return;
}
hdd_image_write(drive->hdd_num, addr, 1,
(uint8_t *)dev->sector_buf);
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 1);
next_sector(dev, drive);
dev->buf_idx = 0;
if (--dev->count == 0) {
ui_sb_update_icon(SB_HDD|HDD_BUS_MFM, 0);
hd20_intr(dev);
break;
}
dev->state = STATE_RXDTA;
if (! (dev->mask & DMA_ENA)) {
dev->buf_ptr = dev->data;
dev->status = STAT_BSY|STAT_REQ;
} else {
dev->buf_ptr = dev->sector_buf;
dev->callback = HDC_TIME;
}
}
break;
case CMD_SEEK:
if (! drive->present) {
dev->comp |= COMP_ERR;
dev->sense = ERR_NOTRDY;
hd20_intr(dev);
break;
}
/* Seek to cylinder. */
val = dcb->cyl | (dcb->cylh<<2);
if (val >= drive->cfg_tracks)
drive->cur_cyl = drive->cfg_tracks-1;
else
drive->cur_cyl = val;
#if HDC_DEBUG
pclog("HD20: seek(%d) %d/%d\n",
dcb->drvsel, val, drive->cur_cyl);
#endif
if (val != drive->cur_cyl) {
dev->comp |= COMP_ERR;
dev->sense = ERR_SEEK;
}
hd20_intr(dev);
break;
case CMD_SET_DRIVE_PARAMS:
if (dev->state == STATE_RUN) {
dev->state = STATE_RXDTA;
dev->buf_idx = 0;
dev->buf_len = sizeof(struct dprm);
dev->buf_ptr = (uint8_t *)&drive->params;
dev->status = STAT_BSY|STAT_REQ;
} else {
dev->buf_ptr=(uint8_t *)&drive->params;
pclog("HD20: PARAMS=[");
for(val=0;val<8;val++)pclog(" %02x",*dev->buf_ptr++);
pclog(" ]\n");
#if 0
drive->cfg_tracks = drive->params.tracks;
drive->cfg_hpc = drive->params.heads;
drive->cfg_spt = drive->spt;
#endif
#if HDC_DEBUG
pclog("HD20: set_params(%d) cyl=%d,hd=%d,spt=%d\n",
dcb->drvsel, drive->cfg_tracks,
drive->cfg_hpc, drive->cfg_spt);
#endif
hd20_intr(dev);
}
break;
case CMD_WRITE_SECTOR_BUFFER:
switch (dev->state) {
case STATE_RUN:
#if HDC_DEBUG
pclog("HD20: write_sector_buffer(%d)\n",
dcb->drvsel);
#endif
dev->buf_idx = 0;
dev->buf_len = 512;
dev->state = STATE_RXDTA;
if (! (dev->mask & DMA_ENA)) {
dev->buf_ptr = dev->data;
dev->status = STAT_BSY|STAT_REQ;
} else {
dev->buf_ptr = dev->sector_buf;
dev->callback = HDC_TIME;
}
break;
case STATE_RXDTA:
dev->status = STAT_BSY;
if (! (dev->mask & DMA_ENA)) break;
while (dev->buf_idx++ < dev->buf_len) {
val = dma_channel_read(dev->dma);
if (val == DMA_NODATA) {
pclog("CMD_WRITE_SECTORS out of data!\n");
dev->status = STAT_BSY|STAT_CD|STAT_IO|STAT_REQ;
dev->callback = HDC_TIME;
return;
}
*dev->buf_ptr++ = (val & 0xff);
}
dev->state = STATE_RDATA;
dev->callback = HDC_TIME;
break;
case STATE_RDATA:
if (! (dev->mask & DMA_ENA))
memcpy(dev->sector_buf, dev->data, 512);
hd20_intr(dev);
break;
}
break;
case CMD_RAM_DIAGS:
#if HDC_DEBUG
pclog("HD20: ram_diags\n");
#endif
dev->callback = 5*HDC_TIME;
hd20_intr(dev);
break;
case CMD_DRIVE_DIAGS:
#if HDC_DEBUG
pclog("HD20: drive_diags(%d)\n", dcb->drvsel);
#endif
dev->callback = 5*HDC_TIME;
hd20_intr(dev);
break;
case CMD_CTRL_DIAGS:
#if HDC_DEBUG
pclog("HD20: ctrl_diags\n");
#endif
dev->callback = 5*HDC_TIME;
hd20_intr(dev);
break;
default:
pclog("HD20: unknown command - %02x\n", dcb->cmd);
dev->comp |= COMP_ERR;
dev->sense = ERR_ILLCMD;
hd20_intr(dev);
}
}
/* Read one of the HD controller registers. */
static uint8_t
hd20_read(uint16_t port, void *priv)
{
hd20_t *dev = (hd20_t *)priv;
uint8_t ret = 0xff;
switch (port-dev->base) {
case 0: /* read data */
dev->status &= ~STAT_IRQ;
if (dev->state == STATE_TXDTA) {
if ((dev->status & 0x0f) !=
(STAT_IO|STAT_REQ|STAT_BSY))
fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", dev->status);
if (dev->buf_idx > dev->buf_len) {
pclog("HD20: read with empty buffer!\n");
dev->comp |= COMP_ERR;
dev->sense = ERR_ILLCMD;
break;
}
ret = dev->data[dev->buf_idx++];
if (dev->buf_idx == dev->buf_len) {
dev->status = STAT_BSY;
dev->state = STATE_TDATA;
dev->callback = HDC_TIME;
}
} else if (dev->state == STATE_COMPL) {
if ((dev->status & 0x0f) !=
(STAT_CD|STAT_IO|STAT_REQ|STAT_BSY))
fatal("Read data STATE_COMPL, status=%02x\n", dev->status);
ret = dev->comp;
dev->status = 0x00;
dev->state = STATE_IDLE;
}
break;
case 1: /* read status */
ret = dev->status;
break;
case 2: /* read option jumpers */
ret = 0x00;
break;
}
#if HDC_DEBUG > 1
pclog("HD20: read(%04x) = %02x\n", port, ret);
#endif
return(ret);
}
static void
hd20_write(uint16_t port, uint8_t val, void *priv)
{
hd20_t *dev = (hd20_t *)priv;
#if HDC_DEBUG > 1
pclog("HD20: write(%04x,%02x)\n", port, val);
#endif
switch (port-dev->base) {
case 0: /* write command/data */
if (! (dev->status & STAT_REQ)) {
pclog("HD20: not ready for command/data!\n");
dev->comp |= COMP_ERR;
dev->sense = ERR_ILLCMD;
break;
}
if (dev->buf_idx >= dev->buf_len) {
pclog("HD20: write with full buffer!\n");
dev->comp |= COMP_ERR;
dev->sense = ERR_ILLCMD;
break;
}
/* Store the data into the buffer. */
*dev->buf_ptr++ = val;
if (++dev->buf_idx == dev->buf_len) {
/* We got all the data we need. */
dev->status &= ~STAT_REQ;
dev->state = (dev->state==STATE_CMD) ? STATE_RUN : STATE_RDATA;
dev->callback = HDC_TIME;
}
break;
case 1: /* controller reset */
dev->sense = 0x00;
/*FALLTHROUGH*/
case 2: /* generate controller-select-pulse */
dev->status = STAT_BSY|STAT_CD|STAT_REQ;
dev->buf_idx = 0;
dev->buf_len = sizeof(struct dcb);
dev->buf_ptr = (uint8_t *)&dev->dcb;
dev->state = STATE_CMD;
break;
case 3: /* DMA/IRQ mask register */
dev->mask = val;
break;
}
}
static void *
hd20_init(const device_t *info)
{
drive_t *drive;
hd20_t *dev;
int c, i;
pclog("EuroPC: initializing HD20 controller.\n");
dev = malloc(sizeof(hd20_t));
memset(dev, 0x00, sizeof(hd20_t));
dev->base = HDD_IOADDR;
dev->irq = HDD_IRQCHAN;
dev->dma = HDD_DMACHAN;
for (c=0,i=0; i<HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) {
drive = &dev->drives[hdd[i].mfm_channel];
if (! hdd_image_load(i)) {
drive->present = 0;
continue;
}
/* These are the "hardware" parameters (from the image.) */
drive->spt = hdd[i].spt;
drive->hpc = hdd[i].hpc;
drive->tracks = hdd[i].tracks;
/* Use them as "configured" parameters until overwritten. */
drive->cfg_spt = drive->spt;
drive->cfg_hpc = drive->hpc;
drive->cfg_tracks = drive->tracks;
drive->hdd_num = i;
drive->present = 1;
pclog("HD20: drive%d (cyl=%d,hd=%d,spt=%d), disk %d\n",
hdd[i].mfm_channel,drive->tracks,drive->hpc,drive->spt,i);
if (++c > MFM_NUM) break;
}
}
io_sethandler(dev->base, 4,
hd20_read, NULL, NULL, hd20_write, NULL, NULL, dev);
timer_add(hd20_callback, &dev->callback, &dev->callback, dev);
return(dev);
}
static void
hd20_close(void *priv)
{
hd20_t *dev = (hd20_t *)priv;
drive_t *drive;
int d;
for (d=0; d<2; d++) {
drive = &dev->drives[d];
hdd_image_close(drive->hdd_num);
}
free(dev);
}
static int
hd20_available(void)
{
return(1);
}
const device_t europc_hdc_device = {
"EuroPC HD20",
0, 0,
hd20_init, hd20_close, NULL,
hd20_available, NULL, NULL, NULL,
NULL
};

View File

@@ -8,7 +8,7 @@
*
* Emulation of the Olivetti M24.
*
* Version: @(#)m_olivetti_m24.c 1.0.12 2018/03/19
* Version: @(#)m_olivetti_m24.c 1.0.14 2018/04/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -795,7 +795,7 @@ const device_t m24_device = {
NULL, vid_close, NULL,
NULL,
speed_changed,
NULL, NULL,
NULL,
NULL
};
@@ -849,7 +849,7 @@ machine_olim24_init(const machine_t *model)
device_add(&gameport_device);
/* FIXME: make sure this is correct?? */
nvr_at_init(8);
device_add(&at_nvr_device);
nmi_init();
}

View File

@@ -8,7 +8,7 @@
*
* Emulation of the IBM PCjr.
*
* Version: @(#)m_pcjr.c 1.0.6 2018/03/18
* Version: @(#)m_pcjr.c 1.0.8 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -18,12 +18,14 @@
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../io.h"
#include "../nmi.h"
@@ -603,9 +605,6 @@ kbd_read(uint16_t port, void *priv)
pcjr->latched = 0;
ret = 0;
break;
default:
pclog("\nBad PCjr keyboard read %04X\n", port);
}
return(ret);
@@ -721,7 +720,6 @@ static const device_t pcjr_device = {
NULL,
speed_changed,
NULL,
NULL,
pcjr_config
};

View File

@@ -28,7 +28,7 @@
* boot. Sometimes, they do, and then it shows an "Incorrect
* DOS" error message?? --FvK
*
* Version: @(#)m_ps1.c 1.0.7 2018/03/18
* Version: @(#)m_ps1.c 1.0.9 2018/04/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -88,7 +88,8 @@ typedef struct {
rom_t high_rom;
uint8_t ps1_92,
uint8_t ps1_91,
ps1_92,
ps1_94,
ps1_102,
ps1_103,
@@ -97,11 +98,6 @@ typedef struct {
ps1_190;
int ps1_e0_addr;
uint8_t ps1_e0_regs[256];
struct {
uint8_t status, int_status;
uint8_t attention, ctrl;
} hd;
} ps1_t;
@@ -271,7 +267,6 @@ static const device_t snd_device = {
snd_init, snd_close, NULL,
NULL,
NULL,
NULL,
NULL
};
@@ -334,7 +329,7 @@ ps1_write(uint16_t port, uint8_t val, void *priv)
lpt1_remove();
if (val & 0x04)
serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ);
else
else
serial_remove(1);
if (val & 0x10) {
switch ((val >> 5) & 3) {
@@ -367,22 +362,6 @@ ps1_write(uint16_t port, uint8_t val, void *priv)
case 0x0190:
ps->ps1_190 = val;
break;
case 0x0322:
if (ps->model == 2011) {
ps->hd.ctrl = val;
if (val & 0x80)
ps->hd.status |= 0x02;
}
break;
case 0x0324:
if (ps->model == 2011) {
ps->hd.attention = val & 0xf0;
if (ps->hd.attention)
ps->hd.status = 0x14;
}
break;
}
}
@@ -395,7 +374,8 @@ ps1_read(uint16_t port, void *priv)
switch (port) {
case 0x0091:
ret = 0;
ret = ps->ps1_91;
ps->ps1_91 = 0;
break;
case 0x0092:
@@ -438,19 +418,6 @@ ps1_read(uint16_t port, void *priv)
ret = ps->ps1_190;
break;
case 0x0322:
if (ps->model == 2011) {
ret = ps->hd.status;
}
break;
case 0x0324:
if (ps->model == 2011) {
ret = ps->hd.int_status;
ps->hd.int_status &= ~0x02;
}
break;
default:
break;
}
@@ -463,6 +430,7 @@ static void
ps1_setup(int model)
{
ps1_t *ps;
void *priv;
ps = (ps1_t *)malloc(sizeof(ps1_t));
memset(ps, 0x00, sizeof(ps1_t));
@@ -479,23 +447,15 @@ ps1_setup(int model)
io_sethandler(0x0190, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
lpt1_remove();
lpt1_init(0x3bc);
if (model == 2011) {
io_sethandler(0x0320, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0322, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
io_sethandler(0x0324, 1,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
#if 0
rom_init(&ps->high_rom,
L"roms/machines/ibmps1es/f80000_shell.bin",
L"roms/machines/ibmps1es/f80000.bin",
0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL);
#endif
lpt1_remove();
lpt2_remove();
lpt1_init(0x03bc);
serial_remove(1);
serial_remove(2);
@@ -505,31 +465,44 @@ ps1_setup(int model)
device_add(&ps1vga_device);
else
device_add(&ibm_ps1_2121_device);
device_add(&snd_device);
device_add(&fdc_at_actlow_device);
/* Enable the builtin HDC. */
if (hdc_current == 1) {
priv = device_add(&ps1_hdc_device);
ps1_hdc_inform(priv, ps);
}
}
if (model == 2121) {
io_sethandler(0x00e0, 2,
ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps);
#if 1
#if 0
rom_init(&ps->high_rom,
L"roms/machines/ibmps1_2121/fc0000.bin",
0xfc0000, 0x20000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL);
#else
rom_init(&ps->high_rom,
L"roms/machines/ibmps1_2121/fc0000_shell.bin",
0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL);
#endif
lpt1_init(0x03bc);
/* Initialize the video controller. */
if (gfxcard == GFX_INTERNAL)
device_add(&ibm_ps1_2121_device);
device_add(&fdc_at_ps1_device);
device_add(&ide_isa_device);
device_add(&snd_device);
}
if (model == 2133) {
lpt1_init(0x03bc);
device_add(&fdc_at_device);
device_add(&ide_isa_device);
}
}
@@ -546,29 +519,26 @@ ps1_common_init(const machine_t *model)
dma16_init();
pic2_init();
nvr_at_init(8);
if (romset != ROM_IBMPS1_2011)
device_add(&ide_isa_device);
device_add(&ps_nvr_device);
device_add(&keyboard_ps2_device);
if (romset == ROM_IBMPS1_2133)
device_add(&fdc_at_device);
else {
if ((romset == ROM_IBMPS1_2121) || (romset == ROM_IBMPS1_2121_ISA))
device_add(&fdc_at_ps1_device);
else
device_add(&fdc_at_actlow_device);
device_add(&snd_device);
}
/* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */
if (joystick_type != 7)
device_add(&gameport_201_device);
}
/* Set the Card Selected Flag */
void
ps1_set_feedback(void *priv)
{
ps1_t *ps = (ps1_t *)priv;
ps->ps1_91 |= 0x01;
}
void
machine_ps1_m2011_init(const machine_t *model)
{

1364
src/machine/m_ps1_hdc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -156,7 +156,7 @@ machine_ps2_m30_286_init(const machine_t *model)
pit_set_out_func(&pit, 1, pit_refresh_timer_at);
dma16_init();
device_add(&keyboard_ps2_device);
nvr_at_init(8);
device_add(&ps_nvr_device);
pic2_init();
ps2board_init();
device_add(&ps1vga_device);

View File

@@ -1,7 +1,9 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../cpu/cpu.h"
#include "../cpu/x86.h"
@@ -94,9 +96,30 @@ static struct
static uint8_t ps2_cache[65536];
static int ps2_cache_valid[65536/8];
#ifdef ENABLE_PS2_MCA_LOG
int ps2_mca_do_log = ENABLE_PS2_MCA_LOG;
#endif
static void
ps2_mca_log(const char *format, ...)
{
#ifdef ENABLE_PS2_MCA_LOG
va_list ap;
if (ps2_mca_do_log) {
va_start(ap, format);
pclog_ex(format, ap);
va_end(ap);
}
#endif
}
static uint8_t ps2_read_cache_ram(uint32_t addr, void *priv)
{
// pclog("ps2_read_cache_ram: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc);
ps2_mca_log("ps2_read_cache_ram: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc);
if (!ps2_cache_valid[addr >> 3])
{
ps2_cache_valid[addr >> 3] = 1;
@@ -109,7 +132,7 @@ static uint8_t ps2_read_cache_ram(uint32_t addr, void *priv)
}
static uint16_t ps2_read_cache_ramw(uint32_t addr, void *priv)
{
// pclog("ps2_read_cache_ramw: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc);
ps2_mca_log("ps2_read_cache_ramw: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc);
if (!ps2_cache_valid[addr >> 3])
{
ps2_cache_valid[addr >> 3] = 1;
@@ -122,7 +145,7 @@ static uint16_t ps2_read_cache_ramw(uint32_t addr, void *priv)
}
static uint32_t ps2_read_cache_raml(uint32_t addr, void *priv)
{
// pclog("ps2_read_cache_raml: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc);
ps2_mca_log("ps2_read_cache_raml: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc);
if (!ps2_cache_valid[addr >> 3])
{
ps2_cache_valid[addr >> 3] = 1;
@@ -135,7 +158,7 @@ static uint32_t ps2_read_cache_raml(uint32_t addr, void *priv)
}
static void ps2_write_cache_ram(uint32_t addr, uint8_t val, void *priv)
{
// pclog("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS,cpu_state.pc, ins);
ps2_mca_log("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS,cpu_state.pc, ins);
ps2_cache[addr] = val;
}
@@ -408,10 +431,10 @@ static void model_55sx_write(uint16_t port, uint8_t val)
case 0x104:
ps2.memory_bank[ps2.option[3] & 7] &= ~0xf;
ps2.memory_bank[ps2.option[3] & 7] |= (val & 0xf);
/* pclog("Write memory bank %i %02x\n", ps2.option[3] & 7, val); */
ps2_mca_log("Write memory bank %i %02x\n", ps2.option[3] & 7, val);
break;
case 0x105:
/* pclog("Write POS3 %02x\n", val); */
ps2_mca_log("Write POS3 %02x\n", val);
ps2.option[3] = val;
shadowbios = !(val & 0x10);
shadowbios_write = val & 0x10;
@@ -636,14 +659,14 @@ uint8_t ps2_mca_read(uint16_t port, void *p)
break;
}
/* pclog("ps2_read: port=%04x temp=%02x\n", port, temp); */
return temp;
ps2_mca_log("ps2_read: port=%04x temp=%02x\n", port, temp);
return temp;
}
static void ps2_mca_write(uint16_t port, uint8_t val, void *p)
{
/* pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); */
ps2_mca_log("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc);
switch (port)
{
@@ -893,18 +916,18 @@ static void mem_encoding_update()
if (ps2.mem_regs[1] & 2) {
mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
/* pclog("PS/2 Model 80-111: ROM space enabled\n"); */
ps2_mca_log("PS/2 Model 80-111: ROM space enabled\n");
} else {
mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
/* pclog("PS/2 Model 80-111: ROM space disabled\n"); */
ps2_mca_log("PS/2 Model 80-111: ROM space disabled\n");
}
if (ps2.mem_regs[1] & 4) {
mem_mapping_set_addr(&ram_low_mapping, 0x00000, 0x80000);
/* pclog("PS/2 Model 80-111: 00080000- 0009FFFF disabled\n"); */
ps2_mca_log("PS/2 Model 80-111: 00080000- 0009FFFF disabled\n");
} else {
mem_mapping_set_addr(&ram_low_mapping, 0x00000, 0xa0000);
/* pclog("PS/2 Model 80-111: 00080000- 0009FFFF enabled\n"); */
ps2_mca_log("PS/2 Model 80-111: 00080000- 0009FFFF enabled\n");
}
if (!(ps2.mem_regs[1] & 8))
@@ -920,10 +943,9 @@ static void mem_encoding_update()
mem_mapping_set_exec(&ps2.split_mapping, &ram[ps2.split_phys]);
mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, ps2.split_size << 10);
/* pclog("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr); */
} /* else {
pclog("PS/2 Model 80-111: Split memory block disabled\n");
} */
ps2_mca_log("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr);
} else
ps2_mca_log("PS/2 Model 80-111: Split memory block disabled\n");
}
static uint8_t mem_encoding_read(uint16_t addr, void *p)
@@ -982,7 +1004,7 @@ static void mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p)
ps2.mem_regs[2] = (ps2.mem_regs[2] & 0x80) | (val & ~0x88);
if (val & 2)
{
// pclog("Clear latch - %i\n", ps2.pending_cache_miss);
ps2_mca_log("Clear latch - %i\n", ps2.pending_cache_miss);
if (ps2.pending_cache_miss)
ps2.mem_regs[2] |= 0x80;
else
@@ -1000,7 +1022,7 @@ static void mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p)
ram_mid_mapping.flags &= ~MEM_MAPPING_ROM;
break;
}
// pclog("mem_encoding_write: addr=%02x val=%02x %04x:%04x %02x %02x\n", addr, val, CS,cpu_state.pc, ps2.mem_regs[1],ps2.mem_regs[2]);
ps2_mca_log("mem_encoding_write: addr=%02x val=%02x %04x:%04x %02x %02x\n", addr, val, CS,cpu_state.pc, ps2.mem_regs[1],ps2.mem_regs[2]);
mem_encoding_update();
if ((ps2.mem_regs[1] & 0x10) && (ps2.mem_regs[2] & 0x21) == 0x20)
{
@@ -1172,7 +1194,7 @@ machine_ps2_common_init(const machine_t *model)
dma16_init();
ps2_dma_init();
device_add(&keyboard_ps2_mca_device);
nvr_at_init(8);
device_add(&ps_nvr_device);
pic2_init();
pit_ps2_init();

View File

@@ -8,7 +8,7 @@
*
* Emulation of Tandy models 1000, 1000HX and 1000SL2.
*
* Version: @(#)m_tandy.c 1.0.5 2018/03/19
* Version: @(#)m_tandy.c 1.0.7 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -16,12 +16,14 @@
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <math.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../io.h"
#include "../pit.h"
@@ -397,6 +399,28 @@ static int eep_data_out;
static uint8_t vid_in(uint16_t addr, void *priv);
static void vid_out(uint16_t addr, uint8_t val, void *priv);
#ifdef ENABLE_TANDY_LOG
int tandy_do_log = ENABLE_TANDY_LOG;
#endif
static void
tandy_log(const char *fmt, ...)
{
#ifdef ENABLE_TANDY_LOG
va_list ap;
if (tandy_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static void
recalc_mapping(tandy_t *dev)
{
@@ -1381,7 +1405,6 @@ static const device_t vid_device = {
NULL,
vid_speed_changed,
NULL,
NULL,
vid_config
};
@@ -1392,7 +1415,6 @@ static const device_t vid_device_hx = {
NULL,
vid_speed_changed,
NULL,
NULL,
vid_config
};
@@ -1403,7 +1425,6 @@ static const device_t vid_device_sl = {
NULL,
vid_speed_changed,
NULL,
NULL,
NULL
};
@@ -1552,7 +1573,7 @@ static const device_t eep_device = {
"Tandy 1000 EEPROM",
0, 0,
eep_init, eep_close, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL
};
@@ -1669,7 +1690,7 @@ init_rom(tandy_t *dev)
if (! rom_load_interleaved(L"roms/machines/tandy1000sl2/8079047.hu1",
L"roms/machines/tandy1000sl2/8079048.hu2",
0x000000, 0x80000, 0, dev->rom)) {
pclog("TANDY: unable to load BIOS for 1000/SL2 !\n");
tandy_log("TANDY: unable to load BIOS for 1000/SL2 !\n");
free(dev->rom);
dev->rom = NULL;
return;

View File

@@ -51,7 +51,7 @@
* NOTE: Still need to figure out a way to load/save ConfigSys and
* HardRAM stuff. Needs to be linked in to the NVR code.
*
* Version: @(#)m_xt_t1000.c 1.0.4 2018/03/19
* Version: @(#)m_xt_t1000.c 1.0.6 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -79,12 +79,14 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <time.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../cpu/cpu.h"
#include "../io.h"
@@ -92,8 +94,8 @@
#include "../nmi.h"
#include "../mem.h"
#include "../rom.h"
#include "../nvr.h"
#include "../device.h"
#include "../nvr.h"
#include "../keyboard.h"
#include "../lpt.h"
#include "../mem.h"
@@ -176,6 +178,27 @@ typedef struct {
static t1000_t t1000;
#ifdef ENABLE_T1000_LOG
int t1000_do_log = ENABLE_T1000_LOG;
#endif
static void
t1000_log(const char *fmt, ...)
{
#ifdef ENABLE_TANDY_LOG
va_list ap;
if (t1000_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
/* Set the chip time. */
static void
tc8521_time_set(uint8_t *regs, struct tm *tm)
@@ -225,7 +248,7 @@ tc8521_time_get(uint8_t *regs, struct tm *tm)
static void
tc8521_tick(nvr_t *nvr)
{
pclog("TC8521: ping\n");
t1000_log("TC8521: ping\n");
}
@@ -336,7 +359,7 @@ ems_execaddr(t1000_t *sys, int pg, uint16_t val)
* HardRAM or conventional RAM */
val &= 0x7f;
#if 0
#if 0
t1000_log("Select EMS page: %d of %d\n", val, sys->ems_pages);
#endif
if (val < sys->ems_pages) {
@@ -354,7 +377,7 @@ ems_in(uint16_t addr, void *priv)
{
t1000_t *sys = (t1000_t *)priv;
#if 0
#if 0
t1000_log("ems_in(%04x)=%02x\n", addr, sys->ems_reg[(addr >> 14) & 3]);
#endif
return(sys->ems_reg[(addr >> 14) & 3]);
@@ -367,7 +390,7 @@ ems_out(uint16_t addr, uint8_t val, void *priv)
t1000_t *sys = (t1000_t *)priv;
int pg = (addr >> 14) & 3;
#if 0
#if 0
t1000_log("ems_out(%04x, %02x) pg=%d\n", addr, val, pg);
#endif
sys->ems_reg[pg] = val;
@@ -394,7 +417,7 @@ ems_set_hardram(t1000_t *sys, uint8_t val)
else
sys->ems_base = 0;
#if 0
#if 0
t1000_log("EMS base set to %02x\n", val);
#endif
sys->ems_pages = 48 - 4 * sys->ems_base;
@@ -424,7 +447,7 @@ ems_set_port(t1000_t *sys, uint8_t val)
{
int n;
#if 0
#if 0
t1000_log("ems_set_port(%d)", val & 0x0f);
#endif
if (sys->ems_port) {
@@ -449,7 +472,7 @@ ems_set_port(t1000_t *sys, uint8_t val)
sys->ems_port = 0;
}
#if 0
#if 0
t1000_log(" -> %04x\n", sys->ems_port);
#endif
}
@@ -484,12 +507,12 @@ ems_read_ramw(uint32_t addr, void *priv)
if (pg < 0) return(0xff);
#if 0
#if 0
t1000_log("ems_read_ramw addr=%05x ", addr);
#endif
addr = sys->page_exec[pg] + (addr & 0x3FFF);
#if 0
#if 0
t1000_log("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]);
#endif
@@ -534,12 +557,12 @@ ems_write_ramw(uint32_t addr, uint16_t val, void *priv)
if (pg < 0) return;
#if 0
#if 0
t1000_log("ems_write_ramw addr=%05x ", addr);
#endif
addr = sys->page_exec[pg] + (addr & 0x3fff);
#if 0
#if 0
t1000_log("-> %06x val=%04x\n", addr, val);
#endif

View File

@@ -9,7 +9,7 @@
* Implementation of the Toshiba T1000 plasma display, which
* has a fixed resolution of 640x200 pixels.
*
* Version: @(#)m_xt_t1000_vid.c 1.0.5 2018/03/18
* Version: @(#)m_xt_t1000_vid.c 1.0.7 2018/04/29
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -185,7 +185,6 @@ static void t1000_write(uint32_t addr, uint8_t val, void *p)
t1000_t *t1000 = (t1000_t *)p;
egawrites++;
// pclog("CGA_WRITE %04X %02X\n", addr, val);
t1000->vram[addr & 0x3fff] = val;
cycles -= 4;
}
@@ -196,7 +195,6 @@ static uint8_t t1000_read(uint32_t addr, void *p)
egareads++;
cycles -= 4;
// pclog("CGA_READ %04X\n", addr);
return t1000->vram[addr & 0x3fff];
}
@@ -736,7 +734,6 @@ const device_t t1000_video_device = {
NULL,
t1000_speed_changed,
NULL,
NULL,
t1000_config
};
@@ -748,6 +745,5 @@ const device_t t1200_video_device = {
NULL,
t1000_speed_changed,
NULL,
NULL,
t1000_config
};

View File

@@ -112,7 +112,6 @@ const device_t xi8088_device =
NULL,
NULL,
NULL,
NULL,
xi8088_config
};
@@ -129,7 +128,7 @@ void machine_xt_xi8088_init(const machine_t *model)
device_add(&fdc_xt_device);
device_add(&keyboard_ps2_device);
nmi_init();
nvr_at_init(8);
device_add(&at_nvr_device);
pic2_init();
if (joystick_type != 7)
device_add(&gameport_device);

View File

@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
* Version: @(#)machine.c 1.0.32 2018/03/19
* Version: @(#)machine.c 1.0.34 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -18,10 +18,12 @@
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "../device.h"
#include "../dma.h"
@@ -31,8 +33,7 @@
#include "../rom.h"
#include "../lpt.h"
#include "../serial.h"
#include "../disk/hdc.h"
#include "../disk/hdc_ide.h"
#include "../cpu/cpu.h"
#include "machine.h"
@@ -41,12 +42,31 @@ int AT, PCI;
int romset;
#ifdef ENABLE_MACHINE_LOG
int machine_do_log = ENABLE_MACHINE_LOG;
#endif
static void
machine_log(const char *fmt, ...)
{
#ifdef ENABLE_TANDY_LOG
va_list ap;
if (machine_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
void
machine_init(void)
{
pclog("Initializing as \"%s\"\n", machine_getname());
ide_set_bus_master(NULL, NULL, NULL);
machine_log("Initializing as \"%s\"\n", machine_getname());
/* Set up the architecture flags. */
AT = IS_ARCH(machine, MACHINE_AT);
@@ -68,10 +88,16 @@ void
machine_common_init(const machine_t *model)
{
/* System devices first. */
dma_init();
pic_init();
dma_init();
pit_init();
cpu_set();
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286)
setrtcconst(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed);
else
setrtcconst(14318184.0);
if (lpt_enabled)
lpt_init();

Some files were not shown because too many files have changed in this diff Show More