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;
This commit is contained in:
parent
406b4d53b8
commit
c05772f9c6
@ -59,12 +59,11 @@ Runs way too fast
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="galactic" supported="no">
|
||||
<software name="galactic" supported="partial">
|
||||
<description>Galactic Pinball (Japan, USA)</description>
|
||||
<year>1995</year>
|
||||
<publisher>Nintendo</publisher>
|
||||
<notes><![CDATA[
|
||||
I/O access (regression)
|
||||
Ball goes out of bounds sometimes on gameplay (verify)
|
||||
]]></notes>
|
||||
<info name="developer" value="Intelligent Systems"/>
|
||||
@ -230,13 +229,10 @@ Gameplay [VIP] flickers too much, framebuffer?
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="panicbom" supported="no">
|
||||
<software name="panicbom" supported="partial">
|
||||
<description>Panic Bomber (USA)</description>
|
||||
<year>1995</year>
|
||||
<publisher>Nintendo</publisher>
|
||||
<notes><![CDATA[
|
||||
I/O access for sound (regression)
|
||||
]]></notes>
|
||||
<info name="developer" value="Raizing"/>
|
||||
<info name="serial" value="VUE-VH2E-USA"/>
|
||||
<info name="release" value="199512xx"/>
|
||||
@ -375,13 +371,10 @@ Verify player KO graphics
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="tobidase" cloneof="panicbom" supported="no">
|
||||
<software name="tobidase" cloneof="panicbom" supported="partial">
|
||||
<description>Tobidase! Panibon (Japan)</description>
|
||||
<year>1995</year>
|
||||
<publisher>Hudson</publisher>
|
||||
<notes><![CDATA[
|
||||
I/O access for sound (regression)
|
||||
]]></notes>
|
||||
<info name="developer" value="Raizing"/>
|
||||
<info name="serial" value="VUE-VH2J-JPN"/>
|
||||
<info name="release" value="19950721"/>
|
||||
@ -432,13 +425,10 @@ Missing GFXs for gender select in name entry
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="vforce" supported="no">
|
||||
<software name="vforce" supported="partial">
|
||||
<description>Vertical Force (USA)</description>
|
||||
<year>1995</year>
|
||||
<publisher>Nintendo</publisher>
|
||||
<notes><![CDATA[
|
||||
I/O access (regression)
|
||||
]]></notes>
|
||||
<info name="developer" value="Hudson"/>
|
||||
<info name="serial" value="VUE-VH3E-USA"/>
|
||||
<info name="release" value="19951201"/>
|
||||
@ -449,13 +439,10 @@ I/O access (regression)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="vforcej" cloneof="vforce" supported="no">
|
||||
<software name="vforcej" cloneof="vforce" supported="partial">
|
||||
<description>Vertical Force (Japan)</description>
|
||||
<year>1995</year>
|
||||
<publisher>Hudson</publisher>
|
||||
<notes><![CDATA[
|
||||
I/O access (regression)
|
||||
]]></notes>
|
||||
<info name="developer" value="Hudson"/>
|
||||
<info name="serial" value="VUE-VH3J-JPN"/>
|
||||
<info name="release" value="19950812"/>
|
||||
|
@ -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<uint8_t[]> m_l_frame_1;
|
||||
std::unique_ptr<uint8_t[]> m_r_frame_0;
|
||||
std::unique_ptr<uint8_t[]> 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<int32_t[]> 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;
|
||||
// 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));
|
||||
|
||||
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();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
void vboy_state::io_w(offs_t offset, uint32_t data)
|
||||
/*
|
||||
* 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()
|
||||
{
|
||||
switch (offset<<2)
|
||||
return m_regs.tcr | 0xe4;
|
||||
}
|
||||
|
||||
void vboy_state::timer_control_w(offs_t offset, u8 data)
|
||||
{
|
||||
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_regs.tlb = m_timer.latch & 0xff;
|
||||
m_regs.thb = m_timer.latch >> 8;
|
||||
m_timer.count = m_timer.latch;
|
||||
|
||||
// only start timer if tcr & 1 is 1 and wasn't before?
|
||||
if (!(m_regs.tcr & 1))
|
||||
{
|
||||
if (data & 0x10)
|
||||
{
|
||||
m_maincpu->set_input_line(1, CLEAR_LINE);
|
||||
m_maintimer->adjust(attotime::from_hz(50000));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_maintimer->adjust(attotime::from_hz(10000));
|
||||
}
|
||||
|
||||
if (data & 1)
|
||||
{
|
||||
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_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 )
|
||||
{
|
||||
m_vboy_regs.klb = (ioport("INPUT")->read() & 0x00ff);
|
||||
m_vboy_regs.khb = (ioport("INPUT")->read() & 0xff00) >> 8;
|
||||
//m_input_latch_time = machine().time();
|
||||
}
|
||||
|
||||
if (data & 1)
|
||||
{
|
||||
m_vboy_regs.klb = 0;
|
||||
m_vboy_regs.khb = 0;
|
||||
//m_input_latch_time = attotime::zero;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user