From c05772f9c62d83290a3695c0a65816745e7efa94 Mon Sep 17 00:00:00 2001 From: angelosa Date: Sat, 8 Apr 2023 01:46:38 +0200 Subject: nintendo/vboy.cpp: convert HW and VIPS I/O to address_map, add IO_SPACE r/w, misc cleanups * fix longstanding regressions with panicbom, galactic and vforce; --- hash/vboy.xml | 23 +- src/mame/nintendo/vboy.cpp | 572 ++++++++++++++++++++++----------------------- 2 files changed, 289 insertions(+), 306 deletions(-) diff --git a/hash/vboy.xml b/hash/vboy.xml index 6d5fa72b3a1..279d5b72cd1 100644 --- a/hash/vboy.xml +++ b/hash/vboy.xml @@ -59,12 +59,11 @@ Runs way too fast - + Galactic Pinball (Japan, USA) 1995 Nintendo @@ -230,13 +229,10 @@ Gameplay [VIP] flickers too much, framebuffer? - + Panic Bomber (USA) 1995 Nintendo - @@ -375,13 +371,10 @@ Verify player KO graphics - + Tobidase! Panibon (Japan) 1995 Hudson - @@ -432,13 +425,10 @@ Missing GFXs for gender select in name entry - + Vertical Force (USA) 1995 Nintendo - @@ -449,13 +439,10 @@ I/O access (regression) - + Vertical Force (Japan) 1995 Hudson - diff --git a/src/mame/nintendo/vboy.cpp b/src/mame/nintendo/vboy.cpp index 6bec6e1b7d4..93ef7f56474 100644 --- a/src/mame/nintendo/vboy.cpp +++ b/src/mame/nintendo/vboy.cpp @@ -91,7 +91,7 @@ private: uint32_t tcr = 0, wcr = 0, kcr = 0x80; }; - struct vip_regs_t + struct vip_io_regs_t { uint16_t INTPND = 0; uint16_t INTENB = 0; @@ -129,9 +129,9 @@ private: std::unique_ptr m_l_frame_1; std::unique_ptr m_r_frame_0; std::unique_ptr m_r_frame_1; - vboy_regs_t m_vboy_regs; - vip_regs_t m_vip_regs; - vboy_timer_t m_vboy_timer; + vboy_regs_t m_regs; + vip_io_regs_t m_vip_io; + vboy_timer_t m_timer; std::unique_ptr m_ovr_tempdraw_map; uint16_t m_frame_count = 0; uint8_t m_displayfb = 0; @@ -139,10 +139,15 @@ private: uint8_t m_row_num = 0; attotime m_input_latch_time; - uint32_t io_r(offs_t offset); - void io_w(offs_t offset, uint32_t data); - uint16_t vip_r(offs_t offset); - void vip_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void io_map(address_map &map); + u8 timer_control_r(); + void timer_control_w(offs_t offset, u8 data); + u8 keypad_control_r(); + void keypad_control_w(offs_t offset, u8 data); + + void vip_map(address_map &map); + uint16_t vip_io_r(offs_t offset); + void vip_io_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void font0_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void font1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void font2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); @@ -151,8 +156,8 @@ private: uint16_t font1_r(offs_t offset); uint16_t font2_r(offs_t offset); uint16_t font3_r(offs_t offset); - void vboy_bgmap_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - uint16_t vboy_bgmap_r(offs_t offset); + void bgmap_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + uint16_t bgmap_r(offs_t offset); uint8_t lfb0_r(offs_t offset); uint8_t lfb1_r(offs_t offset); uint8_t rfb0_r(offs_t offset); @@ -162,9 +167,8 @@ private: void rfb0_w(offs_t offset, uint8_t data); void rfb1_w(offs_t offset, uint8_t data); - void m_timer_tick(); - void m_scanline_tick(int scanline, uint8_t screen_type); - void m_set_irq(uint16_t irq_vector); + void scanline_tick(int scanline, uint8_t screen_type); + void set_irq(uint16_t irq_vector); void put_obj(bitmap_ind16 &bitmap, const rectangle &cliprect, int x, int y, uint16_t code, uint8_t pal); void fill_ovr_char(uint16_t code, uint8_t pal); @@ -174,15 +178,16 @@ private: void draw_affine_map(bitmap_ind16 &bitmap, const rectangle &cliprect, uint16_t param_base, int gx, int gp, int gy, int h, int w, uint16_t x_mask, uint16_t y_mask, uint8_t ovr, bool right, int bg_map_num); uint8_t display_world(int num, bitmap_ind16 &bitmap, const rectangle &cliprect, bool right, int &cur_spt); - void m_set_brightness(); + void set_brightness(); void vboy_palette(palette_device &palette) const; - uint32_t screen_update_vboy_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_vboy_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); TIMER_DEVICE_CALLBACK_MEMBER(timer_main_tick); TIMER_DEVICE_CALLBACK_MEMBER(timer_pad_tick); TIMER_DEVICE_CALLBACK_MEMBER(vboy_scanlineL); - void vboy_mem(address_map &map); + void vboy_map(address_map &map); + void vboy_io(address_map &map); }; @@ -255,7 +260,7 @@ inline int8_t vboy_state::get_bg_map_pixel(int num, int xpos, int ypos) uint8_t const stepx = (x & 0x1c0) >> 6; uint8_t const stepy = ((y & 0x1c0) >> 6) * (stepx+1); uint16_t const val = READ_BGMAP((x & 0x3f) + (64 * (y & 0x3f)) + ((num + stepx + stepy) * 0x1000)); - int const pal = m_vip_regs.GPLT[(val >> 14) & 3]; + int const pal = m_vip_io.GPLT[(val >> 14) & 3]; int const code = val & 0x3fff; uint8_t const yi = ypos & 7; @@ -408,7 +413,7 @@ uint8_t vboy_state::display_world(int num, bitmap_ind16 &bitmap, const rectangle if (mode < 2) // Normal / HBias Mode { if(ovr) - fill_ovr_char(ovr_char & 0x3fff, m_vip_regs.GPLT[(ovr_char >> 14) & 3]); + fill_ovr_char(ovr_char & 0x3fff, m_vip_io.GPLT[(ovr_char >> 14) & 3]); if (lon && (!right)) { @@ -423,7 +428,7 @@ uint8_t vboy_state::display_world(int num, bitmap_ind16 &bitmap, const rectangle else if (mode==2) // Affine Mode { if(ovr) - fill_ovr_char(ovr_char & 0x3fff, m_vip_regs.GPLT[(ovr_char >> 14) & 3]); + fill_ovr_char(ovr_char & 0x3fff, m_vip_io.GPLT[(ovr_char >> 14) & 3]); if (lon && (!right)) { @@ -443,11 +448,11 @@ uint8_t vboy_state::display_world(int num, bitmap_ind16 &bitmap, const rectangle return 0; } - int start_offs = m_vip_regs.SPT[cur_spt]; + int start_offs = m_vip_io.SPT[cur_spt]; int end_offs = 0x3ff; if(cur_spt != 0) - end_offs = m_vip_regs.SPT[cur_spt-1]; + end_offs = m_vip_io.SPT[cur_spt-1]; int i = start_offs; do @@ -461,10 +466,10 @@ uint8_t vboy_state::display_world(int num, bitmap_ind16 &bitmap, const rectangle uint8_t jron = (READ_OBJECTS(start_ndx+1) & 0x4000) >> 14; if (!right && jlon) - put_obj(bitmap, cliprect, (jx-jp) & 0x1ff, jy, val & 0x3fff, m_vip_regs.JPLT[(val>>14) & 3]); + put_obj(bitmap, cliprect, (jx-jp) & 0x1ff, jy, val & 0x3fff, m_vip_io.JPLT[(val>>14) & 3]); if(right && jron) - put_obj(bitmap, cliprect, (jx+jp) & 0x1ff, jy, val & 0x3fff, m_vip_regs.JPLT[(val>>14) & 3]); + put_obj(bitmap, cliprect, (jx+jp) & 0x1ff, jy, val & 0x3fff, m_vip_io.JPLT[(val>>14) & 3]); i--; i &= 0x3ff; @@ -477,12 +482,12 @@ uint8_t vboy_state::display_world(int num, bitmap_ind16 &bitmap, const rectangle return 0; } -uint32_t vboy_state::screen_update_vboy_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t vboy_state::screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - bitmap.fill(m_palette->pen(m_vip_regs.BKCOL), cliprect); + bitmap.fill(m_palette->pen(m_vip_io.BKCOL), cliprect); int cur_spt; - if(!(m_vip_regs.DPCTRL & 2)) /* Don't bother if screen is off */ + if(!(m_vip_io.DPCTRL & 2)) /* Don't bother if screen is off */ return 0; cur_spt = 3; @@ -507,12 +512,12 @@ uint32_t vboy_state::screen_update_vboy_left(screen_device &screen, bitmap_ind16 return 0; } -uint32_t vboy_state::screen_update_vboy_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t vboy_state::screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - bitmap.fill(m_palette->pen(m_vip_regs.BKCOL), cliprect); + bitmap.fill(m_palette->pen(m_vip_io.BKCOL), cliprect); int cur_spt; - if(!(m_vip_regs.DPCTRL & 2)) /* Don't bother if screen is off */ + if(!(m_vip_io.DPCTRL & 2)) /* Don't bother if screen is off */ return 0; cur_spt = 3; @@ -528,135 +533,116 @@ uint32_t vboy_state::screen_update_vboy_right(screen_device &screen, bitmap_ind1 * *********************************/ -uint32_t vboy_state::io_r(offs_t offset) +void vboy_state::io_map(address_map &map) { - uint32_t value = 0x00; - - switch ((offset << 2)) - { - case 0x10: // KLB (Keypad Low Byte) - value = m_vboy_regs.klb; // 0x02 is always 1 - break; - case 0x14: // KHB (Keypad High Byte) - value = m_vboy_regs.khb; - break; - case 0x18: // TLB (Timer Low Byte) - value = m_vboy_regs.tlb; - break; - case 0x1c: // THB (Timer High Byte) - value = m_vboy_regs.thb; - break; - case 0x20: // TCR (Timer Control Reg) - value = m_vboy_regs.tcr; - break; - case 0x24: // WCR (Wait State Control Reg) - value = m_vboy_regs.wcr; - break; - case 0x28: // KCR (Keypad Control Reg) - { -// attotime new_time = machine().time(); + // LPC (Link Port Control Reg) +// map(0x00 / 4, 0x00 / 4) + // LPC2 (Link Port Control Reg) +// map(0x04 / 4, 0x04 / 4) + // LPT (Link Port Transmit) +// map(0x08 / 4, 0x08 / 4) + // LPR (Link Port Receive) (read only) +// map(0x0c / 4, 0x0c / 4) + // KLB (Keypad Low Byte) (read only) + map(0x10 / 4, 0x10 / 4).lr8(NAME([this]() { return m_regs.klb; })); + // KHB (Keypad High Byte) (read only) + map(0x14 / 4, 0x14 / 4).lr8(NAME([this]() { return m_regs.khb; })); + // TLB (Timer Low Byte) + map(0x18 / 4, 0x18 / 4).lrw8( + NAME([this]() { return m_regs.tlb; }), + NAME([this](u8 data) { + m_regs.tlb = data; + m_timer.latch = m_regs.tlb | (m_timer.latch & 0xff00); + }) + ); + // THB (Timer High Byte) + map(0x1c / 4, 0x1c / 4).lrw8( + NAME([this]() { return m_regs.thb; }), + NAME([this](u8 data) { + m_regs.thb = data; + m_timer.latch = (m_regs.thb << 8) | (m_timer.latch & 0xff); + }) + ); + // TCR (Timer Control Reg) + map(0x20 / 4, 0x20 / 4).rw(FUNC(vboy_state::timer_control_r), FUNC(vboy_state::timer_control_w)); + // WCR (Wait State Control Reg) + // according to docs: bits 2 to 7 are unused and set to 1. + map(0x24 / 4, 0x24 / 4).lrw8( + NAME([this]() { return m_regs.wcr | 0xfc; }), + NAME([this](u8 data) { m_regs.wcr = data | 0xfc; }) + ); + // KCR (Keypad Control Reg) + map(0x28 / 4, 0x28 / 4).rw(FUNC(vboy_state::keypad_control_r), FUNC(vboy_state::keypad_control_w)); -// if((new_time - m_input_latch_time) < m_maincpu->cycles_to_attotime(640)) -// value |= machine().rand() & 2; +} - value = m_vboy_regs.kcr | 0x4c; - } - break; - case 0x00: // LPC (Link Port Control Reg) - case 0x04: // LPC2 (Link Port Control Reg) - case 0x08: // LPT (Link Port Transmit) - case 0x0c: // LPR (Link Port Receive) - default: - logerror("Unemulated read: offset %08x\n", 0x02000000 + (offset << 2)); - break; - } - return value; +/* + * 111- ---- always 1 + * ---x ---- timer select (1=20 us, 0=100 us) + * ---- x--- timer irq + * ---- -x-- resets timer zero flag + * ---- --x- timer is zero flag + * ---- ---x enables timer + */ +u8 vboy_state::timer_control_r() +{ + return m_regs.tcr | 0xe4; } -void vboy_state::io_w(offs_t offset, uint32_t data) +void vboy_state::timer_control_w(offs_t offset, u8 data) { - switch (offset<<2) + if (!(data & 0x08)) + m_maincpu->set_input_line(1, CLEAR_LINE); + + if (data & 1) { - case 0x0c: // LPR (Link Port Receive) - case 0x10: // KLB (Keypad Low Byte) - case 0x14: // KHB (Keypad High Byte) - //logerror("Ilegal write: offset %02x should be only read\n", offset); - break; - case 0x18: // TLB (Timer Low Byte) - m_vboy_regs.tlb = data; - m_vboy_timer.latch = m_vboy_regs.tlb | (m_vboy_timer.latch & 0xff00); - break; - case 0x1c: // THB (Timer High Byte) - m_vboy_regs.thb = data; - m_vboy_timer.latch = (m_vboy_regs.thb<<8) | (m_vboy_timer.latch & 0xff); - break; - case 0x20: // TCR (Timer Control Reg) - /* - 111- ---- always 1 - ---x ---- timer select (1=20 us, 0=100 us) - ---- x--- timer irq - ---- -x-- resets timer zero flag - ---- --x- timer is zero flag - ---- ---x enables timer - */ - if (!(data & 0x08)) - { - m_maincpu->set_input_line(1, CLEAR_LINE); - } + m_regs.tlb = m_timer.latch & 0xff; + m_regs.thb = m_timer.latch >> 8; + m_timer.count = m_timer.latch; - if (data & 1) + // only start timer if tcr & 1 is 1 and wasn't before? + if (!(m_regs.tcr & 1)) + { + if (data & 0x10) { - m_vboy_regs.tlb = m_vboy_timer.latch & 0xff; - m_vboy_regs.thb = m_vboy_timer.latch >> 8; - m_vboy_timer.count = m_vboy_timer.latch; - - // only start timer if tcr & 1 is 1 and wasn't before? - if (!(m_vboy_regs.tcr & 1)) - { - if (data & 0x10) - { - m_maintimer->adjust(attotime::from_hz(50000)); - } - else - { - m_maintimer->adjust(attotime::from_hz(10000)); - } - - } + m_maintimer->adjust(attotime::from_hz(50000)); } - - m_vboy_regs.tcr = (data & 0xfd) | (0xe4) | (m_vboy_regs.tcr & 2); // according to docs: bits 5, 6 & 7 are unused and set to 1, bit 1 is read only. - if(data & 4) - m_vboy_regs.tcr &= 0xfd; - break; - case 0x24: // WCR (Wait State Control Reg) - m_vboy_regs.wcr = data | 0xfc; // according to docs: bits 2 to 7 are unused and set to 1. - break; - case 0x28: // KCR (Keypad Control Reg) - if (data & 0x04 ) + else { - m_vboy_regs.klb = (ioport("INPUT")->read() & 0x00ff); - m_vboy_regs.khb = (ioport("INPUT")->read() & 0xff00) >> 8; - //m_input_latch_time = machine().time(); + m_maintimer->adjust(attotime::from_hz(10000)); } - if (data & 1) - { - m_vboy_regs.klb = 0; - m_vboy_regs.khb = 0; - //m_input_latch_time = attotime::zero; - } + } + } + m_regs.tcr = (data & 0xfd) | (0xe4) | (m_regs.tcr & 2); // according to docs: bits 5, 6 & 7 are unused and set to 1, bit 1 is read only. + if(data & 4) + m_regs.tcr &= 0xfd; +} - m_vboy_regs.kcr = (data | 0x48) & 0xfd; // according to docs: bit 6 & bit 3 are unused and set to 1, bit 1 is read only. - break; - case 0x00: // LPC (Link Port Control Reg) - case 0x04: // LPC2 (Link Port Control Reg) - case 0x08: // LPT (Link Port Transmit) - default: - logerror("Unemulated write: offset %08x, data %04x\n", 0x02000000 + (offset << 2), data); - break; +u8 vboy_state::keypad_control_r() +{ + return m_regs.kcr | 0x4c; +} + +void vboy_state::keypad_control_w(offs_t offset, u8 data) +{ + if (data & 0x04 ) + { + m_regs.klb = (ioport("INPUT")->read() & 0x00ff); + m_regs.khb = (ioport("INPUT")->read() & 0xff00) >> 8; + //m_input_latch_time = machine().time(); + } + + if (data & 1) + { + m_regs.klb = 0; + m_regs.khb = 0; + //m_input_latch_time = attotime::zero; } + + // according to docs: bit 6 & bit 3 are unused and set to 1, bit 1 is read only. + m_regs.kcr = (data | 0x48) & 0xfd; } @@ -665,17 +651,40 @@ void vboy_state::io_w(offs_t offset, uint32_t data) * VIP * *********************************/ -/* -TODO: brightness presumably isn't a linear algorithm, also REST needs to be taken into account (needs a working example) -*/ -void vboy_state::m_set_brightness() + +void vboy_state::vip_map(address_map &map) +{ + map(0x00000000, 0x00005fff).rw(FUNC(vboy_state::lfb0_r), FUNC(vboy_state::lfb0_w)); // L frame buffer 0 + map(0x00006000, 0x00007fff).rw(FUNC(vboy_state::font0_r), FUNC(vboy_state::font0_w)); // Font 0-511 + map(0x00008000, 0x0000dfff).rw(FUNC(vboy_state::lfb1_r), FUNC(vboy_state::lfb1_w)); // L frame buffer 1 + map(0x0000e000, 0x0000ffff).rw(FUNC(vboy_state::font1_r), FUNC(vboy_state::font1_w)); // Font 512-1023 + map(0x00010000, 0x00015fff).rw(FUNC(vboy_state::rfb0_r), FUNC(vboy_state::rfb0_w)); // R frame buffer 0 + map(0x00016000, 0x00017fff).rw(FUNC(vboy_state::font2_r), FUNC(vboy_state::font2_w)); // Font 1024-1535 + map(0x00018000, 0x0001dfff).rw(FUNC(vboy_state::rfb1_r), FUNC(vboy_state::rfb1_w)); // R frame buffer 1 + map(0x0001e000, 0x0001ffff).rw(FUNC(vboy_state::font3_r), FUNC(vboy_state::font3_w)); // Font 1536-2047 + + map(0x00020000, 0x0003ffff).rw(FUNC(vboy_state::bgmap_r), FUNC(vboy_state::bgmap_w)); // VIPC memory + + //map(0x00040000, 0x0005ffff).ram(); // VIPC + map(0x0005f800, 0x0005f87f).rw(FUNC(vboy_state::vip_io_r), FUNC(vboy_state::vip_io_w)); + + map(0x00078000, 0x00079fff).rw(FUNC(vboy_state::font0_r), FUNC(vboy_state::font0_w)); // Font 0-511 mirror + map(0x0007a000, 0x0007bfff).rw(FUNC(vboy_state::font1_r), FUNC(vboy_state::font1_w)); // Font 512-1023 mirror + map(0x0007c000, 0x0007dfff).rw(FUNC(vboy_state::font2_r), FUNC(vboy_state::font2_w)); // Font 1024-1535 mirror + map(0x0007e000, 0x0007ffff).rw(FUNC(vboy_state::font3_r), FUNC(vboy_state::font3_w)); // Font 1536-2047 mirror +} + +// TODO: verify against real HW +// - brightness presumably isn't a linear algorithm +// - REST needs to be taken into account (needs a working example) +void vboy_state::set_brightness() { int a,b,c; - //d = (m_vip_regs.BRTA + m_vip_regs.BRTB + m_vip_regs.BRTC + m_vip_regs.REST); - a = (0xff * (m_vip_regs.BRTA)) / 0x80; - b = (0xff * (m_vip_regs.BRTA + m_vip_regs.BRTB)) / 0x80; - c = (0xff * (m_vip_regs.BRTA + m_vip_regs.BRTB + m_vip_regs.BRTC)) / 0x80; + //d = (m_vip_io.BRTA + m_vip_io.BRTB + m_vip_io.BRTC + m_vip_io.REST); + a = (0xff * (m_vip_io.BRTA)) / 0x80; + b = (0xff * (m_vip_io.BRTA + m_vip_io.BRTB)) / 0x80; + c = (0xff * (m_vip_io.BRTA + m_vip_io.BRTB + m_vip_io.BRTC)) / 0x80; if(a < 0) { a = 0; } if(b < 0) { b = 0; } @@ -684,19 +693,19 @@ void vboy_state::m_set_brightness() if(b > 0xff) { b = 0xff; } if(c > 0xff) { c = 0xff; } -// popmessage("%02x %02x %02x %02x",m_vip_regs.BRTA,m_vip_regs.BRTB,m_vip_regs.BRTC,m_vip_regs.REST); +// popmessage("%02x %02x %02x %02x",m_vip_io.BRTA,m_vip_io.BRTB,m_vip_io.BRTC,m_vip_io.REST); m_palette->set_pen_color(1, a,0,0); m_palette->set_pen_color(2, b,0,0); m_palette->set_pen_color(3, c,0,0); } -uint16_t vboy_state::vip_r(offs_t offset) +uint16_t vboy_state::vip_io_r(offs_t offset) { switch(offset << 1) { case 0x00: //INTPND - return m_vip_regs.INTPND; + return m_vip_io.INTPND; case 0x02: //INTENB - return m_vip_regs.INTENB; + return m_vip_io.INTENB; case 0x04: //INTCLR logerror("Error reading INTCLR\n"); break; @@ -717,9 +726,9 @@ uint16_t vboy_state::vip_r(offs_t offset) { uint16_t res; - res = m_vip_regs.DPCTRL & 0x0702; + res = m_vip_io.DPCTRL & 0x0702; - if(m_vip_regs.DPCTRL & 2) + if(m_vip_io.DPCTRL & 2) { if(m_row_num < 224/8) { @@ -735,20 +744,20 @@ uint16_t vboy_state::vip_r(offs_t offset) return res; } case 0x22: //DPCTRL - return m_vip_regs.DPCTRL; + return m_vip_io.DPCTRL; case 0x24: //BRTA - return m_vip_regs.BRTA; + return m_vip_io.BRTA; case 0x26: //BRTB - return m_vip_regs.BRTB; + return m_vip_io.BRTB; case 0x28: //BRTC - return m_vip_regs.BRTC; + return m_vip_io.BRTC; case 0x2A: //REST - return m_vip_regs.REST; + return m_vip_io.REST; case 0x2E: //FRMCYC - return m_vip_regs.FRMCYC; + return m_vip_io.FRMCYC; case 0x30: //CTA printf("Read CTA\n"); - return m_vip_regs.CTA; + return m_vip_io.CTA; case 0x40: //XPSTTS, piXel Processor STaTuS { /* @@ -764,7 +773,7 @@ uint16_t vboy_state::vip_r(offs_t offset) //printf("%d\n",row_num); - res = m_vip_regs.XPSTTS & 0x00f3; // empty ^^' + res = m_vip_io.XPSTTS & 0x00f3; // empty ^^' res |= m_drawfb << 2; if(m_row_num < 224/8) @@ -776,36 +785,36 @@ uint16_t vboy_state::vip_r(offs_t offset) return res; } case 0x42: //XPCTRL - return m_vip_regs.XPCTRL; + return m_vip_io.XPCTRL; case 0x44: //VER printf("%08x read VER\n",m_maincpu->pc()); - return m_vip_regs.VER; + return m_vip_io.VER; case 0x48: //SPT0 - return m_vip_regs.SPT[0]; + return m_vip_io.SPT[0]; case 0x4A: //SPT1 - return m_vip_regs.SPT[1]; + return m_vip_io.SPT[1]; case 0x4C: //SPT2 - return m_vip_regs.SPT[2]; + return m_vip_io.SPT[2]; case 0x4E: //SPT3 - return m_vip_regs.SPT[3]; + return m_vip_io.SPT[3]; case 0x60: //GPLT0 - return m_vip_regs.GPLT[0]; + return m_vip_io.GPLT[0]; case 0x62: //GPLT1 - return m_vip_regs.GPLT[1]; + return m_vip_io.GPLT[1]; case 0x64: //GPLT2 - return m_vip_regs.GPLT[2]; + return m_vip_io.GPLT[2]; case 0x66: //GPLT3 - return m_vip_regs.GPLT[3]; + return m_vip_io.GPLT[3]; case 0x68: //JPLT0 - return m_vip_regs.JPLT[0]; + return m_vip_io.JPLT[0]; case 0x6A: //JPLT1 - return m_vip_regs.JPLT[1]; + return m_vip_io.JPLT[1]; case 0x6C: //JPLT2 - return m_vip_regs.JPLT[2]; + return m_vip_io.JPLT[2]; case 0x6E: //JPLT3 - return m_vip_regs.JPLT[3]; + return m_vip_io.JPLT[3]; case 0x70: //BKCOL - return m_vip_regs.BKCOL; + return m_vip_io.BKCOL; default: logerror("Unemulated read: addr %08x\n", offset * 2 + 0x0005f800); break; @@ -813,7 +822,7 @@ uint16_t vboy_state::vip_r(offs_t offset) return 0xffff; } -void vboy_state::vip_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void vboy_state::vip_io_w(offs_t offset, uint16_t data, uint16_t mem_mask) { if(mem_mask != 0xffff) printf("%04x %02x\n",mem_mask,offset*2); @@ -833,15 +842,15 @@ void vboy_state::vip_w(offs_t offset, uint16_t data, uint16_t mem_mask) logerror("Error writing INTPND\n"); break; case 0x02: //INTENB - m_vip_regs.INTENB = data; - m_set_irq(0); + m_vip_io.INTENB = data; + set_irq(0); //printf("%04x ENB\n",data); break; case 0x04: //INTCLR - m_vip_regs.INTPND &= ~data; - m_set_irq(0); + m_vip_io.INTPND &= ~data; + set_irq(0); //else - // printf("%04x\n",m_vip_regs.INTPND); + // printf("%04x\n",m_vip_io.INTPND); break; case 0x20: //DPSTTS logerror("Error writing DPSTTS\n"); @@ -854,38 +863,38 @@ void vboy_state::vip_w(offs_t offset, uint16_t data, uint16_t mem_mask) ---- ---- ---- ---x DPRST (Resets the VIP internal counter) */ case 0x22: //DPCTRL - m_vip_regs.DPCTRL = data & 0x0702; + m_vip_io.DPCTRL = data & 0x0702; if(data & 1) { - m_vip_regs.INTPND &= 0xe000; // reset FRAME_START, GAME_START, RFB_END, LFB_END and SCAN_ERR irqs - m_set_irq(0); + m_vip_io.INTPND &= 0xe000; // reset FRAME_START, GAME_START, RFB_END, LFB_END and SCAN_ERR irqs + set_irq(0); } break; case 0x24: //BRTA - m_vip_regs.BRTA = data; - m_set_brightness(); + m_vip_io.BRTA = data; + set_brightness(); break; case 0x26: //BRTB - m_vip_regs.BRTB = data; - m_set_brightness(); + m_vip_io.BRTB = data; + set_brightness(); break; case 0x28: //BRTC - m_vip_regs.BRTC = data; - m_set_brightness(); + m_vip_io.BRTC = data; + set_brightness(); break; case 0x2A: //REST - m_vip_regs.REST = data; - m_set_brightness(); + m_vip_io.REST = data; + set_brightness(); if(data) printf("%04x REST\n",data); break; case 0x2E: //FRMCYC //printf("%d\n",data); - m_vip_regs.FRMCYC = data; + m_vip_io.FRMCYC = data; break; case 0x30: //CTA - m_vip_regs.CTA = data; + m_vip_io.CTA = data; printf("%04x CTA\n",data); break; case 0x40: //XPSTTS @@ -896,58 +905,58 @@ void vboy_state::vip_w(offs_t offset, uint16_t data, uint16_t mem_mask) ---- ---- ---- --x- ---- ---- ---- ---x Reset Pixel Processor */ - m_vip_regs.XPCTRL = data & 0x1f02; + m_vip_io.XPCTRL = data & 0x1f02; //if(data & 0x1f00) // printf("%04x SBCMP\n",data); if(data & 1) { - m_vip_regs.INTPND &= 0x1fff; // reset SB_HIT, XP_END and TIME_ERR irqs - m_set_irq(0); + m_vip_io.INTPND &= 0x1fff; // reset SB_HIT, XP_END and TIME_ERR irqs + set_irq(0); } break; case 0x44: //VER - //m_vip_regs.VER = data; + //m_vip_io.VER = data; break; case 0x48: //SPT0 - m_vip_regs.SPT[0] = data & 0x3ff; + m_vip_io.SPT[0] = data & 0x3ff; break; case 0x4A: //SPT1 - m_vip_regs.SPT[1] = data & 0x3ff; + m_vip_io.SPT[1] = data & 0x3ff; break; case 0x4C: //SPT2 - m_vip_regs.SPT[2] = data & 0x3ff; + m_vip_io.SPT[2] = data & 0x3ff; break; case 0x4E: //SPT3 - m_vip_regs.SPT[3] = data & 0x3ff; + m_vip_io.SPT[3] = data & 0x3ff; break; case 0x60: //GPLT0 - m_vip_regs.GPLT[0] = data; + m_vip_io.GPLT[0] = data; break; case 0x62: //GPLT1 - m_vip_regs.GPLT[1] = data; + m_vip_io.GPLT[1] = data; break; case 0x64: //GPLT2 - m_vip_regs.GPLT[2] = data; + m_vip_io.GPLT[2] = data; break; case 0x66: //GPLT3 - m_vip_regs.GPLT[3] = data; + m_vip_io.GPLT[3] = data; break; case 0x68: //JPLT0 - m_vip_regs.JPLT[0] = data & 0xfc; + m_vip_io.JPLT[0] = data & 0xfc; break; case 0x6A: //JPLT1 - m_vip_regs.JPLT[1] = data & 0xfc; + m_vip_io.JPLT[1] = data & 0xfc; break; case 0x6C: //JPLT2 - m_vip_regs.JPLT[2] = data & 0xfc; + m_vip_io.JPLT[2] = data & 0xfc; break; case 0x6E: //JPLT3 - m_vip_regs.JPLT[3] = data & 0xfc; + m_vip_io.JPLT[3] = data & 0xfc; break; case 0x70: //BKCOL - m_vip_regs.BKCOL = data & 3; + m_vip_io.BKCOL = data & 3; break; default: logerror("Unemulated write: addr %08x, data %04x\n", offset * 2 + 0x0005f800, data); @@ -997,12 +1006,12 @@ uint16_t vboy_state::font3_r(offs_t offset) return READ_FONT(offset + 0x3000); } -void vboy_state::vboy_bgmap_w(offs_t offset, uint16_t data, uint16_t mem_mask) +void vboy_state::bgmap_w(offs_t offset, uint16_t data, uint16_t mem_mask) { m_bgmap[offset] = data | (m_bgmap[offset] & (mem_mask ^ 0xffff)); } -uint16_t vboy_state::vboy_bgmap_r(offs_t offset) +uint16_t vboy_state::bgmap_r(offs_t offset) { return m_bgmap[offset]; } @@ -1017,36 +1026,27 @@ void vboy_state::rfb0_w(offs_t offset, uint8_t data) { m_r_frame_0[offset] = dat void vboy_state::rfb1_w(offs_t offset, uint8_t data) { m_r_frame_1[offset] = data; } -void vboy_state::vboy_mem(address_map &map) +void vboy_state::vboy_map(address_map &map) { map.global_mask(0x07ffffff); - map(0x00000000, 0x00005fff).rw(FUNC(vboy_state::lfb0_r), FUNC(vboy_state::lfb0_w)); // L frame buffer 0 - map(0x00006000, 0x00007fff).rw(FUNC(vboy_state::font0_r), FUNC(vboy_state::font0_w)); // Font 0-511 - map(0x00008000, 0x0000dfff).rw(FUNC(vboy_state::lfb1_r), FUNC(vboy_state::lfb1_w)); // L frame buffer 1 - map(0x0000e000, 0x0000ffff).rw(FUNC(vboy_state::font1_r), FUNC(vboy_state::font1_w)); // Font 512-1023 - map(0x00010000, 0x00015fff).rw(FUNC(vboy_state::rfb0_r), FUNC(vboy_state::rfb0_w)); // R frame buffer 0 - map(0x00016000, 0x00017fff).rw(FUNC(vboy_state::font2_r), FUNC(vboy_state::font2_w)); // Font 1024-1535 - map(0x00018000, 0x0001dfff).rw(FUNC(vboy_state::rfb1_r), FUNC(vboy_state::rfb1_w)); // R frame buffer 1 - map(0x0001e000, 0x0001ffff).rw(FUNC(vboy_state::font3_r), FUNC(vboy_state::font3_w)); // Font 1536-2047 - - map(0x00020000, 0x0003ffff).rw(FUNC(vboy_state::vboy_bgmap_r), FUNC(vboy_state::vboy_bgmap_w)); // VIPC memory - - //map(0x00040000, 0x0005ffff).ram(); // VIPC - map(0x0005f800, 0x0005f87f).rw(FUNC(vboy_state::vip_r), FUNC(vboy_state::vip_w)); - - map(0x00078000, 0x00079fff).rw(FUNC(vboy_state::font0_r), FUNC(vboy_state::font0_w)); // Font 0-511 mirror - map(0x0007a000, 0x0007bfff).rw(FUNC(vboy_state::font1_r), FUNC(vboy_state::font1_w)); // Font 512-1023 mirror - map(0x0007c000, 0x0007dfff).rw(FUNC(vboy_state::font2_r), FUNC(vboy_state::font2_w)); // Font 1024-1535 mirror - map(0x0007e000, 0x0007ffff).rw(FUNC(vboy_state::font3_r), FUNC(vboy_state::font3_w)); // Font 1536-2047 mirror - + map(0x00000000, 0x0007ffff).m(FUNC(vboy_state::vip_map)); map(0x01000000, 0x010005ff).rw("vbsnd", FUNC(vboysnd_device::read), FUNC(vboysnd_device::write)); - map(0x02000000, 0x0200002b).mirror(0x0ffff00).rw(FUNC(vboy_state::io_r), FUNC(vboy_state::io_w)); // Hardware control registers mask 0xff + map(0x02000000, 0x020000ff).mirror(0x0ffff00).m(FUNC(vboy_state::io_map)).umask32(0x000000ff); //map(0x04000000, 0x04ffffff) cartslot EXP map(0x05000000, 0x0500ffff).mirror(0x0ff0000).ram().share("wram");// Main RAM - 64K mask 0xffff //map(0x06000000, 0x06ffffff) cartslot CHIP //map(0x07000000, 0x07ffffff) cartslot ROM } +void vboy_state::vboy_io(address_map &map) +{ + map.global_mask(0x07ffffff); + map(0x00000000, 0x0007ffff).m(FUNC(vboy_state::vip_map)); + map(0x01000000, 0x010005ff).rw("vbsnd", FUNC(vboysnd_device::read), FUNC(vboysnd_device::write)); + map(0x02000000, 0x020000ff).mirror(0x0ffff00).m(FUNC(vboy_state::io_map)).umask32(0x000000ff); + // TODO: verify if ROM/RAM mirrors on I/O space (nesterfb) +} + /* Input ports */ static INPUT_PORTS_START( vboy ) PORT_START("INPUT") @@ -1072,46 +1072,46 @@ INPUT_PORTS_END void vboy_state::machine_reset() { /* Initial values taken from Reality Boy, to be verified when emulation improves */ - m_vboy_regs.lpc = 0x6d; - m_vboy_regs.lpc2 = 0xff; - m_vboy_regs.lpt = 0x00; - m_vboy_regs.lpr = 0x00; - m_vboy_regs.klb = 0x00; - m_vboy_regs.khb = 0x00; - m_vboy_regs.tlb = 0xff; - m_vboy_regs.thb = 0xff; - m_vboy_regs.tcr = 0xe4; - m_vboy_regs.wcr = 0xfc; - m_vboy_regs.kcr = 0x4c | 0x80; - m_vip_regs.DPCTRL = 2; // ssquash relies on this at boot otherwise no frame_start irq is fired + m_regs.lpc = 0x6d; + m_regs.lpc2 = 0xff; + m_regs.lpt = 0x00; + m_regs.lpr = 0x00; + m_regs.klb = 0x00; + m_regs.khb = 0x00; + m_regs.tlb = 0xff; + m_regs.thb = 0xff; + m_regs.tcr = 0xe4; + m_regs.wcr = 0xfc; + m_regs.kcr = 0x4c | 0x80; + m_vip_io.DPCTRL = 2; // ssquash relies on this at boot otherwise no frame_start irq is fired m_displayfb = 0; m_drawfb = 0; - m_vboy_timer.count = 0; + m_timer.count = 0; m_maintimer->adjust(attotime::never); } -void vboy_state::m_timer_tick() +TIMER_DEVICE_CALLBACK_MEMBER(vboy_state::timer_main_tick) { - if(m_vboy_timer.count > 0) + if(m_timer.count > 0) { - m_vboy_timer.count--; - m_vboy_regs.tlb = m_vboy_timer.count & 0xff; - m_vboy_regs.thb = m_vboy_timer.count >> 8; + m_timer.count--; + m_regs.tlb = m_timer.count & 0xff; + m_regs.thb = m_timer.count >> 8; } - if (m_vboy_timer.count == 0) + if (m_timer.count == 0) { - m_vboy_timer.count = m_vboy_timer.latch; - m_vboy_regs.tcr |= 0x02; - if(m_vboy_regs.tcr & 8) + m_timer.count = m_timer.latch; + m_regs.tcr |= 0x02; + if(m_regs.tcr & 8) { m_maincpu->set_input_line(1, ASSERT_LINE); } } - if (m_vboy_regs.tcr & 0x10) + if (m_regs.tcr & 0x10) { m_maintimer->adjust(attotime::from_hz(50000)); } @@ -1121,14 +1121,9 @@ void vboy_state::m_timer_tick() } } -TIMER_DEVICE_CALLBACK_MEMBER(vboy_state::timer_main_tick) -{ - m_timer_tick(); -} - TIMER_DEVICE_CALLBACK_MEMBER(vboy_state::timer_pad_tick) { - if((m_vboy_regs.kcr & 0x80) == 0) + if((m_regs.kcr & 0x80) == 0) m_maincpu->set_input_line(0, HOLD_LINE); } @@ -1140,37 +1135,37 @@ void vboy_state::vboy_palette(palette_device &palette) const palette.set_pen_color(3, rgb_t::black()); } -void vboy_state::m_set_irq(uint16_t irq_vector) +void vboy_state::set_irq(uint16_t irq_vector) { - m_vip_regs.INTPND |= irq_vector; + m_vip_io.INTPND |= irq_vector; - if(m_vip_regs.INTENB & m_vip_regs.INTPND) + if(m_vip_io.INTENB & m_vip_io.INTPND) m_maincpu->set_input_line(4, ASSERT_LINE); - if((m_vip_regs.INTENB & m_vip_regs.INTPND) == 0) + if((m_vip_io.INTENB & m_vip_io.INTPND) == 0) m_maincpu->set_input_line(4, CLEAR_LINE); } /* TODO: obviously all of this needs clean-ups and better implementation ... */ -void vboy_state::m_scanline_tick(int scanline, uint8_t screen_type) +void vboy_state::scanline_tick(int scanline, uint8_t screen_type) { if(screen_type == 0) m_row_num = (scanline / 8) & 0x1f; if(scanline == 0) { - if(m_vip_regs.DPCTRL & 2) - m_set_irq(0x0010); // FRAME_START + if(m_vip_io.DPCTRL & 2) + set_irq(0x0010); // FRAME_START m_frame_count++; - if(m_frame_count > m_vip_regs.FRMCYC) + if(m_frame_count > m_vip_io.FRMCYC) { - m_set_irq(0x0008); // GAME_START + set_irq(0x0008); // GAME_START m_frame_count = 0; } - if(m_vip_regs.DPCTRL & 2) + if(m_vip_io.DPCTRL & 2) m_displayfb ^= 1; } @@ -1180,23 +1175,23 @@ void vboy_state::m_scanline_tick(int scanline, uint8_t screen_type) m_drawfb = 1; else m_drawfb = 2; - m_set_irq(0x4000); // XPEND + set_irq(0x4000); // XPEND } if(scanline == 232) { m_drawfb = 0; - m_set_irq(0x0002); // LFBEND + set_irq(0x0002); // LFBEND } if(scanline == 240) { - m_set_irq(0x0004); // RFBEND + set_irq(0x0004); // RFBEND } - if(m_row_num == ((m_vip_regs.XPCTRL & 0x1f00) >> 8)) + if(m_row_num == ((m_vip_io.XPCTRL & 0x1f00) >> 8)) { - m_set_irq(0x2000); // SBHIT + set_irq(0x2000); // SBHIT } } @@ -1205,7 +1200,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(vboy_state::vboy_scanlineL) { int scanline = param; - m_scanline_tick(scanline,0); + scanline_tick(scanline,0); } #if 0 @@ -1213,7 +1208,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(vboy_state::vboy_scanlineR) { int scanline = param; - //m_scanline_tick(scanline,1); + //scanline_tick(scanline,1); } #endif @@ -1222,7 +1217,8 @@ void vboy_state::vboy(machine_config &config) { /* basic machine hardware */ V810(config, m_maincpu, XTAL(20'000'000)); - m_maincpu->set_addrmap(AS_PROGRAM, &vboy_state::vboy_mem); + m_maincpu->set_addrmap(AS_PROGRAM, &vboy_state::vboy_map); + m_maincpu->set_addrmap(AS_IO, &vboy_state::vboy_io); TIMER(config, "scantimer_l").configure_scanline(FUNC(vboy_state::vboy_scanlineL), "3dleft", 0, 1); //TIMER(config, "scantimer_r").configure_scanline(FUNC(vboy_state::vboy_scanlineR), "3dright", 0, 1); @@ -1240,13 +1236,13 @@ void vboy_state::vboy(machine_config &config) /* Left screen */ screen_device &lscreen(SCREEN(config, "3dleft", SCREEN_TYPE_RASTER)); lscreen.set_raw(XTAL(20'000'000)/2,757,0,384,264,0,224); - lscreen.set_screen_update(FUNC(vboy_state::screen_update_vboy_left)); + lscreen.set_screen_update(FUNC(vboy_state::screen_update_left)); lscreen.set_palette(m_palette); /* Right screen */ screen_device &rscreen(SCREEN(config, "3dright", SCREEN_TYPE_RASTER)); rscreen.set_raw(XTAL(20'000'000)/2,757,0,384,264,0,224); - rscreen.set_screen_update(FUNC(vboy_state::screen_update_vboy_right)); + rscreen.set_screen_update(FUNC(vboy_state::screen_update_right)); rscreen.set_palette(m_palette); /* cartridge */ -- cgit v1.2.3