2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
14 //#define _DEBUG_PC80S31K
16 #define SET_BANK(s, e, w, r) { \
17 int sb = (s) >> 13, eb = (e) >> 13; \
18 for(int i = sb; i <= eb; i++) { \
22 wbank[i] = (w) + 0x2000 * (i - sb); \
27 rbank[i] = (r) + 0x2000 * (i - sb); \
32 void PC80S31K::initialize()
35 pc80s31k_no_wait = osd->check_feature(_T("PC80S31K_NO_WAIT"));
36 _debug_pc80s31k = osd->check_feature(_T("_DEBUG_PC80S31K"));
38 memset(rom, 0xff, sizeof(rom));
39 memset(ram, 0, sizeof(ram));
40 memset(rdmy, 0xff, sizeof(rdmy));
43 FILEIO* fio = new FILEIO();
44 if(fio->Fopen(create_local_path(_T("PC88.ROM")), FILEIO_READ_BINARY)) {
45 fio->Fseek(0x14000, FILEIO_SEEK_CUR);
46 fio->Fread(rom, sizeof(rom), 1);
48 } else if(fio->Fopen(create_local_path(_T("DISK.ROM")), FILEIO_READ_BINARY)) {
49 fio->Fread(rom, sizeof(rom), 1);
53 d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
58 SET_BANK(0x0000, 0x1fff, wdmy, rom);
59 SET_BANK(0x2000, 0x3fff, wdmy, rdmy);
60 SET_BANK(0x4000, 0x7fff, ram, ram);
61 SET_BANK(0x8000, 0xffff, wdmy, rdmy);
64 // both drives always set force ready signal
65 d_fdc->write_signal(SIG_UPD765A_FREADY, 1, 1);
68 void PC80S31K::reset()
70 d_fdc->set_drive_type(0, DRIVE_TYPE_2D);
71 d_fdc->set_drive_type(1, DRIVE_TYPE_2D);
74 d_pio->write_io8(1, 0);
75 d_pio->write_io8(2, 0);
78 uint32_t PC80S31K::read_data8(uint32_t addr)
81 return rbank[addr >> 13][addr & 0x1fff];
84 uint32_t PC80S31K::fetch_op(uint32_t addr, int *wait)
87 //#ifdef PC80S31K_NO_WAIT
88 if(pc80s31k_no_wait) {
90 // no access wait (both ROM and RAM)
94 *wait = (addr < 0x2000) ? 1 : 0;
97 return rbank[addr >> 13][addr & 0x1fff];
100 void PC80S31K::write_data8(uint32_t addr, uint32_t data)
103 if(addr == 0x7f15 && data == 0x1f && d_cpu->get_pc() < 0x2000) {
104 // ugly patch to enable both #1 and #2 drives
107 wbank[addr >> 13][addr & 0x1fff] = data;
110 uint32_t PC80S31K::read_io8(uint32_t addr)
114 switch(addr & 0xff) {
116 d_fdc->write_signal(SIG_UPD765A_TC, 1, 1);
120 return d_fdc->read_io8(addr & 1);
123 val = d_pio->read_io8(addr & 3);
124 //#ifdef _DEBUG_PC80S31K
125 if(_debug_pc80s31k) this->out_debug_log(_T("SUB\tIN RECV(%d)=%2x\n"), addr & 3, val);
129 val = d_pio->read_io8(addr & 3);
130 //#ifdef _DEBUG_PC80S31K
131 if(_debug_pc80s31k) {
132 static uint32_t prev = -1;
134 // this->out_debug_log(_T("SUB\tIN DAV=%d,RFD=%d,DAC=%d,ATN=%d\n"), val&1, (val>>1)&1, (val>>2)&1, (val>>3)&1);
144 void PC80S31K::write_io8(uint32_t addr, uint32_t data)
146 switch(addr & 0xff) {
149 // MR/MH/MA/MA2/MA... type ROM only
150 if(rom[0x7ee] != 0xfe) {
153 for(int drv = 0; drv < 2; drv++) {
154 uint32_t mode = data >> drv;
156 d_fdc->set_drive_type(drv, DRIVE_TYPE_2HD);
157 } else if(mode & 4) {
158 d_fdc->set_drive_type(drv, DRIVE_TYPE_2DD);
160 d_fdc->set_drive_type(drv, DRIVE_TYPE_2D);
165 // external printer port
168 // TODO: we need to update uPD765A to let the motor of each drive on/off
171 d_fdc->write_io8(addr & 1, data);
175 //#ifdef _DEBUG_PC80S31K
176 if(_debug_pc80s31k) this->out_debug_log(_T("SUB\tOUT SEND(%d)=%2x\n"), addr & 3, data);
178 d_pio->write_io8(addr & 3, data);
181 // this->out_debug_log(_T("SUB\tOUT DAV=%d,RFD=%d,DAC=%d,ATN=%d\n"), (data>>4)&1, (data>>5)&1, (data>>6)&1, (data>>7)&1);
182 d_pio->write_io8(addr & 3, data);
186 int bit = (data >> 1) & 7;
188 // this->out_debug_log(_T("SUB\tOUT DAV=%d\n"), data & 1);
189 } else if(bit == 5) {
190 // this->out_debug_log(_T("SUB\tOUT RFD=%d\n"), data & 1);
191 } else if(bit == 6) {
192 // this->out_debug_log(_T("SUB\tOUT DAC=%d\n"), data & 1);
193 } else if(bit == 7) {
194 // this->out_debug_log(_T("SUB\tOUT ATN=%d\n"), data & 1);
197 d_pio->write_io8(addr & 3, data);
202 uint32_t PC80S31K::get_intr_ack()
207 #define STATE_VERSION 1
209 bool PC80S31K::process_state(FILEIO* state_fio, bool loading)
212 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
215 if(!state_fio->StateCheckInt32(this_device_id)) {
218 state_fio->StateArray(ram, sizeof(ram), 1);