mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Applied all relevant PCem commits;
Extensively cleaned up and changed the CD-ROM code; Removed CD-ROM IOCTTL (it was causing performance and stability issues); Turned a lot of things into device_t's; Added the PS/1 Model 2011 XTA and standalone XTA hard disk controllers, ported from Varcem; Numerous FDC fixes for the PS/1 Model 2121; NVR changes ported from Varcem; The PCap code no longer requires libpcap to be compiled; Numerous fixes to various SCSI controllers; Updated NukedOPL to 1.8; Fixes to OpenAL initialization and closing, should give less Audio issues now; Revorked parts of the common (S)VGA code (also based on code from QEMU); Removed the Removable SCSI hard disks (they were a never finished experiment so there was no need to keep them there); Cleaned up the SCSI hard disk and Iomega ZIP code (but more cleanups of that are coming in the future); In some occasions (IDE hard disks in multiple sector mode and SCSI hard disks) the status bar icon is no longer updated, should improve performance a bit; Redid the way the tertiary and quaternary IDE controllers are configured (and they are now device_t's); Extensively reworked the IDE code and fixed quite a few bugs; Fixes to XT MFM, AT MFM, and AT ESDI code; Some changes to XTIDE and MCA ESDI code; Some fixes to the CD-ROM image handler.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Main include file for the application.
|
||||
*
|
||||
* Version: @(#)86box.h 1.0.21 2018/03/19
|
||||
* Version: @(#)86box.h 1.0.22 2018/03/28
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -100,7 +100,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 */
|
||||
@@ -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);
|
||||
|
||||
@@ -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.11 2018/03/26
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -38,6 +38,7 @@ STUFF :=
|
||||
# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_KEYBOARD_LOG=N sets logging level at N.
|
||||
# -DENABLE_PCI_LOG=N sets logging level at N.
|
||||
# -DENABLE_PIIX_LOG=N sets logging level at N.
|
||||
# -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.
|
||||
|
||||
5807
src/cdrom/cdrom.c
5807
src/cdrom/cdrom.c
File diff suppressed because it is too large
Load Diff
@@ -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.11 2018/03/26
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
@@ -19,22 +19,22 @@
|
||||
#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
|
||||
|
||||
@@ -46,177 +46,106 @@
|
||||
|
||||
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, scsi_device_lun,
|
||||
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];
|
||||
|
||||
#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 +153,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 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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
404
src/config.c
404
src/config.c
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Configuration file handler.
|
||||
*
|
||||
* Version: @(#)config.c 1.0.46 2018/03/18
|
||||
* Version: @(#)config.c 1.0.47 2018/03/26
|
||||
*
|
||||
* Authors: Sarah Walker,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -31,11 +31,10 @@
|
||||
#include <inttypes.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"
|
||||
@@ -47,6 +46,7 @@
|
||||
#include "mouse.h"
|
||||
#include "network/network.h"
|
||||
#include "scsi/scsi.h"
|
||||
#include "cdrom/cdrom.h"
|
||||
#include "sound/sound.h"
|
||||
#include "sound/midi.h"
|
||||
#include "sound/snd_dbopl.h"
|
||||
@@ -522,7 +522,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 +535,11 @@ 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);
|
||||
}
|
||||
|
||||
video_speed = config_get_int(cat, "video_speed", -1);
|
||||
|
||||
voodoo_enabled = !!config_get_int(cat, "voodoo", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -612,12 +611,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");
|
||||
@@ -714,8 +713,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 +745,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 +762,15 @@ 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;
|
||||
|
||||
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 +786,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 +819,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 +834,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;
|
||||
@@ -889,12 +858,11 @@ 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)) {
|
||||
if (hdd[c].bus == HDD_BUS_SCSI) {
|
||||
sprintf(tmp2, "%02u:%02u", c, 0);
|
||||
p = config_get_string(cat, temp, tmp2);
|
||||
|
||||
sscanf(p, "%02u:%02u",
|
||||
sscanf(p, "%02i:%02i",
|
||||
(int *)&hdd[c].scsi_id, (int *)&hdd[c].scsi_lun);
|
||||
|
||||
if (hdd[c].scsi_id > 15)
|
||||
@@ -956,181 +924,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)
|
||||
@@ -1235,20 +1028,13 @@ 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;
|
||||
@@ -1335,20 +1121,13 @@ 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;
|
||||
@@ -1420,16 +1199,28 @@ load_other_removable_devices(void)
|
||||
void
|
||||
config_load(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pclog("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;
|
||||
#ifdef USE_LANGUAGE
|
||||
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");
|
||||
video_speed = -1;
|
||||
enable_sync = 1;
|
||||
joystick_type = 7;
|
||||
if (hdc_name) {
|
||||
@@ -1438,12 +1229,20 @@ 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);
|
||||
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);
|
||||
|
||||
fdd_set_turbo(i, 0);
|
||||
fdd_set_check_bpb(i, 1);
|
||||
}
|
||||
mem_size = 640;
|
||||
opl_type = 0;
|
||||
|
||||
pclog("Config file not present or invalid!\n");
|
||||
return;
|
||||
@@ -1460,7 +1259,6 @@ 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;
|
||||
@@ -1730,10 +1528,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 +1619,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 +1628,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 +1661,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,9 +1674,9 @@ 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);
|
||||
|
||||
@@ -1891,7 +1687,7 @@ save_hard_disks(void)
|
||||
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);
|
||||
@@ -1899,7 +1695,7 @@ save_hard_disks(void)
|
||||
}
|
||||
|
||||
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))) {
|
||||
if (! hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_SCSI)) {
|
||||
config_delete_var(cat, temp);
|
||||
} else {
|
||||
sprintf(tmp2, "%02u:%02u", hdd[c].scsi_id, hdd[c].scsi_lun);
|
||||
@@ -2002,10 +1798,9 @@ 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);
|
||||
@@ -2040,10 +1835,9 @@ 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);
|
||||
@@ -2157,7 +1951,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 +1972,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 +1993,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)
|
||||
|
||||
@@ -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.3 2018/04/19
|
||||
*
|
||||
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -58,9 +58,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"
|
||||
|
||||
|
||||
@@ -648,7 +645,6 @@ void resetx86()
|
||||
#endif
|
||||
x86_was_reset = 1;
|
||||
port_92_clear_reset();
|
||||
scsi_card_reset();
|
||||
}
|
||||
|
||||
void softresetx86()
|
||||
@@ -658,7 +654,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 +681,6 @@ void softresetx86()
|
||||
x86seg_reset();
|
||||
x86_was_reset = 1;
|
||||
port_92_clear_reset();
|
||||
scsi_card_reset();
|
||||
}
|
||||
|
||||
static void setznp8(uint8_t val)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* CPU type handler.
|
||||
*
|
||||
* Version: @(#)cpu.c 1.0.14 2018/03/11
|
||||
* Version: @(#)cpu.c 1.0.15 2018/04/08
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
@@ -1313,7 +1313,7 @@ void cpu_CPUID()
|
||||
EDX = CPUID_FPU; /*FPU*/
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
case CPU_iDX4:
|
||||
@@ -1331,7 +1331,7 @@ void cpu_CPUID()
|
||||
EDX = CPUID_FPU | CPUID_VME;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
case CPU_Am486SX:
|
||||
@@ -1348,7 +1348,7 @@ void cpu_CPUID()
|
||||
EBX = ECX = EDX = 0; /*No FPU*/
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
case CPU_Am486DX:
|
||||
@@ -1366,7 +1366,7 @@ void cpu_CPUID()
|
||||
EDX = CPUID_FPU; /*FPU*/
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
case CPU_WINCHIP:
|
||||
@@ -1397,7 +1397,7 @@ void cpu_CPUID()
|
||||
EDX |= CPUID_MMX;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
case CPU_PENTIUM:
|
||||
@@ -1415,7 +1415,7 @@ 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
|
||||
@@ -1435,7 +1435,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 +1487,7 @@ void cpu_CPUID()
|
||||
EDX = 0x10040120;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
case CPU_K6:
|
||||
@@ -1549,7 +1549,7 @@ void cpu_CPUID()
|
||||
EDX = 0x444D416E;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@@ -1569,7 +1569,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 +1588,7 @@ void cpu_CPUID()
|
||||
EDX = CPUID_FPU;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1607,7 +1607,7 @@ void cpu_CPUID()
|
||||
EDX = CPUID_FPU | CPUID_CMPXCHG8B;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1626,7 +1626,7 @@ void cpu_CPUID()
|
||||
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1646,7 +1646,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 +1669,7 @@ void cpu_CPUID()
|
||||
{
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
|
||||
/* case CPU_PENTIUM2:
|
||||
@@ -1693,7 +1693,7 @@ void cpu_CPUID()
|
||||
EDX = 0x0C040843;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break; */
|
||||
|
||||
case CPU_PENTIUM2D:
|
||||
@@ -1717,7 +1717,7 @@ void cpu_CPUID()
|
||||
EDX = 0x0C040844;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@@ -2260,7 +2260,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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -8,18 +8,20 @@
|
||||
*
|
||||
* AMD SYSCALL and SYSRET CPU Instructions.
|
||||
*
|
||||
* Version: @(#)x86_ops_amd.h 1.0.1 2018/01/01
|
||||
* Version: @(#)x86_ops_amd.h 1.0.2 2018/03/26
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifndef internal_illegal
|
||||
static int internal_illegal(char *s)
|
||||
{
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86gpf(s, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 0 = Limit 0-15
|
||||
1 = Base 0-15
|
||||
|
||||
@@ -8,12 +8,21 @@
|
||||
*
|
||||
* 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.3 2018/03/26
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifndef internal_illegal
|
||||
static int internal_illegal(char *s)
|
||||
{
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86gpf(s, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 0 = Limit 0-15
|
||||
1 = Base 0-15
|
||||
2 = Base 16-23 (bits 0-7), Access rights
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "cpu.h"
|
||||
#include "../device.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../mem.h"
|
||||
#include "../nvr.h"
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
*
|
||||
* x87 FPU instructions core.
|
||||
*
|
||||
* Version: @(#)x87_ops.h 1.0.1 2017/10/28
|
||||
* Version: @(#)x87_ops.h 1.0.2 2018/04/05
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 leilei.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 leilei.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
@@ -80,6 +80,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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
25
src/device.c
25
src/device.c
@@ -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.6 2018/03/26
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -82,18 +82,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
|
||||
else
|
||||
pclog("DEVICE: device init failed\n");
|
||||
|
||||
device_priv[c] = NULL;
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
devices[c] = (device_t *)d;
|
||||
device_priv[c] = priv;
|
||||
|
||||
return(priv);
|
||||
@@ -152,6 +156,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)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the device handler.
|
||||
*
|
||||
* Version: @(#)device.h 1.0.3 2018/03/15
|
||||
* Version: @(#)device.h 1.0.4 2018/03/26
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -119,6 +119,7 @@ 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);
|
||||
|
||||
@@ -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.13 2018/04/04
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "../device.h"
|
||||
#include "hdc.h"
|
||||
#include "hdc_ide.h"
|
||||
#include "hdd.h"
|
||||
|
||||
|
||||
char *hdc_name; /* configured HDC name */
|
||||
@@ -106,6 +107,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 },
|
||||
|
||||
@@ -146,6 +150,9 @@ hdc_init(char *name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Zero all the hard disk image arrays. */
|
||||
hdd_image_init();
|
||||
}
|
||||
|
||||
|
||||
@@ -154,20 +161,17 @@ void
|
||||
hdc_reset(void)
|
||||
{
|
||||
pclog("HDC: reset(current=%d, internal=%d)\n",
|
||||
hdc_current, (machines[machine].flags & MACHINE_HDC)?1:0);
|
||||
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 +189,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 +212,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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.10 2018/04/17
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -104,35 +104,28 @@ typedef struct {
|
||||
} esdi_t;
|
||||
|
||||
|
||||
static __inline void irq_raise(esdi_t *esdi)
|
||||
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);
|
||||
}
|
||||
if (!(esdi->fdisk&2))
|
||||
picint(1 << 14);
|
||||
|
||||
/* Remember this. */
|
||||
esdi->irqstat = 1;
|
||||
}
|
||||
esdi->irqstat=1;
|
||||
}
|
||||
|
||||
|
||||
static __inline void irq_lower(esdi_t *esdi)
|
||||
static inline void
|
||||
irq_lower(esdi_t *esdi)
|
||||
{
|
||||
/* If raised.. */
|
||||
if (esdi->irqstat) {
|
||||
/* If enabled in the control register.. */
|
||||
if (! (esdi->fdisk & 0x02)) {
|
||||
/* .. drop IRQ14. */
|
||||
picintc(1<<14);
|
||||
}
|
||||
picintc(1 << 14);
|
||||
}
|
||||
|
||||
/* Remember this. */
|
||||
esdi->irqstat = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
irq_update(esdi_t *esdi)
|
||||
{
|
||||
if (esdi->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(esdi->fdisk & 2))
|
||||
picint(1 << 14);
|
||||
}
|
||||
|
||||
|
||||
@@ -384,6 +377,7 @@ esdi_write(uint16_t port, uint8_t val, void *priv)
|
||||
esdi->status = STAT_BUSY;
|
||||
}
|
||||
esdi->fdisk = val;
|
||||
irq_update(esdi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.11 2018/04/17
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -101,8 +101,6 @@ typedef struct esdi_drive {
|
||||
} drive_t;
|
||||
|
||||
typedef struct esdi {
|
||||
uint16_t base;
|
||||
int8_t irq;
|
||||
int8_t dma;
|
||||
|
||||
uint32_t bios;
|
||||
@@ -190,6 +188,7 @@ 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)
|
||||
|
||||
|
||||
@@ -197,14 +196,14 @@ 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 +249,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 +395,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 +457,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 +469,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 +491,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 +507,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 +522,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 +550,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);
|
||||
|
||||
@@ -557,8 +576,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 +585,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 +706,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 +731,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;
|
||||
@@ -739,9 +755,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);
|
||||
pclog("ESDI: wr(%04x, %02x)\n", port & 7, val);
|
||||
#endif
|
||||
switch (port-dev->base) {
|
||||
switch (port & 7) {
|
||||
case 2: /*Basic control register*/
|
||||
if ((dev->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) {
|
||||
dev->in_reset = 1;
|
||||
@@ -751,7 +767,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 +781,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 +810,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 +833,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 +864,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;
|
||||
}
|
||||
@@ -870,9 +888,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);
|
||||
pclog("ESDI: wrw(%04x, %04x)\n", port & 7, val);
|
||||
#endif
|
||||
switch (port-dev->base) {
|
||||
switch (port & 7) {
|
||||
case 0: /*Command Interface Register*/
|
||||
if (dev->cmd_pos >= 4)
|
||||
fatal("CIR pos 4\n");
|
||||
@@ -919,123 +937,55 @@ esdi_mca_write(int port, uint8_t val, void *priv)
|
||||
pclog("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);
|
||||
pclog("ESDI: I/O=3510, IRQ=14, DMA=%d, BIOS @%05X\n",
|
||||
dev->dma, dev->bios);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1054,9 +1004,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 +1027,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. */
|
||||
|
||||
4859
src/disk/hdc_ide.c
4859
src/disk/hdc_ide.c
File diff suppressed because it is too large
Load Diff
@@ -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.9 2018/03/26
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -21,59 +21,53 @@
|
||||
|
||||
|
||||
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, specify_success,
|
||||
mdma_mode, do_initial_read,
|
||||
spt, hpc,
|
||||
tracks;
|
||||
uint32_t secount, sector,
|
||||
cylinder, head,
|
||||
drive, cylprecomp,
|
||||
t_spt, t_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 +75,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*/
|
||||
|
||||
@@ -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.14 2018/04/16
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -110,35 +110,28 @@ typedef struct {
|
||||
} mfm_t;
|
||||
|
||||
|
||||
static __inline void irq_raise(mfm_t *mfm)
|
||||
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);
|
||||
}
|
||||
if (!(mfm->fdisk&2))
|
||||
picint(1 << 14);
|
||||
|
||||
/* Remember this. */
|
||||
mfm->irqstat = 1;
|
||||
}
|
||||
mfm->irqstat=1;
|
||||
}
|
||||
|
||||
|
||||
static __inline void irq_lower(mfm_t *mfm)
|
||||
static inline void
|
||||
irq_lower(mfm_t *mfm)
|
||||
{
|
||||
/* If raised.. */
|
||||
if (mfm->irqstat) {
|
||||
/* If enabled in the control register.. */
|
||||
if (! (mfm->fdisk&0x02)) {
|
||||
/* .. drop IRQ14. */
|
||||
picintc(1<<14);
|
||||
}
|
||||
picintc(1 << 14);
|
||||
}
|
||||
|
||||
/* Remember this. */
|
||||
mfm->irqstat = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
irq_update(mfm_t *mfm)
|
||||
{
|
||||
if (mfm->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(mfm->fdisk & 2))
|
||||
picint(1 << 14);
|
||||
}
|
||||
|
||||
|
||||
@@ -233,6 +226,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
}
|
||||
|
||||
irq_lower(mfm);
|
||||
mfm->command = val;
|
||||
mfm->error = 0;
|
||||
|
||||
switch (val & 0xf0) {
|
||||
@@ -244,13 +238,13 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
#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,6 +252,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
break;
|
||||
|
||||
default:
|
||||
mfm->command = val;
|
||||
switch (val) {
|
||||
case CMD_READ:
|
||||
case CMD_READ+1:
|
||||
@@ -267,7 +262,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
pclog("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;
|
||||
@@ -284,7 +279,7 @@ mfm_cmd(mfm_t *mfm, uint8_t val)
|
||||
pclog("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 +288,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 +296,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;
|
||||
@@ -417,7 +410,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 +421,22 @@ 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;
|
||||
irq_update(mfm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -619,19 +613,18 @@ 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:
|
||||
|
||||
@@ -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.15 2018/04/18
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -71,7 +71,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"
|
||||
|
||||
@@ -429,7 +430,7 @@ mfm_callback(void *priv)
|
||||
}
|
||||
|
||||
hdd_image_zero(drive->hdd_num, addr, 17);
|
||||
|
||||
|
||||
mfm_complete(mfm);
|
||||
break;
|
||||
|
||||
@@ -757,7 +758,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;
|
||||
}
|
||||
@@ -859,7 +860,7 @@ mfm_close(void *priv)
|
||||
static int
|
||||
xebec_available(void)
|
||||
{
|
||||
return(rom_present(XEBEC_BIOS_FILE));
|
||||
return(rom_present(XEBEC_BIOS_FILE));
|
||||
}
|
||||
|
||||
|
||||
@@ -884,7 +885,7 @@ dtc5150x_init(const device_t *info)
|
||||
pclog("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);
|
||||
pclog("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;
|
||||
|
||||
1200
src/disk/hdc_xta.c
Normal file
1200
src/disk/hdc_xta.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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.12 2018/04/05
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -248,7 +260,7 @@ const device_t xtide_at_device = {
|
||||
"XTIDE (AT)",
|
||||
DEVICE_ISA | DEVICE_AT,
|
||||
0,
|
||||
xtide_at_init, xtide_close, NULL,
|
||||
xtide_at_init, xtide_at_close, NULL,
|
||||
xtide_at_available, NULL, 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_init, xtide_at_close, NULL,
|
||||
xtide_at_ps2_available, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -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.8 2018/04/24
|
||||
*
|
||||
* 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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.4 2018/03/29
|
||||
*
|
||||
* 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,16 @@ 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 +101,7 @@ typedef struct {
|
||||
|
||||
|
||||
extern hard_disk_t hdd[HDD_NUM];
|
||||
extern uint64_t hdd_table[128][3];
|
||||
extern unsigned int hdd_table[128][3];
|
||||
|
||||
|
||||
extern int hdd_init(void);
|
||||
@@ -75,6 +109,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);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of hard disk image files.
|
||||
*
|
||||
* Version: @(#)hdd_image.c 1.0.13 2018/03/19
|
||||
* Version: @(#)hdd_image.c 1.0.14 2018/03/28
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -34,11 +34,11 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FILE *file;
|
||||
uint32_t base;
|
||||
uint32_t last_sector;
|
||||
uint8_t type;
|
||||
uint8_t loaded;
|
||||
FILE *file;
|
||||
uint32_t base;
|
||||
uint32_t last_sector;
|
||||
uint8_t type;
|
||||
uint8_t loaded;
|
||||
} hdd_image_t;
|
||||
|
||||
|
||||
@@ -69,393 +69,442 @@ hdd_image_log(const char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
int image_is_hdi(const wchar_t *s)
|
||||
int
|
||||
image_is_hdi(const wchar_t *s)
|
||||
{
|
||||
int len;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
char *ws = (char *) s;
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
return 0;
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (! wcscasecmp(ext, L".HDI"))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
int len;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
char *ws = (char *) s;
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
return 0;
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (! wcscasecmp(ext, L".HDI"))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
image_is_hdx(const wchar_t *s, int check_signature)
|
||||
{
|
||||
int len;
|
||||
FILE *f;
|
||||
uint64_t filelen;
|
||||
uint64_t signature;
|
||||
char *ws = (char *) s;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
return 0;
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcscasecmp(ext, L".HDX") == 0) {
|
||||
if (check_signature) {
|
||||
f = plat_fopen((wchar_t *)s, L"rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
fseeko64(f, 0, SEEK_END);
|
||||
filelen = ftello64(f);
|
||||
fseeko64(f, 0, SEEK_SET);
|
||||
if (filelen < 44)
|
||||
return 0;
|
||||
fread(&signature, 1, 8, f);
|
||||
fclose(f);
|
||||
if (signature == 0xD778A82044445459ll)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int len;
|
||||
FILE *f;
|
||||
uint64_t filelen;
|
||||
uint64_t signature;
|
||||
char *ws = (char *) s;
|
||||
wchar_t ext[5] = { 0, 0, 0, 0, 0 };
|
||||
len = wcslen(s);
|
||||
if ((len < 4) || (s[0] == L'.'))
|
||||
return 0;
|
||||
memcpy(ext, ws + ((len - 4) << 1), 8);
|
||||
if (wcscasecmp(ext, L".HDX") == 0) {
|
||||
if (check_signature) {
|
||||
f = plat_fopen((wchar_t *)s, L"rb");
|
||||
if (!f)
|
||||
return 0;
|
||||
fseeko64(f, 0, SEEK_END);
|
||||
filelen = ftello64(f);
|
||||
fseeko64(f, 0, SEEK_SET);
|
||||
if (filelen < 44)
|
||||
return 0;
|
||||
fread(&signature, 1, 8, f);
|
||||
fclose(f);
|
||||
if (signature == 0xD778A82044445459ll)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int hdd_image_load(int id)
|
||||
static int
|
||||
prepare_new_hard_disk(uint8_t id, uint64_t full_size)
|
||||
{
|
||||
uint32_t sector_size = 512;
|
||||
uint32_t zero = 0;
|
||||
uint64_t signature = 0xD778A82044445459ll;
|
||||
uint64_t full_size = 0;
|
||||
uint64_t spt = 0, hpc = 0, tracks = 0;
|
||||
int c;
|
||||
uint64_t i = 0, s = 0, t = 0;
|
||||
wchar_t *fn = hdd[id].fn;
|
||||
int is_hdx[2] = { 0, 0 };
|
||||
uint64_t target_size = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file);
|
||||
|
||||
memset(empty_sector, 0, sizeof(empty_sector));
|
||||
uint32_t size;
|
||||
uint32_t t, i;
|
||||
|
||||
hdd_images[id].base = 0;
|
||||
t = (uint32_t) (target_size >> 20); /* Amount of 1 MB blocks. */
|
||||
size = (uint32_t) (target_size & 0xfffff); /* 1 MB mask. */
|
||||
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
empty_sector_1mb = (char *) malloc(1048576);
|
||||
memset(empty_sector_1mb, 0, 1048576);
|
||||
|
||||
/* Temporarily switch off suppression of seen messages so that the
|
||||
progress gets displayed. */
|
||||
pclog_toggle_suppr();
|
||||
pclog("Writing image sectors: [");
|
||||
|
||||
/* First, write all the 1 MB blocks. */
|
||||
if (t > 0) {
|
||||
for (i = 0; i < t; i++) {
|
||||
fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file);
|
||||
pclog("#");
|
||||
}
|
||||
}
|
||||
|
||||
is_hdx[0] = image_is_hdx(fn, 0);
|
||||
is_hdx[1] = image_is_hdx(fn, 1);
|
||||
/* Then, write the remainder. */
|
||||
fwrite(empty_sector_1mb, 1, size, hdd_images[id].file);
|
||||
pclog("#]\n");
|
||||
/* Switch the suppression of seen messages back on. */
|
||||
pclog_toggle_suppr();
|
||||
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.') {
|
||||
hdd_image_log("File name starts with .\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
free(empty_sector_1mb);
|
||||
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
|
||||
hdd_images[id].loaded = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HDD_NUM; i++)
|
||||
memset(&hdd_images[i], 0, sizeof(hdd_image_t));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hdd_image_load(int id)
|
||||
{
|
||||
uint32_t sector_size = 512;
|
||||
uint32_t zero = 0;
|
||||
uint64_t signature = 0xD778A82044445459ll;
|
||||
uint64_t full_size = 0;
|
||||
uint64_t spt = 0, hpc = 0, tracks = 0;
|
||||
int c;
|
||||
uint64_t s = 0;
|
||||
wchar_t *fn = hdd[id].fn;
|
||||
int is_hdx[2] = { 0, 0 };
|
||||
|
||||
memset(empty_sector, 0, sizeof(empty_sector));
|
||||
|
||||
hdd_images[id].base = 0;
|
||||
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
hdd_images[id].file = plat_fopen(fn, L"rb+");
|
||||
if (hdd_images[id].file == NULL) {
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT) {
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdd[id].wp) {
|
||||
hdd_image_log("A write-protected image must exist\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
}
|
||||
|
||||
hdd_images[id].file = plat_fopen(fn, L"wb+");
|
||||
if (hdd_images[id].file == NULL) {
|
||||
hdd_image_log("Unable to open image\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
hdd_images[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 1;
|
||||
} else if (is_hdx[0]) {
|
||||
full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
hdd_images[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 8, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
}
|
||||
else
|
||||
hdd_images[id].type = 0;
|
||||
hdd_images[id].last_sector = 0;
|
||||
}
|
||||
is_hdx[0] = image_is_hdx(fn, 0);
|
||||
is_hdx[1] = image_is_hdx(fn, 1);
|
||||
|
||||
s = full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
|
||||
goto prepare_new_hard_disk;
|
||||
} else {
|
||||
/* Failed for another reason */
|
||||
hdd_image_log("Failed for another reason\n");
|
||||
/* Try to open existing hard disk image */
|
||||
if (fn[0] == '.') {
|
||||
hdd_image_log("File name starts with .\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
hdd_images[id].file = plat_fopen(fn, L"rb+");
|
||||
if (hdd_images[id].file == NULL) {
|
||||
/* Failed to open existing hard disk image */
|
||||
if (errno == ENOENT) {
|
||||
/* Failed because it does not exist,
|
||||
so try to create new file */
|
||||
if (hdd[id].wp) {
|
||||
hdd_image_log("A write-protected image must exist\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
fseeko64(hdd_images[id].file, 0x8, SEEK_SET);
|
||||
fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0xC, SEEK_SET);
|
||||
full_size = 0;
|
||||
fread(&full_size, 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDI: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) {
|
||||
if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks)) {
|
||||
hdd_image_log("HDI: Geometry mismatch\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
hdd_images[id].type = 1;
|
||||
}
|
||||
else if (is_hdx[1]) {
|
||||
hdd_images[id].base = 0x28;
|
||||
fseeko64(hdd_images[id].file, 8, SEEK_SET);
|
||||
fread(&full_size, 1, 8, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDX: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
if (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) {
|
||||
if ((spt != hdd[id].spt) || (hpc != hdd[id].hpc) || (tracks != hdd[id].tracks)) {
|
||||
hdd_image_log("HDX: Geometry mismatch\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
fread(&(hdd[id].at_spt), 1, 4, hdd_images[id].file);
|
||||
fread(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
|
||||
hdd_images[id].file = plat_fopen(fn, L"wb+");
|
||||
if (hdd_images[id].file == NULL) {
|
||||
hdd_image_log("Unable to open image\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
} else {
|
||||
full_size = hdd[id].spt * hdd[id].hpc * hdd[id].tracks * 512;
|
||||
hdd_images[id].type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
if (ftello64(hdd_images[id].file) < (full_size + hdd_images[id].base)) {
|
||||
s = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file);
|
||||
prepare_new_hard_disk:
|
||||
t = s >> 20; /* Amount of 1 MB blocks. */
|
||||
s &= 0xfffff; /* 1 MB mask. */
|
||||
|
||||
empty_sector_1mb = (char *) malloc(1048576);
|
||||
memset(empty_sector_1mb, 0, 1048576);
|
||||
|
||||
/* Temporarily switch off suppression of seen messages so that the
|
||||
progress gets displayed. */
|
||||
pclog_toggle_suppr();
|
||||
pclog("Writing image sectors: [");
|
||||
|
||||
/* First, write all the 1 MB blocks. */
|
||||
if (t > 0) {
|
||||
for (i = 0; i < t; i++) {
|
||||
fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file);
|
||||
pclog("#");
|
||||
if (image_is_hdi(fn)) {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].base = 0x1000;
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
for (c = 0; c < 0x3f8; c++)
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 1;
|
||||
} else if (is_hdx[0]) {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].base = 0x28;
|
||||
fwrite(&signature, 1, 8, hdd_images[id].file);
|
||||
fwrite(&full_size, 1, 8, hdd_images[id].file);
|
||||
fwrite(§or_size, 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].hpc), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].tracks), 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
fwrite(&zero, 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
}
|
||||
else
|
||||
hdd_images[id].type = 0;
|
||||
hdd_images[id].last_sector = 0;
|
||||
}
|
||||
|
||||
/* Then, write the remainder. */
|
||||
fwrite(empty_sector_1mb, 1, s, hdd_images[id].file);
|
||||
pclog("#]\n");
|
||||
pclog_toggle_suppr();
|
||||
s = full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
|
||||
free(empty_sector_1mb);
|
||||
return prepare_new_hard_disk(id, full_size);
|
||||
} else {
|
||||
/* Failed for another reason */
|
||||
hdd_image_log("Failed for another reason\n");
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
|
||||
hdd_images[id].loaded = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
{
|
||||
off64_t addr = sector;
|
||||
addr = (uint64_t)sector * 512;
|
||||
|
||||
fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET);
|
||||
}
|
||||
|
||||
void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector * 512) + hdd_images[id].base, SEEK_SET);
|
||||
fread(buffer, 1, count * 512, hdd_images[id].file);
|
||||
}
|
||||
|
||||
uint32_t hdd_sectors(uint8_t id)
|
||||
{
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
return (uint32_t) (ftello64(hdd_images[id].file) >> 9);
|
||||
}
|
||||
|
||||
int hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
uint32_t transfer_sectors = count;
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector * 512) + hdd_images[id].base, SEEK_SET);
|
||||
fread(buffer, 1, transfer_sectors * 512, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector * 512) + hdd_images[id].base, SEEK_SET);
|
||||
fwrite(buffer, count * 512, 1, hdd_images[id].file);
|
||||
}
|
||||
|
||||
int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
uint32_t transfer_sectors = count;
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector * 512) + hdd_images[id].base, SEEK_SET);
|
||||
fwrite(buffer, transfer_sectors * 512, 1, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector * 512) + hdd_images[id].base, SEEK_SET);
|
||||
for (i = 0; i < count; i++)
|
||||
fwrite(empty_sector, 512, 1, hdd_images[id].file);
|
||||
}
|
||||
|
||||
int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
uint32_t transfer_sectors = count;
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector * 512) + hdd_images[id].base, SEEK_SET);
|
||||
for (i = 0; i < transfer_sectors; i++)
|
||||
fwrite(empty_sector, 1, 512, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t hdd_image_get_last_sector(uint8_t id)
|
||||
{
|
||||
return hdd_images[id].last_sector;
|
||||
}
|
||||
|
||||
uint8_t hdd_image_get_type(uint8_t id)
|
||||
{
|
||||
return hdd_images[id].type;
|
||||
}
|
||||
|
||||
void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt)
|
||||
{
|
||||
if (hdd_images[id].type == 2)
|
||||
{
|
||||
hdd[id].at_hpc = hpc;
|
||||
hdd[id].at_spt = spt;
|
||||
fseeko64(hdd_images[id].file, 0x20, SEEK_SET);
|
||||
fwrite(&(hdd[id].at_spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
|
||||
void hdd_image_unload(uint8_t id, int fn_preserve)
|
||||
{
|
||||
if (wcslen(hdd[id].fn) == 0)
|
||||
return;
|
||||
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file != NULL) {
|
||||
} else {
|
||||
if (image_is_hdi(fn)) {
|
||||
fseeko64(hdd_images[id].file, 0x8, SEEK_SET);
|
||||
fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0xC, SEEK_SET);
|
||||
full_size = 0LL;
|
||||
fread(&full_size, 1, 4, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDI: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
hdd_images[id].type = 1;
|
||||
} else if (is_hdx[1]) {
|
||||
hdd_images[id].base = 0x28;
|
||||
fseeko64(hdd_images[id].file, 8, SEEK_SET);
|
||||
fread(&full_size, 1, 8, hdd_images[id].file);
|
||||
fseeko64(hdd_images[id].file, 0x10, SEEK_SET);
|
||||
fread(§or_size, 1, 4, hdd_images[id].file);
|
||||
if (sector_size != 512) {
|
||||
/* Sector size is not 512 */
|
||||
hdd_image_log("HDX: Sector size is not 512\n");
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
return 0;
|
||||
}
|
||||
fread(&spt, 1, 4, hdd_images[id].file);
|
||||
fread(&hpc, 1, 4, hdd_images[id].file);
|
||||
fread(&tracks, 1, 4, hdd_images[id].file);
|
||||
hdd[id].spt = spt;
|
||||
hdd[id].hpc = hpc;
|
||||
hdd[id].tracks = tracks;
|
||||
fread(&(hdd[id].at_spt), 1, 4, hdd_images[id].file);
|
||||
fread(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file);
|
||||
hdd_images[id].type = 2;
|
||||
} else {
|
||||
full_size = ((uint64_t) hdd[id].spt) *
|
||||
((uint64_t) hdd[id].hpc) *
|
||||
((uint64_t) hdd[id].tracks) << 9LL;
|
||||
hdd_images[id].type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hdd_images[id].last_sector = -1;
|
||||
|
||||
memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn));
|
||||
if (fn_preserve)
|
||||
wcscpy(hdd[id].prev_fn, hdd[id].fn);
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
s = ftello64(hdd_images[id].file);
|
||||
if (s < (full_size + hdd_images[id].base))
|
||||
return prepare_new_hard_disk(id, full_size);
|
||||
else {
|
||||
hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1;
|
||||
hdd_images[id].loaded = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void hdd_image_close(uint8_t id)
|
||||
|
||||
void
|
||||
hdd_image_seek(uint8_t id, uint32_t sector)
|
||||
{
|
||||
off64_t addr = sector;
|
||||
addr = (uint64_t)sector * 512;
|
||||
|
||||
fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fread(buffer, 1, count << 9, hdd_images[id].file);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
hdd_sectors(uint8_t id)
|
||||
{
|
||||
fseeko64(hdd_images[id].file, 0, SEEK_END);
|
||||
return (uint32_t) ((ftello64(hdd_images[id].file) - hdd_images[id].base) >> 9);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
uint32_t transfer_sectors = count;
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fread(buffer, 1, transfer_sectors << 9, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fwrite(buffer, count << 9, 1, hdd_images[id].file);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer)
|
||||
{
|
||||
uint32_t transfer_sectors = count;
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
fwrite(buffer, transfer_sectors << 9, 1, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
for (i = 0; i < count; i++)
|
||||
fwrite(empty_sector, 512, 1, hdd_images[id].file);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
uint32_t transfer_sectors = count;
|
||||
uint32_t sectors = hdd_sectors(id);
|
||||
|
||||
if ((sectors - sector) < transfer_sectors)
|
||||
transfer_sectors = sectors - sector;
|
||||
|
||||
fseeko64(hdd_images[id].file, ((uint64_t)sector << 9LL) + hdd_images[id].base, SEEK_SET);
|
||||
for (i = 0; i < transfer_sectors; i++)
|
||||
fwrite(empty_sector, 1, 512, hdd_images[id].file);
|
||||
|
||||
if (count != transfer_sectors)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
hdd_image_get_last_sector(uint8_t id)
|
||||
{
|
||||
return hdd_images[id].last_sector;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
hdd_image_get_type(uint8_t id)
|
||||
{
|
||||
return hdd_images[id].type;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt)
|
||||
{
|
||||
if (hdd_images[id].type == 2) {
|
||||
hdd[id].at_hpc = hpc;
|
||||
hdd[id].at_spt = spt;
|
||||
fseeko64(hdd_images[id].file, 0x20, SEEK_SET);
|
||||
fwrite(&(hdd[id].at_spt), 1, 4, hdd_images[id].file);
|
||||
fwrite(&(hdd[id].at_hpc), 1, 4, hdd_images[id].file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_unload(uint8_t id, int fn_preserve)
|
||||
{
|
||||
if (wcslen(hdd[id].fn) == 0)
|
||||
return;
|
||||
|
||||
if (hdd_images[id].loaded) {
|
||||
if (hdd_images[id].file != NULL) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
hdd_images[id].loaded = 0;
|
||||
}
|
||||
|
||||
hdd_images[id].last_sector = -1;
|
||||
|
||||
memset(hdd[id].prev_fn, 0, sizeof(hdd[id].prev_fn));
|
||||
if (fn_preserve)
|
||||
wcscpy(hdd[id].prev_fn, hdd[id].fn);
|
||||
memset(hdd[id].fn, 0, sizeof(hdd[id].fn));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hdd_image_close(uint8_t id)
|
||||
{
|
||||
hdd_image_log("hdd_image_close(%i)\n", id);
|
||||
|
||||
if (!hdd_images[id].loaded)
|
||||
return;
|
||||
|
||||
if (hdd_images[id].file != NULL) {
|
||||
fclose(hdd_images[id].file);
|
||||
hdd_images[id].file = NULL;
|
||||
}
|
||||
memset(&hdd_images[id], 0, sizeof(hdd_image_t));
|
||||
hdd_images[id].loaded = 0;
|
||||
}
|
||||
|
||||
@@ -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 },
|
||||
|
||||
4569
src/disk/zip.c
4569
src/disk/zip.c
File diff suppressed because it is too large
Load Diff
165
src/disk/zip.h
165
src/disk/zip.h
@@ -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.5 2018/03/26
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
@@ -19,15 +19,15 @@
|
||||
#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
|
||||
@@ -42,134 +42,81 @@
|
||||
|
||||
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;
|
||||
uint8_t previous_command, error,
|
||||
features, status,
|
||||
phase, *buffer,
|
||||
atapi_cdb[16],
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
int toctimes;
|
||||
int media_status;
|
||||
uint16_t request_length, max_transfer_len;
|
||||
|
||||
int is_dma;
|
||||
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;
|
||||
|
||||
int requested_blocks; /* This will be set to something other than 1 when block reads are implemented. */
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len, pos,
|
||||
seek_pos;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
uint64_t current_page_code;
|
||||
} zip_t;
|
||||
|
||||
typedef struct {
|
||||
int host_drive;
|
||||
int prev_host_drive;
|
||||
unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */
|
||||
uint8_t ide_channel,
|
||||
bus_mode; /* Bit 0 = PIO suported;
|
||||
Bit 1 = DMA supportd. */
|
||||
|
||||
unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */
|
||||
uint8_t bus_mode; /* Bit 0 = PIO suported;
|
||||
Bit 1 = DMA supportd. */
|
||||
unsigned int scsi_device_id, scsi_device_lun,
|
||||
is_250;
|
||||
|
||||
uint8_t ide_channel;
|
||||
wchar_t image_path[1024],
|
||||
prev_image_path[1024];
|
||||
|
||||
unsigned int scsi_device_id;
|
||||
unsigned int scsi_device_lun;
|
||||
|
||||
unsigned int is_250;
|
||||
unsigned int atapi_dma;
|
||||
int read_only, ui_writeprot;
|
||||
|
||||
wchar_t image_path[1024];
|
||||
wchar_t prev_image_path[1024];
|
||||
uint32_t medium_size, base;
|
||||
|
||||
uint32_t medium_size;
|
||||
|
||||
int read_only;
|
||||
int ui_writeprot;
|
||||
|
||||
uint32_t base;
|
||||
|
||||
FILE *f;
|
||||
FILE *f;
|
||||
} zip_drive_t;
|
||||
|
||||
|
||||
extern zip_t zip[ZIP_NUM];
|
||||
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];
|
||||
|
||||
#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 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]
|
||||
|
||||
|
||||
#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 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 void ioctl_close(uint8_t id);
|
||||
|
||||
extern uint32_t zip_mode_sense_get_channel(uint8_t id, int channel);
|
||||
@@ -183,8 +130,6 @@ extern void zip_phase_callback(uint8_t id);
|
||||
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);
|
||||
@@ -200,6 +145,8 @@ 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_destroy_drives(void);
|
||||
extern void zip_close(uint8_t id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
74
src/dma.h
74
src/dma.h
@@ -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);
|
||||
|
||||
150
src/floppy/fdc.c
150
src/floppy/fdc.c
@@ -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.6 2018/04/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)
|
||||
@@ -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;
|
||||
@@ -1055,6 +1066,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc_seek(fdc, fdc->drive, -fdc->max_track);
|
||||
fdc_log("Recalibrating...\n");
|
||||
fdc->time = 5000LL;
|
||||
fdc->step = fdc->seek_dir = 1;
|
||||
break;
|
||||
case 0x0d: /*Format*/
|
||||
fdc_rate(fdc, fdc->drive);
|
||||
@@ -1098,14 +1110,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->step = 1;
|
||||
} else {
|
||||
fdc->st0 = 0x20 | (fdc->params[0] & 7);
|
||||
fdc->interrupt = -3;
|
||||
@@ -1125,9 +1140,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->step = 1;
|
||||
fdc_log("fdc->time = %i\n", fdc->time);
|
||||
}
|
||||
break;
|
||||
@@ -1154,7 +1174,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 +1193,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 +1308,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 +1341,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;
|
||||
@@ -1530,7 +1601,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,7 +1684,8 @@ 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;
|
||||
fdc->res[5] = st5;
|
||||
@@ -1977,7 +2050,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 +2068,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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the floppy drive emulation.
|
||||
*
|
||||
* Version: @(#)fdd.c 1.0.5 2018/03/16
|
||||
* Version: @(#)fdd.c 1.0.6 2018/04/10
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -495,7 +495,6 @@ void fdd_close(int 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 +505,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.8 2018/04/11
|
||||
*
|
||||
* 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"
|
||||
|
||||
1477
src/intel_piix.c
1477
src/intel_piix.c
File diff suppressed because it is too large
Load Diff
267
src/intel_sio.c
267
src/intel_sio.c
@@ -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.7 2018/03/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,181 @@
|
||||
#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,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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.34 2018/03/26
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -2044,15 +2044,25 @@ const device_t keyboard_ps2_quadtel_device = {
|
||||
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, 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, NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
|
||||
@@ -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.12 2018/04/11
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -1205,7 +1205,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,16 +8,17 @@
|
||||
*
|
||||
* Implementation of the Intel 430FX PCISet chip.
|
||||
*
|
||||
* Version: @(#)m_at_430fx.c 1.0.14 2018/03/18
|
||||
* Version: @(#)m_at_430fx.c 1.0.16 2018/04/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016,2018 Miran Grca.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
@@ -36,220 +37,231 @@
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
static uint8_t card_i430fx[256];
|
||||
|
||||
|
||||
static void i430fx_map(uint32_t addr, uint32_t size, int state)
|
||||
typedef struct
|
||||
{
|
||||
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();
|
||||
}
|
||||
uint8_t regs[256];
|
||||
} i430fx_t;
|
||||
|
||||
|
||||
static void i430fx_write(int func, int addr, uint8_t val, void *priv)
|
||||
static void
|
||||
i430fx_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
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);
|
||||
switch (state & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
|
||||
card_i430fx[addr] = val;
|
||||
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 uint8_t i430fx_read(int func, int addr, void *priv)
|
||||
static void
|
||||
i430fx_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
i430fx_t *dev = (i430fx_t *) priv;
|
||||
|
||||
return card_i430fx[addr];
|
||||
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 ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i430fx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i430fx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i430fx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i430fx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i430fx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i430fx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i430fx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i430fx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i430fx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i430fx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i430fx_map(0xe4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i430fx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i430fx_map(0xec000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x72: /*SMRAM*/
|
||||
if ((dev->regs[0x72] ^ val) & 0x48)
|
||||
i430fx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void i430fx_reset(void)
|
||||
static uint8_t
|
||||
i430fx_read(int func, int addr, void *priv)
|
||||
{
|
||||
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;
|
||||
}
|
||||
i430fx_t *dev = (i430fx_t *) priv;
|
||||
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return dev->regs[addr];
|
||||
}
|
||||
|
||||
|
||||
static void i430fx_pci_reset(void)
|
||||
static void
|
||||
i430fx_reset(void *priv)
|
||||
{
|
||||
i430fx_write(0, 0x59, 0x00, NULL);
|
||||
i430fx_write(0, 0x72, 0x02, NULL);
|
||||
i430fx_write(0, 0x59, 0x00, priv);
|
||||
i430fx_write(0, 0x72, 0x02, priv);
|
||||
}
|
||||
|
||||
|
||||
static void i430fx_init(void)
|
||||
static void
|
||||
i430fx_close(void *p)
|
||||
{
|
||||
pci_add_card(0, i430fx_read, i430fx_write, NULL);
|
||||
i430fx_t *i430fx = (i430fx_t *)p;
|
||||
|
||||
i430fx_reset();
|
||||
|
||||
pci_reset_handler.pci_master_reset = i430fx_pci_reset;
|
||||
free(i430fx);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*i430fx_init(const device_t *info)
|
||||
{
|
||||
i430fx_t *i430fx = (i430fx_t *) malloc(sizeof(i430fx_t));
|
||||
memset(i430fx, 0, sizeof(i430fx_t));
|
||||
|
||||
i430fx->regs[0x00] = 0x86; i430fx->regs[0x01] = 0x80; /*Intel*/
|
||||
i430fx->regs[0x02] = 0x2d; i430fx->regs[0x03] = 0x12; /*SB82437FX-66*/
|
||||
i430fx->regs[0x04] = 0x06; i430fx->regs[0x05] = 0x00;
|
||||
i430fx->regs[0x06] = 0x00; i430fx->regs[0x07] = 0x82;
|
||||
i430fx->regs[0x08] = 0x00; /*A0 stepping*/
|
||||
i430fx->regs[0x09] = 0x00; i430fx->regs[0x0a] = 0x00; i430fx->regs[0x0b] = 0x06;
|
||||
i430fx->regs[0x52] = 0x40; /*256kb PLB cache*/
|
||||
i430fx->regs[0x57] = 0x01;
|
||||
i430fx->regs[0x60] = i430fx->regs[0x61] = i430fx->regs[0x62] = i430fx->regs[0x63] = 0x02;
|
||||
i430fx->regs[0x64] = 0x02;
|
||||
i430fx->regs[0x72] = 0x02;
|
||||
|
||||
pci_add_card(0, i430fx_read, i430fx_write, i430fx);
|
||||
|
||||
return i430fx;
|
||||
}
|
||||
|
||||
|
||||
const device_t i430fx_device =
|
||||
{
|
||||
"Intel SB82437FX-66",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
i430fx_init,
|
||||
i430fx_close,
|
||||
i430fx_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
machine_at_p54tp4xe_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430fx_init();
|
||||
piix3_init(7);
|
||||
fdc37c665_init();
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
pc87306_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
if (gfxcard == GFX_INTERNAL)
|
||||
device_add(&s3_phoenix_trio64_onboard_pci_device);
|
||||
if (gfxcard == GFX_INTERNAL)
|
||||
device_add(&s3_phoenix_trio64_onboard_pci_device);
|
||||
}
|
||||
|
||||
|
||||
@@ -263,83 +275,85 @@ at_endeavor_get_device(void)
|
||||
void
|
||||
machine_at_zappa_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
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);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
pc87306_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_mb500n_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
fdc37c665_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_president_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
w83877f_init();
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
i430fx_init();
|
||||
piix_init(7);
|
||||
pc87306_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Intel 430HX PCISet chip.
|
||||
*
|
||||
* Version: @(#)m_at_430hx.c 1.0.11 2018/03/18
|
||||
* Version: @(#)m_at_430hx.c 1.0.12 2018/04/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
@@ -33,297 +34,372 @@
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
static uint8_t card_i430hx[256];
|
||||
typedef struct
|
||||
{
|
||||
uint8_t regs[256];
|
||||
} i430hx_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int index;
|
||||
} acerm3a_t;
|
||||
|
||||
|
||||
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);
|
||||
switch (state & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
|
||||
card_i430hx[addr] = val;
|
||||
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 uint8_t i430hx_read(int func, int addr, void *priv)
|
||||
static void
|
||||
i430hx_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
i430hx_t *dev = (i430hx_t *) priv;
|
||||
|
||||
return card_i430hx[addr];
|
||||
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 ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i430hx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i430hx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i430hx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i430hx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i430hx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i430hx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i430hx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i430hx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i430hx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i430hx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i430hx_map(0xe4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i430hx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i430hx_map(0xec000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x72: /*SMRAM*/
|
||||
if ((dev->regs[0x72] ^ val) & 0x48)
|
||||
i430hx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
i430hx_read(int func, int addr, void *priv)
|
||||
{
|
||||
i430hx_t *dev = (i430hx_t *) priv;
|
||||
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return dev->regs[addr];
|
||||
}
|
||||
|
||||
|
||||
static void i430hx_reset(void)
|
||||
static void
|
||||
i430hx_reset(void *priv)
|
||||
{
|
||||
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);
|
||||
i430hx_write(0, 0x59, 0x00, priv);
|
||||
i430hx_write(0, 0x72, 0x02, priv);
|
||||
}
|
||||
|
||||
|
||||
static void i430hx_init(void)
|
||||
static void
|
||||
i430hx_close(void *p)
|
||||
{
|
||||
pci_add_card(0, i430hx_read, i430hx_write, NULL);
|
||||
i430hx_t *i430hx = (i430hx_t *)p;
|
||||
|
||||
i430hx_reset();
|
||||
|
||||
pci_reset_handler.pci_master_reset = i430hx_pci_reset;
|
||||
free(i430hx);
|
||||
}
|
||||
|
||||
|
||||
static int acerm3a_index;
|
||||
static void
|
||||
*i430hx_init(const device_t *info)
|
||||
{
|
||||
i430hx_t *i430hx = (i430hx_t *) malloc(sizeof(i430hx_t));
|
||||
memset(i430hx, 0, sizeof(i430hx_t));
|
||||
|
||||
i430hx->regs[0x00] = 0x86; i430hx->regs[0x01] = 0x80; /*Intel*/
|
||||
i430hx->regs[0x02] = 0x50; i430hx->regs[0x03] = 0x12; /*82439HX*/
|
||||
i430hx->regs[0x04] = 0x06; i430hx->regs[0x05] = 0x00;
|
||||
i430hx->regs[0x06] = 0x00; i430hx->regs[0x07] = 0x02;
|
||||
i430hx->regs[0x08] = 0x00; /*A0 stepping*/
|
||||
i430hx->regs[0x09] = 0x00; i430hx->regs[0x0a] = 0x00; i430hx->regs[0x0b] = 0x06;
|
||||
i430hx->regs[0x51] = 0x20;
|
||||
i430hx->regs[0x52] = 0xB5; /*512kb cache*/
|
||||
i430hx->regs[0x59] = 0x40;
|
||||
i430hx->regs[0x5A] = i430hx->regs[0x5B] = i430hx->regs[0x5C] = i430hx->regs[0x5D] = 0x44;
|
||||
i430hx->regs[0x5E] = i430hx->regs[0x5F] = 0x44;
|
||||
i430hx->regs[0x56] = 0x52; /*DRAM control*/
|
||||
i430hx->regs[0x57] = 0x01;
|
||||
i430hx->regs[0x60] = i430hx->regs[0x61] = i430hx->regs[0x62] = i430hx->regs[0x63] = 0x02;
|
||||
i430hx->regs[0x64] = i430hx->regs[0x65] = i430hx->regs[0x66] = i430hx->regs[0x67] = 0x02;
|
||||
i430hx->regs[0x68] = 0x11;
|
||||
i430hx->regs[0x72] = 0x02;
|
||||
|
||||
pci_add_card(0, i430hx_read, i430hx_write, i430hx);
|
||||
|
||||
return i430hx;
|
||||
}
|
||||
|
||||
|
||||
const device_t i430hx_device =
|
||||
{
|
||||
"Intel 82439HX",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
i430hx_init,
|
||||
i430hx_close,
|
||||
i430hx_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
acerm3a_out(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
if (port == 0xea)
|
||||
acerm3a_index = val;
|
||||
acerm3a_t *dev = (acerm3a_t *) p;
|
||||
|
||||
if (port == 0xea)
|
||||
dev->index = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
acerm3a_in(uint16_t port, void *p)
|
||||
{
|
||||
if (port == 0xeb)
|
||||
{
|
||||
switch (acerm3a_index)
|
||||
{
|
||||
case 2:
|
||||
return 0xfd;
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
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,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
machine_at_acerm3a_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430hx_init();
|
||||
piix3_init(7);
|
||||
fdc37c932fr_init();
|
||||
io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, NULL);
|
||||
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);
|
||||
device_add(&intel_flash_bxb_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_acerv35n_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430hx_init();
|
||||
piix3_init(7);
|
||||
fdc37c932fr_init();
|
||||
io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, NULL);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
i430hx_init();
|
||||
piix3_init(7);
|
||||
fdc37c669_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_p55t2p4_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430hx_init();
|
||||
piix3_init(7);
|
||||
w83877f_init();
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
i430hx_init();
|
||||
piix3_init(7);
|
||||
pc87306_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Intel 430LX and 430NX PCISet chips.
|
||||
*
|
||||
* Version: @(#)m_at_430lx_nx.c 1.0.10 2018/03/18
|
||||
* Version: @(#)m_at_430lx_nx.c 1.0.11 2018/04/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
@@ -34,217 +35,240 @@
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
static uint8_t card_i430_lx_nx[256];
|
||||
|
||||
|
||||
static void i430lx_nx_map(uint32_t addr, uint32_t size, int state)
|
||||
typedef struct
|
||||
{
|
||||
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();
|
||||
uint8_t regs[256];
|
||||
} i430lx_nx_t;
|
||||
|
||||
|
||||
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)
|
||||
static void
|
||||
i430lx_nx_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return;
|
||||
i430lx_nx_t *dev = (i430lx_nx_t *) priv;
|
||||
|
||||
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);
|
||||
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 ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i430lx_nx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
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;
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i430lx_nx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i430lx_nx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i430lx_nx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i430lx_nx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i430lx_nx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i430lx_nx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i430lx_nx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i430lx_nx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i430lx_nx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i430lx_nx_map(0xe4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i430lx_nx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i430lx_nx_map(0xec000, 0x04000, val >> 4);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t i430lx_nx_read(int func, int addr, void *priv)
|
||||
static uint8_t
|
||||
i430lx_nx_read(int func, int addr, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
i430lx_nx_t *dev = (i430lx_nx_t *) priv;
|
||||
|
||||
return card_i430_lx_nx[addr];
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return dev->regs[addr];
|
||||
}
|
||||
|
||||
|
||||
static void i430lx_nx_reset_common(void)
|
||||
static void
|
||||
i430lx_nx_reset(void *priv)
|
||||
{
|
||||
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;
|
||||
i430lx_nx_write(0, 0x59, 0x00, priv);
|
||||
}
|
||||
|
||||
|
||||
static void i430lx_reset(void)
|
||||
static void
|
||||
i430lx_nx_close(void *p)
|
||||
{
|
||||
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*/
|
||||
i430lx_nx_t *i430lx_nx = (i430lx_nx_t *)p;
|
||||
|
||||
free(i430lx_nx);
|
||||
}
|
||||
|
||||
|
||||
static void i430nx_reset(void)
|
||||
static void
|
||||
*i430lx_nx_init(const device_t *info)
|
||||
{
|
||||
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;
|
||||
i430lx_nx_t *i430lx_nx = (i430lx_nx_t *) malloc(sizeof(i430lx_nx_t));
|
||||
memset(i430lx_nx, 0, sizeof(i430lx_nx_t));
|
||||
|
||||
i430lx_nx->regs[0x00] = 0x86; i430lx_nx->regs[0x01] = 0x80; /*Intel*/
|
||||
i430lx_nx->regs[0x02] = 0xa3; i430lx_nx->regs[0x03] = 0x04; /*82434LX/NX*/
|
||||
i430lx_nx->regs[0x04] = 0x06; i430lx_nx->regs[0x05] = 0x00;
|
||||
i430lx_nx->regs[0x06] = 0x00; i430lx_nx->regs[0x07] = 0x02;
|
||||
i430lx_nx->regs[0x09] = 0x00; i430lx_nx->regs[0x0a] = 0x00; i430lx_nx->regs[0x0b] = 0x06;
|
||||
i430lx_nx->regs[0x57] = 0x31;
|
||||
i430lx_nx->regs[0x60] = i430lx_nx->regs[0x61] = i430lx_nx->regs[0x62] = i430lx_nx->regs[0x63] = 0x02;
|
||||
i430lx_nx->regs[0x64] = 0x02;
|
||||
|
||||
if (info->local == 1) {
|
||||
i430lx_nx->regs[0x08] = 0x10; /*A0 stepping*/
|
||||
i430lx_nx->regs[0x50] = 0xA0;
|
||||
i430lx_nx->regs[0x52] = 0x44; /*256kb PLB cache*/
|
||||
i430lx_nx->regs[0x66] = i430lx_nx->regs[0x67] = 0x02;
|
||||
} else {
|
||||
i430lx_nx->regs[0x08] = 0x03; /*A3 stepping*/
|
||||
i430lx_nx->regs[0x50] = 0x80;
|
||||
i430lx_nx->regs[0x52] = 0x40; /*256kb PLB cache*/
|
||||
}
|
||||
|
||||
pci_add_card(0, i430lx_nx_read, i430lx_nx_write, i430lx_nx);
|
||||
|
||||
return i430lx_nx;
|
||||
}
|
||||
|
||||
|
||||
static void i430lx_nx_pci_reset(void)
|
||||
const device_t i430lx_device =
|
||||
{
|
||||
i430lx_nx_write(0, 0x59, 0x00, NULL);
|
||||
}
|
||||
"Intel 82434LX",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
i430lx_nx_init,
|
||||
i430lx_nx_close,
|
||||
i430lx_nx_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static void i430lx_init(void)
|
||||
const device_t i430nx_device =
|
||||
{
|
||||
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;
|
||||
}
|
||||
"Intel 82434NX",
|
||||
DEVICE_PCI,
|
||||
1,
|
||||
i430lx_nx_init,
|
||||
i430lx_nx_close,
|
||||
i430lx_nx_reset,
|
||||
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_device);
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_ps2_ami_pci_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();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_batman_init(const machine_t *model)
|
||||
{
|
||||
machine_at_premiere_common_init(model);
|
||||
machine_at_premiere_common_init(model);
|
||||
|
||||
i430lx_init();
|
||||
device_add(&i430lx_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_plato_init(const machine_t *model)
|
||||
{
|
||||
machine_at_premiere_common_init(model);
|
||||
machine_at_premiere_common_init(model);
|
||||
|
||||
i430nx_init();
|
||||
device_add(&i430nx_device);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Intel 430VX PCISet chip.
|
||||
*
|
||||
* Version: @(#)m_at_430vx.c 1.0.11 2018/03/18
|
||||
* Version: @(#)m_at_430vx.c 1.0.12 2018/04/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -18,237 +18,269 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.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)
|
||||
typedef struct
|
||||
{
|
||||
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();
|
||||
uint8_t regs[256];
|
||||
} i430vx_t;
|
||||
|
||||
|
||||
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)
|
||||
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);
|
||||
i430vx_t *dev = (i430vx_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*/
|
||||
val &= 0x02;
|
||||
val |= 0x04;
|
||||
break;
|
||||
}
|
||||
|
||||
card_i430vx[addr] = val;
|
||||
case 0x05:
|
||||
val = 0;
|
||||
break;
|
||||
|
||||
case 0x06: /*Status*/
|
||||
val = 0;
|
||||
break;
|
||||
case 0x07:
|
||||
val &= 0x80;
|
||||
val |= 0x02;
|
||||
break;
|
||||
|
||||
case 0x59: /*PAM0*/
|
||||
if ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i430vx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i430vx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i430vx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i430vx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i430vx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i430vx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i430vx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i430vx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i430vx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i430vx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i430vx_map(0xe4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i430vx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i430vx_map(0xec000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x72: /*SMRAM*/
|
||||
if ((dev->regs[0x72] ^ val) & 0x48)
|
||||
i430vx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t i430vx_read(int func, int addr, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
i430vx_t *dev = (i430vx_t *) priv;
|
||||
|
||||
return card_i430vx[addr];
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return dev->regs[addr];
|
||||
}
|
||||
|
||||
|
||||
static void i430vx_reset(void)
|
||||
|
||||
static void
|
||||
i430vx_reset(void *priv)
|
||||
{
|
||||
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;
|
||||
i430vx_write(0, 0x59, 0x00, priv);
|
||||
i430vx_write(0, 0x72, 0x02, priv);
|
||||
}
|
||||
|
||||
|
||||
static void i430vx_pci_reset(void)
|
||||
|
||||
static void
|
||||
i430vx_close(void *p)
|
||||
{
|
||||
i430vx_write(0, 0x59, 0x00, NULL);
|
||||
i430vx_write(0, 0x72, 0x02, NULL);
|
||||
i430vx_t *i430vx = (i430vx_t *)p;
|
||||
|
||||
free(i430vx);
|
||||
}
|
||||
|
||||
|
||||
void i430vx_init(void)
|
||||
static void
|
||||
*i430vx_init(const device_t *info)
|
||||
{
|
||||
pci_add_card(0, i430vx_read, i430vx_write, NULL);
|
||||
|
||||
i430vx_reset();
|
||||
i430vx_t *i430vx = (i430vx_t *) malloc(sizeof(i430vx_t));
|
||||
memset(i430vx, 0, sizeof(i430vx_t));
|
||||
|
||||
pci_reset_handler.pci_master_reset = i430vx_pci_reset;
|
||||
i430vx->regs[0x00] = 0x86; i430vx->regs[0x01] = 0x80; /*Intel*/
|
||||
i430vx->regs[0x02] = 0x30; i430vx->regs[0x03] = 0x70; /*82437VX*/
|
||||
i430vx->regs[0x04] = 0x06; i430vx->regs[0x05] = 0x00;
|
||||
i430vx->regs[0x06] = 0x00; i430vx->regs[0x07] = 0x02;
|
||||
i430vx->regs[0x08] = 0x00; /*A0 stepping*/
|
||||
i430vx->regs[0x09] = 0x00; i430vx->regs[0x0a] = 0x00; i430vx->regs[0x0b] = 0x06;
|
||||
i430vx->regs[0x52] = 0x42; /*256kb PLB cache*/
|
||||
i430vx->regs[0x53] = 0x14;
|
||||
i430vx->regs[0x56] = 0x52; /*DRAM control*/
|
||||
i430vx->regs[0x57] = 0x01;
|
||||
i430vx->regs[0x60] = i430vx->regs[0x61] = i430vx->regs[0x62] = i430vx->regs[0x63] = 0x02;
|
||||
i430vx->regs[0x64] = 0x02;
|
||||
i430vx->regs[0x67] = 0x11;
|
||||
i430vx->regs[0x69] = 0x03;
|
||||
i430vx->regs[0x70] = 0x20;
|
||||
i430vx->regs[0x72] = 0x02;
|
||||
i430vx->regs[0x74] = 0x0e;
|
||||
i430vx->regs[0x78] = 0x23;
|
||||
|
||||
pci_add_card(0, i430vx_read, i430vx_write, i430vx);
|
||||
|
||||
return i430vx;
|
||||
}
|
||||
|
||||
|
||||
const device_t i430vx_device =
|
||||
{
|
||||
"Intel 82437VX",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
i430vx_init,
|
||||
i430vx_close,
|
||||
i430vx_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
machine_at_p55tvp4_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430vx_init();
|
||||
piix3_init(7);
|
||||
w83877f_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_i430vx_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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(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();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_p55va_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i430vx_init();
|
||||
piix3_init(7);
|
||||
fdc37c932fr_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(&i430vx_device);
|
||||
device_add(&piix3_device);
|
||||
fdc37c932fr_init();
|
||||
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the Intel 440FX PCISet chip.
|
||||
*
|
||||
* Version: @(#)m_at_440fx.c 1.0.11 2018/03/18
|
||||
* Version: @(#)m_at_440fx.c 1.0.12 2018/04/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
@@ -33,207 +34,239 @@
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
static uint8_t card_i440fx[256];
|
||||
|
||||
|
||||
static void i440fx_map(uint32_t addr, uint32_t size, int state)
|
||||
typedef struct
|
||||
{
|
||||
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();
|
||||
}
|
||||
uint8_t regs[256];
|
||||
} i440fx_t;
|
||||
|
||||
|
||||
static void i440fx_write(int func, int addr, uint8_t val, void *priv)
|
||||
static void
|
||||
i440fx_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
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);
|
||||
switch (state & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
|
||||
card_i440fx[addr] = val;
|
||||
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 uint8_t i440fx_read(int func, int addr, void *priv)
|
||||
static void
|
||||
i440fx_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (func)
|
||||
return 0xff;
|
||||
i440fx_t *dev = (i440fx_t *) priv;
|
||||
|
||||
return card_i440fx[addr];
|
||||
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 ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i440fx_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i440fx_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i440fx_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i440fx_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i440fx_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i440fx_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i440fx_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i440fx_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i440fx_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i440fx_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i440fx_map(0xe4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i440fx_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i440fx_map(0xec000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x72: /*SMRAM*/
|
||||
if ((dev->regs[0x72] ^ val) & 0x48)
|
||||
i440fx_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
i440fx_read(int func, int addr, void *priv)
|
||||
{
|
||||
i440fx_t *dev = (i440fx_t *) priv;
|
||||
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return dev->regs[addr];
|
||||
}
|
||||
|
||||
|
||||
static void i440fx_reset(void)
|
||||
static void
|
||||
i440fx_reset(void *priv)
|
||||
{
|
||||
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);
|
||||
i440fx_write(0, 0x59, 0x00, priv);
|
||||
i440fx_write(0, 0x72, 0x02, priv);
|
||||
}
|
||||
|
||||
|
||||
static void i440fx_init(void)
|
||||
static void
|
||||
i440fx_close(void *p)
|
||||
{
|
||||
pci_add_card(0, i440fx_read, i440fx_write, NULL);
|
||||
|
||||
i440fx_reset();
|
||||
i440fx_t *i440fx = (i440fx_t *)p;
|
||||
|
||||
pci_reset_handler.pci_master_reset = i440fx_pci_reset;
|
||||
free(i440fx);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*i440fx_init(const device_t *info)
|
||||
{
|
||||
i440fx_t *i440fx = (i440fx_t *) malloc(sizeof(i440fx_t));
|
||||
memset(i440fx, 0, sizeof(i440fx_t));
|
||||
|
||||
i440fx->regs[0x00] = 0x86; i440fx->regs[0x01] = 0x80; /*Intel*/
|
||||
i440fx->regs[0x02] = 0x37; i440fx->regs[0x03] = 0x12; /*82441FX*/
|
||||
i440fx->regs[0x04] = 0x03; i440fx->regs[0x05] = 0x01;
|
||||
i440fx->regs[0x06] = 0x80; i440fx->regs[0x07] = 0x00;
|
||||
i440fx->regs[0x08] = 0x02; /*A0 stepping*/
|
||||
i440fx->regs[0x09] = 0x00; i440fx->regs[0x0a] = 0x00; i440fx->regs[0x0b] = 0x06;
|
||||
i440fx->regs[0x0d] = 0x00;
|
||||
i440fx->regs[0x0f] = 0x00;
|
||||
i440fx->regs[0x2c] = 0xf4;
|
||||
i440fx->regs[0x2d] = 0x1a;
|
||||
i440fx->regs[0x2e] = 0x00;
|
||||
i440fx->regs[0x2f] = 0x11;
|
||||
i440fx->regs[0x50] = 0x00;
|
||||
i440fx->regs[0x51] = 0x01;
|
||||
i440fx->regs[0x52] = i440fx->regs[0x54] = i440fx->regs[0x55] = i440fx->regs[0x56] = 0x00;
|
||||
i440fx->regs[0x53] = 0x80;
|
||||
i440fx->regs[0x57] = 0x01;
|
||||
i440fx->regs[0x58] = 0x10;
|
||||
i440fx->regs[0x5a] = i440fx->regs[0x5b] = i440fx->regs[0x5c] = i440fx->regs[0x5d] = 0x11;
|
||||
i440fx->regs[0x5e] = 0x11;
|
||||
i440fx->regs[0x5f] = 0x31;
|
||||
i440fx->regs[0x72] = 0x02;
|
||||
|
||||
pci_add_card(0, i440fx_read, i440fx_write, i440fx);
|
||||
|
||||
return i440fx;
|
||||
}
|
||||
|
||||
|
||||
const device_t i440fx_device =
|
||||
{
|
||||
"Intel 82441FX",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
i440fx_init,
|
||||
i440fx_close,
|
||||
i440fx_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
machine_at_i440fx_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ps2_init(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);
|
||||
i440fx_init();
|
||||
piix3_init(7);
|
||||
fdc37c665_init();
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
i440fx_init();
|
||||
piix3_init(7);
|
||||
fdc37c665_init();
|
||||
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);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
}
|
||||
|
||||
@@ -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.0 2018/04/17
|
||||
*
|
||||
* 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,196 @@
|
||||
|
||||
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,
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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.4 2018/04/11
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -120,8 +120,8 @@
|
||||
#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"
|
||||
@@ -652,13 +652,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);
|
||||
}
|
||||
@@ -715,12 +718,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. */
|
||||
@@ -735,9 +739,6 @@ machine_europc_init(const machine_t *model)
|
||||
/* 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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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.13 2018/04/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.8 2018/04/10
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -334,7 +330,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 +363,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 +375,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 +419,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 +431,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 +448,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 +466,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 +520,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)
|
||||
{
|
||||
|
||||
1523
src/machine/m_ps1_hdc.c
Normal file
1523
src/machine/m_ps1_hdc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -1172,7 +1172,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();
|
||||
|
||||
@@ -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.5 2018/04/11
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -92,8 +92,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"
|
||||
|
||||
@@ -129,7 +129,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);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the emulated machines.
|
||||
*
|
||||
* Version: @(#)machine.c 1.0.32 2018/03/19
|
||||
* Version: @(#)machine.c 1.0.33 2018/03/26
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -31,8 +31,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"
|
||||
|
||||
|
||||
@@ -46,8 +45,6 @@ machine_init(void)
|
||||
{
|
||||
pclog("Initializing as \"%s\"\n", machine_getname());
|
||||
|
||||
ide_set_bus_master(NULL, NULL, NULL);
|
||||
|
||||
/* Set up the architecture flags. */
|
||||
AT = IS_ARCH(machine, MACHINE_AT);
|
||||
PCI = IS_ARCH(machine, MACHINE_PCI);
|
||||
@@ -68,10 +65,16 @@ void
|
||||
machine_common_init(const machine_t *model)
|
||||
{
|
||||
/* System devices first. */
|
||||
dma_init();
|
||||
pic_init();
|
||||
dma_init();
|
||||
pit_init();
|
||||
|
||||
cpu_set();
|
||||
if (AT)
|
||||
setrtcconst(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed);
|
||||
else
|
||||
setrtcconst(14318184.0);
|
||||
|
||||
if (lpt_enabled)
|
||||
lpt_init();
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the emulated machines.
|
||||
*
|
||||
* Version: @(#)machine.h 1.0.22 2018/03/18
|
||||
* Version: @(#)machine.h 1.0.23 2018/03/28
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -55,7 +55,7 @@ typedef struct _machine_ {
|
||||
} cpu[5];
|
||||
int fixed_gfxcard;
|
||||
int flags;
|
||||
int min_ram, max_ram;
|
||||
uint32_t min_ram, max_ram;
|
||||
int ram_granularity;
|
||||
int nvrmask;
|
||||
void (*init)(const struct _machine_ *);
|
||||
@@ -64,7 +64,6 @@ typedef struct _machine_ {
|
||||
#else
|
||||
void *get_device;
|
||||
#endif
|
||||
void (*nvr_close)(void);
|
||||
} machine_t;
|
||||
|
||||
|
||||
@@ -156,6 +155,12 @@ extern void machine_at_4gpv31_init(const machine_t *);
|
||||
extern void machine_pcjr_init(const machine_t *);
|
||||
|
||||
extern void machine_ps1_m2011_init(const machine_t *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern void ps1_hdc_inform(void *, void *);
|
||||
extern void ps1_set_feedback(void *);
|
||||
extern const device_t ps1_hdc_device;
|
||||
#endif
|
||||
|
||||
extern void machine_ps1_m2121_init(const machine_t *);
|
||||
extern void machine_ps1_m2133_init(const machine_t *);
|
||||
|
||||
@@ -173,8 +178,7 @@ extern void machine_amstrad_init(const machine_t *);
|
||||
|
||||
extern void machine_europc_init(const machine_t *);
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t europc_device,
|
||||
europc_hdc_device;
|
||||
extern const device_t europc_device;
|
||||
#endif
|
||||
|
||||
extern void machine_olim24_init(const machine_t *);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* NOTES: OpenAT wip for 286-class machine with open BIOS.
|
||||
* PS2_M80-486 wip, pending receipt of TRM's for machine.
|
||||
*
|
||||
* Version: @(#)machine_table.c 1.0.27 2018/03/22
|
||||
* Version: @(#)machine_table.c 1.0.28 2018/04/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -28,155 +28,146 @@
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../mem.h"
|
||||
#include "../nvr.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
const machine_t machines[] = {
|
||||
{ "[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL },
|
||||
{ "[8088] Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL, NULL },
|
||||
{ "[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL },
|
||||
{ "[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 32, 0, machine_xt_init, NULL, NULL },
|
||||
{ "[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device, NULL },
|
||||
{ "[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL },
|
||||
{ "[8088] Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL },
|
||||
{ "[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL },
|
||||
{ "[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL },
|
||||
{ "[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"Siemens",cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL, NULL },
|
||||
{ "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device, NULL },
|
||||
{ "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device, NULL },
|
||||
{ "[8088] Toshiba 1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, NULL, NULL },
|
||||
{ "[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
|
||||
{ "[8088] Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL },
|
||||
{ "[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
|
||||
{ "[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 32, 0, machine_xt_init, NULL },
|
||||
{ "[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device },
|
||||
{ "[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
|
||||
{ "[8088] Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
|
||||
{ "[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
|
||||
{ "[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
|
||||
{ "[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"Siemens",cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL },
|
||||
{ "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device },
|
||||
{ "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device },
|
||||
{ "[8088] Toshiba T1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, NULL },
|
||||
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
|
||||
{ "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL, NULL },
|
||||
{ "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL },
|
||||
#endif
|
||||
{ "[8088] Xi8088", ROM_XI8088, "xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, NULL, nvr_at_close },
|
||||
{ "[8088] Xi8088", ROM_XI8088, "xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, NULL },
|
||||
|
||||
{ "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL, nvr_at_close },
|
||||
{ "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL, nvr_at_close },
|
||||
{ "[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL, nvr_at_close },
|
||||
{ "[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL, nvr_at_close },
|
||||
{ "[8086] Amstrad PC20(0)", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL, nvr_at_close },
|
||||
{ "[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL, NULL },
|
||||
{ "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL, NULL },
|
||||
{ "[8086] Toshiba 1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, NULL, NULL },
|
||||
{ "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL },
|
||||
{ "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
|
||||
{ "[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
|
||||
{ "[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
|
||||
{ "[8086] Amstrad PC20(0)", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL },
|
||||
{ "[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL },
|
||||
{ "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL },
|
||||
{ "[8086] Toshiba T1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, NULL },
|
||||
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
|
||||
{ "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_laserxt_init, NULL, NULL },
|
||||
{ "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_laserxt_init, NULL },
|
||||
#endif
|
||||
|
||||
{ "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_neat_ami_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_compaq_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_neat_ami_init, NULL },
|
||||
{ "[286 ISA] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL },
|
||||
{ "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL },
|
||||
{ "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_compaq_init, NULL },
|
||||
#if defined(DEV_BRANCH) && defined(USE_PORTABLE3)
|
||||
{ "[286 ISA] Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 127, machine_at_compaq_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO, 640,16384, 128, 127, machine_at_compaq_init, NULL },
|
||||
#endif
|
||||
{ "[286 ISA] GW-286CT GEAR", ROM_GW286CT, "gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 512,16384, 512, 127, machine_ps1_m2011_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] IBM PS/2 model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 127, machine_at_scat_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 127, machine_at_scat_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] GW-286CT GEAR", ROM_GW286CT, "gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL },
|
||||
{ "[286 ISA] Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL },
|
||||
{ "[286 ISA] IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 63, machine_at_ibm_init, NULL },
|
||||
{ "[286 ISA] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2 | MACHINE_HDC_PS2, 512,16384, 512, 63, machine_ps1_m2011_init, NULL },
|
||||
{ "[286 ISA] IBM PS/2 model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 16, 1, 127, machine_ps2_m30_286_init, NULL },
|
||||
{ "[286 ISA] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 256,15872, 128, 127, machine_at_ibm_init, NULL },
|
||||
{ "[286 ISA] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 127, machine_at_scat_init, NULL },
|
||||
{ "[286 ISA] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 127, machine_at_scat_init, NULL },
|
||||
#ifdef WALTJE
|
||||
{ "[286 ISA] OpenAT 286", ROM_OPENAT, "open_at", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512, 4096, 128, 127, machine_at_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] OpenAT 286", ROM_OPENAT, "open_at", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512, 4096, 128, 127, machine_at_init, NULL },
|
||||
#endif
|
||||
{ "[286 ISA] Toshiba 3100e", ROM_T3100E, "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL, nvr_at_close },
|
||||
{ "[286 ISA] Toshiba T3100e", ROM_T3100E, "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL },
|
||||
|
||||
{ "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 10, 1, 63, machine_ps2_model_50_init, NULL, nvr_at_close },
|
||||
{ "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 10, 1, 63, machine_ps2_model_50_init, NULL },
|
||||
|
||||
{ "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL, nvr_at_close },
|
||||
{ "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL, nvr_at_close },
|
||||
{ "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL, nvr_at_close },
|
||||
{ "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_neat_init, NULL, nvr_at_close },
|
||||
{ "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 127, machine_ps1_m2121_init, NULL, nvr_at_close },
|
||||
{ "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 127, machine_ps1_m2121_init, NULL, nvr_at_close },
|
||||
{ "[386SX ISA] KMX-C-02", ROM_KMXC02, "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_scatsx_init, NULL, nvr_at_close },
|
||||
{ "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL },
|
||||
{ "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL },
|
||||
{ "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL },
|
||||
{ "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_neat_init, NULL },
|
||||
{ "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
|
||||
{ "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
|
||||
{ "[386SX ISA] KMX-C-02", ROM_KMXC02, "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_scatsx_init, NULL },
|
||||
|
||||
{ "[386SX MCA] IBM PS/2 model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL, nvr_at_close },
|
||||
{ "[386SX MCA] IBM PS/2 model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL },
|
||||
|
||||
{ "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL, nvr_at_close },
|
||||
{ "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL, nvr_at_close },
|
||||
{ "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL, nvr_at_close },
|
||||
{ "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL, nvr_at_close },
|
||||
{ "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL },
|
||||
{ "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL },
|
||||
{ "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL },
|
||||
{ "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL },
|
||||
#if defined(DEV_BRANCH) && defined(USE_PORTABLE3)
|
||||
{ "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL, nvr_at_close },
|
||||
#endif
|
||||
{ "[386DX MCA] IBM PS/2 model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL, nvr_at_close },
|
||||
|
||||
{ "[386DX MCA] IBM PS/2 model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 12, 1, 63, machine_ps2_model_80_init, NULL, nvr_at_close },
|
||||
|
||||
{ "[486 ISA] AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ali1429_init, NULL, nvr_at_close },
|
||||
{ "[486 ISA] AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ali1429_init, NULL, nvr_at_close },
|
||||
{ "[486 ISA] Award 486 clone", ROM_AWARD486_OPTI495, "award486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL, nvr_at_close },
|
||||
{ "[486 ISA] DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_dtk486_init, NULL, nvr_at_close },
|
||||
{ "[486 ISA] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 64, 1, 127, machine_ps1_m2133_init, NULL, nvr_at_close },
|
||||
|
||||
{ "[486 MCA] IBM PS/2 model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL, nvr_at_close },
|
||||
|
||||
#ifdef WALTJE
|
||||
{ "[486 MCA] IBM PS/2 model 80-486", ROM_IBMPS2_M80_486, "ibmps2_m80-486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 32, 1, 63, machine_ps2_model_80_486_init, NULL, nvr_at_close },
|
||||
{ "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL },
|
||||
#endif
|
||||
|
||||
{ "[486 PCI] Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL, nvr_at_close },
|
||||
{ "[386DX MCA] IBM PS/2 model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL },
|
||||
{ "[386DX MCA] IBM PS/2 model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 12, 1, 63, machine_ps2_model_80_init, NULL },
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_GREENB)
|
||||
{ "[486 VLB] Green-B 4GP V3.1", ROM_4GPV31, "4gpv31", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT, 1, 128, 1, 127, machine_at_4gpv31_init, NULL, nvr_at_close },
|
||||
#endif
|
||||
{ "[486 ISA] AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ali1429_init, NULL },
|
||||
{ "[486 ISA] AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ali1429_init, NULL },
|
||||
{ "[486 ISA] Award 486 clone", ROM_AWARD486_OPTI495, "award486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL },
|
||||
{ "[486 ISA] DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_dtk486_init, NULL },
|
||||
{ "[486 ISA] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 64, 1, 127, machine_ps1_m2133_init, NULL },
|
||||
|
||||
{ "[Socket 4 LX] Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL, nvr_at_close },
|
||||
{ "[486 MCA] IBM PS/2 model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL },
|
||||
|
||||
{ "[486 PCI] Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL },
|
||||
|
||||
{ "[Socket 4 LX] Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL },
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
|
||||
{ "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL },
|
||||
|
||||
{ "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device, nvr_at_close },
|
||||
{ "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL },
|
||||
{ "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device },
|
||||
{ "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL },
|
||||
{ "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
|
||||
{ "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL },
|
||||
|
||||
{ "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL },
|
||||
{ "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL },
|
||||
|
||||
{ "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p55t2p4_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL },
|
||||
{ "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL },
|
||||
{ "[Socket 7 HX] AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL },
|
||||
{ "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p55t2p4_init, NULL },
|
||||
{ "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL },
|
||||
|
||||
{ "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL },
|
||||
{ "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL },
|
||||
{ "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL },
|
||||
#else
|
||||
{ "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL },
|
||||
|
||||
{ "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device, nvr_at_close },
|
||||
{ "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL, nvr_at_close },
|
||||
{ "[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL },
|
||||
{ "[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device },
|
||||
{ "[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL },
|
||||
{ "[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
|
||||
{ "[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL },
|
||||
|
||||
{ "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL },
|
||||
{ "[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL },
|
||||
|
||||
{ "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p55t2p4_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL },
|
||||
{ "[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL },
|
||||
{ "[Socket 7 HX] AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL },
|
||||
{ "[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_p55t2p4_init, NULL },
|
||||
{ "[Socket 7 HX] SuperMicro Super P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL },
|
||||
|
||||
{ "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL, nvr_at_close },
|
||||
{ "[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL },
|
||||
{ "[Socket 7 VX] Award 430VX PCI", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL },
|
||||
{ "[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL },
|
||||
#endif
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
{ "[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_i440fx_init, NULL, nvr_at_close },
|
||||
{ "[Socket 8 FX] Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL, nvr_at_close },
|
||||
{ "[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_i440fx_init, NULL },
|
||||
{ "[Socket 8 FX] Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL },
|
||||
#endif
|
||||
{ "", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0 }
|
||||
{ "", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -267,11 +258,3 @@ machine_get_machine_from_internal_name(char *s)
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_close(void)
|
||||
{
|
||||
if (machines[machine].nvr_close)
|
||||
machines[machine].nvr_close();
|
||||
}
|
||||
|
||||
79
src/mem.c
79
src/mem.c
@@ -193,11 +193,11 @@ flushmmucache(void)
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (readlookup[c] != 0xffffffff) {
|
||||
if (readlookup[c] != (int) 0xffffffff) {
|
||||
readlookup2[readlookup[c]] = -1;
|
||||
readlookup[c] = 0xffffffff;
|
||||
}
|
||||
if (writelookup[c] != 0xffffffff) {
|
||||
if (writelookup[c] != (int) 0xffffffff) {
|
||||
page_lookup[writelookup[c]] = NULL;
|
||||
writelookup2[writelookup[c]] = -1;
|
||||
writelookup[c] = 0xffffffff;
|
||||
@@ -220,11 +220,11 @@ flushmmucache_nopc(void)
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (readlookup[c] != 0xffffffff) {
|
||||
if (readlookup[c] != (int) 0xffffffff) {
|
||||
readlookup2[readlookup[c]] = -1;
|
||||
readlookup[c] = 0xffffffff;
|
||||
}
|
||||
if (writelookup[c] != 0xffffffff) {
|
||||
if (writelookup[c] != (int) 0xffffffff) {
|
||||
page_lookup[writelookup[c]] = NULL;
|
||||
writelookup2[writelookup[c]] = -1;
|
||||
writelookup[c] = 0xffffffff;
|
||||
@@ -239,11 +239,11 @@ flushmmucache_cr3(void)
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (readlookup[c] != 0xffffffff) {
|
||||
if (readlookup[c] != (int) 0xffffffff) {
|
||||
readlookup2[readlookup[c]] = -1;
|
||||
readlookup[c] = 0xffffffff;
|
||||
}
|
||||
if (writelookup[c] != 0xffffffff) {
|
||||
if (writelookup[c] != (int) 0xffffffff) {
|
||||
page_lookup[writelookup[c]] = NULL;
|
||||
writelookup2[writelookup[c]] = -1;
|
||||
writelookup[c] = 0xffffffff;
|
||||
@@ -259,7 +259,7 @@ mem_flush_write_page(uint32_t addr, uint32_t virt)
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
if (writelookup[c] != 0xffffffff) {
|
||||
if (writelookup[c] != (int) 0xffffffff) {
|
||||
uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)];
|
||||
|
||||
if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) {
|
||||
@@ -403,9 +403,9 @@ addreadlookup(uint32_t virt, uint32_t phys)
|
||||
{
|
||||
if (virt == 0xffffffff) return;
|
||||
|
||||
if (readlookup2[virt>>12] != -1) return;
|
||||
if (readlookup2[virt>>12] != (uintptr_t) -1) return;
|
||||
|
||||
if (readlookup[readlnext] != 0xffffffff)
|
||||
if (readlookup[readlnext] != (int) 0xffffffff)
|
||||
readlookup2[readlookup[readlnext]] = -1;
|
||||
|
||||
readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)];
|
||||
@@ -496,7 +496,7 @@ readmembl(uint32_t addr)
|
||||
|
||||
if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
|
||||
addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
|
||||
if(addr < mem_size * 1024) return ram[addr];
|
||||
if(addr < (uint32_t) (mem_size * 1024)) return ram[addr];
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ writemembl(uint32_t addr, uint8_t val)
|
||||
|
||||
if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
|
||||
addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
|
||||
if (addr < mem_size * 1024)
|
||||
if (addr < (uint32_t) (mem_size * 1024))
|
||||
ram[addr] = val;
|
||||
return;
|
||||
}
|
||||
@@ -545,7 +545,7 @@ writemembl(uint32_t addr, uint8_t val)
|
||||
|
||||
uint8_t
|
||||
readmemb386l(uint32_t seg, uint32_t addr)
|
||||
{
|
||||
{
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
|
||||
@@ -554,7 +554,7 @@ readmemb386l(uint32_t seg, uint32_t addr)
|
||||
|
||||
mem_logical_addr = addr = addr + seg;
|
||||
if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
|
||||
addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
|
||||
addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
|
||||
if (addr < (uint32_t) (mem_size * 1024))
|
||||
return ram[addr];
|
||||
return 0xff;
|
||||
@@ -577,7 +577,7 @@ readmemb386l(uint32_t seg, uint32_t addr)
|
||||
|
||||
void
|
||||
writememb386l(uint32_t seg, uint32_t addr, uint8_t val)
|
||||
{
|
||||
{
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
return;
|
||||
@@ -585,7 +585,7 @@ writememb386l(uint32_t seg, uint32_t addr, uint8_t val)
|
||||
|
||||
mem_logical_addr = addr = addr + seg;
|
||||
if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) {
|
||||
addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
|
||||
addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff);
|
||||
if (addr < (uint32_t) (mem_size * 1024))
|
||||
ram[addr] = val;
|
||||
return;
|
||||
@@ -613,7 +613,7 @@ readmemwl(uint32_t seg, uint32_t addr)
|
||||
readmemwl(uint32_t seg, uint32_t addr)
|
||||
{
|
||||
uint32_t addr2 = mem_logical_addr = seg + addr;
|
||||
|
||||
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
return -1;
|
||||
@@ -626,16 +626,16 @@ readmemwl(uint32_t seg, uint32_t addr)
|
||||
if (cr0 >> 31) {
|
||||
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff;
|
||||
if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff;
|
||||
}
|
||||
if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8);
|
||||
}
|
||||
if (is386) return readmemb386l(seg,addr)|(((uint16_t) readmemb386l(seg,addr+1))<<8);
|
||||
else return readmembl(seg+addr)|(((uint16_t) readmembl(seg+addr+1))<<8);
|
||||
}
|
||||
}
|
||||
else if (readlookup2[addr2 >> 12] != (uintptr_t) -1)
|
||||
return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2);
|
||||
}
|
||||
|
||||
if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) {
|
||||
addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
|
||||
addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff);
|
||||
if (addr < (uint32_t) (mem_size * 1024))
|
||||
return *((uint16_t *)&ram[addr]);
|
||||
return 0xffff;
|
||||
@@ -653,9 +653,11 @@ readmemwl(uint32_t seg, uint32_t addr)
|
||||
return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
|
||||
|
||||
if (_mem_read_b[addr2 >> 14]) {
|
||||
if (AT)
|
||||
if (AT)
|
||||
return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) |
|
||||
((uint16_t) (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14])) << 8);
|
||||
else
|
||||
else
|
||||
return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) |
|
||||
((uint16_t) (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14])) << 8);
|
||||
}
|
||||
|
||||
@@ -667,7 +669,7 @@ writememwl(uint32_t seg, uint32_t addr, uint16_t val)
|
||||
writememwl(uint32_t seg, uint32_t addr, uint16_t val)
|
||||
{
|
||||
uint32_t addr2 = mem_logical_addr = seg + addr;
|
||||
|
||||
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
return;
|
||||
@@ -695,7 +697,7 @@ writememwl(uint32_t seg, uint32_t addr, uint16_t val)
|
||||
writemembl(seg+addr,val);
|
||||
writemembl(seg+addr+1,val>>8);
|
||||
}
|
||||
return;
|
||||
return;
|
||||
} else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) {
|
||||
*(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val;
|
||||
return;
|
||||
@@ -736,7 +738,7 @@ readmemll(uint32_t seg, uint32_t addr)
|
||||
readmemll(uint32_t seg, uint32_t addr)
|
||||
{
|
||||
uint32_t addr2 = mem_logical_addr = seg + addr;
|
||||
|
||||
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
return -1;
|
||||
@@ -757,7 +759,7 @@ readmemll(uint32_t seg, uint32_t addr)
|
||||
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
|
||||
if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff;
|
||||
}
|
||||
return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16);
|
||||
return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16);
|
||||
} else if (readlookup2[addr2 >> 12] != (uintptr_t) -1)
|
||||
return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2);
|
||||
}
|
||||
@@ -773,10 +775,14 @@ readmemll(uint32_t seg, uint32_t addr)
|
||||
if (_mem_read_l[addr2 >> 14])
|
||||
return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]);
|
||||
|
||||
if (_mem_read_w[addr2 >> 14])
|
||||
if (_mem_read_w[addr2 >> 14])
|
||||
return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) |
|
||||
((uint32_t) (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14])) << 16);
|
||||
|
||||
if (_mem_read_b[addr2 >> 14])
|
||||
if (_mem_read_b[addr2 >> 14])
|
||||
return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) |
|
||||
((uint32_t) (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14])) << 8) |
|
||||
((uint32_t) (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14])) << 16) |
|
||||
((uint32_t) (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14])) << 24);
|
||||
|
||||
return 0xffffffff;
|
||||
@@ -787,7 +793,7 @@ writememll(uint32_t seg, uint32_t addr, uint32_t val)
|
||||
writememll(uint32_t seg, uint32_t addr, uint32_t val)
|
||||
{
|
||||
uint32_t addr2 = mem_logical_addr = seg + addr;
|
||||
|
||||
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
return;
|
||||
@@ -810,7 +816,7 @@ writememll(uint32_t seg, uint32_t addr, uint32_t val)
|
||||
}
|
||||
writememwl(seg,addr,val);
|
||||
writememwl(seg,addr+2,val>>16);
|
||||
return;
|
||||
return;
|
||||
} else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) {
|
||||
*(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val;
|
||||
return;
|
||||
@@ -852,7 +858,7 @@ readmemql(uint32_t seg, uint32_t addr)
|
||||
readmemql(uint32_t seg, uint32_t addr)
|
||||
{
|
||||
uint32_t addr2 = mem_logical_addr = seg + addr;
|
||||
|
||||
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
return -1;
|
||||
@@ -872,7 +878,7 @@ readmemql(uint32_t seg, uint32_t addr)
|
||||
if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff;
|
||||
if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff;
|
||||
}
|
||||
return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32);
|
||||
return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32);
|
||||
} else if (readlookup2[addr2 >> 12] != (uintptr_t) -1)
|
||||
return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2);
|
||||
}
|
||||
@@ -897,7 +903,7 @@ writememql(uint32_t seg, uint32_t addr, uint64_t val)
|
||||
writememql(uint32_t seg, uint32_t addr, uint64_t val)
|
||||
{
|
||||
uint32_t addr2 = mem_logical_addr = seg + addr;
|
||||
|
||||
|
||||
if (seg == (uint32_t) -1) {
|
||||
x86gpf("NULL segment", 0);
|
||||
return;
|
||||
@@ -919,7 +925,7 @@ writememql(uint32_t seg, uint32_t addr, uint64_t val)
|
||||
}
|
||||
writememll(seg, addr, val);
|
||||
writememll(seg, addr+4, val >> 32);
|
||||
return;
|
||||
return;
|
||||
} else if (writelookup2[addr2 >> 12] != (uintptr_t) -1) {
|
||||
*(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val;
|
||||
return;
|
||||
@@ -1278,6 +1284,7 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
|
||||
for (c = base; c < base + size; c += 0x4000) {
|
||||
_mem_read_b[c >> 14] = NULL;
|
||||
_mem_read_w[c >> 14] = NULL;
|
||||
_mem_read_l[c >> 14] = NULL;
|
||||
_mem_exec[c >> 14] = NULL;
|
||||
_mem_priv_r[c >> 14] = NULL;
|
||||
_mem_mapping_r[c >> 14] = NULL;
|
||||
@@ -1760,7 +1767,7 @@ mem_init(void)
|
||||
|
||||
|
||||
static void
|
||||
mem_remap_top(int max_size)
|
||||
mem_remap_top(int max_size)
|
||||
{
|
||||
uint32_t c;
|
||||
|
||||
@@ -1799,7 +1806,7 @@ mem_remap_top_384k(void)
|
||||
|
||||
|
||||
void
|
||||
mem_reset_page_blocks(void)
|
||||
mem_reset_page_blocks(void)
|
||||
{
|
||||
uint32_t c;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <pcap/pcap.h>
|
||||
// #include <pcap/pcap.h>
|
||||
#include "../86box.h"
|
||||
#include "../config.h"
|
||||
#include "../device.h"
|
||||
@@ -58,8 +58,53 @@
|
||||
#include "network.h"
|
||||
|
||||
|
||||
typedef int bpf_int32;
|
||||
typedef unsigned int bpf_u_int32;
|
||||
|
||||
/*
|
||||
* The instruction data structure.
|
||||
*/
|
||||
struct bpf_insn {
|
||||
unsigned short code;
|
||||
unsigned char jt;
|
||||
unsigned char jf;
|
||||
bpf_u_int32 k;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
|
||||
*/
|
||||
struct bpf_program {
|
||||
unsigned int bf_len;
|
||||
struct bpf_insn *bf_insns;
|
||||
};
|
||||
|
||||
typedef struct pcap_if pcap_if_t;
|
||||
|
||||
typedef struct timeval {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
} timeval;
|
||||
|
||||
#define PCAP_ERRBUF_SIZE 256
|
||||
|
||||
struct pcap_pkthdr {
|
||||
struct timeval ts;
|
||||
bpf_u_int32 caplen;
|
||||
bpf_u_int32 len;
|
||||
};
|
||||
|
||||
struct pcap_if {
|
||||
struct pcap_if *next;
|
||||
char *name;
|
||||
char *description;
|
||||
void *addresses;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
|
||||
static volatile void *pcap_handle; /* handle to WinPcap DLL */
|
||||
static volatile pcap_t *pcap; /* handle to WinPcap library */
|
||||
static volatile void *pcap; /* handle to WinPcap library */
|
||||
static volatile thread_t *poll_tid;
|
||||
static const netcard_t *poll_card; /* netcard linked to us */
|
||||
static event_t *poll_state;
|
||||
@@ -68,14 +113,15 @@ static event_t *poll_state;
|
||||
/* Pointers to the real functions. */
|
||||
static const char *(*f_pcap_lib_version)(void);
|
||||
static int (*f_pcap_findalldevs)(pcap_if_t **,char *);
|
||||
static void (*f_pcap_freealldevs)(pcap_if_t *);
|
||||
static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *);
|
||||
static int (*f_pcap_compile)(pcap_t *,struct bpf_program *,
|
||||
static void (*f_pcap_freealldevs)(void *);
|
||||
static void *(*f_pcap_open_live)(const char *,int,int,int,char *);
|
||||
static int (*f_pcap_compile)(void *,void *,
|
||||
const char *,int,bpf_u_int32);
|
||||
static int (*f_pcap_setfilter)(pcap_t *,struct bpf_program *);
|
||||
static const u_char *(*f_pcap_next)(pcap_t *,struct pcap_pkthdr *);
|
||||
static int (*f_pcap_sendpacket)(pcap_t *,const u_char *,int);
|
||||
static void (*f_pcap_close)(pcap_t *);
|
||||
static int (*f_pcap_setfilter)(void *,void *);
|
||||
static const unsigned char
|
||||
*(*f_pcap_next)(void *,void *);
|
||||
static int (*f_pcap_sendpacket)(void *,const unsigned char *,int);
|
||||
static void (*f_pcap_close)(void *);
|
||||
static dllimp_t pcap_imports[] = {
|
||||
{ "pcap_lib_version", &f_pcap_lib_version },
|
||||
{ "pcap_findalldevs", &f_pcap_findalldevs },
|
||||
@@ -118,7 +164,7 @@ poll_thread(void *arg)
|
||||
if (pcap == NULL) break;
|
||||
|
||||
/* Wait for the next packet to arrive. */
|
||||
data = (uint8_t *)f_pcap_next((pcap_t *)pcap, &h);
|
||||
data = (uint8_t *)f_pcap_next((void *)pcap, &h);
|
||||
if (data != NULL) {
|
||||
/* Received MAC. */
|
||||
mac_cmp32[0] = *(uint32_t *)(data+6);
|
||||
@@ -251,14 +297,14 @@ net_pcap_init(void)
|
||||
void
|
||||
net_pcap_close(void)
|
||||
{
|
||||
pcap_t *pc;
|
||||
void *pc;
|
||||
|
||||
if (pcap == NULL) return;
|
||||
|
||||
pclog("PCAP: closing.\n");
|
||||
|
||||
/* Tell the polling thread to shut down. */
|
||||
pc = (pcap_t *)pcap; pcap = NULL;
|
||||
pc = (void *)pcap; pcap = NULL;
|
||||
|
||||
/* Tell the thread to terminate. */
|
||||
if (poll_tid != NULL) {
|
||||
@@ -326,15 +372,15 @@ net_pcap_reset(const netcard_t *card, uint8_t *mac)
|
||||
"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
if (f_pcap_compile((pcap_t *)pcap, &fp, filter_exp, 0, 0xffffffff) != -1) {
|
||||
if (f_pcap_setfilter((pcap_t *)pcap, &fp) != 0) {
|
||||
if (f_pcap_compile((void *)pcap, &fp, filter_exp, 0, 0xffffffff) != -1) {
|
||||
if (f_pcap_setfilter((void *)pcap, &fp) != 0) {
|
||||
pclog("PCAP: error installing filter (%s) !\n", filter_exp);
|
||||
f_pcap_close((pcap_t *)pcap);
|
||||
f_pcap_close((void *)pcap);
|
||||
return(-1);
|
||||
}
|
||||
} else {
|
||||
pclog("PCAP: could not compile filter (%s) !\n", filter_exp);
|
||||
f_pcap_close((pcap_t *)pcap);
|
||||
f_pcap_close((void *)pcap);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -358,7 +404,7 @@ net_pcap_in(uint8_t *bufp, int len)
|
||||
|
||||
network_busy(1);
|
||||
|
||||
f_pcap_sendpacket((pcap_t *)pcap, bufp, len);
|
||||
f_pcap_sendpacket((void *)pcap, bufp, len);
|
||||
|
||||
network_busy(0);
|
||||
}
|
||||
|
||||
315
src/nvr.c
315
src/nvr.c
@@ -8,9 +8,7 @@
|
||||
*
|
||||
* Implement a generic NVRAM/CMOS/RTC device.
|
||||
*
|
||||
* NOTE: I should re-do 'intclk' using a TM struct.
|
||||
*
|
||||
* Version: @(#)nvr.c 1.0.3 2018/03/19
|
||||
* Version: @(#)nvr.c 1.0.6 2018/04/11
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -65,23 +63,11 @@
|
||||
#include "nvr.h"
|
||||
|
||||
|
||||
/* Define the internal clock. */
|
||||
typedef struct {
|
||||
int16_t year;
|
||||
int8_t sec;
|
||||
int8_t min;
|
||||
int8_t hour;
|
||||
int8_t mday;
|
||||
int8_t mon;
|
||||
} intclk_t;
|
||||
|
||||
|
||||
int enable_sync; /* configuration variable: enable time sync */
|
||||
int nvr_dosave; /* NVR is dirty, needs saved */
|
||||
|
||||
|
||||
static int8_t days_in_month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
|
||||
static intclk_t intclk;
|
||||
static struct tm intclk;
|
||||
static nvr_t *saved_nvr = NULL;
|
||||
|
||||
|
||||
@@ -113,25 +99,23 @@ static void
|
||||
rtc_tick(void)
|
||||
{
|
||||
/* Ping the internal clock. */
|
||||
if (++intclk.sec == 60) {
|
||||
intclk.sec = 0;
|
||||
intclk.min++;
|
||||
}
|
||||
if (intclk.min == 60) {
|
||||
intclk.min = 0;
|
||||
intclk.hour++;
|
||||
}
|
||||
if (intclk.hour == 24) {
|
||||
intclk.hour = 0;
|
||||
intclk.mday++;
|
||||
}
|
||||
if (intclk.mday == (nvr_get_days(intclk.mon, intclk.year) + 1)) {
|
||||
intclk.mday = 1;
|
||||
intclk.mon++;
|
||||
}
|
||||
if (intclk.mon == 13) {
|
||||
intclk.mon = 1;
|
||||
intclk.year++;
|
||||
if (++intclk.tm_sec == 60) {
|
||||
intclk.tm_sec = 0;
|
||||
if (++intclk.tm_min == 60) {
|
||||
intclk.tm_min = 0;
|
||||
if (++intclk.tm_hour == 24) {
|
||||
intclk.tm_hour = 0;
|
||||
if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon,
|
||||
intclk.tm_year) + 1)) {
|
||||
intclk.tm_mday = 1;
|
||||
intclk.tm_mon++;
|
||||
if (++intclk.tm_mon == 13) {
|
||||
intclk.tm_mon = 1;
|
||||
intclk.tm_year++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,9 +152,9 @@ nvr_init(nvr_t *nvr)
|
||||
|
||||
/* Set up the NVR file's name. */
|
||||
sprintf(temp, "%s.nvr", machine_get_internal_name());
|
||||
c = strlen(temp)+1;
|
||||
nvr->fn = (wchar_t *)malloc(c*sizeof(wchar_t));
|
||||
mbstowcs(nvr->fn, temp, c);
|
||||
c = strlen(temp);
|
||||
nvr->fn = (wchar_t *)malloc((c + 1) * sizeof(wchar_t));
|
||||
mbstowcs(nvr->fn, temp, c + 1);
|
||||
|
||||
/* Initialize the internal clock as needed. */
|
||||
memset(&intclk, 0x00, sizeof(intclk));
|
||||
@@ -183,8 +167,8 @@ nvr_init(nvr_t *nvr)
|
||||
nvr_time_set(tm);
|
||||
} else {
|
||||
/* Reset the internal clock to 1980/01/01 00:00. */
|
||||
intclk.mon = 1;
|
||||
intclk.year = 1980;
|
||||
intclk.tm_mon = 1;
|
||||
intclk.tm_year = 1980;
|
||||
}
|
||||
|
||||
/* Set up our timer. */
|
||||
@@ -201,124 +185,7 @@ nvr_init(nvr_t *nvr)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load an NVR from file.
|
||||
*
|
||||
* This function does two things, really. It clears and initializes
|
||||
* the RTC and NVRAM areas, sets up defaults for the RTC part, and
|
||||
* then attempts to load data from a saved file.
|
||||
*
|
||||
* Either way, after that, it will continue to configure the local
|
||||
* RTC to operate, so it can update either the local RTC, and/or
|
||||
* the one supplied by a client.
|
||||
*/
|
||||
int
|
||||
nvr_load(void)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
/* Make sure we have been initialized. */
|
||||
if (saved_nvr == NULL) return(0);
|
||||
|
||||
/* Clear out any old data. */
|
||||
memset(saved_nvr->regs, 0xff, sizeof(saved_nvr->regs));
|
||||
|
||||
/* Set the defaults. */
|
||||
if (saved_nvr->reset != NULL)
|
||||
saved_nvr->reset(saved_nvr);
|
||||
|
||||
/* Load the (relevant) part of the NVR contents. */
|
||||
if (saved_nvr->size != 0) {
|
||||
pclog("NVR: loading from '%ls'\n", nvr_path(saved_nvr->fn));
|
||||
f = plat_fopen(nvr_path(saved_nvr->fn), L"rb");
|
||||
if (f != NULL) {
|
||||
/* Read NVR contents from file. */
|
||||
(void)fread(saved_nvr->regs, saved_nvr->size, 1, f);
|
||||
(void)fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
if (romset == ROM_T1000)
|
||||
t1000_nvr_load();
|
||||
else if (romset == ROM_T1200)
|
||||
t1200_nvr_load();
|
||||
|
||||
/* Get the local RTC running! */
|
||||
if (saved_nvr->start != NULL)
|
||||
saved_nvr->start(saved_nvr);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Save the current NVR to a file. */
|
||||
int
|
||||
nvr_save(void)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
/* Make sure we have been initialized. */
|
||||
if (saved_nvr == NULL) return(0);
|
||||
|
||||
if (saved_nvr->size != 0) {
|
||||
pclog("NVR: saving to '%ls'\n", nvr_path(saved_nvr->fn));
|
||||
f = plat_fopen(nvr_path(saved_nvr->fn), L"wb");
|
||||
if (f != NULL) {
|
||||
/* Save NVR contents to file. */
|
||||
(void)fwrite(saved_nvr->regs, saved_nvr->size, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
if (romset == ROM_T1000)
|
||||
t1000_nvr_save();
|
||||
else if (romset == ROM_T1200)
|
||||
t1200_nvr_save();
|
||||
|
||||
/* Device is clean again. */
|
||||
nvr_dosave = 0;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Get current time from internal clock. */
|
||||
void
|
||||
nvr_time_get(struct tm *tm)
|
||||
{
|
||||
int8_t dom, mon, sum, wd;
|
||||
int16_t cent, yr;
|
||||
|
||||
tm->tm_sec = intclk.sec;
|
||||
tm->tm_min = intclk.min;
|
||||
tm->tm_hour = intclk.hour;
|
||||
dom = intclk.mday;
|
||||
mon = intclk.mon;
|
||||
yr = (intclk.year % 100);
|
||||
cent = ((intclk.year - yr) / 100) % 4;
|
||||
sum = dom+mon+yr+cent;
|
||||
wd = ((sum + 6) % 7);
|
||||
tm->tm_wday = wd;
|
||||
tm->tm_mday = intclk.mday;
|
||||
tm->tm_mon = (intclk.mon - 1);
|
||||
tm->tm_year = (intclk.year - 1900);
|
||||
}
|
||||
|
||||
|
||||
/* Set internal clock time. */
|
||||
void
|
||||
nvr_time_set(struct tm *tm)
|
||||
{
|
||||
intclk.sec = tm->tm_sec;
|
||||
intclk.min = tm->tm_min;
|
||||
intclk.hour = tm->tm_hour;
|
||||
intclk.mday = tm->tm_mday;
|
||||
intclk.mon = (tm->tm_mon + 1);
|
||||
intclk.year = (tm->tm_year + 1900);
|
||||
}
|
||||
|
||||
|
||||
/* Get an absolute path to the NVR folder. */
|
||||
/* Get path to the NVR folder. */
|
||||
wchar_t *
|
||||
nvr_path(wchar_t *str)
|
||||
{
|
||||
@@ -341,6 +208,138 @@ nvr_path(wchar_t *str)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load an NVR from file.
|
||||
*
|
||||
* This function does two things, really. It clears and initializes
|
||||
* the RTC and NVRAM areas, sets up defaults for the RTC part, and
|
||||
* then attempts to load data from a saved file.
|
||||
*
|
||||
* Either way, after that, it will continue to configure the local
|
||||
* RTC to operate, so it can update either the local RTC, and/or
|
||||
* the one supplied by a client.
|
||||
*/
|
||||
int
|
||||
nvr_load(void)
|
||||
{
|
||||
wchar_t *path;
|
||||
FILE *fp;
|
||||
|
||||
/* Make sure we have been initialized. */
|
||||
if (saved_nvr == NULL) return(0);
|
||||
|
||||
/* Clear out any old data. */
|
||||
memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs));
|
||||
|
||||
/* Set the defaults. */
|
||||
if (saved_nvr->reset != NULL)
|
||||
saved_nvr->reset(saved_nvr);
|
||||
|
||||
/* Load the (relevant) part of the NVR contents. */
|
||||
if (saved_nvr->size != 0) {
|
||||
path = nvr_path(saved_nvr->fn);
|
||||
pclog("NVR: loading from '%ls'\n", path);
|
||||
fp = plat_fopen(path, L"rb");
|
||||
if (fp != NULL) {
|
||||
/* Read NVR contents from file. */
|
||||
(void)fread(saved_nvr->regs, saved_nvr->size, 1, fp);
|
||||
(void)fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
if (romset == ROM_T1000)
|
||||
t1000_nvr_load();
|
||||
else if (romset == ROM_T1200)
|
||||
t1200_nvr_load();
|
||||
|
||||
/* Get the local RTC running! */
|
||||
if (saved_nvr->start != NULL)
|
||||
saved_nvr->start(saved_nvr);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Save the current NVR to a file. */
|
||||
int
|
||||
nvr_save(void)
|
||||
{
|
||||
wchar_t *path;
|
||||
FILE *fp;
|
||||
|
||||
/* Make sure we have been initialized. */
|
||||
if (saved_nvr == NULL) return(0);
|
||||
|
||||
if (saved_nvr->size != 0) {
|
||||
path = nvr_path(saved_nvr->fn);
|
||||
pclog("NVR: saving to '%ls'\n", path);
|
||||
fp = plat_fopen(path, L"wb");
|
||||
if (fp != NULL) {
|
||||
/* Save NVR contents to file. */
|
||||
(void)fwrite(saved_nvr->regs, saved_nvr->size, 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
if (romset == ROM_T1000)
|
||||
t1000_nvr_save();
|
||||
else if (romset == ROM_T1200)
|
||||
t1200_nvr_save();
|
||||
|
||||
/* Device is clean again. */
|
||||
nvr_dosave = 0;
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nvr_period_recalc(void)
|
||||
{
|
||||
/* Make sure we have been initialized. */
|
||||
if (saved_nvr == NULL) return;
|
||||
|
||||
if (saved_nvr->size != 0)
|
||||
saved_nvr->recalc(saved_nvr);
|
||||
}
|
||||
|
||||
|
||||
/* Get current time from internal clock. */
|
||||
void
|
||||
nvr_time_get(struct tm *tm)
|
||||
{
|
||||
int8_t dom, mon, sum, wd;
|
||||
int16_t cent, yr;
|
||||
|
||||
tm->tm_sec = intclk.tm_sec;
|
||||
tm->tm_min = intclk.tm_min;
|
||||
tm->tm_hour = intclk.tm_hour;
|
||||
dom = intclk.tm_mday;
|
||||
mon = intclk.tm_mon;
|
||||
yr = (intclk.tm_year % 100);
|
||||
cent = ((intclk.tm_year - yr) / 100) % 4;
|
||||
sum = dom+mon+yr+cent;
|
||||
wd = ((sum + 6) % 7);
|
||||
tm->tm_wday = wd;
|
||||
tm->tm_mday = intclk.tm_mday;
|
||||
tm->tm_mon = (intclk.tm_mon - 1);
|
||||
tm->tm_year = (intclk.tm_year - 1900);
|
||||
}
|
||||
|
||||
|
||||
/* Set internal clock time. */
|
||||
void
|
||||
nvr_time_set(struct tm *tm)
|
||||
{
|
||||
intclk.tm_sec = tm->tm_sec;
|
||||
intclk.tm_min = tm->tm_min;
|
||||
intclk.tm_hour = tm->tm_hour;
|
||||
intclk.tm_mday = tm->tm_mday;
|
||||
intclk.tm_mon = (tm->tm_mon + 1);
|
||||
intclk.tm_year = (tm->tm_year + 1900);
|
||||
}
|
||||
|
||||
|
||||
/* Open or create a file in the NVR area. */
|
||||
FILE *
|
||||
nvr_fopen(wchar_t *str, wchar_t *mode)
|
||||
|
||||
34
src/nvr.h
34
src/nvr.h
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the generic NVRAM/CMOS driver.
|
||||
*
|
||||
* Version: @(#)nvr.h 1.0.2 2018/03/11
|
||||
* Version: @(#)nvr.h 1.0.6 2018/04/11
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -58,29 +58,36 @@
|
||||
|
||||
/* Define a generic RTC/NVRAM device. */
|
||||
typedef struct _nvr_ {
|
||||
uint8_t regs[NVR_MAXSIZE]; /* these are the registers */
|
||||
wchar_t *fn;
|
||||
/* pathname of image file */
|
||||
wchar_t *fn; /* pathname of image file */
|
||||
uint16_t size; /* device configuration */
|
||||
int8_t irq;
|
||||
|
||||
int8_t irq;
|
||||
|
||||
int8_t upd_stat, /* FIXME: move to private struct */
|
||||
addr;
|
||||
int64_t upd_ecount, /* FIXME: move to private struct */
|
||||
onesec_time,
|
||||
uint8_t onesec_cnt;
|
||||
int64_t onesec_time;
|
||||
|
||||
void *data; /* local data */
|
||||
|
||||
/* Hooks to device functions. */
|
||||
void (*reset)(struct _nvr_ *);
|
||||
void (*start)(struct _nvr_ *);
|
||||
void (*tick)(struct _nvr_ *);
|
||||
void (*recalc)(struct _nvr_ *);
|
||||
|
||||
uint8_t regs[NVR_MAXSIZE]; /* these are the registers */
|
||||
} nvr_t;
|
||||
|
||||
|
||||
extern int nvr_dosave;
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t at_nvr_device;
|
||||
extern const device_t ps_nvr_device;
|
||||
extern const device_t amstrad_nvr_device;
|
||||
#endif
|
||||
|
||||
|
||||
extern void nvr_init(nvr_t *);
|
||||
extern wchar_t *nvr_path(wchar_t *str);
|
||||
extern FILE *nvr_fopen(wchar_t *str, wchar_t *mode);
|
||||
extern int nvr_load(void);
|
||||
extern int nvr_save(void);
|
||||
|
||||
@@ -88,12 +95,7 @@ extern int nvr_is_leap(int year);
|
||||
extern int nvr_get_days(int month, int year);
|
||||
extern void nvr_time_get(struct tm *);
|
||||
extern void nvr_time_set(struct tm *);
|
||||
extern void nvr_time_get(struct tm *);
|
||||
extern void nvr_time_set(struct tm *);
|
||||
|
||||
extern wchar_t *nvr_path(wchar_t *str);
|
||||
extern FILE *nvr_fopen(wchar_t *str, wchar_t *mode);
|
||||
|
||||
extern void nvr_period_recalc(void);
|
||||
|
||||
|
||||
#endif /*EMU_NVR_H*/
|
||||
|
||||
311
src/nvr_at.c
311
src/nvr_at.c
@@ -189,7 +189,7 @@
|
||||
* including the later update (DS12887A) which implemented a
|
||||
* "century" register to be compatible with Y2K.
|
||||
*
|
||||
* Version: @(#)nvr_at.c 1.0.3 2018/03/11
|
||||
* Version: @(#)nvr_at.c 1.0.5 2018/04/09
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -218,6 +218,7 @@
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -228,19 +229,20 @@
|
||||
#include "cpu/cpu.h"
|
||||
#include "machine/machine.h"
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
#include "mem.h"
|
||||
#include "nmi.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
#include "rom.h"
|
||||
#include "timer.h"
|
||||
#include "device.h"
|
||||
#include "nvr.h"
|
||||
#include "rom.h"
|
||||
|
||||
|
||||
/* RTC registers and bit definitions. */
|
||||
#define RTC_SECONDS 0
|
||||
#define RTC_ALSECONDS 1
|
||||
# define AL_DONTCARE 0xc0 /* Alarm time is not set */
|
||||
#define RTC_MINUTES 2
|
||||
#define RTC_ALMINUTES 3
|
||||
#define RTC_HOURS 4
|
||||
@@ -277,43 +279,53 @@
|
||||
# define REGC_UF 0x10
|
||||
#define RTC_REGD 13
|
||||
# define REGD_VRT 0x80
|
||||
#define RTC_CENTURY 0x32 /* century register */
|
||||
#define RTC_CENTURY_AT 0x32 /* century register for AT etc */
|
||||
#define RTC_CENTURY_PS 0x37 /* century register for PS/1 PS/2 */
|
||||
#define RTC_REGS 14 /* number of registers */
|
||||
|
||||
|
||||
static nvr_t *nvrp;
|
||||
typedef struct {
|
||||
int8_t stat;
|
||||
uint8_t cent;
|
||||
|
||||
uint16_t addr;
|
||||
|
||||
int64_t ecount,
|
||||
rtctime;
|
||||
} local_t;
|
||||
|
||||
|
||||
/* Get the current NVR time. */
|
||||
static void
|
||||
time_get(uint8_t *regs, struct tm *tm)
|
||||
time_get(nvr_t *nvr, struct tm *tm)
|
||||
{
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
int8_t temp;
|
||||
|
||||
if (regs[RTC_REGB] & REGB_DM) {
|
||||
if (nvr->regs[RTC_REGB] & REGB_DM) {
|
||||
/* NVR is in Binary data mode. */
|
||||
tm->tm_sec = regs[RTC_SECONDS];
|
||||
tm->tm_min = regs[RTC_MINUTES];
|
||||
temp = regs[RTC_HOURS];
|
||||
tm->tm_wday = (regs[RTC_DOW] - 1);
|
||||
tm->tm_mday = regs[RTC_DOM];
|
||||
tm->tm_mon = (regs[RTC_MONTH] - 1);
|
||||
tm->tm_year = regs[RTC_YEAR];
|
||||
tm->tm_year += (regs[RTC_CENTURY] * 100) - 1900;
|
||||
tm->tm_sec = nvr->regs[RTC_SECONDS];
|
||||
tm->tm_min = nvr->regs[RTC_MINUTES];
|
||||
temp = nvr->regs[RTC_HOURS];
|
||||
tm->tm_wday = (nvr->regs[RTC_DOW] - 1);
|
||||
tm->tm_mday = nvr->regs[RTC_DOM];
|
||||
tm->tm_mon = (nvr->regs[RTC_MONTH] - 1);
|
||||
tm->tm_year = nvr->regs[RTC_YEAR];
|
||||
tm->tm_year += (nvr->regs[local->cent] * 100) - 1900;
|
||||
} else {
|
||||
/* NVR is in BCD data mode. */
|
||||
tm->tm_sec = RTC_DCB(regs[RTC_SECONDS]);
|
||||
tm->tm_min = RTC_DCB(regs[RTC_MINUTES]);
|
||||
temp = RTC_DCB(regs[RTC_HOURS]);
|
||||
tm->tm_wday = (RTC_DCB(regs[RTC_DOW]) - 1);
|
||||
tm->tm_mday = RTC_DCB(regs[RTC_DOM]);
|
||||
tm->tm_mon = (RTC_DCB(regs[RTC_MONTH]) - 1);
|
||||
tm->tm_year = RTC_DCB(regs[RTC_YEAR]);
|
||||
tm->tm_year += (RTC_DCB(regs[RTC_CENTURY]) * 100) - 1900;
|
||||
tm->tm_sec = RTC_DCB(nvr->regs[RTC_SECONDS]);
|
||||
tm->tm_min = RTC_DCB(nvr->regs[RTC_MINUTES]);
|
||||
temp = RTC_DCB(nvr->regs[RTC_HOURS]);
|
||||
tm->tm_wday = (RTC_DCB(nvr->regs[RTC_DOW]) - 1);
|
||||
tm->tm_mday = RTC_DCB(nvr->regs[RTC_DOM]);
|
||||
tm->tm_mon = (RTC_DCB(nvr->regs[RTC_MONTH]) - 1);
|
||||
tm->tm_year = RTC_DCB(nvr->regs[RTC_YEAR]);
|
||||
tm->tm_year += (RTC_DCB(nvr->regs[local->cent]) * 100) - 1900;
|
||||
}
|
||||
|
||||
/* Adjust for 12/24 hour mode. */
|
||||
if (regs[RTC_REGB] & REGB_2412)
|
||||
if (nvr->regs[RTC_REGB] & REGB_2412)
|
||||
tm->tm_hour = temp;
|
||||
else
|
||||
tm->tm_hour = ((temp & ~RTC_AMPM)%12) + ((temp&RTC_AMPM) ? 12 : 0);
|
||||
@@ -322,49 +334,50 @@ time_get(uint8_t *regs, struct tm *tm)
|
||||
|
||||
/* Set the current NVR time. */
|
||||
static void
|
||||
time_set(uint8_t *regs, struct tm *tm)
|
||||
time_set(nvr_t *nvr, struct tm *tm)
|
||||
{
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
int year = (tm->tm_year + 1900);
|
||||
|
||||
if (regs[RTC_REGB] & REGB_DM) {
|
||||
if (nvr->regs[RTC_REGB] & REGB_DM) {
|
||||
/* NVR is in Binary data mode. */
|
||||
regs[RTC_SECONDS] = tm->tm_sec;
|
||||
regs[RTC_MINUTES] = tm->tm_min;
|
||||
regs[RTC_DOW] = (tm->tm_wday + 1);
|
||||
regs[RTC_DOM] = tm->tm_mday;
|
||||
regs[RTC_MONTH] = (tm->tm_mon + 1);
|
||||
regs[RTC_YEAR] = (year % 100);
|
||||
regs[RTC_CENTURY] = (year / 100);
|
||||
nvr->regs[RTC_SECONDS] = tm->tm_sec;
|
||||
nvr->regs[RTC_MINUTES] = tm->tm_min;
|
||||
nvr->regs[RTC_DOW] = (tm->tm_wday + 1);
|
||||
nvr->regs[RTC_DOM] = tm->tm_mday;
|
||||
nvr->regs[RTC_MONTH] = (tm->tm_mon + 1);
|
||||
nvr->regs[RTC_YEAR] = (year % 100);
|
||||
nvr->regs[local->cent] = (year / 100);
|
||||
|
||||
if (regs[RTC_REGB] & REGB_2412) {
|
||||
if (nvr->regs[RTC_REGB] & REGB_2412) {
|
||||
/* NVR is in 24h mode. */
|
||||
regs[RTC_HOURS] = tm->tm_hour;
|
||||
nvr->regs[RTC_HOURS] = tm->tm_hour;
|
||||
} else {
|
||||
/* NVR is in 12h mode. */
|
||||
regs[RTC_HOURS] = (tm->tm_hour % 12) ? (tm->tm_hour % 12) : 12;
|
||||
nvr->regs[RTC_HOURS] = (tm->tm_hour % 12) ? (tm->tm_hour % 12) : 12;
|
||||
if (tm->tm_hour > 11)
|
||||
regs[RTC_HOURS] |= RTC_AMPM;
|
||||
nvr->regs[RTC_HOURS] |= RTC_AMPM;
|
||||
}
|
||||
} else {
|
||||
/* NVR is in BCD data mode. */
|
||||
regs[RTC_SECONDS] = RTC_BCD(tm->tm_sec);
|
||||
regs[RTC_MINUTES] = RTC_BCD(tm->tm_min);
|
||||
regs[RTC_DOW] = (RTC_BCD(tm->tm_wday) + 1);
|
||||
regs[RTC_DOM] = RTC_BCD(tm->tm_mday);
|
||||
regs[RTC_MONTH] = (RTC_BCD(tm->tm_mon) + 1);
|
||||
regs[RTC_YEAR] = RTC_BCD(year % 100);
|
||||
regs[RTC_CENTURY] = RTC_BCD(year / 100);
|
||||
nvr->regs[RTC_SECONDS] = RTC_BCD(tm->tm_sec);
|
||||
nvr->regs[RTC_MINUTES] = RTC_BCD(tm->tm_min);
|
||||
nvr->regs[RTC_DOW] = (RTC_BCD(tm->tm_wday) + 1);
|
||||
nvr->regs[RTC_DOM] = RTC_BCD(tm->tm_mday);
|
||||
nvr->regs[RTC_MONTH] = (RTC_BCD(tm->tm_mon) + 1);
|
||||
nvr->regs[RTC_YEAR] = RTC_BCD(year % 100);
|
||||
nvr->regs[local->cent] = RTC_BCD(year / 100);
|
||||
|
||||
if (regs[RTC_REGB] & REGB_2412) {
|
||||
if (nvr->regs[RTC_REGB] & REGB_2412) {
|
||||
/* NVR is in 24h mode. */
|
||||
regs[RTC_HOURS] = RTC_BCD(tm->tm_hour);
|
||||
nvr->regs[RTC_HOURS] = RTC_BCD(tm->tm_hour);
|
||||
} else {
|
||||
/* NVR is in 12h mode. */
|
||||
regs[RTC_HOURS] = (tm->tm_hour % 12)
|
||||
nvr->regs[RTC_HOURS] = (tm->tm_hour % 12)
|
||||
? RTC_BCD(tm->tm_hour % 12)
|
||||
: RTC_BCD(12);
|
||||
if (tm->tm_hour > 11)
|
||||
regs[RTC_HOURS] |= RTC_AMPM;
|
||||
nvr->regs[RTC_HOURS] |= RTC_AMPM;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -372,19 +385,19 @@ time_set(uint8_t *regs, struct tm *tm)
|
||||
|
||||
/* Check if the current time matches a set alarm time. */
|
||||
static int8_t
|
||||
check_alarm(uint8_t *regs, int8_t addr)
|
||||
check_alarm(nvr_t *nvr, int8_t addr)
|
||||
{
|
||||
#define ALARM_DONTCARE 0xc0
|
||||
return((regs[addr+1] == regs[addr]) ||
|
||||
((regs[addr+1] & ALARM_DONTCARE) == ALARM_DONTCARE));
|
||||
return((nvr->regs[addr+1] == nvr->regs[addr]) ||
|
||||
((nvr->regs[addr+1] & AL_DONTCARE) == AL_DONTCARE));
|
||||
}
|
||||
|
||||
|
||||
/* Update the NVR registers from the internal clock. */
|
||||
static void
|
||||
update_timer(void *priv)
|
||||
timer_update(void *priv)
|
||||
{
|
||||
nvr_t *nvr = (nvr_t *)priv;
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
struct tm tm;
|
||||
|
||||
if (! (nvr->regs[RTC_REGB] & REGB_SET)) {
|
||||
@@ -392,22 +405,22 @@ update_timer(void *priv)
|
||||
nvr_time_get(&tm);
|
||||
|
||||
/* Update registers with current time. */
|
||||
time_set(nvr->regs, &tm);
|
||||
|
||||
time_set(nvr, &tm);
|
||||
|
||||
/* Clear update status. */
|
||||
/* Clear update status. */
|
||||
local->stat = 0x00;
|
||||
|
||||
/* Check for any alarms we need to handle. */
|
||||
/* Check for any alarms we need to handle. */
|
||||
if (check_alarm(nvr->regs, RTC_SECONDS) &&
|
||||
check_alarm(nvr->regs, RTC_MINUTES) &&
|
||||
if (check_alarm(nvr, RTC_SECONDS) &&
|
||||
check_alarm(nvr, RTC_MINUTES) &&
|
||||
check_alarm(nvr, RTC_HOURS)) {
|
||||
nvr->regs[RTC_REGC] |= REGC_AF;
|
||||
if (nvr->regs[RTC_REGB] & REGB_AIE) {
|
||||
nvr->regs[RTC_REGC] |= REGC_IRQF;
|
||||
|
||||
/* Generate an interrupt. */
|
||||
if (nvr->irq != -1)
|
||||
if (nvr->irq != -1)
|
||||
picint(1 << nvr->irq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,41 +434,43 @@ update_timer(void *priv)
|
||||
|
||||
/* Generate an interrupt. */
|
||||
if (nvr->irq != -1)
|
||||
if (nvr->irq != -1)
|
||||
picint(1 << nvr->irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
local->ecount = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Re-calculate the timer values. */
|
||||
static void
|
||||
static void
|
||||
timer_recalc(nvr_t *nvr, int add)
|
||||
{
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
int64_t c, nt;
|
||||
|
||||
|
||||
c = 1ULL << ((nvr->regs[RTC_REGA] & REGA_RS) - 1);
|
||||
nt = (int64_t)(RTCCONST * c * (1<<TIMER_SHIFT));
|
||||
if (add)
|
||||
if (add)
|
||||
nvr->rtctime += nt;
|
||||
else if (nvr->rtctime > nt)
|
||||
local->rtctime += nt;
|
||||
else if (local->rtctime > nt)
|
||||
local->rtctime = nt;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
static void
|
||||
timer_intr(void *priv)
|
||||
{
|
||||
nvr_t *nvr = (nvr_t *)priv;
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
|
||||
if (! (nvr->regs[RTC_REGA] & REGA_RS)) {
|
||||
if (! (nvr->regs[RTC_REGA] & REGA_RS)) {
|
||||
local->rtctime = 0x7fffffff;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update our timer interval. */
|
||||
/* Update our timer interval. */
|
||||
timer_recalc(nvr, 1);
|
||||
|
||||
nvr->regs[RTC_REGC] |= REGC_PF;
|
||||
if (nvr->regs[RTC_REGB] & REGB_PIE) {
|
||||
@@ -463,20 +478,27 @@ rtc_timer(void *priv)
|
||||
|
||||
/* Generate an interrupt. */
|
||||
if (nvr->irq != -1)
|
||||
if (nvr->irq != -1)
|
||||
picint(1 << nvr->irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Callback from internal clock, another second passed. */
|
||||
static void
|
||||
static void
|
||||
timer_tick(nvr_t *nvr)
|
||||
{
|
||||
{
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
|
||||
|
||||
/* Only update it there is no SET in progress. */
|
||||
if (! (nvr->regs[RTC_REGB] & REGB_SET)) {
|
||||
/* Set the UIP bit, announcing the update. */
|
||||
local->stat = REGA_UIP;
|
||||
|
||||
|
||||
timer_recalc(nvr, 0);
|
||||
|
||||
/* Schedule the actual update. */
|
||||
local->ecount = (int64_t)((244.0 + 1984.0) * TIMER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -485,20 +507,21 @@ static void
|
||||
nvr_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
nvr_t *nvr = (nvr_t *)priv;
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
struct tm tm;
|
||||
uint8_t old;
|
||||
|
||||
cycles -= ISA_CYCLES(8);
|
||||
|
||||
if (addr & 1) {
|
||||
if (addr & 1) {
|
||||
old = nvr->regs[nvr->addr];
|
||||
old = nvr->regs[local->addr];
|
||||
switch(local->addr) {
|
||||
case RTC_REGA:
|
||||
nvr->regs[RTC_REGA] = val;
|
||||
if (val & REGA_RS)
|
||||
if (val & REGA_RS)
|
||||
timer_recalc(nvr, 1);
|
||||
else
|
||||
else
|
||||
local->rtctime = 0x7fffffff;
|
||||
break;
|
||||
|
||||
case RTC_REGB:
|
||||
@@ -515,25 +538,25 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
default: /* non-RTC registers are just NVRAM */
|
||||
default: /* non-RTC registers are just NVRAM */
|
||||
if (nvr->regs[nvr->addr] != val) {
|
||||
if (nvr->regs[local->addr] != val) {
|
||||
nvr->regs[local->addr] = val;
|
||||
nvr_dosave = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ((nvr->addr < RTC_REGA) || (nvr->addr == RTC_CENTURY)) {
|
||||
if ((local->addr < RTC_REGA) || (local->addr == local->cent)) {
|
||||
if ((local->addr != 1) && (local->addr != 3) && (local->addr != 5)) {
|
||||
if ((old != val) && !enable_sync) {
|
||||
/* Update internal clock. */
|
||||
/* Update internal clock. */
|
||||
time_get(nvr, &tm);
|
||||
nvr_time_set(&tm);
|
||||
nvr_dosave = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
local->addr = (val & (nvr->size - 1));
|
||||
if (!(machines[machine].flags & MACHINE_MCA) &&
|
||||
(romset != ROM_IBMPS1_2133))
|
||||
nmi_mask = (~val & 0x80);
|
||||
@@ -546,17 +569,18 @@ static uint8_t
|
||||
nvr_read(uint16_t addr, void *priv)
|
||||
{
|
||||
nvr_t *nvr = (nvr_t *)priv;
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
uint8_t ret;
|
||||
|
||||
cycles -= ISA_CYCLES(8);
|
||||
|
||||
|
||||
if (addr & 1) switch(local->addr) {
|
||||
case RTC_REGA:
|
||||
case RTC_REGA:
|
||||
ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat;
|
||||
break;
|
||||
|
||||
case RTC_REGC:
|
||||
case RTC_REGC:
|
||||
picintc(1 << nvr->irq);
|
||||
ret = nvr->regs[RTC_REGC];
|
||||
nvr->regs[RTC_REGC] = 0x00;
|
||||
break;
|
||||
@@ -567,10 +591,10 @@ nvr_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
ret = nvr->regs[local->addr];
|
||||
break;
|
||||
} else {
|
||||
} else {
|
||||
ret = local->addr;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
@@ -579,19 +603,21 @@ nvr_read(uint16_t addr, void *priv)
|
||||
|
||||
/* Reset the RTC state to 1980/01/01 00:00. */
|
||||
static void
|
||||
static void
|
||||
nvr_reset(nvr_t *nvr)
|
||||
{
|
||||
local_t *local = (local_t *)nvr->data;
|
||||
|
||||
memset(nvr->regs, 0x00, RTC_REGS);
|
||||
nvr->regs[RTC_DOM] = 1;
|
||||
nvr->regs[RTC_MONTH] = 1;
|
||||
nvr->regs[RTC_YEAR] = RTC_BCD(80);
|
||||
nvr->regs[RTC_YEAR] = RTC_BCD(80);
|
||||
nvr->regs[local->cent] = RTC_BCD(19);
|
||||
}
|
||||
|
||||
|
||||
/* Process after loading from file. */
|
||||
static void
|
||||
static void
|
||||
nvr_start(nvr_t *nvr)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
@@ -599,63 +625,120 @@ nvr_at_start(nvr_t *nvr)
|
||||
if (enable_sync) {
|
||||
/* Use the internal clock's time. */
|
||||
nvr_time_get(&tm);
|
||||
nvr_time_get(&tm);
|
||||
time_set(nvr, &tm);
|
||||
} else {
|
||||
/* Set the internal clock from the chip time. */
|
||||
/* Set the internal clock from the chip time. */
|
||||
time_get(nvr, &tm);
|
||||
nvr_time_set(&tm);
|
||||
}
|
||||
|
||||
/* Start the RTC. */
|
||||
nvr->regs[RTC_REGA] = (REGA_RS2|REGA_RS1);
|
||||
nvr->regs[RTC_REGB] = REGB_2412;
|
||||
nvr->regs[RTC_REGB] = REGB_2412;
|
||||
timer_recalc(nvr, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
nvr_recalc(nvr_t *nvr)
|
||||
{
|
||||
timer_recalc(nvr, 0);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
nvr_at_init(const device_t *info)
|
||||
{
|
||||
local_t *local;
|
||||
nvr_t *nvr;
|
||||
|
||||
/* Allocate an NVR for this machine. */
|
||||
nvr = (nvr_t *)malloc(sizeof(nvr_t));
|
||||
nvr = (nvr_t *)malloc(sizeof(nvr_t));
|
||||
if (nvr == NULL) return(NULL);
|
||||
memset(nvr, 0x00, sizeof(nvr_t));
|
||||
|
||||
local = (local_t *)malloc(sizeof(local_t));
|
||||
memset(local, 0xff, sizeof(local_t));
|
||||
nvr->data = local;
|
||||
|
||||
/* This is machine specific. */
|
||||
nvr->size = machines[machine].nvrmask + 1;
|
||||
nvr->size = machines[machine].nvrmask + 1;
|
||||
switch(info->local) {
|
||||
case 0: /* standard AT */
|
||||
nvr->irq = 8;
|
||||
local->cent = RTC_CENTURY_AT;
|
||||
break;
|
||||
|
||||
case 1: /* PS/1 or PS/2 */
|
||||
nvr->irq = 8;
|
||||
local->cent = RTC_CENTURY_PS;
|
||||
break;
|
||||
|
||||
case 2: /* Amstrad PC's */
|
||||
nvr->irq = 1;
|
||||
local->cent = RTC_CENTURY_AT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set up any local handlers here. */
|
||||
/* Set up any local handlers here. */
|
||||
nvr->reset = nvr_at_reset;
|
||||
nvr->start = nvr_at_start;
|
||||
nvr->reset = nvr_reset;
|
||||
nvr->start = nvr_start;
|
||||
nvr->tick = timer_tick;
|
||||
nvr->recalc = nvr_recalc;
|
||||
|
||||
/* Initialize the generic NVR. */
|
||||
nvr_init(nvr);
|
||||
|
||||
/* Start the timers. */
|
||||
/* Start the timers. */
|
||||
timer_add(update_timer, &nvr->upd_ecount, &nvr->upd_ecount, nvr);
|
||||
timer_add(timer_update, &local->ecount, &local->ecount, nvr);
|
||||
timer_add(timer_intr, &local->rtctime, TIMER_ALWAYS_ENABLED, nvr);
|
||||
|
||||
/* Set up the I/O handler for this device. */
|
||||
io_sethandler(0x0070, 2,
|
||||
nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr);
|
||||
|
||||
|
||||
return(nvr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
nvr_at_close(void *priv)
|
||||
{
|
||||
{
|
||||
nvr_t *nvr = (nvr_t *)priv;
|
||||
|
||||
|
||||
if (nvrp->fn != NULL)
|
||||
if (nvr->fn != NULL)
|
||||
free(nvr->fn);
|
||||
|
||||
|
||||
if (nvr->data != NULL)
|
||||
free(nvr->data);
|
||||
|
||||
|
||||
free(nvr);
|
||||
}
|
||||
|
||||
|
||||
const device_t at_nvr_device = {
|
||||
"PC/AT NVRAM",
|
||||
DEVICE_ISA | DEVICE_AT,
|
||||
0,
|
||||
nvr_at_init, nvr_at_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t ps_nvr_device = {
|
||||
"PS/1 or PS/2 NVRAM",
|
||||
DEVICE_PS2,
|
||||
1,
|
||||
nvr_at_init, nvr_at_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t amstrad_nvr_device = {
|
||||
"Amstrad NVRAM",
|
||||
MACHINE_ISA | MACHINE_AT,
|
||||
2,
|
||||
nvr_at_init, nvr_at_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
163
src/pc.c
163
src/pc.c
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Main emulator module where most things are controlled.
|
||||
*
|
||||
* Version: @(#)pc.c 1.0.68 2018/03/19
|
||||
* Version: @(#)pc.c 1.0.69 2018/03/26
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "mem.h"
|
||||
#include "rom.h"
|
||||
#include "dma.h"
|
||||
#include "pci.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
#include "random.h"
|
||||
@@ -57,21 +58,14 @@
|
||||
#include "disk/hdc.h"
|
||||
#include "disk/hdc_ide.h"
|
||||
#include "disk/zip.h"
|
||||
#include "scsi/scsi.h"
|
||||
#include "cdrom/cdrom.h"
|
||||
#include "cdrom/cdrom_image.h"
|
||||
#include "cdrom/cdrom_null.h"
|
||||
#include "scsi/scsi.h"
|
||||
#include "network/network.h"
|
||||
#include "sound/sound.h"
|
||||
#include "sound/midi.h"
|
||||
#include "sound/snd_cms.h"
|
||||
#include "sound/snd_dbopl.h"
|
||||
#include "sound/snd_mpu401.h"
|
||||
#include "sound/snd_opl.h"
|
||||
#include "sound/snd_gus.h"
|
||||
#include "sound/snd_sb.h"
|
||||
#include "sound/snd_speaker.h"
|
||||
#include "sound/snd_ssi2001.h"
|
||||
#include "video/video.h"
|
||||
#include "ui.h"
|
||||
#include "plat.h"
|
||||
@@ -120,7 +114,7 @@ int sound_is_float = 1, /* (C) sound uses FP values */
|
||||
GUS = 0, /* (C) sound option */
|
||||
SSI2001 = 0, /* (C) sound option */
|
||||
voodoo_enabled = 0; /* (C) video option */
|
||||
int mem_size = 0; /* (C) memory size */
|
||||
uint32_t mem_size = 0; /* (C) memory size */
|
||||
int cpu_manufacturer = 0, /* (C) cpu manufacturer */
|
||||
cpu_use_dynarec = 0, /* (C) cpu uses/needs Dyna */
|
||||
cpu = 3, /* (C) cpu type */
|
||||
@@ -299,6 +293,7 @@ pc_init(int argc, wchar_t *argv[])
|
||||
struct tm *info;
|
||||
time_t now;
|
||||
int c;
|
||||
uint32_t *uid, *shwnd;
|
||||
|
||||
/* Grab the executable's full path. */
|
||||
plat_get_exe_name(exe_path, sizeof(exe_path)-1);
|
||||
@@ -329,12 +324,8 @@ usage:
|
||||
printf("-D or --debug - force debug output logging\n");
|
||||
#endif
|
||||
printf("-F or --fullscreen - start in fullscreen mode\n");
|
||||
printf("-M or --memdump - dump memory on exit\n");
|
||||
printf("-L or --logfile path - set 'path' to be the logfile\n");
|
||||
printf("-P or --vmpath path - set 'path' to be root for vm\n");
|
||||
#ifdef USE_WX
|
||||
printf("-R or --fps num - set render speed to 'num' fps\n");
|
||||
#endif
|
||||
printf("-S or --settings - show only the settings dialog\n");
|
||||
#ifdef _WIN32
|
||||
printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n");
|
||||
@@ -357,20 +348,11 @@ usage:
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
||||
wcscpy(log_path, argv[++c]);
|
||||
} else if (!wcscasecmp(argv[c], L"--memdump") ||
|
||||
!wcscasecmp(argv[c], L"-M")) {
|
||||
} else if (!wcscasecmp(argv[c], L"--vmpath") ||
|
||||
!wcscasecmp(argv[c], L"-P")) {
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
||||
wcscpy(path, argv[++c]);
|
||||
#ifdef USE_WX
|
||||
} else if (!wcscasecmp(argv[c], L"--fps") ||
|
||||
!wcscasecmp(argv[c], L"-R")) {
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
||||
video_fps = wcstol(argv[++c], NULL, 10);
|
||||
#endif
|
||||
} else if (!wcscasecmp(argv[c], L"--settings") ||
|
||||
!wcscasecmp(argv[c], L"-S")) {
|
||||
settings_only = 1;
|
||||
@@ -381,7 +363,9 @@ usage:
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
||||
wcstombs(temp, argv[++c], 128);
|
||||
sscanf(temp, "%016" PRIX64 ",%016" PRIX64, &unique_id, &source_hwnd);
|
||||
uid = (uint32_t *) &unique_id;
|
||||
shwnd = (uint32_t *) &source_hwnd;
|
||||
sscanf(temp, "%08X%08X,%08X%08X", uid + 1, uid, shwnd + 1, shwnd);
|
||||
#endif
|
||||
} else if (!wcscasecmp(argv[c], L"--test")) {
|
||||
/* some (undocumented) test function here.. */
|
||||
@@ -512,6 +496,8 @@ pc_full_speed(void)
|
||||
setpitclock(14318184.0);
|
||||
}
|
||||
atfullspeed = 1;
|
||||
|
||||
nvr_period_recalc();
|
||||
}
|
||||
|
||||
|
||||
@@ -522,9 +508,12 @@ pc_speed_changed(void)
|
||||
setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed);
|
||||
else
|
||||
setpitclock(14318184.0);
|
||||
|
||||
nvr_period_recalc();
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* Re-load system configuration and restart. */
|
||||
/* FIXME: this has to be reviewed! */
|
||||
void
|
||||
@@ -536,10 +525,8 @@ pc_reload(wchar_t *fn)
|
||||
|
||||
for (i=0; i<FDD_NUM; i++)
|
||||
fdd_close(i);
|
||||
for (i=0; i<CDROM_NUM; i++) {
|
||||
cdrom_drives[i].handler->exit(i);
|
||||
cdrom_close(i);
|
||||
}
|
||||
|
||||
cdrom_close();
|
||||
|
||||
pc_reset_hard_close();
|
||||
|
||||
@@ -547,24 +534,9 @@ pc_reload(wchar_t *fn)
|
||||
|
||||
config_load();
|
||||
|
||||
for (i=0; i<CDROM_NUM; i++) {
|
||||
if (cdrom_drives[i].bus_type)
|
||||
SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun);
|
||||
cdrom_hard_reset();
|
||||
|
||||
if (cdrom_drives[i].host_drive == 200)
|
||||
image_open(i, cdrom_image[i].image_path);
|
||||
else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z'))
|
||||
ioctl_open(i, cdrom_drives[i].host_drive);
|
||||
else
|
||||
cdrom_null_open(i, cdrom_drives[i].host_drive);
|
||||
}
|
||||
|
||||
for (i=0; i<ZIP_NUM; i++) {
|
||||
if (zip_drives[i].bus_type)
|
||||
SCSIReset(zip_drives[i].scsi_device_id, zip_drives[i].scsi_device_lun);
|
||||
|
||||
zip_load(i, zip_drives[i].image_path);
|
||||
}
|
||||
zip_hard_reset();
|
||||
|
||||
fdd_load(0, floppyfns[0]);
|
||||
fdd_load(1, floppyfns[1]);
|
||||
@@ -575,6 +547,7 @@ pc_reload(wchar_t *fn)
|
||||
|
||||
pc_reset_hard_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Initialize modules, ran once, after pc_init. */
|
||||
@@ -653,21 +626,13 @@ again2:
|
||||
codegen_init();
|
||||
#endif
|
||||
|
||||
#ifdef WALTJE_SERIAL
|
||||
serial_init();
|
||||
#endif
|
||||
keyboard_init();
|
||||
joystick_init();
|
||||
video_init();
|
||||
|
||||
ide_init_first();
|
||||
|
||||
device_init();
|
||||
|
||||
timer_reset();
|
||||
|
||||
sound_reset();
|
||||
|
||||
fdd_init();
|
||||
|
||||
sound_init();
|
||||
@@ -677,8 +642,6 @@ again2:
|
||||
cdrom_hard_reset();
|
||||
zip_hard_reset();
|
||||
|
||||
ide_reset_hard();
|
||||
|
||||
scsi_card_init();
|
||||
|
||||
pc_full_speed();
|
||||
@@ -699,16 +662,23 @@ pc_keyboard_send(uint8_t val)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pc_send_ca(uint8_t sc)
|
||||
{
|
||||
pc_keyboard_send(29); /* Ctrl key pressed */
|
||||
pc_keyboard_send(56); /* Alt key pressed */
|
||||
pc_keyboard_send(sc);
|
||||
pc_keyboard_send(sc | 0x80);
|
||||
pc_keyboard_send(184); /* Alt key released */
|
||||
pc_keyboard_send(157); /* Ctrl key released */
|
||||
}
|
||||
|
||||
|
||||
/* Send the machine a Control-Alt-DEL sequence. */
|
||||
void
|
||||
pc_send_cad(void)
|
||||
{
|
||||
pc_keyboard_send(29); /* Ctrl key pressed */
|
||||
pc_keyboard_send(56); /* Alt key pressed */
|
||||
pc_keyboard_send(83); /* Delete key pressed */
|
||||
pc_keyboard_send(157); /* Ctrl key released */
|
||||
pc_keyboard_send(184); /* Alt key released */
|
||||
pc_keyboard_send(211); /* Delete key released */
|
||||
pc_send_ca(83);
|
||||
}
|
||||
|
||||
|
||||
@@ -716,37 +686,19 @@ pc_send_cad(void)
|
||||
void
|
||||
pc_send_cae(void)
|
||||
{
|
||||
pc_keyboard_send(29); /* Ctrl key pressed */
|
||||
pc_keyboard_send(56); /* Alt key pressed */
|
||||
pc_keyboard_send(1); /* Esc key pressed */
|
||||
pc_keyboard_send(129); /* Esc key released */
|
||||
pc_keyboard_send(184); /* Alt key released */
|
||||
pc_keyboard_send(157); /* Ctrl key released */
|
||||
}
|
||||
|
||||
|
||||
/* Send the machine a Control-Alt-Break sequence. */
|
||||
void
|
||||
pc_send_cab(void)
|
||||
{
|
||||
pc_keyboard_send(29); /* Ctrl key pressed */
|
||||
pc_keyboard_send(56); /* Alt key pressed */
|
||||
pc_keyboard_send(1); /* Esc key pressed */
|
||||
pc_keyboard_send(157); /* Ctrl key released */
|
||||
pc_keyboard_send(184); /* Alt key released */
|
||||
pc_keyboard_send(129); /* Esc key released */
|
||||
pc_send_ca(1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pc_reset_hard_close(void)
|
||||
{
|
||||
pclog("pc_reset_hard_close()\n");
|
||||
|
||||
suppress_overscan = 0;
|
||||
|
||||
nvr_save();
|
||||
|
||||
machine_close();
|
||||
|
||||
mouse_close();
|
||||
|
||||
lpt_devices_close();
|
||||
@@ -755,6 +707,8 @@ pc_reset_hard_close(void)
|
||||
|
||||
midi_close();
|
||||
|
||||
cdrom_close();
|
||||
|
||||
closeal();
|
||||
}
|
||||
|
||||
@@ -768,29 +722,27 @@ pc_reset_hard_close(void)
|
||||
void
|
||||
pc_reset_hard_init(void)
|
||||
{
|
||||
pclog("pc_reset_hard_init()\n");
|
||||
|
||||
/*
|
||||
* First, we reset the modules that are not part of
|
||||
* the actual machine, but which support some of the
|
||||
* modules that are.
|
||||
*/
|
||||
sound_realloc_buffers();
|
||||
sound_cd_thread_reset();
|
||||
initalmain(0, NULL);
|
||||
|
||||
/* Reset the general machine support modules. */
|
||||
io_init();
|
||||
// cpu_set();
|
||||
timer_reset();
|
||||
|
||||
device_init();
|
||||
|
||||
midi_device_init();
|
||||
inital();
|
||||
sound_reset();
|
||||
|
||||
#ifndef WALTJE_SERIAL
|
||||
/* This is needed to initialize the serial timer. */
|
||||
serial_init();
|
||||
#endif
|
||||
|
||||
cdrom_hard_reset();
|
||||
zip_hard_reset();
|
||||
|
||||
/* Initialize the actual machine and its basic modules. */
|
||||
machine_init();
|
||||
@@ -810,11 +762,7 @@ pc_reset_hard_init(void)
|
||||
speaker_init();
|
||||
serial_reset();
|
||||
lpt_devices_init();
|
||||
|
||||
/* Reset keyboard and/or mouse. */
|
||||
// FIXME: do we really have to reset the *AT* keyboard?? --FvK
|
||||
shadowbios = 0;
|
||||
keyboard_at_reset();
|
||||
|
||||
/*
|
||||
* This has to be after the serial initialization so that
|
||||
@@ -826,30 +774,18 @@ pc_reset_hard_init(void)
|
||||
/* Reset the video card. */
|
||||
video_reset(gfxcard);
|
||||
|
||||
cdrom_hard_reset();
|
||||
zip_hard_reset();
|
||||
|
||||
/* Reset the Hard Disk Controller module. */
|
||||
hdc_reset();
|
||||
|
||||
/* Reset and reconfigure the SCSI layer. */
|
||||
scsi_card_init();
|
||||
|
||||
/* Reset and reconfigure the Sound Card layer. */
|
||||
sound_card_reset();
|
||||
|
||||
/* Reset and reconfigure the Network Card layer. */
|
||||
network_reset();
|
||||
|
||||
/* Reset and reconfigure the Sound Card layer. */
|
||||
// FIXME: should be just one sound_reset() here. --FvK
|
||||
sound_card_init();
|
||||
if (mpu401_standalone_enable)
|
||||
mpu401_device_add();
|
||||
if (GUS)
|
||||
device_add(&gus_device);
|
||||
if (GAMEBLASTER)
|
||||
device_add(&cms_device);
|
||||
if (SSI2001)
|
||||
device_add(&ssi2001_device);
|
||||
|
||||
if (joystick_type != 7)
|
||||
gameport_update_joystick_type();
|
||||
|
||||
@@ -866,7 +802,6 @@ pc_reset_hard_init(void)
|
||||
device_add(&bugger_device);
|
||||
|
||||
/* Reset the CPU module. */
|
||||
cpu_set();
|
||||
resetx86();
|
||||
dma_reset();
|
||||
pic_reset();
|
||||
@@ -938,9 +873,6 @@ pc_close(thread_t *ptr)
|
||||
for (i=0; i<ZIP_NUM; i++)
|
||||
zip_close(i);
|
||||
|
||||
for (i=0; i<CDROM_NUM; i++)
|
||||
cdrom_drives[i].handler->exit(i);
|
||||
|
||||
for (i=0; i<FDD_NUM; i++)
|
||||
fdd_close(i);
|
||||
|
||||
@@ -957,10 +889,9 @@ pc_close(thread_t *ptr)
|
||||
network_close();
|
||||
|
||||
sound_cd_thread_end();
|
||||
cdrom_close();
|
||||
|
||||
ide_destroy_buffers();
|
||||
|
||||
cdrom_destroy_drives();
|
||||
zip_destroy_drives();
|
||||
}
|
||||
|
||||
|
||||
|
||||
45
src/pci.c
45
src/pci.c
@@ -12,11 +12,15 @@
|
||||
#include "mem.h"
|
||||
#include "device.h"
|
||||
#include "pci.h"
|
||||
#include "piix.h"
|
||||
#include "keyboard.h"
|
||||
#if 0
|
||||
#include "scsi/scsi.h"
|
||||
#include "cdrom/cdrom.h"
|
||||
#include "disk/hdc.h"
|
||||
#include "disk/hdc_ide.h"
|
||||
#include "disk/zip.h"
|
||||
#endif
|
||||
|
||||
|
||||
static uint64_t pci_irq_hold[16];
|
||||
@@ -52,8 +56,6 @@ int pci_burst_time, pci_nonburst_time;
|
||||
|
||||
static int trc_reg = 0;
|
||||
|
||||
PCI_RESET pci_reset_handler;
|
||||
|
||||
#ifdef ENABLE_PCI_LOG
|
||||
int pci_do_log = ENABLE_PCI_LOG;
|
||||
#endif
|
||||
@@ -636,44 +638,11 @@ static uint8_t trc_read(uint16_t port, void *priv)
|
||||
|
||||
static void trc_reset(uint8_t val)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (val & 2)
|
||||
{
|
||||
if (pci_reset_handler.pci_master_reset)
|
||||
{
|
||||
pci_reset_handler.pci_master_reset();
|
||||
}
|
||||
|
||||
if (pci_reset_handler.pci_set_reset)
|
||||
{
|
||||
pci_reset_handler.pci_set_reset();
|
||||
}
|
||||
|
||||
if (pci_reset_handler.super_io_reset)
|
||||
{
|
||||
pci_reset_handler.super_io_reset();
|
||||
}
|
||||
|
||||
/* ide_reset(); */
|
||||
ide_set_all_signatures();
|
||||
for (i = 0; i < CDROM_NUM; i++)
|
||||
{
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA))
|
||||
{
|
||||
cdrom_reset(i);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ZIP_NUM; i++)
|
||||
{
|
||||
if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI_PIO_ONLY) || (zip_drives[i].bus_type == ZIP_BUS_ATAPI_PIO_AND_DMA))
|
||||
{
|
||||
zip_reset(i);
|
||||
}
|
||||
}
|
||||
device_reset_all_pci();
|
||||
|
||||
port_92_reset();
|
||||
keyboard_at_reset();
|
||||
|
||||
pci_reset();
|
||||
}
|
||||
@@ -732,10 +701,6 @@ void pci_init(int type)
|
||||
pci_mirqs[c].enabled = 0;
|
||||
pci_mirqs[c].irq_line = PCI_IRQ_DISABLED;
|
||||
}
|
||||
|
||||
pci_reset_handler.pci_master_reset = NULL;
|
||||
pci_reset_handler.pci_set_reset = NULL;
|
||||
pci_reset_handler.super_io_reset = NULL;
|
||||
}
|
||||
|
||||
void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd)
|
||||
|
||||
10
src/pci.h
10
src/pci.h
@@ -15,6 +15,7 @@ void pci_clear_irq(uint8_t card, uint8_t pci_int);
|
||||
void pci_reset(void);
|
||||
void pci_init(int type);
|
||||
void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd);
|
||||
void pci_close(void);
|
||||
uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
|
||||
|
||||
#define PCI_REG_COMMAND 0x04
|
||||
@@ -53,13 +54,4 @@ typedef union {
|
||||
uint8_t addr_regs[4];
|
||||
} bar_t;
|
||||
|
||||
typedef struct PCI_RESET
|
||||
{
|
||||
void (*pci_master_reset)(void);
|
||||
void (*pci_set_reset)(void);
|
||||
void (*super_io_reset)(void);
|
||||
} PCI_RESET;
|
||||
|
||||
extern PCI_RESET pci_reset_handler;
|
||||
|
||||
extern void trc_init(void);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "86box.h"
|
||||
#include "io.h"
|
||||
#include "pci.h"
|
||||
#include "pci_dummy.h"
|
||||
|
||||
24
src/piix.h
24
src/piix.h
@@ -8,26 +8,18 @@
|
||||
*
|
||||
* Emulation core dispatcher.
|
||||
*
|
||||
* Version: @(#)piix.h 1.0.2 2017/10/25
|
||||
* Version: @(#)piix.h 1.0.3 2018/03/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.
|
||||
*/
|
||||
|
||||
extern void piix_init(int card);
|
||||
extern const device_t piix_device;
|
||||
extern const device_t piix3_device;
|
||||
|
||||
extern void piix3_init(int card);
|
||||
extern int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv);
|
||||
extern int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv);
|
||||
|
||||
extern void piix4_init(int card);
|
||||
|
||||
extern uint8_t piix_bus_master_read(uint16_t port, void *priv);
|
||||
extern void piix_bus_master_write(uint16_t port, uint8_t val, void *priv);
|
||||
|
||||
extern int piix_bus_master_get_count(int channel);
|
||||
|
||||
extern int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length);
|
||||
extern int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length);
|
||||
|
||||
extern void piix_bus_master_set_irq(int channel);
|
||||
extern void piix_bus_master_set_irq(int channel, void *priv);
|
||||
|
||||
12
src/pit.c
12
src/pit.c
@@ -39,6 +39,12 @@ float VGACONST1,
|
||||
float RTCCONST;
|
||||
|
||||
int64_t firsttime=1;
|
||||
void setrtcconst(float clock)
|
||||
{
|
||||
RTCCONST=clock/32768.0;
|
||||
TIMER_USEC = (int64_t)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
void setpitclock(float clock)
|
||||
{
|
||||
cpuclock=clock;
|
||||
@@ -52,8 +58,8 @@ void setpitclock(float clock)
|
||||
video_update_timing();
|
||||
|
||||
xt_cpu_multi = (int64_t)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed);
|
||||
RTCCONST=clock/32768.0;
|
||||
TIMER_USEC = (int64_t)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT));
|
||||
/* RTCCONST=clock/32768.0;
|
||||
TIMER_USEC = (int64_t)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); */
|
||||
device_speed_changed();
|
||||
}
|
||||
|
||||
@@ -336,7 +342,6 @@ void pit_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
PIT *pit = (PIT *)p;
|
||||
int t;
|
||||
cycles -= (int)PITCONST;
|
||||
|
||||
switch (addr&3)
|
||||
{
|
||||
@@ -444,7 +449,6 @@ uint8_t pit_read(uint16_t addr, void *p)
|
||||
PIT *pit = (PIT *)p;
|
||||
int64_t t;
|
||||
uint8_t temp = 0xff;
|
||||
cycles -= (int)PITCONST;
|
||||
switch (addr&3)
|
||||
{
|
||||
case 0: case 1: case 2: /*Timers*/
|
||||
|
||||
@@ -58,6 +58,8 @@ extern void pit_set_using_timer(PIT *pit, int t, int using_timer);
|
||||
extern void pit_set_out_func(PIT *pit, int t, void (*func)(int new_out, int old_out));
|
||||
extern void pit_clock(PIT *pit, int t);
|
||||
|
||||
extern void setrtcconst(float clock);
|
||||
|
||||
extern void setpitclock(float clock);
|
||||
extern float pit_timer0_freq(void);
|
||||
|
||||
|
||||
@@ -107,14 +107,13 @@ extern void do_stop(void);
|
||||
extern uint8_t host_cdrom_drive_available[26];
|
||||
extern uint8_t host_cdrom_drive_available_num;
|
||||
|
||||
#ifdef USE_IOCTL
|
||||
extern void cdrom_init_host_drives(void);
|
||||
#endif
|
||||
extern void cdrom_eject(uint8_t id);
|
||||
extern void cdrom_reload(uint8_t id);
|
||||
extern void zip_eject(uint8_t id);
|
||||
extern void zip_reload(uint8_t id);
|
||||
extern void removable_disk_unload(uint8_t id);
|
||||
extern void removable_disk_eject(uint8_t id);
|
||||
extern void removable_disk_reload(uint8_t id);
|
||||
extern int ioctl_open(uint8_t id, char d);
|
||||
extern void ioctl_reset(uint8_t id);
|
||||
extern void ioctl_close(uint8_t id);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the SCSI controllers.
|
||||
*
|
||||
* Version: @(#)scsi.c 1.0.17 2018/03/18
|
||||
* Version: @(#)scsi.c 1.0.18 2018/03/26
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -27,11 +27,12 @@
|
||||
#include "../rom.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "scsi_device.h"
|
||||
#include "scsi_aha154x.h"
|
||||
#include "scsi_buslogic.h"
|
||||
#include "scsi_ncr5380.h"
|
||||
@@ -60,30 +61,29 @@ typedef const struct {
|
||||
const char *name;
|
||||
const char *internal_name;
|
||||
const device_t *device;
|
||||
void (*reset)(void *p);
|
||||
} SCSI_CARD;
|
||||
|
||||
|
||||
static SCSI_CARD scsi_cards[] = {
|
||||
{ "None", "none", NULL, NULL },
|
||||
{ "[ISA] Adaptec AHA-1540B","aha1540b", &aha1540b_device, x54x_device_reset },
|
||||
{ "[ISA] Adaptec AHA-1542C","aha1542c", &aha1542c_device, x54x_device_reset },
|
||||
{ "[ISA] Adaptec AHA-1542CF","aha1542cf", &aha1542cf_device, x54x_device_reset },
|
||||
{ "[ISA] BusLogic BT-542BH","bt542bh", &buslogic_device, BuslogicDeviceReset },
|
||||
{ "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device,BuslogicDeviceReset },
|
||||
{ "[ISA] Longshine LCS-6821N","lcs6821n", &scsi_lcs6821n_device,NULL },
|
||||
{ "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, NULL },
|
||||
{ "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, NULL },
|
||||
{ "[ISA] Sumo SCSI-AT", "scsiat", &scsi_scsiat_device, NULL },
|
||||
{ "None", "none", NULL, },
|
||||
{ "[ISA] Adaptec AHA-1540B","aha1540b", &aha1540b_device, },
|
||||
{ "[ISA] Adaptec AHA-1542C","aha1542c", &aha1542c_device, },
|
||||
{ "[ISA] Adaptec AHA-1542CF","aha1542cf", &aha1542cf_device, },
|
||||
{ "[ISA] BusLogic BT-542BH","bt542bh", &buslogic_device, },
|
||||
{ "[ISA] BusLogic BT-545S", "bt545s", &buslogic_545s_device,},
|
||||
{ "[ISA] Longshine LCS-6821N","lcs6821n", &scsi_lcs6821n_device,},
|
||||
{ "[ISA] Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, },
|
||||
{ "[ISA] Trantor T130B", "t130b", &scsi_t130b_device, },
|
||||
{ "[ISA] Sumo SCSI-AT", "scsiat", &scsi_scsiat_device, },
|
||||
#ifdef WALTJE
|
||||
{ "[ISA] Generic WDC33C93", "wd33c93", &scsi_wd33c93_device, NULL },
|
||||
{ "[ISA] Generic WDC33C93", "wd33c93", &scsi_wd33c93_device, },
|
||||
#endif
|
||||
{ "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, x54x_device_reset },
|
||||
{ "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,BuslogicDeviceReset },
|
||||
{ "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, BuslogicDeviceReset },
|
||||
{ "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device,NULL },
|
||||
{ "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device,BuslogicDeviceReset },
|
||||
{ "", "", NULL, NULL },
|
||||
{ "[MCA] Adaptec AHA-1640", "aha1640", &aha1640_device, },
|
||||
{ "[MCA] BusLogic BT-640A", "bt640a", &buslogic_640a_device,},
|
||||
{ "[PCI] BusLogic BT-958D", "bt958d", &buslogic_pci_device, },
|
||||
{ "[PCI] NCR 53C810", "ncr53c810", &ncr53c810_pci_device,},
|
||||
{ "[VLB] BusLogic BT-445S", "bt445s", &buslogic_445s_device,},
|
||||
{ "", "", NULL, },
|
||||
};
|
||||
|
||||
|
||||
@@ -149,6 +149,9 @@ void scsi_card_init(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!scsi_cards[scsi_card_current].device)
|
||||
return;
|
||||
|
||||
pclog("Building SCSI hard disk map...\n");
|
||||
build_scsi_hd_map();
|
||||
pclog("Building SCSI CD-ROM map...\n");
|
||||
@@ -158,41 +161,24 @@ void scsi_card_init(void)
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
for (j=0; j<SCSI_LUN_MAX; j++) {
|
||||
if (scsi_hard_disks[i][j] != 0xff) {
|
||||
if (scsi_hard_disks[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_DISK;
|
||||
} else if (scsi_cdrom_drives[i][j] != 0xff) {
|
||||
else if (scsi_cdrom_drives[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_CDROM;
|
||||
} else if (scsi_zip_drives[i][j] != 0xff) {
|
||||
else if (scsi_zip_drives[i][j] != 0xff)
|
||||
SCSIDevices[i][j].LunType = SCSI_ZIP;
|
||||
} else {
|
||||
else
|
||||
SCSIDevices[i][j].LunType = SCSI_NONE;
|
||||
}
|
||||
SCSIDevices[i][j].CmdBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (scsi_cards[scsi_card_current].device)
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
|
||||
scsi_card_last = scsi_card_current;
|
||||
}
|
||||
|
||||
|
||||
void scsi_card_reset(void)
|
||||
{
|
||||
void *p = NULL;
|
||||
|
||||
if (scsi_cards[scsi_card_current].device) {
|
||||
p = device_get_priv(scsi_cards[scsi_card_current].device);
|
||||
if (p) {
|
||||
if (scsi_cards[scsi_card_current].reset) {
|
||||
scsi_cards[scsi_card_current].reset(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialization function for the SCSI layer */
|
||||
void SCSIReset(uint8_t id, uint8_t lun)
|
||||
{
|
||||
@@ -200,20 +186,16 @@ void SCSIReset(uint8_t id, uint8_t lun)
|
||||
uint8_t zip_id = scsi_zip_drives[id][lun];
|
||||
uint8_t hdc_id = scsi_hard_disks[id][lun];
|
||||
|
||||
if (hdc_id != 0xff) {
|
||||
scsi_hd_reset(hdc_id);
|
||||
if (hdc_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_DISK;
|
||||
} else {
|
||||
if (cdrom_id != 0xff) {
|
||||
cdrom_reset(cdrom_id);
|
||||
SCSIDevices[id][lun].LunType = SCSI_CDROM;
|
||||
} else if (zip_id != 0xff) {
|
||||
zip_reset(zip_id);
|
||||
SCSIDevices[id][lun].LunType = SCSI_ZIP;
|
||||
} else {
|
||||
SCSIDevices[id][lun].LunType = SCSI_NONE;
|
||||
}
|
||||
}
|
||||
else if (cdrom_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_CDROM;
|
||||
else if (zip_id != 0xff)
|
||||
SCSIDevices[id][lun].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[id][lun].LunType = SCSI_NONE;
|
||||
|
||||
scsi_device_reset(id, lun);
|
||||
|
||||
if (SCSIDevices[id][lun].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id][lun].CmdBuffer);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* SCSI controller handler header.
|
||||
*
|
||||
* Version: @(#)scsi_h 1.0.15 2018/03/21
|
||||
* Version: @(#)scsi_h 1.0.16 2018/03/28
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -103,6 +103,13 @@
|
||||
#define GPMODE_CAPABILITIES_PAGE 0x2a
|
||||
#define GPMODE_ALL_PAGES 0x3f
|
||||
|
||||
/* Mode page codes for presence */
|
||||
#define GPMODEP_R_W_ERROR_PAGE 0x0000000000000002LL
|
||||
#define GPMODEP_CDROM_PAGE 0x0000000000002000LL
|
||||
#define GPMODEP_CDROM_AUDIO_PAGE 0x0000000000004000LL
|
||||
#define GPMODEP_CAPABILITIES_PAGE 0x0000040000000000LL
|
||||
#define GPMODEP_ALL_PAGES 0x8000000000000000LL
|
||||
|
||||
/* SCSI Status Codes */
|
||||
#define SCSI_STATUS_OK 0
|
||||
#define SCSI_STATUS_CHECK_CONDITION 2
|
||||
@@ -306,7 +313,6 @@ extern char *scsi_card_get_internal_name(int card);
|
||||
extern int scsi_card_get_from_internal_name(char *s);
|
||||
extern void scsi_mutex(uint8_t start);
|
||||
extern void scsi_card_init(void);
|
||||
extern void scsi_card_reset(void);
|
||||
|
||||
extern uint8_t scsi_hard_disks[16][8];
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* made by Adaptec, Inc. These controllers were designed for
|
||||
* the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_aha154x.c 1.0.40 2018/03/18
|
||||
* Version: @(#)scsi_aha154x.c 1.0.40 2018/04/11
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Original Buslogic version by SA1988 and Miran Grca.
|
||||
@@ -30,11 +30,11 @@
|
||||
#include "../mem.h"
|
||||
#include "../mca.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../dma.h"
|
||||
#include "../pic.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../plat.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "scsi.h"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* 1 - BT-545S ISA;
|
||||
* 2 - BT-958D PCI
|
||||
*
|
||||
* Version: @(#)scsi_buslogic.c 1.0.36 2018/03/18
|
||||
* Version: @(#)scsi_buslogic.c 1.0.37 2018/03/28
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -33,12 +33,12 @@
|
||||
#include "../mem.h"
|
||||
#include "../mca.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../dma.h"
|
||||
#include "../pic.h"
|
||||
#include "../pci.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi_buslogic.h"
|
||||
@@ -529,6 +529,7 @@ buslogic_param_len(void *p)
|
||||
case 0x91:
|
||||
return 2;
|
||||
case 0x94:
|
||||
case 0xFB:
|
||||
return 3;
|
||||
case 0x93: /* Valid only for VLB */
|
||||
return (bl->chip == CHIP_BUSLOGIC_VLB) ? 1 : 0;
|
||||
@@ -550,7 +551,7 @@ static void
|
||||
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN, int dir)
|
||||
{
|
||||
uint32_t DataPointer = ESCSICmd->DataPointer;
|
||||
uint32_t DataLength = ESCSICmd->DataLength;
|
||||
int DataLength = ESCSICmd->DataLength;
|
||||
uint32_t Address;
|
||||
uint32_t TransferLength;
|
||||
|
||||
@@ -997,6 +998,9 @@ buslogic_cmds(void *p)
|
||||
|
||||
dev->DataReply = 0;
|
||||
break;
|
||||
case 0xFB:
|
||||
dev->DataReplyLeft = dev->CmdBuf[2];
|
||||
break;
|
||||
default:
|
||||
dev->DataReplyLeft = 0;
|
||||
dev->Status |= STAT_INVCMD;
|
||||
@@ -1583,6 +1587,7 @@ buslogic_init(const device_t *info)
|
||||
dev->cdrom_boot = 1;
|
||||
dev->bit32 = 1;
|
||||
dev->ha_bps = 20000000.0; /* ultra SCSI */
|
||||
dev->max_id = 15; /* wide SCSI */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1683,7 +1688,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"0x134", 0x134
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -1709,7 +1714,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"IRQ 15", 15
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -1726,7 +1731,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"DMA 7", 7
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -1746,7 +1751,7 @@ static const device_config_t BT_ISA_Config[] = {
|
||||
"D800H", 0xd8000
|
||||
},
|
||||
{
|
||||
""
|
||||
"", 0
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* The generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.c 1.0.15 2018/03/16
|
||||
* Version: @(#)scsi_device.c 1.0.16 2018/03/26
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -22,10 +22,10 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/hdd.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ static uint8_t scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
cdrom_command(id, cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(id);
|
||||
cdrom_command(cdrom[id], cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
@@ -64,7 +64,7 @@ static void scsi_device_target_phase_callback(int lun_type, uint8_t id)
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
cdrom_phase_callback(id);
|
||||
cdrom_phase_callback(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
@@ -85,7 +85,7 @@ static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
||||
}
|
||||
else if (lun_type == SCSI_CDROM)
|
||||
{
|
||||
return cdrom_CDROM_PHASE_to_scsi(id);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t c
|
||||
}
|
||||
else if (lun_type == SCSI_ZIP)
|
||||
{
|
||||
zip[id].request_length = cdb_byte;
|
||||
zip[id]->request_length = cdb_byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -137,7 +137,7 @@ int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip[id].callback;
|
||||
return zip[id]->callback;
|
||||
break;
|
||||
default:
|
||||
return -1LL;
|
||||
@@ -164,7 +164,7 @@ uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip[id].sense;
|
||||
return zip[id]->sense;
|
||||
break;
|
||||
default:
|
||||
return scsi_null_device_sense;
|
||||
@@ -187,7 +187,7 @@ void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffe
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
cdrom_request_sense_for_scsi(id, buffer, alloc_length);
|
||||
cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
@@ -200,7 +200,7 @@ void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *buffe
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb)
|
||||
void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
|
||||
@@ -210,8 +210,28 @@ void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uin
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||
*type = 0x00;
|
||||
*rmb = (hdd[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 0x80 : 0x00;
|
||||
scsi_hd_reset(id);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
cdrom_reset(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
zip_reset(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uint8_t *rmb)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
*type = *rmb = 0x00;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
*type = 0x05;
|
||||
@@ -222,7 +242,7 @@ void scsi_device_type_data(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *type, uin
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
default:
|
||||
*type = *rmb = 0xFF;
|
||||
*type = *rmb = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -241,7 +261,7 @@ int scsi_device_read_capacity(uint8_t scsi_id, uint8_t scsi_lun, uint8_t *cdb, u
|
||||
return scsi_hd_read_capacity(id, cdb, buffer, len);
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||
return cdrom_read_capacity(id, cdb, buffer, len);
|
||||
return cdrom_read_capacity(cdrom[id], cdb, buffer, len);
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip_read_capacity(id, cdb, buffer, len);
|
||||
@@ -304,7 +324,7 @@ int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun)
|
||||
return cdrom[id]->cdb_len;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id][scsi_lun];
|
||||
return zip[id].cdb_len;
|
||||
return zip[id]->cdb_len;
|
||||
default:
|
||||
return 12;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.h 1.0.6 2018/03/07
|
||||
* Version: @(#)scsi_device.h 1.0.7 2018/03/29
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -39,6 +39,7 @@ extern int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t scsi_lun,
|
||||
uint8_t *buffer,
|
||||
uint8_t alloc_length);
|
||||
extern void scsi_device_reset(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
extern int scsi_device_read_capacity(uint8_t id, uint8_t lun,
|
||||
uint8_t *cdb, uint8_t *buffer,
|
||||
uint32_t *len);
|
||||
|
||||
2262
src/scsi/scsi_disk.c
2262
src/scsi/scsi_disk.c
File diff suppressed because it is too large
Load Diff
@@ -6,54 +6,31 @@
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.h 1.0.3 2017/10/14
|
||||
* Version: @(#)scsi_disk.h 1.0.4 2018/04/24
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2017 Miran Grca.
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* Stuff for SCSI hard disks. */
|
||||
uint8_t cdb[16];
|
||||
uint8_t current_cdb[16];
|
||||
uint8_t max_cdb_len;
|
||||
int requested_blocks;
|
||||
int max_blocks_at_once;
|
||||
uint8_t status, phase,
|
||||
error,
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint16_t request_length;
|
||||
int block_total;
|
||||
int all_blocks_total;
|
||||
uint32_t packet_len;
|
||||
int packet_status;
|
||||
uint8_t status;
|
||||
uint8_t phase;
|
||||
uint32_t pos;
|
||||
int callback;
|
||||
int total_read;
|
||||
int unit_attention;
|
||||
uint8_t sense[256];
|
||||
uint8_t previous_command;
|
||||
uint8_t error;
|
||||
uint32_t sector_pos;
|
||||
uint32_t sector_len;
|
||||
uint32_t seek_pos;
|
||||
int data_pos;
|
||||
int old_len;
|
||||
int request_pos;
|
||||
uint8_t hd_cdb[16];
|
||||
|
||||
int requested_blocks, block_total,
|
||||
packet_status, callback,
|
||||
block_descriptor_len,
|
||||
total_length, do_page_save;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len;
|
||||
|
||||
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;
|
||||
int block_descriptor_len;
|
||||
|
||||
uint8_t *temp_buffer;
|
||||
} scsi_hard_disk_t;
|
||||
@@ -63,9 +40,6 @@ extern scsi_hard_disk_t shdc[HDD_NUM];
|
||||
extern FILE *shdf[HDD_NUM];
|
||||
|
||||
|
||||
extern void scsi_disk_insert(uint8_t id);
|
||||
extern void scsi_loadhd(int scsi_id, int scsi_lun, int id);
|
||||
extern void scsi_reloadhd(int id);
|
||||
extern void scsi_unloadhd(int scsi_id, int scsi_lun, int id);
|
||||
|
||||
int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the NCR 5380 series of SCSI Host Adapters
|
||||
* made by NCR. These controllers were designed for the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.12 2018/03/18
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.13 2018/04/11
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* TheCollector1995, <mariogplayer@gmail.com>
|
||||
@@ -34,8 +34,8 @@
|
||||
#include "../mca.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../nvr.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* NCR and later Symbios and LSI. This controller was designed
|
||||
* for the PCI bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.10 2018/03/18
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.11 2018/03/28
|
||||
*
|
||||
* Authors: Paul Brook (QEMU)
|
||||
* Artyom Tarasenko (QEMU)
|
||||
@@ -35,8 +35,8 @@
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../pci.h"
|
||||
#include "../nvr.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "scsi.h"
|
||||
@@ -329,6 +329,8 @@ ncr53c810_irq_on_rsl(ncr53c810_t *dev)
|
||||
static void
|
||||
ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
ncr53c810_log("LSI Reset\n");
|
||||
dev->timer_period = dev->timer_enabled = 0;
|
||||
|
||||
@@ -383,13 +385,18 @@ ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
dev->last_level = 0;
|
||||
dev->gpreg0 = 0;
|
||||
dev->sstop = 1;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ncr53c810_read(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
ncr53c810_log("ncr53c810_read(): %08X-%08X, length %i\n", addr, (addr + len - 1), len);
|
||||
|
||||
@@ -407,7 +414,7 @@ ncr53c810_read(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
|
||||
static void
|
||||
ncr53c810_write(ncr53c810_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
ncr53c810_log("ncr53c810_write(): %08X-%08X, length %i\n", addr, (addr + len - 1), len);
|
||||
|
||||
@@ -582,13 +589,14 @@ ncr53c810_command_complete(void *priv, uint32_t status)
|
||||
static void
|
||||
ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
{
|
||||
uint32_t addr, count, tdbc;
|
||||
uint32_t addr, tdbc;
|
||||
int count;
|
||||
|
||||
scsi_device_t *sd;
|
||||
|
||||
sd = &SCSIDevices[id][dev->current_lun];
|
||||
|
||||
if ((((id) == -1) && !scsi_device_present(id, dev->current_lun))) {
|
||||
if ((!scsi_device_present(id, dev->current_lun))) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Device not present when attempting to do DMA\n", id, dev->current_lun, dev->last_command);
|
||||
return;
|
||||
}
|
||||
@@ -673,7 +681,7 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->command_complete = 0;
|
||||
|
||||
sd = &SCSIDevices[id][dev->current_lun];
|
||||
if (((id == -1) || !scsi_device_present(id, dev->current_lun))) {
|
||||
if (!scsi_device_present(id, dev->current_lun)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
return 0;
|
||||
@@ -747,7 +755,7 @@ ncr53c810_do_status(ncr53c810_t *dev)
|
||||
static void
|
||||
ncr53c810_do_msgin(ncr53c810_t *dev)
|
||||
{
|
||||
int len;
|
||||
uint32_t len;
|
||||
ncr53c810_log("Message in len=%d/%d\n", dev->dbc, dev->msg_len);
|
||||
dev->sfbr = dev->msg[0];
|
||||
len = dev->msg_len;
|
||||
@@ -1067,7 +1075,7 @@ again:
|
||||
}
|
||||
dev->sstat0 |= NCR_SSTAT0_WOA;
|
||||
dev->scntl1 &= ~NCR_SCNTL1_IARB;
|
||||
if (((id == -1) || !scsi_device_present(id, 0))) {
|
||||
if (!scsi_device_present(id, 0)) {
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* series of SCSI Host Adapters made by Mylex.
|
||||
* These controllers were designed for various buses.
|
||||
*
|
||||
* Version: @(#)scsi_x54x.c 1.0.20 2018/03/18
|
||||
* Version: @(#)scsi_x54x.c 1.0.21 2018/03/28
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -36,8 +36,8 @@
|
||||
#include "../mca.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../nvr.h"
|
||||
#include "../device.h"
|
||||
#include "../nvr.h"
|
||||
#include "../timer.h"
|
||||
#include "../plat.h"
|
||||
#include "../cpu/cpu.h"
|
||||
@@ -720,8 +720,7 @@ x54x_get_length(Req_t *req, int Is24bit)
|
||||
uint32_t DataPointer, DataLength;
|
||||
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
|
||||
SGE32 SGBuffer;
|
||||
uint32_t DataToTransfer = 0;
|
||||
int i = 0;
|
||||
uint32_t DataToTransfer = 0, i = 0;
|
||||
|
||||
if (Is24bit) {
|
||||
DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer);
|
||||
@@ -793,8 +792,7 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
{
|
||||
uint32_t DataPointer, DataLength;
|
||||
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
|
||||
uint32_t Address;
|
||||
int i = 0;
|
||||
uint32_t Address, i;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID][req->LUN].BufferLength;
|
||||
uint8_t read_from_host = (dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
uint8_t write_to_host = (!dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
@@ -823,7 +821,7 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
x54x_rd_sge(Is24bit, DataPointer + i, &SGBuffer);
|
||||
|
||||
Address = SGBuffer.SegmentPointer;
|
||||
DataToTransfer = MIN(SGBuffer.Segment, BufLen);
|
||||
DataToTransfer = MIN((int) SGBuffer.Segment, BufLen);
|
||||
|
||||
if (read_from_host && DataToTransfer) {
|
||||
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
@@ -851,9 +849,9 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
|
||||
if (read_from_host)
|
||||
DMAPageRead(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength));
|
||||
DMAPageRead(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
else if (write_to_host)
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, DataLength));
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID][req->LUN].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1061,7 +1059,6 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
{
|
||||
Req_t *req = &dev->Req;
|
||||
uint8_t id, lun;
|
||||
uint8_t max_id = SCSI_ID_MAX-1;
|
||||
|
||||
/* Fetch data from the Command Control Block. */
|
||||
DMAPageRead(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32));
|
||||
@@ -1074,7 +1071,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
|
||||
id = req->TargetID;
|
||||
lun = req->LUN;
|
||||
if ((id > max_id) || (lun > 7)) {
|
||||
if ((id > dev->max_id) || (lun > 7)) {
|
||||
x54x_log("SCSI Target ID %i or LUN %i is not valid\n",id,lun);
|
||||
x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock,
|
||||
CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
|
||||
@@ -1110,12 +1107,14 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
}
|
||||
if (req->CmdBlock.common.Opcode == 0x81) {
|
||||
x54x_log("Bus reset opcode\n");
|
||||
scsi_device_reset(id, lun);
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
x54x_log("%s: Callback: Send incoming mailbox\n", dev->name);
|
||||
x54x_notify(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->CmdBlock.common.ControlByte > 0x03) {
|
||||
x54x_log("Invalid control byte: %02X\n",
|
||||
req->CmdBlock.common.ControlByte);
|
||||
@@ -1276,7 +1275,12 @@ x54x_cmd_callback(void *priv)
|
||||
double period;
|
||||
x54x_t *dev = (x54x_t *) x54x_dev;
|
||||
|
||||
if ((dev->Status & STAT_INIT) || (!dev->MailboxInit && !dev->BIOSMailboxInit) || (!dev->MailboxReq && !dev->BIOSMailboxReq)) {
|
||||
int mailboxes_present, bios_mailboxes_present;
|
||||
|
||||
mailboxes_present = (!(dev->Status & STAT_INIT) && dev->MailboxInit && dev->MailboxReq);
|
||||
bios_mailboxes_present = (dev->ven_callback && dev->BIOSMailboxInit && dev->BIOSMailboxReq);
|
||||
|
||||
if (!mailboxes_present && !bios_mailboxes_present) {
|
||||
/* If we did not get anything, do nothing and wait 10 us. */
|
||||
dev->timer_period = 10LL * TIMER_USEC;
|
||||
return;
|
||||
@@ -1284,11 +1288,21 @@ x54x_cmd_callback(void *priv)
|
||||
|
||||
dev->temp_period = dev->media_period = 0LL;
|
||||
|
||||
if (!(x54x_dev->Status & STAT_INIT) && x54x_dev->MailboxInit && dev->MailboxReq)
|
||||
x54x_do_mail(dev);
|
||||
|
||||
if (dev->ven_callback)
|
||||
if (!mailboxes_present) {
|
||||
/* Do only BIOS mailboxes. */
|
||||
dev->ven_callback(dev);
|
||||
} else if (!bios_mailboxes_present) {
|
||||
/* Do only normal mailboxes. */
|
||||
x54x_do_mail(dev);
|
||||
} else {
|
||||
/* Do both kinds of mailboxes. */
|
||||
if (dev->callback_phase)
|
||||
dev->ven_callback(dev);
|
||||
else
|
||||
x54x_do_mail(dev);
|
||||
|
||||
dev->callback_phase = (dev->callback_phase + 1) & 0x01;
|
||||
}
|
||||
|
||||
period = (1000000.0 / x54x_dev->ha_bps) * ((double) TIMER_USEC) * ((double) dev->temp_period);
|
||||
dev->timer_period = dev->media_period + ((int64_t) period) + (40LL * TIMER_USEC);
|
||||
@@ -1319,7 +1333,10 @@ x54x_in(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ret = dev->Interrupt;
|
||||
if (dev->int_geom_writable)
|
||||
ret = dev->Interrupt;
|
||||
else
|
||||
ret = dev->Interrupt & ~0x70;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@@ -1406,11 +1423,14 @@ x54x_reset_poll(void *priv)
|
||||
static void
|
||||
x54x_reset(x54x_t *dev)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
clear_irq(dev);
|
||||
if (dev->int_geom_writable)
|
||||
dev->Geometry = 0x80;
|
||||
else
|
||||
dev->Geometry = 0x00;
|
||||
dev->callback_phase = 0;
|
||||
dev->Command = 0xFF;
|
||||
dev->CmdParam = 0;
|
||||
dev->CmdParamLeft = 0;
|
||||
@@ -1422,9 +1442,14 @@ x54x_reset(x54x_t *dev)
|
||||
dev->MailboxCount = 0;
|
||||
dev->MailboxOutPosCur = 0;
|
||||
|
||||
if (dev->ven_reset) {
|
||||
dev->ven_reset(dev);
|
||||
/* Reset all devices on controller reset. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
|
||||
if (dev->ven_reset)
|
||||
dev->ven_reset(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -1476,6 +1501,14 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (val & CTRL_SCRST) {
|
||||
/* Reset all devices on SCSI bus reset. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
scsi_device_reset(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
if (val & CTRL_IRST) {
|
||||
clear_irq(dev);
|
||||
x54x_log("Interrupt reset: ");
|
||||
@@ -1643,7 +1676,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (dev->ven_get_host_id)
|
||||
host_id = dev->ven_get_host_id(dev);
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
for (i=0; i<8; i++) {
|
||||
dev->DataBuf[i] = 0x00;
|
||||
|
||||
/* Skip the HA .. */
|
||||
@@ -1902,6 +1935,7 @@ x54x_init(const device_t *info)
|
||||
dev->type = info->local;
|
||||
|
||||
dev->bus = info->flags;
|
||||
dev->callback_phase = 0;
|
||||
|
||||
timer_add(x54x_reset_poll, &dev->ResetCB, &dev->ResetCB, dev);
|
||||
dev->timer_period = 10LL * TIMER_USEC;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* of SCSI Host Adapters made by Mylex.
|
||||
* These controllers were designed for various buses.
|
||||
*
|
||||
* Version: @(#)scsi_x54x.h 1.0.6 2018/03/18
|
||||
* Version: @(#)scsi_x54x.h 1.0.7 2018/04/06
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -333,6 +333,7 @@ typedef struct {
|
||||
char name[16]; /* name of device */
|
||||
|
||||
int64_t timer_period, temp_period;
|
||||
uint8_t callback_phase;
|
||||
int64_t media_period;
|
||||
double ha_bps; /* bytes per second */
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implementation of the SMC FDC37C669 Super I/O Chip.
|
||||
*
|
||||
* Version: @(#)sio_fdc37c669.c 1.0.7 2018/01/16
|
||||
* Version: @(#)sio_fdc37c669.c 1.0.8 2018/04/04
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
@@ -125,7 +125,7 @@ process_value:
|
||||
if (valxor & 3)
|
||||
{
|
||||
ide_pri_disable();
|
||||
if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable_ex();
|
||||
if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -206,7 +206,7 @@ process_value:
|
||||
ide_set_side(0, make_port(0x22));
|
||||
break;
|
||||
}
|
||||
if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable_ex();
|
||||
if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
@@ -345,6 +345,4 @@ void fdc37c669_init()
|
||||
io_sethandler(0x3f0, 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, NULL);
|
||||
|
||||
fdc37c669_reset();
|
||||
|
||||
pci_reset_handler.super_io_reset = fdc37c669_reset;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the SMC FDC37C663 and FDC37C665 Super
|
||||
* I/O Chips.
|
||||
*
|
||||
* Version: @(#)sio_fdc37c66x.c 1.0.10 2018/01/16
|
||||
* Version: @(#)sio_fdc37c66x.c 1.0.11 2018/04/04
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -73,7 +73,7 @@ static void ide_handler()
|
||||
}
|
||||
ide_set_base(0, 0x170 | or_value);
|
||||
ide_set_side(0, 0x376 | or_value);
|
||||
ide_pri_enable_ex();
|
||||
ide_pri_enable();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -319,8 +319,6 @@ void fdc37c663_init()
|
||||
io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, NULL);
|
||||
|
||||
fdc37c663_reset();
|
||||
|
||||
pci_reset_handler.super_io_reset = fdc37c663_reset;
|
||||
}
|
||||
|
||||
void fdc37c665_init()
|
||||
@@ -330,6 +328,4 @@ void fdc37c665_init()
|
||||
io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, NULL);
|
||||
|
||||
fdc37c665_reset();
|
||||
|
||||
pci_reset_handler.super_io_reset = fdc37c665_reset;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the SMC FDC37C932FR and FDC37C935 Super
|
||||
* I/O Chips.
|
||||
*
|
||||
* Version: @(#)sio_fdc37c93x.c 1.0.11 2018/03/14
|
||||
* Version: @(#)sio_fdc37c93x.c 1.0.12 2018/04/04
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
@@ -566,14 +566,10 @@ void fdc37c932fr_init(void)
|
||||
{
|
||||
fdc37c93x_init();
|
||||
fdc37c932fr_reset();
|
||||
|
||||
pci_reset_handler.super_io_reset = fdc37c932fr_reset;
|
||||
}
|
||||
|
||||
void fdc37c935_init(void)
|
||||
{
|
||||
fdc37c93x_init();
|
||||
fdc37c935_reset();
|
||||
|
||||
pci_reset_handler.super_io_reset = fdc37c935_reset;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Emulation of the NatSemi PC87306 Super I/O chip.
|
||||
*
|
||||
* Version: @(#)sio_pc87306.c 1.0.9 2018/01/17
|
||||
* Version: @(#)sio_pc87306.c 1.0.10 2018/04/04
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
@@ -256,7 +256,7 @@ process_value:
|
||||
ide_set_side(0, 0x376 | or_value);
|
||||
if (val & 0x40)
|
||||
{
|
||||
ide_pri_enable_ex();
|
||||
ide_pri_enable();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -476,6 +476,4 @@ void pc87306_init()
|
||||
pc87306_reset();
|
||||
|
||||
io_sethandler(0x02e, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, NULL);
|
||||
|
||||
pci_reset_handler.super_io_reset = pc87306_reset;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user