From 47d950be1d14216376d5b694602c7ab4e4fa7efb Mon Sep 17 00:00:00 2001 From: "K.Ohta" Date: Sun, 23 Aug 2015 02:34:49 +0900 Subject: [PATCH] [VM][FM77AV40] Fix using both 2DD and 2D.Now enable to boot from 2DD. [VM][DISK][FM77AV] Fix disk-reading timing of PSY-O-BLADE.Need more adjusting. --- source/src/vm/disk.cpp | 85 ++++++++++++++++++++++++++------ source/src/vm/disk.h | 3 +- source/src/vm/fm7/display.cpp | 46 +++++------------- source/src/vm/fm7/floppy.cpp | 42 +++++++++++----- source/src/vm/fm7/fm7.cpp | 25 ++++++++-- source/src/vm/fm7/fm7_common.h | 4 ++ source/src/vm/fm7/fm7_display.h | 4 +- source/src/vm/fm7/fm7_mainio.cpp | 28 ++++++++--- source/src/vm/fm7/fm7_mainmem.cpp | 100 +++++++++++++++++++++++++++++++++----- source/src/vm/fm7/fm7_mainmem.h | 4 ++ 10 files changed, 257 insertions(+), 84 deletions(-) diff --git a/source/src/vm/disk.cpp b/source/src/vm/disk.cpp index ced4e05f7..779c52990 100644 --- a/source/src/vm/disk.cpp +++ b/source/src/vm/disk.cpp @@ -332,6 +332,63 @@ file_loaded: t += data_size.sd + 0x10; } } + if(is_special_disk == 0) { + t = buffer + offset.d; + sector_num.read_2bytes_le_from(t + 4); + + for(int i = 0; i < sector_num.sd; i++) { + data_size.read_2bytes_le_from(t + 14); + // FIXME : Check Psy-O-Blade (Program) + if(data_size.sd == 0x100 && t[0] == 0 && t[1] == 0 && t[2] == 0x01 && t[3] == 0x01) { + static const uint8 psyoblade_ipl1[] ={ + 0x03, 0x2d, 0x50, 0x53, 0x59, 0xa5, 0x4f, 0xa5, + 0x42, 0x4c, 0x41, 0x44, 0x45, 0x20, 0x20, 0x20, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x31, 0x39, 0x38, 0x38, 0x20, 0x62, + 0x79, 0x20, 0x54, 0x26, 0x45, 0x20, 0x53, 0x4f, + 0x46, 0x54, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0xb6, + 0xfd, 0x05}; + //$03 + $2D + "PSY-O-BLADE Copyright 1988 by T&E SOFT Inc" + $B6 + $FD + $05 + if(memcmp((void *)(t + 0x58), psyoblade_ipl1, sizeof(psyoblade_ipl1)) == 0) { + is_special_disk = SPECIAL_DISK_FM77AV_PSYOBLADE; + //printf("Disk: PSY-O-BLADE\n"); + } + break; + } + t += data_size.sd + 0x10; + } + } + if(is_special_disk == 0) { + t = buffer + offset.d; + sector_num.read_2bytes_le_from(t + 4); + + for(int i = 0; i < sector_num.sd; i++) { + data_size.read_2bytes_le_from(t + 14); + // FIXME : Check Psy-O-Blade (Program) + if(data_size.sd == 0x100 && t[0] == 0 && t[1] == 0 && t[2] == 0x01 && t[3] == 0x01) { + //IPL Signature1 + static const uint8 psyoblade_disk_1[] ={ + 0xc3, 0x00, 0x01, 0x00, 0x1a, 0x50, 0x86, 0xff, + 0xb7, 0xfd, 0x10, 0xb7, 0xfd, 0x0f, 0x30, 0x8c, + 0x0e, 0x8d, 0x35, 0x30, 0x8c, 0x14, 0x8d, 0x30, + 0x30, 0x8c, 0x14, 0x8d, 0x2b, 0x20, 0xfe, 0x0a, + }; + //$00 + $00 + $03 + $14 + "PSY-O-BLADE DISK" + $B6 + $FD + $05 + static const uint8 psyoblade_disk_2[] ={ + 0x00, 0x00, 0x03, 0x14, 0x50, 0x53, 0x59, 0xa5, + 0x4f, 0xa5, 0x42, 0x4c, 0x41, 0x44, 0x45, 0x20, + 0x20, 0x20, 0x44, 0x49, 0x53, 0x4B, 0x20}; + if(memcmp((void *)(t + 0x10), psyoblade_disk_1, sizeof(psyoblade_disk_1)) == 0) { + if(memcmp((void *)(t + 0x40), psyoblade_disk_2, sizeof(psyoblade_disk_2)) == 0) { + is_special_disk = SPECIAL_DISK_FM77AV_PSYOBLADE; + //printf("Disk: PSY-O-BLADE\n"); + } + } + break; + } + t += data_size.sd + 0x10; + } + } } } #elif defined(_X1) || defined(_X1TWIN) || defined(_X1TURBO) || defined(_X1TURBOZ) @@ -458,12 +515,11 @@ bool DISK::get_track(int trk, int side) sector_size.sd = sector_num.sd = 0; invalid_format = false; no_skew = true; - + // disk not inserted or invalid media type if(!(inserted && check_media_type())) { return false; } - // search track int trkside = is_1dd_image ? trk : (trk * 2 + (side & 1)); if(!(0 <= trkside && trkside < 164)) { @@ -471,19 +527,6 @@ bool DISK::get_track(int trk, int side) } cur_track = trk; cur_side = side; - if(media_type == MEDIA_TYPE_2D) { - if((drive_type == DRIVE_TYPE_2DD) || - (drive_type == DRIVE_TYPE_2HD) || - (drive_type == DRIVE_TYPE_144)) { - if(trk & 1 != 0) { - for(int i = 0; i < get_track_size(); i++) { - track[i] = rand(); - } - return false; - } - cur_track = cur_track >> 1; - } - } pair offset; offset.read_4bytes_le_from(buffer + 0x20 + trkside * 4); @@ -683,7 +726,7 @@ bool DISK::get_sector(int trk, int side, int index) if(!(inserted && check_media_type())) { return false; } - + // search track if(trk == -1 && side == -1) { trk = cur_track; @@ -944,6 +987,11 @@ double DISK::get_usec_per_track() double DISK::get_usec_per_bytes(int bytes) { +#if defined(_FM77AV_VARIANTS) + if(is_special_disk == SPECIAL_DISK_FM77AV_PSYOBLADE) { + return 1000000.0 / (get_track_size() * (get_rpm() / 60.0) * 2.0) * bytes; + } +#endif return 1000000.0 / (get_track_size() * (get_rpm() / 60.0)) * bytes; } @@ -956,7 +1004,12 @@ bool DISK::check_media_type() { switch(drive_type) { case DRIVE_TYPE_2D: +#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \ + defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) + return (media_type == MEDIA_TYPE_2D || media_type == MEDIA_TYPE_2DD); +#else return (media_type == MEDIA_TYPE_2D); +#endif case DRIVE_TYPE_2DD: return (media_type == MEDIA_TYPE_2D || media_type == MEDIA_TYPE_2DD); case DRIVE_TYPE_2HD: diff --git a/source/src/vm/disk.h b/source/src/vm/disk.h index a5f88aa1a..9d1bbda3b 100644 --- a/source/src/vm/disk.h +++ b/source/src/vm/disk.h @@ -31,7 +31,8 @@ #define SPECIAL_DISK_X1TURBO_ALPHA 1 #define SPECIAL_DISK_X1_BATTEN 2 #define SPECIAL_DISK_FM7_GAMBLER 11 -#define SPECIAL_DISK_FM7_DEATHFORCE 12 +#define SPECIAL_DISK_FM7_DEATHFORCE 12 +#define SPECIAL_DISK_FM77AV_PSYOBLADE 13 // d88 constant #define DISK_BUFFER_SIZE 0x380000 // 3.5MB diff --git a/source/src/vm/fm7/display.cpp b/source/src/vm/fm7/display.cpp index b7e05c930..2d0ac291e 100644 --- a/source/src/vm/fm7/display.cpp +++ b/source/src/vm/fm7/display.cpp @@ -65,15 +65,8 @@ void DISPLAY::reset_cpuonly() clock_fast = false; break; } - if(clock_fast) { - subclock = SUBCLOCK_NORMAL; - } else { - subclock = SUBCLOCK_SLOW; - } - is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0); - if(!is_cyclesteal) subclock = subclock / 3; - prev_clock = subclock; - p_vm->set_cpu_clock(subcpu, subclock); + is_cyclesteal = ((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? true : false; + enter_display(); #if defined(_FM77AV_VARIANTS) displine = 0; @@ -174,7 +167,6 @@ void DISPLAY::reset() window_xend = 80; window_opened = false; - kanji2_addr.d = 0; #endif #if defined(_FM77L4) mode400line = false; @@ -190,7 +182,7 @@ void DISPLAY::reset() void DISPLAY::update_config() { uint32 subclock; - set_cyclesteal(config.dipswitch & FM7_DIPSW_CYCLESTEAL); // CYCLE STEAL = bit0. + vram_wrote = true; switch(config.cpu_type) { case 0: clock_fast = true; @@ -199,18 +191,11 @@ void DISPLAY::update_config() clock_fast = false; break; } - if(clock_fast) { - subclock = SUBCLOCK_NORMAL; - } else { - subclock = SUBCLOCK_SLOW; - } - if(is_cyclesteal || !(vram_accessflag)) { - // - } else { - if((config.dipswitch & FM7_DIPSW_CYCLESTEAL) == 0) subclock = subclock / 3; - } - p_vm->set_cpu_clock(subcpu, subclock); - prev_clock = subclock; +#if defined(_FM8) + enter_display(); +#else + set_cyclesteal(((config.dipswitch & FM7_DIPSW_CYCLESTEAL) != 0) ? 0 : 1); // CYCLE STEAL = bit0. +#endif } inline void DISPLAY::GETVRAM_8_200L(int yoff, scrntype *p, uint32 mask) @@ -668,11 +653,9 @@ void DISPLAY::enter_display(void) } else { subclock = SUBCLOCK_SLOW; } - if(!is_cyclesteal && vram_accessflag) { if((config.dipswitch & FM7_DIPSW_CYCLESTEAL) == 0) subclock = subclock / 3; } - //halt_subcpu(); if(prev_clock != subclock) p_vm->set_cpu_clock(subcpu, subclock); prev_clock = subclock; } @@ -749,11 +732,12 @@ void DISPLAY::set_cyclesteal(uint8 val) #if !defined(_FM8) vram_wrote = true; val &= 0x01; - if(val != 0) { + if(val == 0) { is_cyclesteal = true; } else { is_cyclesteal = false; } + enter_display(); #endif } @@ -1174,7 +1158,7 @@ void DISPLAY::event_callback(int event_id, int err) void DISPLAY::event_frame() { - enter_display(); + //enter_display(); } void DISPLAY::event_vline(int v, int clock) @@ -1306,7 +1290,7 @@ void DISPLAY::write_signal(int id, uint32 data, uint32 mask) alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff); vram_wrote = true; } - printf("FD04: VAL=%02x MODE=%d PROTECT=%d\n", data, display_mode, ram_protect ? 1 : 0); + //printf("FD04: VAL=%02x MODE=%d PROTECT=%d\n", data, display_mode, ram_protect ? 1 : 0); } #elif defined(_FM77_VARIANTS) { @@ -1342,7 +1326,7 @@ void DISPLAY::write_signal(int id, uint32 data, uint32 mask) alu->write_signal(SIG_ALU_400LINE, (mode400line) ? 0xff : 0x00, 0xff); vram_wrote = true; } - printf("MODE320: MODE=%d\n", display_mode); + //printf("MODE320: MODE=%d\n", display_mode); } #else if(mode320 != flag) { @@ -2459,8 +2443,6 @@ void DISPLAY::save_state(FILEIO *state_fio) state_fio->FputBool(window_opened); state_fio->FputBool(kanji_level2); - state_fio->FputUint8(kanji2_addr.b.l); - state_fio->FputUint8(kanji2_addr.b.h); state_fio->FputUint8(vram_active_block); state_fio->FputUint8(vram_display_block); @@ -2602,8 +2584,6 @@ bool DISPLAY::load_state(FILEIO *state_fio) window_opened = state_fio->FgetBool(); kanji_level2 = state_fio->FgetBool(); - kanji2_addr.b.l = state_fio->FgetUint8(); - kanji2_addr.b.h = state_fio->FgetUint8(); vram_active_block = state_fio->FgetUint8(); vram_display_block = state_fio->FgetUint8(); diff --git a/source/src/vm/fm7/floppy.cpp b/source/src/vm/fm7/floppy.cpp index 7d0544da7..8cba5b8ff 100644 --- a/source/src/vm/fm7/floppy.cpp +++ b/source/src/vm/fm7/floppy.cpp @@ -37,12 +37,12 @@ void FM7_MAINIO::reset_fdc(void) fdc_sectreg = 0x00; fdc_datareg = 0x00; fdc_headreg = 0xfe; - fdc_drvsel = 0x00; + fdc_drvsel = 0x7c; fdc_motor = false; fdc_cmd_type1 = false; #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \ defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) - fdc_reg_fd1e = 0x00; + fdc_reg_fd1e = 0x80; for(int i = 0; i < 4; i++) { fdc_drive_table[i] = (uint8)i; fdc->set_drive_type(i, DRIVE_TYPE_2D); @@ -116,7 +116,19 @@ void FM7_MAINIO::set_fdc_track(uint8 val) { if(!connect_fdc) return; // if mode is 2DD and type-of-image = 2D then val >>= 1; + fdc_trackreg = val; +#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \ + defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) + uint32 d; + if((fdc_drvsel & 0x40) == 0) { + d = fdc_drive_table[fdc_drvsel & 0x03] & 0x03; + } else { + d = fdc_drvsel & 0x03; + } + DISK *disk = fdc->get_disk_handler(d); + if((fdc_reg_fd1e & 0x40 != 0)) val <<= 1; +#endif fdc->write_io8(1, val); #ifdef _FM7_FDC_DEBUG p_emu->out_debug_log(_T("FDC : Set Track: %d"), val); @@ -170,6 +182,10 @@ uint8 FM7_MAINIO::get_fdc_motor(void) if(fdc_motor) val |= 0x80; //fdc_drvsel = fdc->read_signal(SIG_MB8877_READ_DRIVE_REG); val = val | (fdc_drvsel & 0x03); +#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \ + defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) + val = val | (fdc_drvsel & 0x40); +#endif #ifdef _FM7_FDC_DEBUG p_emu->out_debug_log(_T("FDC: Get motor/Drive: $%02x"), val); #endif @@ -202,16 +218,18 @@ void FM7_MAINIO::set_fdc_fd1d(uint8 val) } else { fdc_motor = false; } - fdc_drvsel = val; + #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \ defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) if((val & 0x40) == 0) { fdc->write_signal(SIG_MB8877_DRIVEREG, fdc_drive_table[val & 0x03], 0x03); } else { - fdc->write_signal(SIG_MB8877_DRIVEREG, fdc_drvsel, 0x03); - } + fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03); + } + fdc_drvsel = val; #else - fdc->write_signal(SIG_MB8877_DRIVEREG, fdc_drvsel, 0x03); + fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03); + fdc_drvsel = val; #endif if(fdc_motor != backup_motor) { @@ -232,11 +250,12 @@ uint8 FM7_MAINIO::get_fdc_fd1e(void) { #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \ defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) - uint8 val = 0x80; - if(fdc->get_drive_type(fdc_drvsel & 0x03) == DRIVE_TYPE_2D) { - val |= 0x40; - } - val |= (fdc_reg_fd1e & 0x1f); + uint8 val = 0xa0; +// if(fdc->get_drive_type(fdc_drvsel & 0x03) == DRIVE_TYPE_2D) { +// val |= 0x40; +// } +// val |= (fdc_reg_fd1e & 0x1f); + val |= (fdc_reg_fd1e & 0x5f); return val; #else return 0xff; @@ -262,7 +281,6 @@ void FM7_MAINIO::set_fdc_fd1e(uint8 val) } else { for(drive = 0; drive < MAX_DRIVE; drive++) fdc->set_drive_type(drive, DRIVE_TYPE_2DD); } - #endif } void FM7_MAINIO::set_irq_mfd(bool flag) diff --git a/source/src/vm/fm7/fm7.cpp b/source/src/vm/fm7/fm7.cpp index 3b2638caf..de7053439 100644 --- a/source/src/vm/fm7/fm7.cpp +++ b/source/src/vm/fm7/fm7.cpp @@ -303,7 +303,7 @@ void VM::connect_bus(void) fdc->set_drive_type(i, DRIVE_TYPE_2D); #endif #if defined(_FM77AV_VARIANTS) - fdc->set_drive_rpm(i, 600); + fdc->set_drive_rpm(i, 360); #else fdc->set_drive_rpm(i, 360); #endif @@ -326,10 +326,29 @@ void VM::update_config() #if !defined(_FM8) switch(config.cpu_type){ case 0: - event->set_secondary_cpu_clock(maincpu, MAINCLOCK_NORMAL); +# if defined(HAS_MMR) + if(mainmem->read_data8(FM7_MAINIO_WINDOW_ENABLED) != 0) { + if(mainmem->read_data8(FM7_MAINIO_WINDOW_FAST) != 0) { + event->set_secondary_cpu_clock(maincpu, MAINCLOCK_FAST_MMR); + } else { + event->set_secondary_cpu_clock(maincpu, MAINCLOCK_MMR); + } + } else + if(mainmem->read_data8(FM7_MAINIO_MMR_ENABLED) != 0) { + if(mainmem->read_data8(FM7_MAINIO_FASTMMR_ENABLED) != 0) { + event->set_secondary_cpu_clock(maincpu, MAINCLOCK_FAST_MMR); + } else { + event->set_secondary_cpu_clock(maincpu, MAINCLOCK_MMR); + } + } else { + event->set_secondary_cpu_clock(maincpu, MAINCLOCK_NORMAL); + } +# else + event->set_secondary_cpu_clock(maincpu, MAINCLOCK_NORMAL); +# endif break; case 1: - event->set_secondary_cpu_clock(maincpu, MAINCLOCK_SLOW); + event->set_secondary_cpu_clock(maincpu, MAINCLOCK_SLOW); break; } #endif diff --git a/source/src/vm/fm7/fm7_common.h b/source/src/vm/fm7/fm7_common.h index 3f1f46726..4f9f18fec 100644 --- a/source/src/vm/fm7/fm7_common.h +++ b/source/src/vm/fm7/fm7_common.h @@ -151,7 +151,11 @@ enum { FM7_MAINIO_WINDOW_ENABLED, FM7_MAINIO_WINDOW_OFFSET, FM7_MAINIO_MMR_SEGMENT, + FM7_MAINIO_MMR_EXTENDED, + FM7_MAINIO_WINDOW_FAST, + FM7_MAINMEM_REFRESH_FAST, FM7_MAINIO_MMR_BANK = 0x200100, + }; enum { diff --git a/source/src/vm/fm7/fm7_display.h b/source/src/vm/fm7/fm7_display.h index 4d2671a7b..a7b4360cb 100644 --- a/source/src/vm/fm7/fm7_display.h +++ b/source/src/vm/fm7/fm7_display.h @@ -278,7 +278,9 @@ class DISPLAY: public DEVICE } void set_context_kanjiclass1(DEVICE *p) { -#if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS) // Really? +#if defined(_FM77_VARIANTS) || \ + defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40SX) || \ + defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX) kanjiclass1 = p; #endif } diff --git a/source/src/vm/fm7/fm7_mainio.cpp b/source/src/vm/fm7/fm7_mainio.cpp index 4027d1eb2..e46dc8eee 100644 --- a/source/src/vm/fm7/fm7_mainio.cpp +++ b/source/src/vm/fm7/fm7_mainio.cpp @@ -1062,6 +1062,10 @@ uint32 FM7_MAINIO::read_data8(uint32 addr) retval = (uint32) get_fdc_motor(); //printf("FDC: READ MOTOR REG %02x\n", retval); break; + case 0x1e: + retval = (uint32) get_fdc_fd1e(); + //printf("FDC: READ MOTOR REG %02x\n", retval); + break; case 0x1f: retval = (uint32) fdc_getdrqirq(); break; @@ -1143,12 +1147,6 @@ uint32 FM7_MAINIO::read_data8(uint32 addr) return retval; } #endif -#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \ - defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX) - else if(addr == FM7_MAINIO_EXTBANK) { - } else if(addr == FM7_MAINIO_EXTROM) { - } -#endif //if((addr >= 0x0006) && (addr != 0x1f)) printf("MAINIO: READ: %08x DATA=%08x\n", addr); return 0xff; } @@ -1276,6 +1274,9 @@ void FM7_MAINIO::write_data8(uint32 addr, uint32 data) set_fdc_fd1d((uint8)data); //printf("FDC: WRITE MOTOR REG %02x\n", data); break; + case 0x1e: + set_fdc_fd1e((uint8)data); + break; case 0x1f: // ?? return; break; @@ -1353,6 +1354,19 @@ void FM7_MAINIO::write_data8(uint32 addr, uint32 data) //} break; #endif +#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \ + defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX) + case 0x94: + mainmem->write_signal(FM7_MAINIO_MMR_EXTENDED, data, 0x80); + mainmem->write_signal(FM7_MAINMEM_REFRESH_FAST, data, 0x04); + mainmem->write_signal(FM7_MAINIO_WINDOW_FAST , data, 0x01); + + break; + case 0x95: + mainmem->write_signal(FM7_MAINIO_FASTMMR_ENABLED, data, 0x08); + mainmem->write_signal(FM7_MAINIO_EXTROM, data & 0x80, 0x80); + break; +#endif #if defined(HAS_DMA) case 0x98: dma_addr = data & 0x1f; @@ -1639,7 +1653,7 @@ bool FM7_MAINIO::load_state(FILEIO *state_fio) stat_400linecard = state_fio->FgetBool(); #elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \ defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) - stat_kanjirom = state_fio->FputBool(); + stat_kanjirom = state_fio->FgetBool(); #endif firq_break_key = state_fio->FgetBool(); firq_sub_attention = state_fio->FgetBool(); diff --git a/source/src/vm/fm7/fm7_mainmem.cpp b/source/src/vm/fm7/fm7_mainmem.cpp index 13b7dc120..bc6f37fb8 100644 --- a/source/src/vm/fm7/fm7_mainmem.cpp +++ b/source/src/vm/fm7/fm7_mainmem.cpp @@ -47,14 +47,14 @@ void FM7_MAINMEM::reset() } #endif #ifdef HAS_MMR - //for(i = 0x00; i < 0x80; i++) { - // mmr_map_data[i] = 0; - //} + mmr_extend = false; mmr_segment = 0; window_offset = 0; mmr_enabled = false; mmr_fast = false; window_enabled = false; + window_fast = false; + refresh_fast = false; #endif if((bootmode & 0x03) == 0) { // IF BASIC BOOT THEN ROM basicrom_fd0f = true; @@ -63,9 +63,58 @@ void FM7_MAINMEM::reset() } clockmode = (config.cpu_type == 0) ? true : false; is_basicrom = ((bootmode & 0x03) == 0) ? true : false; + } - +void FM7_MAINMEM::setclock(int mode) +{ + uint32 clock = MAINCLOCK_SLOW; + if(mode == 1) { // SLOW + clock = MAINCLOCK_SLOW; // Temporally +#if defined(HAS_MMR) + if(!mmr_fast && !window_fast) { + if(refresh_fast) { + if(mmr_enabled || window_enabled) { + clock = (uint32)((double)clock * 1.089); + } else { + clock = (uint32)((double)clock * 1.086); + } + } + } +#endif + } else { +#if defined(HAS_MMR) + if(window_enabled) { + if(window_fast) { + clock = MAINCLOCK_FAST_MMR; + } else { + clock = MAINCLOCK_MMR; + } + } else if(mmr_enabled) { + if(mmr_fast) { + clock = MAINCLOCK_FAST_MMR; + } else { + clock = MAINCLOCK_MMR; + } + } else { + clock = MAINCLOCK_NORMAL; + } + if(!mmr_fast && !window_fast) { + if(refresh_fast) { + if(mmr_enabled || window_enabled) { + clock = (uint32)((double)clock * 1.089); + } else { + clock = (uint32)((double)clock * 1.086); + } + } + } +#else + clock = MAINCLOCK_NORMAL; +#endif + } + p_vm->set_cpu_clock(maincpu, clock); +} + void FM7_MAINMEM::wait() { @@ -73,6 +122,7 @@ void FM7_MAINMEM::wait() // If memory, factor = 2? if(!clockmode) return; // SLOW #ifdef HAS_MMR + //if(!mmr_fast && !window_fast && (window_enabled || mmr_enabled)) waitfactor = 2; if(!ioaccess_wait) { waitfactor = 2; ioaccess_wait = true; @@ -81,8 +131,6 @@ void FM7_MAINMEM::wait() if(mmr_fast) waitfactor = 2; ioaccess_wait = false; } - if((window_enabled) && - (mmr_enabled)) waitfactor = 2; #else waitfactor = 2; #endif @@ -123,8 +171,11 @@ int FM7_MAINMEM::mmr_convert(uint32 addr, uint32 *realaddr) #ifdef HAS_MMR if(addr >= 0xfc00) return -1; - mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | (mmr_segment << 4)] & 0x007f; - + if(mmr_extend) { + mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((mmr_segment & 0x03) << 4)] & 0x003f; + } else { + mmr_bank = mmr_map_data[(addr >> 12) & 0x000f | ((mmr_segment & 0x07) << 4)] & 0x007f; + } // Reallocated by MMR // Bank 3x : Standard memories. if((mmr_bank < 0x3f) && (mmr_bank >= 0x30)) { @@ -193,8 +244,8 @@ int FM7_MAINMEM::mmr_convert(uint32 addr, uint32 *realaddr) case 0x2e: if(((dbank & 0x40) != 0) && (dictrom_connected)) { // Dictionary ROM dbank = dbank & 0x3f; - uint32 extrom = mainio->read_data8(FM7_MAINIO_EXTROM) & 0x80; - //uint32 extrom = extrom_bank; + //uint32 extrom = mainio->read_data8(FM7_MAINIO_EXTROM) & 0x80; + uint32 extrom = extrom_bank; if(extrom == 0) { // Dictionary selected. dbank = dbank << 12; *realaddr = raddr | dbank; @@ -236,7 +287,7 @@ int FM7_MAINMEM::mmr_convert(uint32 addr, uint32 *realaddr) #endif #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \ defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX) - else if(extram_connected) { // PAGE 4- + else if(extram_connected && mmr_extend) { // PAGE 4- if(major_bank >= (extram_pages + 4)) { *realaddr = 0; return FM7_MAINMEM_NULL; // $FF @@ -511,12 +562,21 @@ uint32 FM7_MAINMEM::read_signal(int sigid) case FM7_MAINIO_WINDOW_ENABLED: value = (window_enabled) ? 0xffffffff : 0x00000000; break; + case FM7_MAINIO_WINDOW_FAST: + value = (window_fast) ? 0xffffffff : 0x00000000; + break; case FM7_MAINIO_FASTMMR_ENABLED: value = (mmr_fast) ? 0xffffffff : 0x00000000; break; case FM7_MAINIO_MMR_ENABLED: value = (mmr_enabled) ? 0xffffffff : 0x00000000; break; + case FM7_MAINIO_MMR_EXTENDED: + value = (mmr_extend) ? 0xffffffff : 0x00000000; + break; + case FM7_MAINMEM_REFRESH_FAST: + value = (refresh_fast) ? 0xffffffff : 0x00000000; + break; #endif #if defined(_FM77AV_VARIANTS) case FM7_MAINIO_INITROM_ENABLED: @@ -566,12 +626,26 @@ void FM7_MAINMEM::write_signal(int sigid, uint32 data, uint32 mask) #ifdef HAS_MMR case FM7_MAINIO_WINDOW_ENABLED: window_enabled = flag; + setclock(config.cpu_type); + break; + case FM7_MAINIO_WINDOW_FAST: + window_fast = flag; + setclock(config.cpu_type); break; case FM7_MAINIO_FASTMMR_ENABLED: mmr_fast = flag; + setclock(config.cpu_type); break; case FM7_MAINIO_MMR_ENABLED: mmr_enabled = flag; + setclock(config.cpu_type); + break; + case FM7_MAINIO_MMR_EXTENDED: + mmr_extend = flag; + break; + case FM7_MAINMEM_REFRESH_FAST: + refresh_fast = flag; + setclock(config.cpu_type); break; #endif } @@ -1209,6 +1283,8 @@ void FM7_MAINMEM::save_state(FILEIO *state_fio) state_fio->FputBool(mmr_enabled); state_fio->FputBool(mmr_fast); state_fio->FputUint16_BE(window_offset); + state_fio->FputBool(window_fast); + state_fio->FputBool(refresh_fast); state_fio->FputUint8(mmr_segment); state_fio->Fwrite(mmr_map_data, sizeof(mmr_map_data), 1); #endif @@ -1307,6 +1383,8 @@ bool FM7_MAINMEM::load_state(FILEIO *state_fio) mmr_enabled = state_fio->FgetBool(); mmr_fast = state_fio->FgetBool(); window_offset = state_fio->FgetUint16_BE(); + window_fast = state_fio->FgetBool(); + refresh_fast = state_fio->FgetBool(); mmr_segment = state_fio->FgetUint8(); state_fio->Fread(mmr_map_data, sizeof(mmr_map_data), 1); #endif diff --git a/source/src/vm/fm7/fm7_mainmem.h b/source/src/vm/fm7/fm7_mainmem.h index e17885a8b..fd0453319 100644 --- a/source/src/vm/fm7/fm7_mainmem.h +++ b/source/src/vm/fm7/fm7_mainmem.h @@ -34,8 +34,11 @@ class FM7_MAINMEM : public DEVICE // V2 #ifdef HAS_MMR bool window_enabled; + bool window_fast; bool mmr_enabled; bool mmr_fast; + bool mmr_extend; + bool refresh_fast; uint16 window_offset; uint8 mmr_segment; uint8 mmr_map_data[0x80]; @@ -116,6 +119,7 @@ class FM7_MAINMEM : public DEVICE int nonmmr_convert(uint32 addr, uint32 *realaddr); uint32 read_bios(const char *name, uint8 *ptr, uint32 size); uint32 write_bios(const char *name, uint8 *ptr, uint32 size); + void setclock(int mode); public: FM7_MAINMEM(VM* parent_vm, EMU* parent_emu); -- 2.11.0