From: K.Ohta Date: Tue, 24 Feb 2015 09:02:13 +0000 (+0900) Subject: [VM][FM7] Display sub system : more improve implement. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=36ddda12b63b3d743634f5cab4482b39a69ebd83;p=csp-qt%2Fcommon_source_project-fm7.git [VM][FM7] Display sub system : more improve implement. --- diff --git a/source/src/vm/fm7/display.cpp b/source/src/vm/fm7/display.cpp index 8bcc69119..e6ef2a432 100644 --- a/source/src/vm/fm7/display.cpp +++ b/source/src/vm/fm7/display.cpp @@ -18,76 +18,472 @@ extern "C" { DISPLAY::DISPLAY() { - initvramtbl_4096_vec(); + initvramtbl_4096_vec(); } void DISPLAY::getvram(uint32 *pvram, uint32 pitch) { - int y; - int height = (display_mode == DISPLAY_MODE_8_400L)? 400 : 200; - Uint32 *p; - Uint32 offset = 0x4000; - if(display_mode == DISPLAY_MODE_8_400L) offset = 0x8000; + int y; + int height = (display_mode == DISPLAY_MODE_8_400L) ? 400 : 200; + Uint32 *p; + Uint32 planesize = 0x4000; + uint32 offset; + + if(display_mode == DISPLAY_MODE_8_400L) planesize = 0x8000; +#if defined(_FM77AV_VARIANTS) + if(offset_77av) { + offset = offset_point; + } else { + offset = offset_point & 0x7fff; + } +#else + offset = offset_point & 0x7fff; +#endif + if(display_mode != DISPLAY_MODE_8_400L) offset = offset & 0x3fff; + + + if(!crtflag) { + // Set blank + PutBlank(p, height); + } else if((display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_200L)) { + for(y = 0; y < height; y++) { + p = &pvram[y * pitch]; + if(((y < window_low) && (y > window_high)) || (!window_opened)) { + CreateVirtualVram8_Line(p, y, digital_palette, planesize, offset,multimode_dispmask); + } else { + CreateVirtualVram8_WindowedLine(p, y, window_xbegin, window_xend, + digital_palette, planesize, offset, multimode_dispmask); + } + } + } else if(display_mode == DISPLAY_MODE_4096) { + for(y = 0; y < height; y++) { + p = &pvram[y * pitch]; + if(((y < window_low) && (y > window_high)) || (!window_opened)) { + CreateVirtualVram4096_Line(p, y, offset, analog_palette, multimode_dispmask); + } else { + CreateVirtualVram4096_WindowedLine(p, y, window_xbegin, window_xend, + offset, analog_palette, multimode_dispmask); + } + } + } else { // 256k + for(y = 0; y < height; y++) { + p = &pvram[y * pitch]; + if(((y < window_low) && (y > window_high)) || (!window_opened)) { + CreateVirtualVram256k_Line(p, y, offset, multimode_dispmask); + } else { + CreateVirtualVram256k_WindowedLine(p, y, offset, window_xbegin, window_xend, + multimode_dispmask); + } + } + } +} + +void DISPLAY::set_multimode(uint8 val) +{ + multimode_accessmask = val & 0x07; + multimode_dispmask = (val & 0x70) >> 4; +} + +uint8 DISPLAY::get_multimode(void) +{ + uint8 val = multimode_accessmask & 0x07; + val |= ((multimode_dispmask << 4) & 0x70); + return val; +} + +uint8 DISPLAY::get_cpuaccessmask(void) +{ + return muitimode_accessmask & 0x07; +} + +void DISPLAY::set_dpalette(uint32 addr, uint8 val) +{ + scrntype r, g, b; + addr &= 7; + + dpalette_data[addr] = val | 0b11111000; + b = ((val & 0x01) != 0x00)? 255 : 0x00; + r = ((val & 0x02) != 0x00)? 255 : 0x00; + g = ((val & 0x04) != 0x00)? 255 : 0x00; + dpalette_pixel[addr] = RGB_COLOR(r, g, b); +} + +uint8 DISPLAY::get_dpalette(uint32 addr) +{ + uint8 data; + addr = addr & 7; + + data = dpalet_data[addr]; + return data; +} + +void DISPLAY::calc_apalette(uint32 index) +{ +#if defined(_FM77AV_VARIANTS) + scrntype r, g, b; + r = (apalette_r[index] == 0)? 0 : apalette_r[index] << 4; // + 0x0f? + g = (apalette_g[index] == 0)? 0 : apalette_g[index] << 4; // + 0x0f? + b = (apalette_b[index] == 0)? 0 : apalette_b[index] << 4; // + 0x0f? + apalette_pixel[index] = RGB_COLOR(r, g, b); +#endif +} + +// FD34 +void DISPLAY::set_apalette_g(uint8 val) +{ +#if defined(_FM77AV_VARIANTS) + uint32 index; + index = apalette_index & 0xfff; + apalette_g[index] = val & 0x0f; + calc_apalette(index); +#endif +} + +// FD33 +void DISPLAY::set_apalette_r(uint8 val) +{ +#if defined(_FM77AV_VARIANTS) + uint32 index; + index = apalette_index & 0xfff; + apalette_r[index] = val & 0x0f; + calc_apalette(index); +#endif +} + +// FD32 +void DISPLAY::set_apalette_b(uint8 val) +{ +#if defined(_FM77AV_VARIANTS) + uint32 index; + index = apalette_index & 0xfff; + apalette_b[index] = val & 0x0f; + calc_apalette(index); +#endif +} + +// FD30 +void DISPLAY::set_apalette_index_hi(uint8 val) +{ +#if defined(_FM77AV_VARIANTS) + uint32 index = (uint32)val; + index &= 0x0f; + index <<= 8; // right? + + apalette_index = (apalette_index & 0xff) | index; +#endif +} + +// FD31 +void DISPLAY::set_apalette_index_lo(uint8 val) +{ +#if defined(_FM77AV_VARIANTS) + uint32 index = (uint32)val; + index &= 0xff; + + apalette_index = (apalette_index & 0xf00) | index; +#endif +} + +//SUB:D409:R +uint8 DISPLAY::set_vramaccess(void) +{ + vram_accessflag = true; + if(!is_cyclesteal) { + vram_cpuaccess = true; + } else { + vram_cpuaccess = false; + leave_display(); + } + return 0xff; +} + +//SUB:D409:W +void DISPLAY::reset_vramaccess(void) +{ + vram_accessflag = false; + vram_cpuaccess = false; + leave_display(); +} + +//SUB:D40A:R +uint8 DISPLAY::reset_subbusy(void) +{ + maincpu->write_signal(FM7_SUB_BUSY, 0x00, 0x01); + return 0xff; +} + +//SUB:D40A:W +void DISPLAY::set_subbusy(void) +{ + maincpu->write_signal(FM7_SUB_BUSY, 0x01, 0x01); +} + +//SUB:D430:R +uint8 DISPLAY::get_miscreg(void) +{ + uint8 ret; +#if defined(_FM77AV_VARIANTS) + ret = 0x00; + if(!hblank && !vblank) ret |= 0x80; + if(vsync) ret |= 0x40; + if(alu->read_signal(SIG_ALU_BUSY) == 0) ret |= 0x10; + if(subreset) ret |= 0x01; +#else // 77 or older. + ret = 0xff; +#endif + return ret; +} +//SUB:D430:W +void DISPLAY::set_miscreg(uint8 val) +{ - if((display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_200L)) { - for(y = 0; y < height; y++) { - p = &pvram[y * pitch]; - if(((y < window_low) && (y > window_high)) || (!window_opened)) { - CreateVirtualVram8_Line(p, y, digital_palette, offset, multimode_dispmask); - } else { - CreateVirtualVram8_WindowedLine(p, y, window_xbegin, window_xbegin, digital_palette, offset, multimode_dispmask); - } - } - } else if(display_mode == DISPLAY_MODE_4096) { - for(y = 0; y < height; y++) { - p = &pvram[y * pitch]; - if(((y < window_low) && (y > window_high)) || (!window_opened)) { - CreateVirtualVram4096_Line(p, y, analog_palette, multimode_dispmask); - } else { - CreateVirtualVram4096_WindowedLine(p, y, window_xbegin, window_xbegin, analog_palette, multimode_dispmask); - } +#if defined(_FM77AV40) || defined(_FM77AV40EX) || || defined(_FM77AV40SX) + nmi_enable = ((val & 0x80) == 0) ? true : false; +#endif +#if defined(_FM77AV_VARIANTS) + if((val & 0x40) == 0) { + if(display_page != 0) { + redrawreq(); } - } else { // 256k - for(y = 0; y < height; y++) { - p = &pvram[y * pitch]; - if(((y < window_low) && (y > window_high)) || (!window_opened)) { - CreateVirtualVram256k_Line(p, y, multimode_dispmask); - } else { - CreateVirtualVram256k_WindowedLine(p, y, window_xbegin, window_xbegin, multimode_dispmask); - } + display_page = 0; + } else { + if(display_page == 0) { + redrawreq(); } - } + display_page = 1; + } + active_page = ((val & 0x20) == 0) ? 0 : 1; + if((val & 0x04) == 0) { + offset_77av = false; + } else { + offset_77av = true; + } + submem->write_signal(SIG_FM7SUBMEM_CGROM, val, 0x03); +#endif +} +void DISPLAY::enter_display(void) +{ + if(vram_cpuaccess) { + vram_wait = true; + subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01); + } +} + +void DISPLAY::leave_display(void) +{ + vram_wait = false; + if(sub_run) { + subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01); + } +} + +void DISPLAY::halt_subsystem(void) +{ + sub_run = false; + subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01); + maincpu->write_signal(FM7_SUB_BUSY, 0x01, 0x01); // BUSY +} + +void DISPLAY::restart_subsystem(void) +{ + sub_run = true; + if(!vram_wait) subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01); +} + +//SUB:D408:R +void DISPLAY::set_crtflag(void) +{ + crt_flag = true; +} + +//SUB:D408:W +void DISPLAY::reset_crtflag(void) +{ + crt_flag = false; } -void set_multimode(uint8 val) +//SUB:D402:R +uint8 DISPLAY::cancel_irq(void) { - multimode_accessmask = val & 0x0f; - multimode_dispmask = (val & 0xf0) >> 4; + this->write_signal(SIG_FM7_SUB_CANCEL, 0x01, 0x01); + return 0xff; } -uint8 get_multimode(void) +//SUB:D403:R +uint8 DISPLAY::beep(void) { - uint8 val = multimode_acdcessmask & 0x0f; - val |= ((multimode_dispmask << 4) & 0xf0); - return val; + mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01); + return 0xff; // True? } -void set_dpalette(uint32 addr, uint8 val) + +// SUB:D404 : R +uint8 DISPLAY::attention_irq(void) { - addr &= 7; + mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01); + return 0xff; +} + +// SUB:D405:W +void DISPLAY::set_cyclesteal(uint8 val) +{ + val &= 0x01; + if(val != 0) { + is_cyclesteal = true; + } else { + is_cyclesteal = false; + } +} - dpalet[addr][0] = ((val & 0x01) != 0x00)? 0x01 : 0x00; - dpalet[addr][1] = ((val & 0x02) != 0x00)? 0x01 : 0x00; - dpalet[addr][2] = ((val & 0x04) != 0x00)? 0x01 : 0x00; - dpalet[addr][3] = ((val & 0x08) != 0x00)? 0x01 : 0x00; + + +// Main: FD13 +void DISPLAY::set_monitor_bank(uint8 var) +{ +#if defined(_FM77AV_VARIANTS) + if(is_77av40) { + if((var & 0x04) != 0) { + submem->write_signal(SIG_FM7SUBMEM_MONITOR_RAM, 0x01, 0x01); + } else { + submem->write_signal(SIG_FM7SUBMEM_MONITOR_RAM, 0x00, 0x01); + submem->write_signal(SIG_FM7SUBMEM_MONITOR_ROM, (uint32)var, 0x03); + } + subrom_bank = var & 0x07; + } else { + mem->write_signal(SIG_FM7SUBMEM_MONITOR_RAM, 0x00, 0x01); + submem->write_signal(SIG_FM7SUBMEM_MONITOR_ROM, (uint32)var, 0x03); + subrom_bank = var & 0x03; + } + subcpu_resetreq = true; + maincpu->write_signal(FM7_SUB_BUSY, 0x01, 0x01); +#endif } -uint8 get_dpalette(uint32 addr) +// Timing values from XM7 . Thanks Ryu. +void DISPLAY::event_callback(int event_id, int err) { - uint8 data; - addr = addr & 7; + double usec; + bool f; + switch(event_id) { + case EVENT_FM7SUB_DISPLAY_HALT: + enter_display(); + usec = (2000000.0 / 3.0) / this->event->frame_rate(); // is this right? + register_event(this, EVENT_FM7SUB_DISPLAY_RUN, usec, false, NULL); // NEXT CYCLE_ + break; + case EVENT_FM7SUB_DISPLAY_RUN: + leave_display(); + usec = (1000000.0 / 3.0) / this->event->frame_rate(); // is this right? + register_event(this, EVENT_FM7SUB_DISPLAY_HALT, usec, false, NULL); // NEXT CYCLE_ + break; + case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms + subcpu->write_signal(SIG_CPU_NMI, 0x01, 0x01); + break; + case EVENT_FM7SUB_HDISP: + hblank = false; + usec = 39.5; + if(is_400line) usec = 30.0; + register_event(this, EVENT_FM7SUB_HBLANK, usec, false, NULL); // NEXT CYCLE_ + break; + case EVENT_FM7SUB_HBLANK: + hblank = true; + f = false; + displine++; + if(is_400line) { + usec = 11.0; + if(displine < 400) f = true; + } else { + usec = 24.0; + if(displine < 200) f = true; + } + if(f) { + register_event(this, EVENT_FM7SUB_HDISP, usec, false, NULL); // NEXT CYCLE_ + } else { + // Vblank? + vblank = true; + vsync = true; + if(is_400line) { + usec = 0.31 * 1000.0; + } else { + usec = 0.51 * 1000.0; + } + register_event(this, EVENT_FM7SUB_VSYNC, usec, false, NULL); // NEXT CYCLE_ + } + break; + case EVENT_FM7SUB_VSTART: // Call first. + vblank = false; + vsync = false; + hblank = true; + displine = 0; + if(is_400line) { + usec = 11.0; + } else { + usec = 24.0; + } + register_event(this, EVENT_FM7SUB_HDISP, usec, false, NULL); // NEXT CYCLE_ + break; + case EVENT_FM7SUB_VSYNC: + vblank = true; + vsync = false; + if(is_400line) { + usec = 0.98 * 1000.0; + } else { + usec = 1.91 * 1000.0; + } + register_event(this, EVENT_FM7SUB_VSTART, usec, false, NULL); // NEXT CYCLE_ + break; + } +} - data = (dpalet[addr][0] & 0x01) | ((dpalet[addr][1] & 0x01) << 1) | - ((dpalet[addr][2] & 0x01) << 2) | ((dpalet[addr][3] & 0x01) << 3); - return data; +void DISPLAY::write_signal(int id, uint32 data, uint32 mask) +{ + bool flag = ((data & mask) != 0); + switch(id) { + case SIG_FM7_SUB_HALT: + if(flag) { + halt_subsystem(); + } else { + if(!sub_run) restart_subsytem(); + if(subcpu_resetreq) { + subcpu->reset(); + subcpu_resetreq = false; + } + } + break; + case SIG_FM7_SUB_CANCEL: + if((flag) && (sub_run)) subcpu->write_signal(SIG_CPU_IRQ, 1, 1); + break; +#if defined(_FM77AV_VARIANTS) + case SIG_FM7_SUB_BANK: // Main: FD13 + set_monitor_bank(data & 0xff); + break; +#endif // _FM77AV_VARIANTS + case SIG_FM7_SUB_DPALETTE_ADDR: // Main: FD38-FD3F + dpalette_addr = data & 0x07; + break; + case SIG_FM7_SUB_DPALETTE_DATA: // Main: FD38-FD3F + set_dpalette(dpalette_addr, (uint8)data & 0x07); + break; + case SIG_FM7_SUB_MULTIPAGE: + set_multimode(data & 0xff); + break; +#if defined(_FM77AV_VARIANTS) + case SIG_FM7_SUB_APALETTE_ADDR_HI: + set_apalette_index_hi(data & 0xff); + break; + case SIG_FM7_SUB_APALETTE_ADDR_LO: + set_apalette_index_lo(data & 0xff); + break; + case SIG_FM7_SUB_APALETTE_DATA_R: + set_apalette_r(data & 0xff); + break; + case SIG_FM7_SUB_APALETTE_DATA_G: + set_apalette_g(data & 0xff); + break; + case SIG_FM7_SUB_APALETTE_DATA_B: + set_apalette_b(data & 0xff); + break; +#endif // _FM77AV_VARIANTS + default: + break; + } } diff --git a/source/src/vm/fm7/fm7_mainio.cpp b/source/src/vm/fm7/fm7_mainio.cpp index b2a5616a3..856d2c38f 100644 --- a/source/src/vm/fm7/fm7_mainio.cpp +++ b/source/src/vm/fm7/fm7_mainio.cpp @@ -208,8 +208,8 @@ void FM7_MAINIO::set_beep(uint32 data) // fd03 beep->write_signal(SIG_BEEP_MUTE, data , 0b00000001); if((data & 0x40) != 0) { // beep->write_signal(SIG_BEEP_ON, 0b01000000, 0b01000000); - // BEEP ON, after 200ms, BEEP OFF. - register_event(this, EVENT_BEEP_OFF, 200.0 * 1000.0, false, NULL); // NEXT CYCLE + // BEEP ON, after 205ms, BEEP OFF. + register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE } } @@ -322,8 +322,8 @@ void FM7_MAINIO::set_fd04(uint8 val) void FM7_MAINIO::set_fd05(uint8 val) { - subio->write_signal(SIG_SUBIO_HALT, val, 0b10000000); - subio->write_signal(SIG_SUBIO_IRQ, val, 0b01000000); + display->write_signal(SIG_FM7_SUB_HALT, val, 0b10000000); + display->write_signal(SIG_FM7_SUB_CANCEL, val, 0b01000000); if((val & 0b10000000) == 0) { sub_haltreq = false; } else { @@ -338,6 +338,8 @@ void FM7_MAINIO::set_fd04(uint8 val) } } + + void FM7_MAINIO::set_extdet(bool flag) { extdet_neg = flag; @@ -622,6 +624,7 @@ void FM7_MAINIO::write_signals(int id, uint32 data, uint32 mask) break; case FM7_MAINIO_BEEP: beep->write_signal(SIG_BEEP_ON, data, mask); + register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE break; case FM7_MAINIO_OPNPORTA_CHANGED: opnport_a = data & mask; @@ -670,6 +673,7 @@ void FM7_MAINIO::write_signals(int id, uint32 data, uint32 mask) } + uint8 FM7_MAINIO::fdc_getdrqirq(void) { return irqstat_fdc; @@ -996,6 +1000,18 @@ void FM7_MAINIO::write_data8(uint32 addr, uint32 data) return; } +void FM7_MAINIO::event_callback(int event_id, int err) +{ + switch(event_id) { + case EVENT_BEEP_OFF: + beep->write_signal(SIG_BEEP_ON, 0x00, 0x01); + break; + default: + break; + } +} + + void VM::connect_bus(void) { int i; @@ -1069,3 +1085,4 @@ void VM::connect_bus(void) maincpu->set_context_mem(mainmem); subcpu->set_context_mem(submem); } +