pgm2.cpp, pgm2_memcard.cpp : Cleanups, Updates (#4398)

* pgm2.cpp, pgm2_memcard.cpp : Cleanups, Updates
pgm2.cpp : Do single-pass sprite drawing (uses screen.priority), Remove unused routine/values, Add notes, Shorter type values, Move most of things into private:, Make decrypt rom size related to ROM board integreated RAM size when RAM exists in ROM board, Add input name, Remove machine().save().register_postload, Reduce runtime tag lookups, Remove MCFGs, Remove unnecessary arguments, Simplified gfxdecode
pgm2_memcard.cpp : Shorter type values, Fix naming, Remove unnecessary arguments

* pgm2.cpp : Add Internal ROM version notes related to test mode

* pgm2.cpp : Minor type value correction

* pgm2.cpp : Add more notes, Fix RAM test fail (RAM4 at kov2nl, kov3, kof98umh, ddpdojt), Minor cleanup duplicate
This commit is contained in:
cam900 2018-12-15 04:19:58 +09:00 committed by R. Belmont
parent 2d814a363a
commit c7ce718fbd
5 changed files with 366 additions and 417 deletions

View File

@ -77,13 +77,13 @@
06 - zoom something, 0F-7F, default 1F 06 - zoom something, 0F-7F, default 1F
08 - fg scroll x 08 - fg scroll x
0a - fg scroll y 0a - fg scroll y
0e - resolution, 0 - low (kof98), 1 - high (rest of games) 0e - resolution, 0 - low (kof98umh), 1 - high (rest of games), 2 - higher (kov3)
10 - ? orleg2 - 0x13, kov2nl, kof98, ddpdojt - 0x14 at init 10 - ? orleg2 - 0x13, kov2nl, kov3, kof98umh, ddpdojt - 0x14 at init
14 - sprite enable ? set to 0 before spriteram update, to 1 after 14 - sprite enable ? set to 0 before spriteram update, to 1 after
16 - set to 1 before access to vrams/palettes, reset after. bits: 0 - bg ram and palette, 1 - fg ram and palette, 2 - sprite palette. 16 - set to 1 before access to vrams/palettes, reset after. bits: 0 - bg RAM and palette, 1 - fg RAM and palette, 2 - sprite palette.
18 - vblank ack 18 - vblank ack
1a - ? 0 at init 1a - ? 0 at init
1c - ? orleg2 - 5, kov2nl, kof, ddpdojt - 7 at init 1c - ? orleg2 - 5, kov2nl, kov3, kof98umh, ddpdojt - 7 at init
1e - ? 2 at init 1e - ? 2 at init
32 - shared RAM bank 32 - shared RAM bank
34, 36 - ? 0 at init 34, 36 - ? 0 at init
@ -126,11 +126,11 @@ WRITE32_MEMBER(pgm2_state::sprite_encryption_w)
m_realspritekey = bitswap<32>(m_spritekey ^ 0x90055555, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31); m_realspritekey = bitswap<32>(m_spritekey ^ 0x90055555, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
} }
void pgm2_state::postload() void pgm2_state::device_post_load()
{ {
// make sure the encrypted area is in the correct state after we load a savestate because we don't want to have to save the whole rom. // make sure the encrypted area is in the correct state after we load a savestate because we don't want to have to save the whole rom.
memcpy(memregion("user1")->base(), &m_encrypted_copy[0], memregion("user1")->bytes()); memcpy(m_mainrom->base(), &m_encrypted_copy[0], m_mainrom->bytes());
if (m_has_decrypted_kov3_module) if (m_has_decrypted_kov3_module)
{ {
@ -143,38 +143,31 @@ void pgm2_state::postload()
if (m_romboard_ram) if (m_romboard_ram)
{ {
decrypter.decrypter_rom((uint16_t*)memregion("user1")->base(), memregion("user1")->bytes(), 0x0200000); decrypter.decrypter_rom((u16*)m_mainrom->base(), m_mainrom->bytes(), m_romboard_ram.bytes());
} }
else else
{ {
decrypter.decrypter_rom((uint16_t*)memregion("user1")->base(), memregion("user1")->bytes(), 0); decrypter.decrypter_rom((u16*)m_mainrom->base(), m_mainrom->bytes(), 0);
} }
} }
} }
WRITE32_MEMBER(pgm2_state::encryption_do_w) WRITE32_MEMBER(pgm2_state::encryption_do_w)
{ {
igs036_decryptor decrypter(m_encryption_table);
if (m_romboard_ram) if (m_romboard_ram)
{ {
igs036_decryptor decrypter(m_encryption_table); decrypter.decrypter_rom((u16*)&m_romboard_ram[0], m_romboard_ram.bytes(), 0);
decrypter.decrypter_rom((uint16_t*)&m_romboard_ram[0], 0x0200000, 0); decrypter.decrypter_rom((u16*)m_mainrom->base(), m_mainrom->bytes(), m_romboard_ram.bytes()); // assume the rom at 0x0200000 also gets decrypted as if it was at 0x0200000 even if it isn't used (the game has already copied it to RAM where it properly decrypted)
decrypter.decrypter_rom((uint16_t*)memregion("user1")->base(), memregion("user1")->bytes(), 0x0200000); // assume the rom at 0x0200000 also gets decrypted as if it was at 0x0200000 even if it isn't used (the game has already copied it to RAM where it properly decrypted)
m_has_decrypted = 1;
} }
else else
{ {
igs036_decryptor decrypter(m_encryption_table); decrypter.decrypter_rom((u16*)m_mainrom->base(), m_mainrom->bytes(), 0);
decrypter.decrypter_rom((uint16_t*)memregion("user1")->base(), memregion("user1")->bytes(), 0);
m_has_decrypted = 1;
} }
m_has_decrypted = true;
} }
INTERRUPT_GEN_MEMBER(pgm2_state::igs_interrupt)
{
m_arm_aic->set_irq(12, ASSERT_LINE);
}
WRITE16_MEMBER(pgm2_state::share_bank_w) WRITE16_MEMBER(pgm2_state::share_bank_w)
{ {
COMBINE_DATA(&m_share_bank); COMBINE_DATA(&m_share_bank);
@ -190,7 +183,7 @@ WRITE8_MEMBER(pgm2_state::shareram_w)
} }
TIMER_DEVICE_CALLBACK_MEMBER(pgm2_state::igs_interrupt2) TIMER_DEVICE_CALLBACK_MEMBER(pgm2_state::mcu_interrupt)
{ {
m_arm_aic->set_irq(3, ASSERT_LINE); m_arm_aic->set_irq(3, ASSERT_LINE);
} }
@ -198,21 +191,21 @@ TIMER_DEVICE_CALLBACK_MEMBER(pgm2_state::igs_interrupt2)
// "MPU" MCU HLE starts here // "MPU" MCU HLE starts here
// command delays are far from correct, might not work in other games // command delays are far from correct, might not work in other games
// command results probably incorrect (except for explicit checked bytes) // command results probably incorrect (except for explicit checked bytes)
void pgm2_state::mcu_command(address_space &space, bool is_command) void pgm2_state::mcu_command(bool is_command)
{ {
uint8_t cmd = m_mcu_regs[0] & 0xff; u8 const cmd = m_mcu_regs[0] & 0xff;
// if (is_command && cmd != 0xf6) // if (is_command && cmd != 0xf6)
// logerror("MCU command %08x %08x\n", m_mcu_regs[0], m_mcu_regs[1]); // logerror("MCU command %08x %08x\n", m_mcu_regs[0], m_mcu_regs[1]);
if (is_command) if (is_command)
{ {
m_mcu_last_cmd = cmd; m_mcu_last_cmd = cmd;
uint8_t status = 0xf7; // "command accepted" status u8 status = 0xf7; // "command accepted" status
int delay = 1; int delay = 1;
uint8_t arg1 = m_mcu_regs[0] >> 8; u8 arg1 = m_mcu_regs[0] >> 8;
uint8_t arg2 = m_mcu_regs[0] >> 16; u8 arg2 = m_mcu_regs[0] >> 16;
uint8_t arg3 = m_mcu_regs[0] >> 24; u8 arg3 = m_mcu_regs[0] >> 24;
switch (cmd) switch (cmd)
{ {
case 0xf6: // get result case 0xf6: // get result
@ -224,11 +217,11 @@ void pgm2_state::mcu_command(address_space &space, bool is_command)
m_mcu_result0 = m_mcu_regs[0]; m_mcu_result0 = m_mcu_regs[0];
m_mcu_result1 = m_mcu_regs[1]; m_mcu_result1 = m_mcu_regs[1];
break; break;
case 0xe1: // shared ram access (unimplemented) case 0xe1: // shared RAM access (unimplemented)
{ {
// MCU access to RAM shared at 0x30100000, 2x banks, in the same time CPU and MCU access different banks // MCU access to RAM shared at 0x30100000, 2x banks, in the same time CPU and MCU access different banks
uint8_t mode = m_mcu_regs[0] >> 16; // 0 - ???, 1 - read, 2 - write u8 mode = m_mcu_regs[0] >> 16; // 0 - ???, 1 - read, 2 - write
uint8_t data = m_mcu_regs[0] >> 24; u8 data = m_mcu_regs[0] >> 24;
if (mode == 2) if (mode == 2)
{ {
// where is offset ? so far assume this command fill whole page // where is offset ? so far assume this command fill whole page
@ -249,21 +242,21 @@ void pgm2_state::mcu_command(address_space &space, bool is_command)
status = 0xf4; status = 0xf4;
m_mcu_result0 = cmd; m_mcu_result0 = cmd;
break; break;
case 0xc2: // read data to shared ram case 0xc2: // read data to shared RAM
for (int i = 0; i < arg3; i++) for (int i = 0; i < arg3; i++)
{ {
if (m_memcard[arg1 & 3]->present() != -1) if (m_memcard[arg1 & 3]->present() != -1)
m_shareram[i + (~m_share_bank & 1) * 128] = m_memcard[arg1 & 3]->read(space, arg2 + i); m_shareram[i + (~m_share_bank & 1) * 128] = m_memcard[arg1 & 3]->read(arg2 + i);
else else
status = 0xf4; status = 0xf4;
} }
m_mcu_result0 = cmd; m_mcu_result0 = cmd;
break; break;
case 0xc3: // save data from shared ram case 0xc3: // save data from shared RAM
for (int i = 0; i < arg3; i++) for (int i = 0; i < arg3; i++)
{ {
if (m_memcard[arg1 & 3]->present() != -1) if (m_memcard[arg1 & 3]->present() != -1)
m_memcard[arg1 & 3]->write(space, arg2 + i, m_shareram[i + (~m_share_bank & 1) * 128]); m_memcard[arg1 & 3]->write(arg2 + i, m_shareram[i + (~m_share_bank & 1) * 128]);
else else
status = 0xf4; status = 0xf4;
} }
@ -272,9 +265,9 @@ void pgm2_state::mcu_command(address_space &space, bool is_command)
case 0xc4: // presumable read security mem (password only?) case 0xc4: // presumable read security mem (password only?)
if (m_memcard[arg1 & 3]->present() != -1) if (m_memcard[arg1 & 3]->present() != -1)
{ {
m_mcu_result1 = m_memcard[arg1 & 3]->read_sec(space, 1) | m_mcu_result1 = m_memcard[arg1 & 3]->read_sec(1) |
(m_memcard[arg1 & 3]->read_sec(space, 2) << 8) | (m_memcard[arg1 & 3]->read_sec(2) << 8) |
(m_memcard[arg1 & 3]->read_sec(space, 3) << 16); (m_memcard[arg1 & 3]->read_sec(3) << 16);
} }
else else
status = 0xf4; status = 0xf4;
@ -282,14 +275,14 @@ void pgm2_state::mcu_command(address_space &space, bool is_command)
break; break;
case 0xc5: // write security mem case 0xc5: // write security mem
if (m_memcard[arg1 & 3]->present() != -1) if (m_memcard[arg1 & 3]->present() != -1)
m_memcard[arg1 & 3]->write_sec(space, arg2 & 3, arg3); m_memcard[arg1 & 3]->write_sec(arg2 & 3, arg3);
else else
status = 0xf4; status = 0xf4;
m_mcu_result0 = cmd; m_mcu_result0 = cmd;
break; break;
case 0xc6: // presumable write protection mem case 0xc6: // presumable write protection mem
if (m_memcard[arg1 & 3]->present() != -1) if (m_memcard[arg1 & 3]->present() != -1)
m_memcard[arg1 & 3]->write_prot(space, arg2 & 3, arg3); m_memcard[arg1 & 3]->write_prot(arg2 & 3, arg3);
else else
status = 0xf4; status = 0xf4;
m_mcu_result0 = cmd; m_mcu_result0 = cmd;
@ -297,10 +290,10 @@ void pgm2_state::mcu_command(address_space &space, bool is_command)
case 0xc7: // read protection mem case 0xc7: // read protection mem
if (m_memcard[arg1 & 3]->present() != -1) if (m_memcard[arg1 & 3]->present() != -1)
{ {
m_mcu_result1 = m_memcard[arg1 & 3]->read_prot(space, 0) | m_mcu_result1 = m_memcard[arg1 & 3]->read_prot(0) |
(m_memcard[arg1 & 3]->read_prot(space, 1) << 8) | (m_memcard[arg1 & 3]->read_prot(1) << 8) |
(m_memcard[arg1 & 3]->read_prot(space, 2) << 16) | (m_memcard[arg1 & 3]->read_prot(2) << 16) |
(m_memcard[arg1 & 3]->read_prot(space, 3) << 24); (m_memcard[arg1 & 3]->read_prot(3) << 24);
} }
else else
status = 0xf4; status = 0xf4;
@ -308,7 +301,7 @@ void pgm2_state::mcu_command(address_space &space, bool is_command)
break; break;
case 0xc8: // write data mem case 0xc8: // write data mem
if (m_memcard[arg1 & 3]->present() != -1) if (m_memcard[arg1 & 3]->present() != -1)
m_memcard[arg1 & 3]->write(space, arg2, arg3); m_memcard[arg1 & 3]->write(arg2, arg3);
else else
status = 0xf4; status = 0xf4;
m_mcu_result0 = cmd; m_mcu_result0 = cmd;
@ -350,10 +343,10 @@ WRITE32_MEMBER(pgm2_state::mcu_w)
COMBINE_DATA(&m_mcu_regs[reg]); COMBINE_DATA(&m_mcu_regs[reg]);
if (reg == 2 && m_mcu_regs[2]) // irq to mcu if (reg == 2 && m_mcu_regs[2]) // irq to mcu
mcu_command(space, true); mcu_command(true);
if (reg == 5 && m_mcu_regs[5]) // ack to mcu (written at the end of irq handler routine) if (reg == 5 && m_mcu_regs[5]) // ack to mcu (written at the end of irq handler routine)
{ {
mcu_command(space, false); mcu_command(false);
m_arm_aic->set_irq(3, CLEAR_LINE); m_arm_aic->set_irq(3, CLEAR_LINE);
} }
} }
@ -372,7 +365,7 @@ WRITE16_MEMBER(pgm2_state::unk30120014_w)
else else
{ {
// interesting data // interesting data
//printf("unk30120014_w %d %04x\n", offset, data); //logerror("unk30120014_w %d %04x\n", offset, data);
} }
} }
@ -400,22 +393,22 @@ WRITE16_MEMBER(pgm2_state::unk30120014_w)
or security chip just waiting to be be written magic value at specific address in ROM area, and if this happen enable descrambling using hardcoded values. or security chip just waiting to be be written magic value at specific address in ROM area, and if this happen enable descrambling using hardcoded values.
*/ */
READ_LINE_MEMBER(pgm2_state::module_data_r) int pgm2_state::module_data_r()
{ {
return module_out_latch ? ASSERT_LINE : CLEAR_LINE; return module_out_latch ? ASSERT_LINE : CLEAR_LINE;
} }
WRITE_LINE_MEMBER(pgm2_state::module_data_w) void pgm2_state::module_data_w(int state)
{ {
module_in_latch = (state == ASSERT_LINE) ? 1 : 0; module_in_latch = (state == ASSERT_LINE) ? 1 : 0;
} }
WRITE_LINE_MEMBER(pgm2_state::module_clk_w) void pgm2_state::module_clk_w(int state)
{ {
if (module_prev_state != state && state == CLEAR_LINE) if (module_prev_state != state && state == CLEAR_LINE)
{ {
if (module_clk_cnt < 80) if (module_clk_cnt < 80)
{ {
int offs = module_clk_cnt / 8; s8 const offs = module_clk_cnt / 8;
int bit = (module_clk_cnt & 7) ^ 7; u8 const bit = (module_clk_cnt & 7) ^ 7;
module_rcv_buf[offs] &= ~(1 << bit); module_rcv_buf[offs] &= ~(1 << bit);
module_rcv_buf[offs] |= module_in_latch << bit; module_rcv_buf[offs] |= module_in_latch << bit;
@ -444,9 +437,9 @@ WRITE_LINE_MEMBER(pgm2_state::module_clk_w)
} }
else else
{ {
int offs = (module_clk_cnt - 80) / 8; s8 const offs = (module_clk_cnt - 80) / 8;
int bit = (module_clk_cnt & 7) ^ 7; u8 const bit = (module_clk_cnt & 7) ^ 7;
module_out_latch = (module_send_buf[offs] >> bit) & 1; module_out_latch = BIT(module_send_buf[offs], bit);
++module_clk_cnt; ++module_clk_cnt;
if (module_clk_cnt >= 152) if (module_clk_cnt >= 152)
module_clk_cnt = 0; module_clk_cnt = 0;
@ -461,17 +454,17 @@ READ16_MEMBER(pgm2_state::module_rom_r)
{ {
if (offset == 4) if (offset == 4)
module_sum_read = false; module_sum_read = false;
uint32_t offs = ((offset - 1) * 2) ^ 2; u32 const offs = ((offset - 1) * 2) ^ 2;
return (module_key->sum[offs] ^ module_key->key[offs]) | ((module_key->sum[offs + 1] ^ module_key->key[offs + 1]) << 8); return (module_key->sum[offs] ^ module_key->key[offs]) | ((module_key->sum[offs + 1] ^ module_key->key[offs + 1]) << 8);
} }
return ((uint16_t *)memregion("user1")->base())[offset]; return ((u16 *)m_mainrom->base())[offset];
} }
WRITE16_MEMBER(pgm2_state::module_rom_w) WRITE16_MEMBER(pgm2_state::module_rom_w)
{ {
//printf("module write %04X at %08X\n", data, offset); //logerror("module write %04X at %08X\n", data, offset);
uint32_t dec_val = ((module_key->key[0] | (module_key->key[1] << 8) | (module_key->key[2] << 16)) >> 6) & 0xffff; u32 const dec_val = ((module_key->key[0] | (module_key->key[1] << 8) | (module_key->key[2] << 16)) >> 6) & 0xffff;
if (data == dec_val) if (data == dec_val)
{ {
// might be wrong and normal data access enabled only after whole sequence complete // might be wrong and normal data access enabled only after whole sequence complete
@ -499,15 +492,15 @@ WRITE16_MEMBER(pgm2_state::module_rom_w)
// very primitive Atmel ARM PIO simulation, should be improved and devicified // very primitive Atmel ARM PIO simulation, should be improved and devicified
WRITE32_MEMBER(pgm2_state::pio_sodr_w) WRITE32_MEMBER(pgm2_state::pio_sodr_w)
{ {
pio_out_data |= data & mem_mask; m_pio_out_data |= data & mem_mask;
module_data_w((pio_out_data & 0x100) ? ASSERT_LINE : CLEAR_LINE); module_data_w((m_pio_out_data & 0x100) ? ASSERT_LINE : CLEAR_LINE);
module_clk_w((pio_out_data & 0x200) ? ASSERT_LINE : CLEAR_LINE); module_clk_w((m_pio_out_data & 0x200) ? ASSERT_LINE : CLEAR_LINE);
} }
WRITE32_MEMBER(pgm2_state::pio_codr_w) WRITE32_MEMBER(pgm2_state::pio_codr_w)
{ {
pio_out_data &= ~(data & mem_mask); m_pio_out_data &= ~(data & mem_mask);
module_data_w((pio_out_data & 0x100) ? ASSERT_LINE : CLEAR_LINE); module_data_w((m_pio_out_data & 0x100) ? ASSERT_LINE : CLEAR_LINE);
module_clk_w((pio_out_data & 0x200) ? ASSERT_LINE : CLEAR_LINE); module_clk_w((m_pio_out_data & 0x200) ? ASSERT_LINE : CLEAR_LINE);
} }
READ32_MEMBER(pgm2_state::pio_pdsr_r) READ32_MEMBER(pgm2_state::pio_pdsr_r)
{ {
@ -516,9 +509,9 @@ READ32_MEMBER(pgm2_state::pio_pdsr_r)
void pgm2_state::pgm2_map(address_map &map) void pgm2_state::pgm2_map(address_map &map)
{ {
map(0x00000000, 0x00003fff).rom(); //AM_REGION("user1", 0x00000) // internal ROM map(0x00000000, 0x00003fff).rom(); //AM_REGION("mainrom", 0x00000) // internal ROM
map(0x02000000, 0x0200ffff).ram().share("sram"); // 'battery ram' (in CPU?) map(0x02000000, 0x0200ffff).ram().share("sram"); // 'battery RAM' (in CPU?)
map(0x03600000, 0x036bffff).rw(FUNC(pgm2_state::mcu_r), FUNC(pgm2_state::mcu_w)); map(0x03600000, 0x036bffff).rw(FUNC(pgm2_state::mcu_r), FUNC(pgm2_state::mcu_w));
@ -527,7 +520,8 @@ void pgm2_state::pgm2_map(address_map &map)
map(0x20000000, 0x2007ffff).ram().share("mainram"); map(0x20000000, 0x2007ffff).ram().share("mainram");
map(0x30000000, 0x30001fff).ram().share("sp_videoram"); // spriteram ('move' ram in test mode) map(0x30000000, 0x30001fff).ram().share("sp_videoram"); // spriteram ('move' RAM in test mode)
map(0x30002000, 0x30003fff).ram(); // Second half of RAM 6 area of later RAM test, more sprite RAM or mirror of above?
map(0x30020000, 0x30021fff).ram().w(FUNC(pgm2_state::bg_videoram_w)).share("bg_videoram"); map(0x30020000, 0x30021fff).ram().w(FUNC(pgm2_state::bg_videoram_w)).share("bg_videoram");
map(0x30040000, 0x30045fff).ram().w(FUNC(pgm2_state::fg_videoram_w)).share("fg_videoram"); map(0x30040000, 0x30045fff).ram().w(FUNC(pgm2_state::fg_videoram_w)).share("fg_videoram");
@ -539,12 +533,14 @@ void pgm2_state::pgm2_map(address_map &map)
map(0x300a0000, 0x300a07ff).ram().w(m_tx_palette, FUNC(palette_device::write32)).share("tx_palette"); map(0x300a0000, 0x300a07ff).ram().w(m_tx_palette, FUNC(palette_device::write32)).share("tx_palette");
map(0x300c0000, 0x300c01ff).ram().share("sp_zoom"); // sprite zoom table - it uploads the same data 4x, maybe xshrink,xgrow,yshrink,ygrow or just redundant mirrors map(0x300c0000, 0x300c01ff).ram().share("sp_zoom"); // sprite zoom table - it uploads the same data 4x, maybe xshrink,xgrow,yshrink,ygrow or just redundant mirrors
map(0x300c0200, 0x300c03ff).ram(); // Second half of RAM 4 area of later RAM test, more sprite zoom table or mirror of above?
/* linescroll ram - it clears to 0x3bf on startup which is enough bytes for 240 lines if each rowscroll value was 8 bytes, but each row is 4, /* linescroll RAM - it clears to 0x3bf on startup which is enough bytes for 240 lines if each rowscroll value was 8 bytes, but each row is 4,
so only half of this is used? or tx can do it too (unlikely, as orl2 writes 256 lines of data) maybe just bad mem check bounds on orleg2. so only half of this is used? or tx can do it too (unlikely, as orl2 writes 256 lines of data) maybe just bad mem check bounds on orleg2.
It reports pass even if it fails the first byte but if the first byte passes it attempts to test 0x10000 bytes, which is far too big so It reports pass even if it fails the first byte but if the first byte passes it attempts to test 0x10000 bytes, which is far too big so
what is the real size? */ what is the real size? */
map(0x300e0000, 0x300e03ff).ram().share("lineram").mirror(0x000fc00); map(0x300e0000, 0x300e03ff).ram().share("lineram").mirror(0x000fc00);
map(0x300f0000, 0x300fffff).ram(); // RAM 5 area of later RAM test, more linescroll RAM or mirror of above?
map(0x30100000, 0x301000ff).rw(FUNC(pgm2_state::shareram_r), FUNC(pgm2_state::shareram_w)).umask32(0x00ff00ff); map(0x30100000, 0x301000ff).rw(FUNC(pgm2_state::shareram_r), FUNC(pgm2_state::shareram_w)).umask32(0x00ff00ff);
@ -581,14 +577,14 @@ void pgm2_state::pgm2_map(address_map &map)
void pgm2_state::pgm2_rom_map(address_map &map) void pgm2_state::pgm2_rom_map(address_map &map)
{ {
pgm2_map(map); pgm2_map(map);
map(0x10000000, 0x10ffffff).rom().region("user1", 0); // external ROM map(0x10000000, 0x10ffffff).rom().region("mainrom", 0); // external ROM
} }
void pgm2_state::pgm2_ram_rom_map(address_map &map) void pgm2_state::pgm2_ram_rom_map(address_map &map)
{ {
pgm2_map(map); pgm2_map(map);
map(0x10000000, 0x101fffff).ram().share("romboard_ram"); // we should also probably decrypt writes once the encryption is enabled, but the game never writes with it turned on anyway map(0x10000000, 0x101fffff).ram().share("romboard_ram"); // we should also probably decrypt writes once the encryption is enabled, but the game never writes with it turned on anyway
map(0x10200000, 0x103fffff).rom().region("user1", 0); // external ROM map(0x10200000, 0x103fffff).rom().region("mainrom", 0); // external ROM
} }
void pgm2_state::pgm2_module_rom_map(address_map &map) void pgm2_state::pgm2_module_rom_map(address_map &map)
@ -655,10 +651,10 @@ static INPUT_PORTS_START( pgm2 )
PORT_BIT( 0x00008000, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x00008000, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN3 )
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_COIN4 ) PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_COIN4 )
PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE1 ) // test key p1+p2 PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Test Key P1 & P2") // test key p1+p2
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_SERVICE2 ) // test key p3+p4 PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Test Key P3 & P4") // test key p3+p4
PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_SERVICE3 ) // service key p1+p2 PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_SERVICE3 ) PORT_NAME("Service P1 & P2") // service key p1+p2
PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_SERVICE4 ) // service key p3+p4 PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_SERVICE4 ) PORT_NAME("Service P3 & P4") // service key p3+p4
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNUSED )
@ -689,7 +685,7 @@ INPUT_PORTS_END
WRITE_LINE_MEMBER(pgm2_state::irq) WRITE_LINE_MEMBER(pgm2_state::irq)
{ {
// printf("irq\n"); // logerror("irq\n");
if (state == ASSERT_LINE) m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); if (state == ASSERT_LINE) m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE);
else m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE); else m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE);
} }
@ -707,7 +703,7 @@ void pgm2_state::machine_start()
save_item(NAME(m_mcu_last_cmd)); save_item(NAME(m_mcu_last_cmd));
save_item(NAME(m_shareram)); save_item(NAME(m_shareram));
save_item(NAME(m_share_bank)); save_item(NAME(m_share_bank));
save_item(NAME(pio_out_data)); save_item(NAME(m_pio_out_data));
save_item(NAME(module_in_latch)); save_item(NAME(module_in_latch));
save_item(NAME(module_sum_read)); save_item(NAME(module_sum_read));
save_item(NAME(module_out_latch)); save_item(NAME(module_out_latch));
@ -715,8 +711,6 @@ void pgm2_state::machine_start()
save_item(NAME(module_clk_cnt)); save_item(NAME(module_clk_cnt));
save_item(NAME(module_rcv_buf)); save_item(NAME(module_rcv_buf));
save_item(NAME(module_send_buf)); save_item(NAME(module_send_buf));
machine().save().register_postload(save_prepost_delegate(FUNC(pgm2_state::postload), this));
} }
void pgm2_state::machine_reset() void pgm2_state::machine_reset()
@ -727,12 +721,12 @@ void pgm2_state::machine_reset()
m_share_bank = 0; m_share_bank = 0;
// as the decryption is dynamic controlled by the program, restore the encrypted copy // as the decryption is dynamic controlled by the program, restore the encrypted copy
memcpy(memregion("user1")->base(), &m_encrypted_copy[0], memregion("user1")->bytes()); memcpy(m_mainrom->base(), &m_encrypted_copy[0], m_mainrom->bytes());
m_has_decrypted = 0; m_has_decrypted = false;
m_has_decrypted_kov3_module = 0; m_has_decrypted_kov3_module = false;
pio_out_data = 0; m_pio_out_data = 0;
module_prev_state = 0; module_prev_state = 0;
module_sum_read = false; module_sum_read = false;
module_clk_cnt = 151; // this needed because of "false" clock pulse happen during gpio init module_clk_cnt = 151; // this needed because of "false" clock pulse happen during gpio init
@ -743,9 +737,9 @@ static const gfx_layout tiles8x8_layout =
8,8, 8,8,
RGN_FRAC(1,1), RGN_FRAC(1,1),
4, 4,
{ 0, 1, 2, 3 }, { STEP4(0,1) },
{ 4, 0, 12, 8, 20, 16, 28, 24 }, { 4, 0, 12, 8, 20, 16, 28, 24 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 }, { STEP8(0,4*8) },
32*8 32*8
}; };
@ -755,11 +749,8 @@ static const gfx_layout tiles32x32x8_layout =
RGN_FRAC(1,1), RGN_FRAC(1,1),
7, 7,
{ 1, 2, 3, 4, 5, 6, 7 }, { 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8, { STEP32(0,8) },
16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8, 24*8, 25*8, 26*8, 27*8, 28*8, 29*8, 30*8, 31*8 }, { STEP32(0,8*32) },
{ 0*256, 1*256, 2*256, 3*256, 4*256, 5*256, 6*256, 7*256, 8*256, 9*256, 10*256, 11*256, 12*256, 13*256, 14*256, 15*256,
16*256, 17*256, 18*256, 19*256, 20*256, 21*256, 22*256, 23*256, 24*256, 25*256, 26*256, 27*256, 28*256, 29*256, 30*256, 31*256
},
256*32 256*32
}; };
@ -771,73 +762,66 @@ static GFXDECODE_START( pgm2_bg )
GFXDECODE_ENTRY( "bgtile", 0, tiles32x32x8_layout, 0, 0x2000/4/0x80 ) GFXDECODE_ENTRY( "bgtile", 0, tiles32x32x8_layout, 0, 0x2000/4/0x80 )
GFXDECODE_END GFXDECODE_END
MACHINE_CONFIG_START(pgm2_state::pgm2) void pgm2_state::pgm2(machine_config &config)
{
/* basic machine hardware */ /* basic machine hardware */
MCFG_DEVICE_ADD("maincpu", IGS036, 100000000) // ?? ARM based CPU, has internal ROM. IGS036(config, m_maincpu, 100000000); // Unknown clock / divider
MCFG_DEVICE_PROGRAM_MAP(pgm2_rom_map) m_maincpu->set_addrmap(AS_PROGRAM, &pgm2_state::pgm2_rom_map);
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", pgm2_state, igs_interrupt) TIMER(config, m_mcu_timer, 0).configure_generic(timer_device::expired_delegate(FUNC(pgm2_state::mcu_interrupt), this));
MCFG_TIMER_DRIVER_ADD("mcu_timer", pgm2_state, igs_interrupt2)
ARM_AIC(config, "arm_aic", 0).irq_callback().set(FUNC(pgm2_state::irq)); ARM_AIC(config, m_arm_aic, 0).irq_callback().set(FUNC(pgm2_state::irq));
/* video hardware */ /* video hardware */
MCFG_SCREEN_ADD("screen", RASTER) SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
MCFG_SCREEN_REFRESH_RATE(60) m_screen->set_refresh(HZ_TO_ATTOSECONDS(60));
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
MCFG_SCREEN_SIZE(64*8, 32*8) m_screen->set_size(64*8, 32*8);
MCFG_SCREEN_VISIBLE_AREA(0, 448-1, 0, 224-1) m_screen->set_visarea(0, 448-1, 0, 224-1);
MCFG_SCREEN_UPDATE_DRIVER(pgm2_state, screen_update_pgm2) m_screen->set_screen_update(FUNC(pgm2_state::screen_update));
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, pgm2_state, screen_vblank_pgm2)) m_screen->screen_vblank().set(FUNC(pgm2_state::screen_vblank));
MCFG_DEVICE_ADD("gfxdecode2", GFXDECODE, "tx_palette", pgm2_tx) GFXDECODE(config, m_gfxdecode2, m_tx_palette, pgm2_tx);
GFXDECODE(config, m_gfxdecode3, m_bg_palette, pgm2_bg);
MCFG_DEVICE_ADD("gfxdecode3", GFXDECODE, "bg_palette", pgm2_bg) PALETTE(config, m_sp_palette, 0x4000/4).set_format(PALETTE_FORMAT_XRGB); // sprites
PALETTE(config, m_tx_palette, 0x800/4).set_format(PALETTE_FORMAT_XRGB); // text
MCFG_PALETTE_ADD("sp_palette", 0x4000/4) // sprites PALETTE(config, m_bg_palette, 0x2000/4).set_format(PALETTE_FORMAT_XRGB); // bg
MCFG_PALETTE_FORMAT(XRGB)
MCFG_PALETTE_ADD("tx_palette", 0x800/4) // text
MCFG_PALETTE_FORMAT(XRGB)
MCFG_PALETTE_ADD("bg_palette", 0x2000/4) // bg
MCFG_PALETTE_FORMAT(XRGB)
NVRAM(config, "sram", nvram_device::DEFAULT_ALL_0); NVRAM(config, "sram", nvram_device::DEFAULT_ALL_0);
SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right(); SPEAKER(config, "rspeaker").front_right();
MCFG_DEVICE_ADD("ymz774", YMZ774, 16384000) // is clock correct ?
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) ymz774_device &ymz774(YMZ774(config, "ymz774", 16384000)); // is clock correct ?
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) ymz774.add_route(0, "lspeaker", 1.0);
ymz774.add_route(1, "rspeaker", 1.0);
PGM2_MEMCARD(config, m_memcard[0], 0); PGM2_MEMCARD(config, m_memcard[0], 0);
PGM2_MEMCARD(config, m_memcard[1], 0); PGM2_MEMCARD(config, m_memcard[1], 0);
PGM2_MEMCARD(config, m_memcard[2], 0); PGM2_MEMCARD(config, m_memcard[2], 0);
PGM2_MEMCARD(config, m_memcard[3], 0); PGM2_MEMCARD(config, m_memcard[3], 0);
MACHINE_CONFIG_END }
// not strictly needed as the video code supports changing on the fly, but makes recording easier etc. // not strictly needed as the video code supports changing on the fly, but makes recording easier etc.
MACHINE_CONFIG_START(pgm2_state::pgm2_lores) void pgm2_state::pgm2_lores(machine_config &config)
{
pgm2(config); pgm2(config);
MCFG_SCREEN_MODIFY("screen") m_screen->set_visarea(0, 320-1, 0, 240-1);
MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) }
MACHINE_CONFIG_END
MACHINE_CONFIG_START(pgm2_state::pgm2_hires) void pgm2_state::pgm2_hires(machine_config &config)
{
pgm2(config); pgm2(config);
MCFG_DEVICE_MODIFY("maincpu") m_maincpu->set_addrmap(AS_PROGRAM, &pgm2_state::pgm2_module_rom_map);
MCFG_DEVICE_PROGRAM_MAP(pgm2_module_rom_map) m_screen->set_visarea(0, 512-1, 0, 240-1);
MCFG_SCREEN_MODIFY("screen") }
MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 240-1)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(pgm2_state::pgm2_ramrom) void pgm2_state::pgm2_ramrom(machine_config &config)
{
pgm2(config); pgm2(config);
MCFG_DEVICE_MODIFY("maincpu") m_maincpu->set_addrmap(AS_PROGRAM, &pgm2_state::pgm2_ram_rom_map);
MCFG_DEVICE_PROGRAM_MAP(pgm2_ram_rom_map) }
MACHINE_CONFIG_END
/* using macros for the video / sound roms because the locations never change between sets, and /* using macros for the video / sound roms because the locations never change between sets, and
we're going to have a LOT of clones to cover all the internal rom regions and external rom revision we're going to have a LOT of clones to cover all the internal rom regions and external rom revision
@ -846,7 +830,7 @@ MACHINE_CONFIG_END
// Oriental Legend 2 // Oriental Legend 2
#define ORLEG2_VIDEO_SOUND_ROMS \ #define ORLEG2_VIDEO_SOUND_ROMS \
ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ ROM_REGION( 0x200000, "tiles", ROMREGION_ERASE00 ) \
ROM_LOAD( "ig-a_text.u4", 0x00000000, 0x0200000, CRC(fa444c32) SHA1(31e5e3efa92d52bf9ab97a0ece51e3b77f52ce8a) ) \ ROM_LOAD( "ig-a_text.u4", 0x00000000, 0x0200000, CRC(fa444c32) SHA1(31e5e3efa92d52bf9ab97a0ece51e3b77f52ce8a) ) \
\ \
ROM_REGION( 0x1000000, "bgtile", 0 ) \ ROM_REGION( 0x1000000, "bgtile", 0 ) \
@ -879,15 +863,15 @@ MACHINE_CONFIG_END
*/ */
#define ORLEG2_PROGRAM_104(prefix, extension) \ #define ORLEG2_PROGRAM_104(prefix, extension) \
ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_REGION( 0x1000000, "mainrom", 0 ) \
ROM_LOAD( #prefix "_v104" #extension ".u7", 0x000000, 0x800000, CRC(7c24a4f5) SHA1(3cd9f9264ef2aad0869afdf096e88eb8d74b2570) ) // V104 08-03-03 13:25:37 ROM_LOAD( #prefix "_v104" #extension ".u7", 0x000000, 0x800000, CRC(7c24a4f5) SHA1(3cd9f9264ef2aad0869afdf096e88eb8d74b2570) ) // V104 08-03-03 13:25:37
#define ORLEG2_PROGRAM_103(prefix, extension) \ #define ORLEG2_PROGRAM_103(prefix, extension) \
ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_REGION( 0x1000000, "mainrom", 0 ) \
ROM_LOAD( #prefix "_v103" #extension ".u7", 0x000000, 0x800000, CRC(21c1fae8) SHA1(36eeb7a5e8dc8ee7c834f3ff1173c28cf6c2f1a3) ) // V103 08-01-30 14:45:17 ROM_LOAD( #prefix "_v103" #extension ".u7", 0x000000, 0x800000, CRC(21c1fae8) SHA1(36eeb7a5e8dc8ee7c834f3ff1173c28cf6c2f1a3) ) // V103 08-01-30 14:45:17
#define ORLEG2_PROGRAM_101(prefix, extension) \ #define ORLEG2_PROGRAM_101(prefix, extension) \
ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_REGION( 0x1000000, "mainrom", 0 ) \
ROM_LOAD( #prefix "_v101" #extension ".u7", 0x000000, 0x800000, CRC(45805b53) SHA1(f2a8399c821b75fadc53e914f6f318707e70787c) ) // V101 07-12-24 09:32:32 ROM_LOAD( #prefix "_v101" #extension ".u7", 0x000000, 0x800000, CRC(45805b53) SHA1(f2a8399c821b75fadc53e914f6f318707e70787c) ) // V101 07-12-24 09:32:32
/* /*
@ -899,17 +883,17 @@ MACHINE_CONFIG_END
#define ORLEG2_INTERNAL_CHINA \ #define ORLEG2_INTERNAL_CHINA \
ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_REGION( 0x04000, "maincpu", 0 ) \
ROM_LOAD( "xyj2_cn.igs036", 0x00000000, 0x0004000, CRC(bcce7641) SHA1(c3b5cf6e9f6eae09b6785314777a52b34c3c7657) ) \ ROM_LOAD( "xyj2_cn.igs036", 0x00000000, 0x0004000, CRC(bcce7641) SHA1(c3b5cf6e9f6eae09b6785314777a52b34c3c7657) ) /* Core V100 China */ \
ROM_REGION( 0x108, "default_card", 0 ) \ ROM_REGION( 0x108, "default_card", 0 ) \
ROM_LOAD( "blank_orleg2_china_card.pg2", 0x000, 0x108, CRC(dc29556f) SHA1(2335cc7af25d4dd9763c6944d3f0eb50276de80a) ) ROM_LOAD( "blank_orleg2_china_card.pg2", 0x000, 0x108, CRC(dc29556f) SHA1(2335cc7af25d4dd9763c6944d3f0eb50276de80a) )
#define ORLEG2_INTERNAL_OVERSEAS \ #define ORLEG2_INTERNAL_OVERSEAS \
ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_REGION( 0x04000, "maincpu", 0 ) \
ROM_LOAD( "ol2_fa.igs036", 0x00000000, 0x0004000, CRC(cc4d398a) SHA1(c50bcc81f02cd5aa8ad157d73209dc53bdedc023) ) ROM_LOAD( "ol2_fa.igs036", 0x00000000, 0x0004000, CRC(cc4d398a) SHA1(c50bcc81f02cd5aa8ad157d73209dc53bdedc023) ) // Core V100 Oversea
#define ORLEG2_INTERNAL_JAPAN \ #define ORLEG2_INTERNAL_JAPAN \
ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_REGION( 0x04000, "maincpu", 0 ) \
ROM_LOAD( "ol2_a10.igs036", 0x00000000, 0x0004000, CRC(69375284) SHA1(a120c6a3d8d7898cc3ca508abea78e5e54090c66) ) ROM_LOAD( "ol2_a10.igs036", 0x00000000, 0x0004000, CRC(69375284) SHA1(a120c6a3d8d7898cc3ca508abea78e5e54090c66) ) // Core V100 Japan
ROM_START( orleg2 ) ROM_START( orleg2 )
ORLEG2_INTERNAL_OVERSEAS ORLEG2_INTERNAL_OVERSEAS
@ -968,7 +952,7 @@ ROM_END
// Knights of Valour 2 New Legend // Knights of Valour 2 New Legend
#define KOV2NL_VIDEO_SOUND_ROMS \ #define KOV2NL_VIDEO_SOUND_ROMS \
ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ ROM_REGION( 0x200000, "tiles", ROMREGION_ERASE00 ) \
ROM_LOAD( "ig-a3_text.u4", 0x00000000, 0x0200000, CRC(214530ff) SHA1(4231a02054b0345392a077042b95779fd45d6c22) ) \ ROM_LOAD( "ig-a3_text.u4", 0x00000000, 0x0200000, CRC(214530ff) SHA1(4231a02054b0345392a077042b95779fd45d6c22) ) \
\ \
ROM_REGION( 0x1000000, "bgtile", 0 ) \ ROM_REGION( 0x1000000, "bgtile", 0 ) \
@ -990,22 +974,22 @@ ROM_END
ROM_LOAD("gsyx_nvram", 0x00000000, 0x10000, CRC(22400c16) SHA1(f775a16299c30f2ce23d683161b910e06eff37c1) ) ROM_LOAD("gsyx_nvram", 0x00000000, 0x10000, CRC(22400c16) SHA1(f775a16299c30f2ce23d683161b910e06eff37c1) )
#define KOV2NL_PROGRAM_302(prefix, extension) \ #define KOV2NL_PROGRAM_302(prefix, extension) \
ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_REGION( 0x1000000, "mainrom", 0 ) \
ROM_LOAD( #prefix "_v302" #extension ".u7", 0x00000000, 0x0800000, CRC(b19cf540) SHA1(25da5804bbfd7ef2cdf5cc5aabaa803d18b98929) ) // V302 08-12-03 15:27:34 ROM_LOAD( #prefix "_v302" #extension ".u7", 0x00000000, 0x0800000, CRC(b19cf540) SHA1(25da5804bbfd7ef2cdf5cc5aabaa803d18b98929) ) // V302 08-12-03 15:27:34
#define KOV2NL_PROGRAM_301(prefix, extension) \ #define KOV2NL_PROGRAM_301(prefix, extension) \
ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_REGION( 0x1000000, "mainrom", 0 ) \
ROM_LOAD( #prefix "_v301" #extension ".u7", 0x000000, 0x800000, CRC(c4595c2c) SHA1(09e379556ef76f81a63664f46d3f1415b315f384) ) // V301 08-09-09 09:44:53 ROM_LOAD( #prefix "_v301" #extension ".u7", 0x000000, 0x800000, CRC(c4595c2c) SHA1(09e379556ef76f81a63664f46d3f1415b315f384) ) // V301 08-09-09 09:44:53
#define KOV2NL_PROGRAM_300(prefix, extension) \ #define KOV2NL_PROGRAM_300(prefix, extension) \
ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_REGION( 0x1000000, "mainrom", 0 ) \
ROM_LOAD( #prefix "_v300" #extension ".u7", 0x000000, 0x800000, CRC(08da7552) SHA1(303b97d7694405474c8133a259303ccb49db48b1) ) // V300 08-08-06 18:21:23 ROM_LOAD( #prefix "_v300" #extension ".u7", 0x000000, 0x800000, CRC(08da7552) SHA1(303b97d7694405474c8133a259303ccb49db48b1) ) // V300 08-08-06 18:21:23
// Region 0x00 - China // Region 0x00 - China
#define KOV2NL_INTERNAL_CHINA \ #define KOV2NL_INTERNAL_CHINA \
ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_REGION( 0x04000, "maincpu", 0 ) \
ROM_LOAD( "gsyx_igs036_china.rom", 0x00000000, 0x0004000, CRC(e09fe4ce) SHA1(c0cac64ef8727cbe79d503ec4df66ddb6f2c925e) ) \ ROM_LOAD( "gsyx_igs036_china.rom", 0x00000000, 0x0004000, CRC(e09fe4ce) SHA1(c0cac64ef8727cbe79d503ec4df66ddb6f2c925e) ) /* Core V100 China */ \
ROM_REGION( 0x108, "default_card", 0 ) \ ROM_REGION( 0x108, "default_card", 0 ) \
ROM_LOAD( "blank_gsyx_china.pg2", 0x000, 0x108, CRC(02842ae8) SHA1(a6cda633b09a706039a79b73db2c258094826f85) ) ROM_LOAD( "blank_gsyx_china.pg2", 0x000, 0x108, CRC(02842ae8) SHA1(a6cda633b09a706039a79b73db2c258094826f85) )
@ -1025,7 +1009,7 @@ ROM_END
// Region 0x05 - Overseas // Region 0x05 - Overseas
#define KOV2NL_INTERNAL_OVERSEA \ #define KOV2NL_INTERNAL_OVERSEA \
ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_REGION( 0x04000, "maincpu", 0 ) \
ROM_LOAD( "kov2nl_igs036_oversea.rom", 0x00000000, 0x0004000, CRC(25ec60cd) SHA1(7dd12d2bc642bfa79520676fe5de458ce7d08ef6) ) \ ROM_LOAD( "kov2nl_igs036_oversea.rom", 0x00000000, 0x0004000, CRC(25ec60cd) SHA1(7dd12d2bc642bfa79520676fe5de458ce7d08ef6) ) /* Core V100 oversea */ \
ROM_REGION( 0x108, "default_card", 0 ) \ ROM_REGION( 0x108, "default_card", 0 ) \
ROM_LOAD( "blank_kov2nl_overseas_card.pg2", 0x000, 0x108, CRC(1155f01f) SHA1(60f7bed1461b362a3da687503cd72ed2d5e96f30) ) ROM_LOAD( "blank_kov2nl_overseas_card.pg2", 0x000, 0x108, CRC(1155f01f) SHA1(60f7bed1461b362a3da687503cd72ed2d5e96f30) )
@ -1070,7 +1054,7 @@ ROM_END
// Dodonpachi Daioujou Tamashii // Dodonpachi Daioujou Tamashii
#define DDPDOJT_VIDEO_SOUND_ROMS \ #define DDPDOJT_VIDEO_SOUND_ROMS \
ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ ROM_REGION( 0x200000, "tiles", ROMREGION_ERASE00 ) \
ROM_LOAD( "ddpdoj_text.u1", 0x00000000, 0x0200000, CRC(f18141d1) SHA1(a16e0a76bc926a158bb92dfd35aca749c569ef50) ) \ ROM_LOAD( "ddpdoj_text.u1", 0x00000000, 0x0200000, CRC(f18141d1) SHA1(a16e0a76bc926a158bb92dfd35aca749c569ef50) ) \
\ \
ROM_REGION( 0x2000000, "bgtile", 0 ) \ ROM_REGION( 0x2000000, "bgtile", 0 ) \
@ -1093,9 +1077,9 @@ ROM_END
ROM_START( ddpdojt ) ROM_START( ddpdojt )
ROM_REGION( 0x04000, "maincpu", 0 ) ROM_REGION( 0x04000, "maincpu", 0 )
ROM_LOAD( "ddpdoj_igs036_china.rom", 0x00000000, 0x0004000, CRC(5db91464) SHA1(723d8086285805bd815e62120dfa9a4269bcd932) ) ROM_LOAD( "ddpdoj_igs036_china.rom", 0x00000000, 0x0004000, CRC(5db91464) SHA1(723d8086285805bd815e62120dfa9a4269bcd932) ) // Core V100 China
ROM_REGION( 0x0200000, "user1", 0 ) ROM_REGION( 0x0200000, "mainrom", 0 )
ROM_LOAD( "ddpdoj_v201cn.u4", 0x00000000, 0x0200000, CRC(89e4b760) SHA1(9fad1309da31d12a413731b416a8bbfdb304ed9e) ) // V201 10-03-27 17:45:12 ROM_LOAD( "ddpdoj_v201cn.u4", 0x00000000, 0x0200000, CRC(89e4b760) SHA1(9fad1309da31d12a413731b416a8bbfdb304ed9e) ) // V201 10-03-27 17:45:12
DDPDOJT_VIDEO_SOUND_ROMS DDPDOJT_VIDEO_SOUND_ROMS
@ -1111,7 +1095,7 @@ ROM_END
*/ */
#define KOV3_VIDEO_SOUND_ROMS \ #define KOV3_VIDEO_SOUND_ROMS \
ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ ROM_REGION( 0x200000, "tiles", ROMREGION_ERASE00 ) \
ROM_LOAD( "kov3_text.u1", 0x00000000, 0x0200000, CRC(198b52d6) SHA1(e4502abe7ba01053d16c02114f0c88a3f52f6f40) ) \ ROM_LOAD( "kov3_text.u1", 0x00000000, 0x0200000, CRC(198b52d6) SHA1(e4502abe7ba01053d16c02114f0c88a3f52f6f40) ) \
\ \
ROM_REGION( 0x2000000, "bgtile", 0 ) \ ROM_REGION( 0x2000000, "bgtile", 0 ) \
@ -1134,7 +1118,7 @@ ROM_END
#define KOV3_INTERNAL_CHINA \ #define KOV3_INTERNAL_CHINA \
ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_REGION( 0x04000, "maincpu", 0 ) \
ROM_LOAD( "kov3_igs036_china.rom", 0x00000000, 0x0004000, CRC(c7d33764) SHA1(5cd48f876e637d60391d39ac6e40bf243300cc75) ) \ ROM_LOAD( "kov3_igs036_china.rom", 0x00000000, 0x0004000, CRC(c7d33764) SHA1(5cd48f876e637d60391d39ac6e40bf243300cc75) ) /* Core V100 China */ \
ROM_REGION( 0x108, "default_card", 0 ) \ ROM_REGION( 0x108, "default_card", 0 ) \
ROM_LOAD( "blank_kov3_china_card.pg2", 0x000, 0x108, CRC(bd5a968f) SHA1(b9045eb70e02afda7810431c592208053d863980) ) ROM_LOAD( "blank_kov3_china_card.pg2", 0x000, 0x108, CRC(bd5a968f) SHA1(b9045eb70e02afda7810431c592208053d863980) )
@ -1142,7 +1126,7 @@ ROM_END
ROM_START( kov3 ) ROM_START( kov3 )
KOV3_INTERNAL_CHINA KOV3_INTERNAL_CHINA
ROM_REGION( 0x1000000, "user1", 0 ) ROM_REGION( 0x1000000, "mainrom", 0 )
ROM_LOAD( "kov3_v104cn_raw.bin", 0x00000000, 0x0800000, CRC(1b5cbd24) SHA1(6471d4842a08f404420dea2bd1c8b88798c80fd5) ) // V104 11-12-09 14:29:14 ROM_LOAD( "kov3_v104cn_raw.bin", 0x00000000, 0x0800000, CRC(1b5cbd24) SHA1(6471d4842a08f404420dea2bd1c8b88798c80fd5) ) // V104 11-12-09 14:29:14
KOV3_VIDEO_SOUND_ROMS KOV3_VIDEO_SOUND_ROMS
@ -1151,7 +1135,7 @@ ROM_END
ROM_START( kov3_102 ) ROM_START( kov3_102 )
KOV3_INTERNAL_CHINA KOV3_INTERNAL_CHINA
ROM_REGION( 0x1000000, "user1", 0 ) ROM_REGION( 0x1000000, "mainrom", 0 )
ROM_LOAD( "kov3_v102cn_raw.bin", 0x00000000, 0x0800000, CRC(61d0dabd) SHA1(959b22ef4e342ca39c2386549ac7274f9d580ab8) ) // V102 11-11-01 18:56:07 ROM_LOAD( "kov3_v102cn_raw.bin", 0x00000000, 0x0800000, CRC(61d0dabd) SHA1(959b22ef4e342ca39c2386549ac7274f9d580ab8) ) // V102 11-11-01 18:56:07
KOV3_VIDEO_SOUND_ROMS KOV3_VIDEO_SOUND_ROMS
@ -1160,7 +1144,7 @@ ROM_END
ROM_START( kov3_101 ) ROM_START( kov3_101 )
KOV3_INTERNAL_CHINA KOV3_INTERNAL_CHINA
ROM_REGION( 0x1000000, "user1", 0 ) ROM_REGION( 0x1000000, "mainrom", 0 )
ROM_LOAD( "kov3_v101.bin", 0x00000000, 0x0800000, BAD_DUMP CRC(d6664449) SHA1(64d912425f018c3531951019b33e909657724547) ) // V101 11-10-03 14:37:29; dump was not raw, manually xored with fake value ROM_LOAD( "kov3_v101.bin", 0x00000000, 0x0800000, BAD_DUMP CRC(d6664449) SHA1(64d912425f018c3531951019b33e909657724547) ) // V101 11-10-03 14:37:29; dump was not raw, manually xored with fake value
KOV3_VIDEO_SOUND_ROMS KOV3_VIDEO_SOUND_ROMS
@ -1169,7 +1153,7 @@ ROM_END
ROM_START( kov3_100 ) ROM_START( kov3_100 )
KOV3_INTERNAL_CHINA KOV3_INTERNAL_CHINA
ROM_REGION( 0x1000000, "user1", 0 ) ROM_REGION( 0x1000000, "mainrom", 0 )
ROM_LOAD( "kov3_v100cn_raw.bin", 0x00000000, 0x0800000, CRC(93bca924) SHA1(ecaf2c4676eb3d9f5e4fdbd9388be41e51afa0e4) ) // V100 11-09-14 15:13:14 ROM_LOAD( "kov3_v100cn_raw.bin", 0x00000000, 0x0800000, CRC(93bca924) SHA1(ecaf2c4676eb3d9f5e4fdbd9388be41e51afa0e4) ) // V100 11-09-14 15:13:14
KOV3_VIDEO_SOUND_ROMS KOV3_VIDEO_SOUND_ROMS
@ -1186,7 +1170,7 @@ all others: SPANSION S99-50070
*/ */
#define KOF98UMH_VIDEO_SOUND_ROMS \ #define KOF98UMH_VIDEO_SOUND_ROMS \
ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ ROM_REGION( 0x200000, "tiles", ROMREGION_ERASE00 ) \
ROM_LOAD( "ig-d3_text.u1", 0x00000000, 0x0200000, CRC(9a0ea82e) SHA1(7844fd7e46c3fbb2164060f160da528254fd177e) ) \ ROM_LOAD( "ig-d3_text.u1", 0x00000000, 0x0200000, CRC(9a0ea82e) SHA1(7844fd7e46c3fbb2164060f160da528254fd177e) ) \
\ \
ROM_REGION( 0x2000000, "bgtile", ROMREGION_ERASE00 ) \ ROM_REGION( 0x2000000, "bgtile", ROMREGION_ERASE00 ) \
@ -1214,21 +1198,21 @@ all others: SPANSION S99-50070
ROM_START( kof98umh ) ROM_START( kof98umh )
ROM_REGION( 0x04000, "maincpu", 0 ) ROM_REGION( 0x04000, "maincpu", 0 )
ROM_LOAD( "kof98umh_internal_rom.bin", 0x00000000, 0x0004000, CRC(3ed2e50f) SHA1(35310045d375d9dda36c325e35257123a7b5b8c7) ) ROM_LOAD( "kof98umh_internal_rom.bin", 0x00000000, 0x0004000, CRC(3ed2e50f) SHA1(35310045d375d9dda36c325e35257123a7b5b8c7) ) // Core V100 China
ROM_REGION( 0x1000000, "user1", 0 ) ROM_REGION( 0x1000000, "mainrom", 0 )
ROM_LOAD( "kof98umh_v100cn.u4", 0x00000000, 0x1000000, CRC(2ea91e3b) SHA1(5a586bb99cc4f1b02e0db462d5aff721512e0640) ) // V100 09-08-23 17:52:03 ROM_LOAD( "kof98umh_v100cn.u4", 0x00000000, 0x1000000, CRC(2ea91e3b) SHA1(5a586bb99cc4f1b02e0db462d5aff721512e0640) ) // V100 09-08-23 17:52:03
KOF98UMH_VIDEO_SOUND_ROMS KOF98UMH_VIDEO_SOUND_ROMS
ROM_END ROM_END
static void iga_u16_decode(uint16_t *rom, int len, int ixor) static void iga_u16_decode(u16 *rom, int len, int ixor)
{ {
int i; int i;
for (i = 1; i < len / 2; i+=2) for (i = 1; i < len / 2; i+=2)
{ {
uint16_t x = ixor; u16 x = ixor;
if ( (i>>1) & 0x000001) x ^= 0x0010; if ( (i>>1) & 0x000001) x ^= 0x0010;
if ( (i>>1) & 0x000002) x ^= 0x2004; if ( (i>>1) & 0x000002) x ^= 0x2004;
@ -1247,13 +1231,13 @@ static void iga_u16_decode(uint16_t *rom, int len, int ixor)
} }
} }
static void iga_u12_decode(uint16_t* rom, int len, int ixor) static void iga_u12_decode(u16* rom, int len, int ixor)
{ {
int i; int i;
for (i = 0; i < len / 2; i+=2) for (i = 0; i < len / 2; i+=2)
{ {
uint16_t x = ixor; u16 x = ixor;
if ( (i>>1) & 0x000001) x ^= 0x9004; if ( (i>>1) & 0x000001) x ^= 0x9004;
if ( (i>>1) & 0x000002) x ^= 0x0028; if ( (i>>1) & 0x000002) x ^= 0x0028;
@ -1272,7 +1256,7 @@ static void iga_u12_decode(uint16_t* rom, int len, int ixor)
} }
} }
static void sprite_colour_decode(uint16_t* rom, int len) static void sprite_colour_decode(u16* rom, int len)
{ {
int i; int i;
@ -1289,7 +1273,7 @@ static void sprite_colour_decode(uint16_t* rom, int len)
READ32_MEMBER(pgm2_state::orleg2_speedup_r) READ32_MEMBER(pgm2_state::orleg2_speedup_r)
{ {
int pc = m_maincpu->pc(); u32 const pc = m_maincpu->pc();
if ((pc == 0x1002faec) || (pc == 0x1002f9b8)) if ((pc == 0x1002faec) || (pc == 0x1002f9b8))
{ {
if ((m_mainram[0x20114 / 4] == 0x00) && (m_mainram[0x20118 / 4] == 0x00)) if ((m_mainram[0x20114 / 4] == 0x00) && (m_mainram[0x20118 / 4] == 0x00))
@ -1297,7 +1281,7 @@ READ32_MEMBER(pgm2_state::orleg2_speedup_r)
} }
/*else /*else
{ {
printf("pc is %08x\n", pc); logerror("pc is %08x\n", pc);
}*/ }*/
return m_mainram[0x20114 / 4]; return m_mainram[0x20114 / 4];
@ -1305,7 +1289,7 @@ READ32_MEMBER(pgm2_state::orleg2_speedup_r)
READ32_MEMBER(pgm2_state::kov2nl_speedup_r) READ32_MEMBER(pgm2_state::kov2nl_speedup_r)
{ {
int pc = m_maincpu->pc(); u32 const pc = m_maincpu->pc();
if ((pc == 0x10053a94) || (pc == 0x1005332c) || (pc == 0x1005327c)) if ((pc == 0x10053a94) || (pc == 0x1005332c) || (pc == 0x1005327c))
{ {
@ -1315,7 +1299,7 @@ READ32_MEMBER(pgm2_state::kov2nl_speedup_r)
/* /*
else else
{ {
printf("pc is %08x\n", pc); logerror("pc is %08x\n", pc);
} }
*/ */
@ -1324,7 +1308,7 @@ READ32_MEMBER(pgm2_state::kov2nl_speedup_r)
READ32_MEMBER(pgm2_state::kof98umh_speedup_r) READ32_MEMBER(pgm2_state::kof98umh_speedup_r)
{ {
int pc = m_maincpu->pc(); u32 const pc = m_maincpu->pc();
if (pc == 0x100028f6) if (pc == 0x100028f6)
{ {
@ -1334,7 +1318,7 @@ READ32_MEMBER(pgm2_state::kof98umh_speedup_r)
/* /*
else else
{ {
printf("pc is %08x\n", pc); logerror("pc is %08x\n", pc);
} }
*/ */
@ -1343,7 +1327,7 @@ READ32_MEMBER(pgm2_state::kof98umh_speedup_r)
READ32_MEMBER(pgm2_state::kov3_speedup_r) READ32_MEMBER(pgm2_state::kov3_speedup_r)
{ {
int pc = m_maincpu->pc(); u32 const pc = m_maincpu->pc();
if ((pc == 0x1000729a) || (pc == 0x1000729e)) if ((pc == 0x1000729a) || (pc == 0x1000729e))
{ {
@ -1353,7 +1337,7 @@ READ32_MEMBER(pgm2_state::kov3_speedup_r)
/* /*
else else
{ {
printf("pc is %08x\n", pc); logerror("pc is %08x\n", pc);
} }
*/ */
@ -1365,7 +1349,7 @@ READ32_MEMBER(pgm2_state::kov3_speedup_r)
READ32_MEMBER(pgm2_state::ddpdojt_speedup_r) READ32_MEMBER(pgm2_state::ddpdojt_speedup_r)
{ {
int pc = m_maincpu->pc(); u32 const pc = m_maincpu->pc();
if (pc == 0x10001a7e) if (pc == 0x10001a7e)
{ {
@ -1375,7 +1359,7 @@ READ32_MEMBER(pgm2_state::ddpdojt_speedup_r)
/* /*
else else
{ {
printf("pc is %08x\n", pc); logerror("pc is %08x\n", pc);
} }
*/ */
@ -1384,7 +1368,7 @@ READ32_MEMBER(pgm2_state::ddpdojt_speedup_r)
READ32_MEMBER(pgm2_state::ddpdojt_speedup2_r) READ32_MEMBER(pgm2_state::ddpdojt_speedup2_r)
{ {
int pc = m_maincpu->pc(); u32 const pc = m_maincpu->pc();
if (pc == 0x1008fefe || pc == 0x1008fbe8) if (pc == 0x1008fefe || pc == 0x1008fbe8)
{ {
@ -1394,7 +1378,7 @@ READ32_MEMBER(pgm2_state::ddpdojt_speedup2_r)
/* /*
else else
{ {
printf("pc is %08x\n", pc); logerror("pc is %08x\n", pc);
} }
*/ */
@ -1406,19 +1390,19 @@ READ32_MEMBER(pgm2_state::ddpdojt_speedup2_r)
void pgm2_state::common_encryption_init() void pgm2_state::common_encryption_init()
{ {
// store off a copy of the encrypted rom so we can restore it later when needed // store off a copy of the encrypted rom so we can restore it later when needed
m_encrypted_copy.resize(memregion("user1")->bytes()); m_encrypted_copy.resize(m_mainrom->bytes());
memcpy(&m_encrypted_copy[0], memregion("user1")->base(), memregion("user1")->bytes()); memcpy(&m_encrypted_copy[0], m_mainrom->base(), m_mainrom->bytes());
uint16_t *src = (uint16_t *)memregion("sprites_mask")->base(); u16 *src = (u16 *)memregion("sprites_mask")->base();
iga_u12_decode(src, memregion("sprites_mask")->bytes(), 0x0000); iga_u12_decode(src, memregion("sprites_mask")->bytes(), 0x0000);
iga_u16_decode(src, memregion("sprites_mask")->bytes(), 0x0000); iga_u16_decode(src, memregion("sprites_mask")->bytes(), 0x0000);
m_sprite_predecrypted = 0; m_sprite_predecrypted = false;
src = (uint16_t *)memregion("sprites_colour")->base(); src = (u16 *)memregion("sprites_colour")->base();
sprite_colour_decode(src, memregion("sprites_colour")->bytes()); sprite_colour_decode(src, memregion("sprites_colour")->bytes());
m_has_decrypted = 0; m_has_decrypted = false;
} }
void pgm2_state::init_orleg2() void pgm2_state::init_orleg2()
@ -1452,19 +1436,19 @@ void pgm2_state::init_kov3()
m_maincpu->space(AS_PROGRAM).install_read_handler(0x200000b4, 0x200000b7, read32_delegate(FUNC(pgm2_state::kov3_speedup_r),this)); m_maincpu->space(AS_PROGRAM).install_read_handler(0x200000b4, 0x200000b7, read32_delegate(FUNC(pgm2_state::kov3_speedup_r),this));
} }
void pgm2_state::decrypt_kov3_module(uint32_t addrxor, uint16_t dataxor) void pgm2_state::decrypt_kov3_module(u32 addrxor, u16 dataxor)
{ {
uint16_t *src = (uint16_t *)memregion("user1")->base(); u16 *src = (u16 *)m_mainrom->base();
uint32_t size = memregion("user1")->bytes(); u32 size = m_mainrom->bytes();
std::vector<uint16_t> buffer(size/2); std::vector<u16> buffer(size/2);
for (int i = 0; i < size/2; i++) for (int i = 0; i < size/2; i++)
buffer[i] = src[i^addrxor]^dataxor; buffer[i] = src[i^addrxor]^dataxor;
memcpy(src, &buffer[0], size); memcpy(src, &buffer[0], size);
m_has_decrypted_kov3_module = 1; m_has_decrypted_kov3_module = true;
} }
void pgm2_state::init_kov3_104() void pgm2_state::init_kov3_104()

View File

@ -19,10 +19,10 @@
struct kov3_module_key struct kov3_module_key
{ {
uint8_t key[8]; u8 key[8];
uint8_t sum[8]; u8 sum[8];
uint32_t addr_xor; // 22bit u32 addr_xor; // 22bit
uint16_t data_xor; u16 data_xor;
}; };
class pgm2_state : public driver_device class pgm2_state : public driver_device
@ -51,9 +51,29 @@ public:
m_bg_palette(*this, "bg_palette"), m_bg_palette(*this, "bg_palette"),
m_tx_palette(*this, "tx_palette"), m_tx_palette(*this, "tx_palette"),
m_mcu_timer(*this, "mcu_timer"), m_mcu_timer(*this, "mcu_timer"),
m_memcard(*this, "memcard_p%u", 1U) m_memcard(*this, "memcard_p%u", 1U),
m_mainrom(*this, "mainrom")
{ } { }
void init_kov2nl();
void init_orleg2();
void init_ddpdojt();
void init_kov3();
void init_kov3_104();
void init_kov3_102();
void init_kov3_101();
void init_kov3_100();
void init_kof98umh();
void pgm2_ramrom(machine_config &config);
void pgm2_lores(machine_config &config);
void pgm2(machine_config &config);
void pgm2_hires(machine_config &config);
void pgm2_map(address_map &map);
void pgm2_module_rom_map(address_map &map);
void pgm2_ram_rom_map(address_map &map);
void pgm2_rom_map(address_map &map);
private:
DECLARE_READ32_MEMBER(unk_startup_r); DECLARE_READ32_MEMBER(unk_startup_r);
DECLARE_READ32_MEMBER(rtc_r); DECLARE_READ32_MEMBER(rtc_r);
DECLARE_READ32_MEMBER(mcu_r); DECLARE_READ32_MEMBER(mcu_r);
@ -71,9 +91,9 @@ public:
DECLARE_READ32_MEMBER(pio_pdsr_r); DECLARE_READ32_MEMBER(pio_pdsr_r);
DECLARE_WRITE16_MEMBER(module_rom_w); DECLARE_WRITE16_MEMBER(module_rom_w);
DECLARE_READ16_MEMBER(module_rom_r); DECLARE_READ16_MEMBER(module_rom_r);
DECLARE_READ_LINE_MEMBER(module_data_r); int module_data_r();
DECLARE_WRITE_LINE_MEMBER(module_data_w); void module_data_w(int state);
DECLARE_WRITE_LINE_MEMBER(module_clk_w); void module_clk_w(int state);
DECLARE_READ32_MEMBER(orleg2_speedup_r); DECLARE_READ32_MEMBER(orleg2_speedup_r);
DECLARE_READ32_MEMBER(kov2nl_speedup_r); DECLARE_READ32_MEMBER(kov2nl_speedup_r);
@ -87,112 +107,89 @@ public:
DECLARE_WRITE32_MEMBER(encryption_do_w); DECLARE_WRITE32_MEMBER(encryption_do_w);
DECLARE_WRITE32_MEMBER(sprite_encryption_w); DECLARE_WRITE32_MEMBER(sprite_encryption_w);
void init_kov2nl();
void init_orleg2();
void init_ddpdojt();
void init_kov3();
void init_kov3_104();
void init_kov3_102();
void init_kov3_101();
void init_kov3_100();
void init_kof98umh();
uint32_t screen_update_pgm2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank_pgm2);
DECLARE_WRITE_LINE_MEMBER(irq);
INTERRUPT_GEN_MEMBER(igs_interrupt);
TIMER_DEVICE_CALLBACK_MEMBER(igs_interrupt2);
void pgm2_ramrom(machine_config &config);
void pgm2_lores(machine_config &config);
void pgm2(machine_config &config);
void pgm2_hires(machine_config &config);
void pgm2_map(address_map &map);
void pgm2_module_rom_map(address_map &map);
void pgm2_ram_rom_map(address_map &map);
void pgm2_rom_map(address_map &map);
private:
virtual void machine_start() override; virtual void machine_start() override;
virtual void machine_reset() override; virtual void machine_reset() override;
virtual void video_start() override; virtual void video_start() override;
virtual void device_post_load() override;
TILE_GET_INFO_MEMBER(get_fg_tile_info); TILE_GET_INFO_MEMBER(get_fg_tile_info);
TILE_GET_INFO_MEMBER(get_bg_tile_info); TILE_GET_INFO_MEMBER(get_bg_tile_info);
void decrypt_kov3_module(uint32_t addrxor, uint16_t dataxor); u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
DECLARE_WRITE_LINE_MEMBER(irq);
TIMER_DEVICE_CALLBACK_MEMBER(mcu_interrupt);
void decrypt_kov3_module(u32 addrxor, u16 dataxor);
tilemap_t *m_fg_tilemap; tilemap_t *m_fg_tilemap;
tilemap_t *m_bg_tilemap; tilemap_t *m_bg_tilemap;
std::unique_ptr<uint32_t[]> m_spritebufferram; // buffered spriteram std::unique_ptr<u32[]> m_spritebufferram; // buffered spriteram
bitmap_ind16 m_sprite_bitmap; void skip_sprite_chunk(u32 &palette_offset, u32 maskdata, bool reverse);
void draw_sprite_pixel(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 palette_offset, s16 realx, s16 realy, u16 pal, u8 pri);
void skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse); void draw_sprite_chunk(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 &palette_offset, s16 x, s16 realy,
void draw_sprite_pixel(const rectangle &cliprect, int palette_offset, int realx, int realy, int pal); u16 sizex, int xdraw, u16 pal, u32 maskdata, u32 zoomx_bits, u8 repeats, s16 &realxdraw, s8 realdraw_inc, s8 palette_inc, u8 pri);
void draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int repeats, int &realxdraw, int realdraw_inc, int palette_inc); void draw_sprite_line(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 &mask_offset, u32 &palette_offset, s16 x, s16 realy,
void draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int reverse, int sizex, int pal, int zoomybit, int zoomx_bits, int xrepeats); bool flipx, bool reverse, u16 sizex, u16 pal, u8 zoomybit, u32 zoomx_bits, u8 xrepeats, u8 pri);
void draw_sprites(screen_device &screen, const rectangle &cliprect, uint32_t* spriteram); void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32* spriteram);
void copy_sprites_from_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri);
uint32_t m_sprites_mask_mask;
uint32_t m_sprites_colour_mask;
void common_encryption_init(); void common_encryption_init();
uint8_t m_encryption_table[0x100]; u8 m_encryption_table[0x100];
int m_has_decrypted; // so we only do it once. bool m_has_decrypted; // so we only do it once.
int m_has_decrypted_kov3_module; bool m_has_decrypted_kov3_module;
uint32_t m_spritekey; u32 m_spritekey;
uint32_t m_realspritekey; u32 m_realspritekey;
int m_sprite_predecrypted; bool m_sprite_predecrypted;
uint8_t m_shareram[0x100]; u8 m_shareram[0x100];
uint16_t m_share_bank; u16 m_share_bank;
uint32_t m_mcu_regs[8]; u32 m_mcu_regs[8];
uint32_t m_mcu_result0; u32 m_mcu_result0;
uint32_t m_mcu_result1; u32 m_mcu_result1;
uint8_t m_mcu_last_cmd; u8 m_mcu_last_cmd;
void mcu_command(address_space &space, bool is_command); void mcu_command(bool is_command);
std::vector<uint8_t> m_encrypted_copy; std::vector<u8> m_encrypted_copy;
uint32_t pio_out_data; u32 m_pio_out_data;
const kov3_module_key *module_key; const kov3_module_key *module_key;
bool module_sum_read; bool module_sum_read;
uint32_t module_in_latch; u32 module_in_latch;
uint32_t module_out_latch; u32 module_out_latch;
int module_prev_state; int module_prev_state;
int module_clk_cnt; int module_clk_cnt;
uint8_t module_rcv_buf[10]; u8 module_rcv_buf[10];
uint8_t module_send_buf[9]; u8 module_send_buf[9];
void postload();
// devices // devices
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
required_shared_ptr<uint32_t> m_lineram; required_shared_ptr<u32> m_lineram;
required_shared_ptr<uint32_t> m_sp_zoom; required_shared_ptr<u32> m_sp_zoom;
required_shared_ptr<uint32_t> m_mainram; required_shared_ptr<u32> m_mainram;
optional_shared_ptr<uint32_t> m_romboard_ram; optional_shared_ptr<u32> m_romboard_ram;
required_shared_ptr<uint32_t> m_fg_videoram; required_shared_ptr<u32> m_fg_videoram;
required_shared_ptr<uint32_t> m_bg_videoram; required_shared_ptr<u32> m_bg_videoram;
required_shared_ptr<uint32_t> m_sp_videoram; required_shared_ptr<u32> m_sp_videoram;
required_shared_ptr<uint32_t> m_bgscroll; required_shared_ptr<u32> m_bgscroll;
required_shared_ptr<uint32_t> m_fgscroll; required_shared_ptr<u32> m_fgscroll;
required_shared_ptr<uint32_t> m_vidmode; required_shared_ptr<u32> m_vidmode;
required_device<gfxdecode_device> m_gfxdecode2; required_device<gfxdecode_device> m_gfxdecode2;
required_device<gfxdecode_device> m_gfxdecode3; required_device<gfxdecode_device> m_gfxdecode3;
required_device<arm_aic_device> m_arm_aic; required_device<arm_aic_device> m_arm_aic;
required_region_ptr<uint8_t> m_sprites_mask; required_region_ptr<u8> m_sprites_mask;
required_region_ptr<uint8_t> m_sprites_colour; required_region_ptr<u8> m_sprites_colour;
required_device<palette_device> m_sp_palette; required_device<palette_device> m_sp_palette;
required_device<palette_device> m_bg_palette; required_device<palette_device> m_bg_palette;
required_device<palette_device> m_tx_palette; required_device<palette_device> m_tx_palette;
required_device<timer_device> m_mcu_timer; required_device<timer_device> m_mcu_timer;
optional_device_array<pgm2_memcard_device, 4> m_memcard; optional_device_array<pgm2_memcard_device, 4> m_memcard;
required_memory_region m_mainrom;
}; };
#endif #endif

View File

@ -45,7 +45,7 @@ void pgm2_memcard_device::device_start()
image_init_result pgm2_memcard_device::call_load() image_init_result pgm2_memcard_device::call_load()
{ {
authenticated = false; m_authenticated = false;
if(length() != 0x108) if(length() != 0x108)
return image_init_result::FAIL; return image_init_result::FAIL;
@ -65,7 +65,7 @@ image_init_result pgm2_memcard_device::call_load()
void pgm2_memcard_device::call_unload() void pgm2_memcard_device::call_unload()
{ {
authenticated = false; m_authenticated = false;
fseek(0, SEEK_SET); fseek(0, SEEK_SET);
fwrite(m_memcard_data, 0x100); fwrite(m_memcard_data, 0x100);
fwrite(m_protection_data, 4); fwrite(m_protection_data, 4);
@ -74,7 +74,7 @@ void pgm2_memcard_device::call_unload()
image_init_result pgm2_memcard_device::call_create(int format_type, util::option_resolution *format_options) image_init_result pgm2_memcard_device::call_create(int format_type, util::option_resolution *format_options)
{ {
authenticated = false; m_authenticated = false;
// cards must contain valid defaults for each game / region or they don't work? // cards must contain valid defaults for each game / region or they don't work?
memory_region *rgn = memregion("^default_card"); memory_region *rgn = memregion("^default_card");
@ -92,16 +92,16 @@ image_init_result pgm2_memcard_device::call_create(int format_type, util::option
return image_init_result::PASS; return image_init_result::PASS;
} }
void pgm2_memcard_device::auth(uint8_t p1, uint8_t p2, uint8_t p3) void pgm2_memcard_device::auth(u8 p1, u8 p2, u8 p3)
{ {
if (m_security_data[0] & 7) if (m_security_data[0] & 7)
{ {
if (m_security_data[1] == p1 && m_security_data[2] == p2 && m_security_data[3] == p3) { if (m_security_data[1] == p1 && m_security_data[2] == p2 && m_security_data[3] == p3) {
authenticated = true; m_authenticated = true;
m_security_data[0] = 7; m_security_data[0] = 7;
} }
else { else {
authenticated = false; m_authenticated = false;
m_security_data[0] >>= 1; // hacky m_security_data[0] >>= 1; // hacky
if (m_security_data[0] & 7) if (m_security_data[0] & 7)
popmessage("Wrong IC Card password !!!\n"); popmessage("Wrong IC Card password !!!\n");
@ -111,39 +111,39 @@ void pgm2_memcard_device::auth(uint8_t p1, uint8_t p2, uint8_t p3)
} }
} }
READ8_MEMBER(pgm2_memcard_device::read) u8 pgm2_memcard_device::read(offs_t offset)
{ {
return m_memcard_data[offset]; return m_memcard_data[offset];
} }
WRITE8_MEMBER(pgm2_memcard_device::write) void pgm2_memcard_device::write(offs_t offset, u8 data)
{ {
if (authenticated && (offset >= 0x20 || (m_protection_data[offset>>3] & (1 <<(offset & 7))))) if (m_authenticated && (offset >= 0x20 || (m_protection_data[offset>>3] & (1 <<(offset & 7)))))
{ {
m_memcard_data[offset] = data; m_memcard_data[offset] = data;
} }
} }
READ8_MEMBER(pgm2_memcard_device::read_prot) u8 pgm2_memcard_device::read_prot(offs_t offset)
{ {
return m_protection_data[offset]; return m_protection_data[offset];
} }
WRITE8_MEMBER(pgm2_memcard_device::write_prot) void pgm2_memcard_device::write_prot(offs_t offset, u8 data)
{ {
if (authenticated) if (m_authenticated)
m_protection_data[offset] &= data; m_protection_data[offset] &= data;
} }
READ8_MEMBER(pgm2_memcard_device::read_sec) u8 pgm2_memcard_device::read_sec(offs_t offset)
{ {
if (!authenticated) if (!m_authenticated)
return 0xff; // guess return 0xff; // guess
return m_security_data[offset]; return m_security_data[offset];
} }
WRITE8_MEMBER(pgm2_memcard_device::write_sec) void pgm2_memcard_device::write_sec(offs_t offset, u8 data)
{ {
if (authenticated) if (m_authenticated)
m_security_data[offset] = data; m_security_data[offset] = data;
} }

View File

@ -43,21 +43,21 @@ public:
// device-level overrides // device-level overrides
virtual void device_start() override; virtual void device_start() override;
DECLARE_READ8_MEMBER(read); u8 read(offs_t offset);
DECLARE_WRITE8_MEMBER(write); void write(offs_t offset, u8 data);
DECLARE_READ8_MEMBER(read_prot); u8 read_prot(offs_t offset);
DECLARE_WRITE8_MEMBER(write_prot); void write_prot(offs_t offset, u8 data);
DECLARE_READ8_MEMBER(read_sec); u8 read_sec(offs_t offset);
DECLARE_WRITE8_MEMBER(write_sec); void write_sec(offs_t offset, u8 data);
void auth(uint8_t p1, uint8_t p2, uint8_t p3); void auth(u8 p1, u8 p2, u8 p3);
/* returns the index of the current memory card, or -1 if none */ /* returns the index of the current memory card, or -1 if none */
int present() { return is_loaded() ? 0 : -1; } int present() { return is_loaded() ? 0 : -1; }
private: private:
uint8_t m_memcard_data[0x100]; u8 m_memcard_data[0x100];
uint8_t m_protection_data[4]; u8 m_protection_data[4];
uint8_t m_security_data[4]; u8 m_security_data[4];
bool authenticated; bool m_authenticated;
}; };

View File

@ -4,31 +4,40 @@
#include "emu.h" #include "emu.h"
#include "includes/pgm2.h" #include "includes/pgm2.h"
inline void pgm2_state::draw_sprite_pixel(const rectangle &cliprect, int palette_offset, int realx, int realy, int pal) inline void pgm2_state::draw_sprite_pixel(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 palette_offset, s16 realx, s16 realy, u16 pal, u8 pri)
{ {
if (cliprect.contains(realx, realy)) if (cliprect.contains(realx, realy))
{ {
uint16_t pix = m_sprites_colour[palette_offset] & 0x3f; // there are some stray 0xff bytes in some roms, so mask u8 *dstpri = &m_screen->priority().pix8(realy);
uint16_t pendat = pix + (pal * 0x40); if ((dstpri[realx] & 1) == 0)
uint16_t* dstptr_bitmap = &m_sprite_bitmap.pix16(realy); {
dstptr_bitmap[realx] = pendat; if (!pri || ((dstpri[realx] & 2) == 0))
{
u16 const pix = m_sprites_colour[palette_offset] & 0x3f; // there are some stray 0xff bytes in some roms, so mask
u16 const pendat = pix + (pal * 0x40);
u32* dstptr_bitmap = &bitmap.pix32(realy);
dstptr_bitmap[realx] = m_sp_palette->pen(pendat);
dstpri[realx] |= 1;
}
}
} }
} }
inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int repeats, int &realxdraw, int realdraw_inc, int palette_inc) inline void pgm2_state::draw_sprite_chunk(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 &palette_offset, s16 x, s16 realy,
u16 sizex, int xdraw, u16 pal, u32 maskdata, u32 zoomx_bits, u8 repeats, s16 &realxdraw, s8 realdraw_inc, s8 palette_inc, u8 pri)
{ {
for (int xchunk = 0; xchunk < 32; xchunk++) for (int xchunk = 0; xchunk < 32; xchunk++)
{ {
int pix, xzoombit; u8 pix, xzoombit;
if (palette_inc == -1) if (palette_inc == -1)
{ {
pix = (maskdata >> xchunk) & 1; pix = BIT(maskdata, xchunk);
xzoombit = (zoomx_bits >> xchunk) & 1; xzoombit = BIT(zoomx_bits, xchunk);
} }
else else
{ {
pix = (maskdata >> (31 - xchunk)) & 1; pix = BIT(maskdata, 31 - xchunk);
xzoombit = (zoomx_bits >> (31 - xchunk)) & 1; xzoombit = BIT(zoomx_bits, 31 - xchunk);
} }
if (pix) if (pix)
@ -38,26 +47,26 @@ inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palett
// draw it the base number of times // draw it the base number of times
for (int i = 0; i < repeats; i++) for (int i = 0; i < repeats; i++)
{ {
draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal); draw_sprite_pixel(bitmap, cliprect, palette_offset, x + realxdraw, realy, pal, pri);
realxdraw += realdraw_inc; realxdraw += realdraw_inc;
} }
// draw it again if zoom bit is set // draw it again if zoom bit is set
if (xzoombit) if (xzoombit)
{ {
draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal); draw_sprite_pixel(bitmap, cliprect, palette_offset, x + realxdraw, realy, pal, pri);
realxdraw += realdraw_inc; realxdraw += realdraw_inc;
} }
palette_offset += palette_inc; palette_offset += palette_inc;
palette_offset &= m_sprites_colour_mask; palette_offset &= m_sprites_colour.mask();
} }
else // shrink else // shrink
{ {
if (xzoombit) draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal); if (xzoombit) draw_sprite_pixel(bitmap, cliprect, palette_offset, x + realxdraw, realy, pal, pri);
palette_offset += palette_inc; palette_offset += palette_inc;
palette_offset &= m_sprites_colour_mask; palette_offset &= m_sprites_colour.mask();
if (xzoombit) realxdraw += realdraw_inc; if (xzoombit) realxdraw += realdraw_inc;
@ -86,33 +95,34 @@ inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palett
} }
inline void pgm2_state::skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse) inline void pgm2_state::skip_sprite_chunk(u32 &palette_offset, u32 maskdata, bool reverse)
{ {
int bits = population_count_32(maskdata); s32 bits = population_count_32(maskdata);
if (!reverse) if (!reverse)
{ {
palette_offset+=bits; palette_offset += bits;
} }
else else
{ {
palette_offset-=bits; palette_offset -= bits;
} }
palette_offset &= m_sprites_colour_mask; palette_offset &= m_sprites_colour.mask();
} }
inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int reverse, int sizex, int pal, int zoomybit, int zoomx_bits, int xrepeats) inline void pgm2_state::draw_sprite_line(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 &mask_offset, u32 &palette_offset, s16 x, s16 realy,
bool flipx, bool reverse, u16 sizex, u16 pal, u8 zoomybit, u32 zoomx_bits, u8 xrepeats, u8 pri)
{ {
int realxdraw = 0; s16 realxdraw = 0;
if (flipx ^ reverse) if (flipx ^ reverse)
realxdraw = (population_count_32(zoomx_bits) * sizex) - 1; realxdraw = (population_count_32(zoomx_bits) * sizex) - 1;
for (int xdraw = 0; xdraw < sizex; xdraw++) for (int xdraw = 0; xdraw < sizex; xdraw++)
{ {
uint32_t maskdata = m_sprites_mask[mask_offset + 0] << 24; u32 maskdata = m_sprites_mask[mask_offset + 0] << 24;
maskdata |= m_sprites_mask[mask_offset + 1] << 16; maskdata |= m_sprites_mask[mask_offset + 1] << 16;
maskdata |= m_sprites_mask[mask_offset + 2] << 8; maskdata |= m_sprites_mask[mask_offset + 2] << 8;
maskdata |= m_sprites_mask[mask_offset + 3] << 0; maskdata |= m_sprites_mask[mask_offset + 3] << 0;
@ -128,36 +138,32 @@ inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_of
mask_offset += 4; mask_offset += 4;
} }
mask_offset &= m_sprites_mask.mask();
mask_offset &= m_sprites_mask_mask;
if (zoomybit) if (zoomybit)
{ {
if (!flipx) if (!flipx)
{ {
if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, 1, 1); if (!reverse) draw_sprite_chunk(bitmap, cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, 1, 1, pri);
else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, -1, -1); else draw_sprite_chunk(bitmap, cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, -1, -1, pri);
} }
else else
{ {
if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, -1, 1); if (!reverse) draw_sprite_chunk(bitmap, cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, -1, 1, pri);
else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, 1, -1); else draw_sprite_chunk(bitmap, cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, 1, -1, pri);
} }
} }
else skip_sprite_chunk(palette_offset, maskdata, reverse); else skip_sprite_chunk(palette_offset, maskdata, reverse);
} }
} }
void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect, uint32_t* spriteram) void pgm2_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, u32* spriteram)
{ {
m_sprite_bitmap.fill(0x8000, cliprect); s32 endoflist = -1;
int endoflist = -1; //logerror("frame\n");
//printf("frame\n"); for (int i = 0; i < m_sp_videoram.bytes() / 4; i += 4)
for (int i = 0; i < 0x2000 / 4; i += 4)
{ {
if (spriteram[i + 2] & 0x80000000) if (spriteram[i + 2] & 0x80000000)
{ {
@ -166,47 +172,47 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
} }
} }
if (endoflist != -1) if (endoflist > 0)
{ {
for (int i = 0; i < endoflist - 2; i += 4) for (int i = endoflist - 4; i >= 0; i -= 4)
{ {
//printf("sprite with %08x %08x %08x %08x\n", spriteram[i + 0], spriteram[i + 1], spriteram[i + 2], spriteram[i + 3]); //logerror("sprite with %08x %08x %08x %08x\n", spriteram[i + 0], spriteram[i + 1], spriteram[i + 2], spriteram[i + 3]);
int x = (spriteram[i + 0] & 0x000007ff) >> 0; s16 x = (spriteram[i + 0] & 0x000007ff) >> 0;
int y = (spriteram[i + 0] & 0x003ff800) >> 11; s16 y = (spriteram[i + 0] & 0x003ff800) >> 11;
int pal = (spriteram[i + 0] & 0x0fc00000) >> 22; u16 pal = (spriteram[i + 0] & 0x0fc00000) >> 22;
int pri = (spriteram[i + 0] & 0x80000000) >> 31; u8 const pri = (spriteram[i + 0] & 0x80000000) >> 31;
int unk0 = (spriteram[i + 0] & 0x30000000) >> 0; u32 const unk0 = (spriteram[i + 0] & 0x30000000) >> 0;
// kov3 uses this in places (eg. horsemen special move heads) and shops when it can only possibly mean 'disable' // kov3 uses this in places (eg. horsemen special move heads) and shops when it can only possibly mean 'disable'
// it is also used in places on kov2nl and orleg2, often the 'power up' effects surrounding your character to create an on/off flicker each frame // it is also used in places on kov2nl and orleg2, often the 'power up' effects surrounding your character to create an on/off flicker each frame
int disable = (spriteram[i + 0] & 0x40000000) >> 30; bool disable = (spriteram[i + 0] & 0x40000000) >> 30;
if (disable) continue; if (disable) continue;
int sizex = (spriteram[i + 1] & 0x0000003f) >> 0; u16 const sizex = (spriteram[i + 1] & 0x0000003f) >> 0;
int sizey = (spriteram[i + 1] & 0x00007fc0) >> 6; u16 const sizey = (spriteram[i + 1] & 0x00007fc0) >> 6;
int flipx = (spriteram[i + 1] & 0x00800000) >> 23; bool const flipx = (spriteram[i + 1] & 0x00800000) >> 23;
int reverse = (spriteram[i + 1] & 0x80000000) >> 31; // more of a 'reverse entire drawing' flag than y-flip, but used for that purpose bool const reverse = (spriteram[i + 1] & 0x80000000) >> 31; // more of a 'reverse entire drawing' flag than y-flip, but used for that purpose
int zoomx = (spriteram[i + 1] & 0x007f0000) >> 16; u8 const zoomx = (spriteram[i + 1] & 0x007f0000) >> 16;
int zoomy = (spriteram[i + 1] & 0x7f000000) >> 24; u8 const zoomy = (spriteram[i + 1] & 0x7f000000) >> 24;
int unk1 = (spriteram[i + 1] & 0x00008000) >> 0; u32 const unk1 = (spriteram[i + 1] & 0x00008000) >> 0;
if (unk0 || unk1) if (unk0 || unk1)
{ {
//popmessage("sprite rendering unused bits set unk0 %08x unk1 %08x\n", unk0, unk1); //popmessage("sprite rendering unused bits set unk0 %08x unk1 %08x\n", unk0, unk1);
} }
int mask_offset = (spriteram[i + 2] << 1); u32 mask_offset = (spriteram[i + 2] << 1);
int palette_offset = (spriteram[i + 3]); u32 palette_offset = (spriteram[i + 3]);
// use all the bits of zoom to lookup, probably why the table is copied 4x in RAM // use all the bits of zoom to lookup, probably why the table is copied 4x in RAM
uint32_t zoomy_bits = m_sp_zoom[zoomy]; u32 const zoomy_bits = m_sp_zoom[zoomy];
uint32_t zoomx_bits = m_sp_zoom[zoomx]; u32 const zoomx_bits = m_sp_zoom[zoomx];
// but use these bits as the scale factor // but use these bits as the scale factor
int xrepeats = (zoomx & 0x60)>>5; u8 const xrepeats = (zoomx & 0x60)>>5;
int yrepeats = (zoomy & 0x60)>>5; u8 const yrepeats = (zoomy & 0x60)>>5;
if (x & 0x400) x -= 0x800; if (x & 0x400) x -= 0x800;
if (y & 0x400) y -= 0x800; if (y & 0x400) y -= 0x800;
@ -214,21 +220,19 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
if (reverse) if (reverse)
mask_offset -= 2; mask_offset -= 2;
mask_offset &= m_sprites_mask_mask; mask_offset &= m_sprites_mask.mask();
palette_offset &= m_sprites_colour_mask; palette_offset &= m_sprites_colour.mask();
pal |= (pri << 6); // encode priority with the palette for manual mixing later s16 realy = y;
int realy = y; s16 sourceline = 0;
int sourceline = 0;
for (int ydraw = 0; ydraw < sizey; sourceline++) for (int ydraw = 0; ydraw < sizey; sourceline++)
{ {
int zoomy_bit = (zoomy_bits >> (sourceline & 0x1f)) & 1; u8 zoomy_bit = BIT(zoomy_bits, sourceline & 0x1f);
// store these for when we need to draw a line twice // store these for when we need to draw a line twice
uint32_t pre_palette_offset = palette_offset; u32 const pre_palette_offset = palette_offset;
uint32_t pre_mask_offset = mask_offset; u32 const pre_mask_offset = mask_offset;
if (yrepeats != 0) // grow if (yrepeats != 0) // grow
{ {
@ -237,7 +241,7 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
// draw it the base number of times // draw it the base number of times
palette_offset = pre_palette_offset; palette_offset = pre_palette_offset;
mask_offset = pre_mask_offset; mask_offset = pre_mask_offset;
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats); draw_sprite_line(bitmap, cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats, pri);
realy++; realy++;
} }
@ -245,7 +249,7 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
{ {
palette_offset = pre_palette_offset; palette_offset = pre_palette_offset;
mask_offset = pre_mask_offset; mask_offset = pre_mask_offset;
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats); draw_sprite_line(bitmap, cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats, pri);
realy++; realy++;
} }
@ -253,7 +257,7 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
} }
else // shrink else // shrink
{ {
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats); draw_sprite_line(bitmap, cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats, pri);
if (zoomy_bit) if (zoomy_bit)
{ {
@ -266,38 +270,11 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
} }
} }
void pgm2_state::copy_sprites_from_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri) u32 pgm2_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{ {
pri <<= 12; u32 const mode = m_vidmode[0] & 0x00030000; // other bits not used?
const pen_t *paldata = m_sp_palette->pens(); switch (mode >> 16)
uint16_t* srcptr_bitmap;
uint32_t* dstptr_bitmap;
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
srcptr_bitmap = &m_sprite_bitmap.pix16(y);
dstptr_bitmap = &bitmap.pix32(y);
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
uint16_t pix = srcptr_bitmap[x];
if (pix != 0x8000)
{
if ((pix&0x1000) == pri)
dstptr_bitmap[x] = paldata[pix & 0xfff];
}
}
}
}
uint32_t pgm2_state::screen_update_pgm2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int mode = m_vidmode[0] & 0x00030000; // other bits not used?
switch (mode>>16)
{ {
default: default:
case 0x00: m_screen->set_visible_area(0, 320 - 1, 0, 240 - 1); break; case 0x00: m_screen->set_visible_area(0, 320 - 1, 0, 240 - 1); break;
@ -309,34 +286,30 @@ uint32_t pgm2_state::screen_update_pgm2(screen_device &screen, bitmap_rgb32 &bit
m_fg_tilemap->set_scrolly(0, m_fgscroll[0] >> 16); m_fg_tilemap->set_scrolly(0, m_fgscroll[0] >> 16);
m_bg_tilemap->set_scrolly(0, (m_bgscroll[0x0/4] & 0xffff0000)>>16 ); m_bg_tilemap->set_scrolly(0, (m_bgscroll[0x0/4] & 0xffff0000)>>16 );
for (int y = 0; y <= cliprect.max_y; y++) for (s16 y = cliprect.top(); y <= cliprect.bottom(); y++)
{ {
uint16_t linescroll = (y & 1) ? ((m_lineram[(y >> 1)] & 0xffff0000) >> 16) : (m_lineram[(y >> 1)] & 0x0000ffff); u16 const linescroll = (y & 1) ? ((m_lineram[(y >> 1)] & 0xffff0000) >> 16) : (m_lineram[(y >> 1)] & 0x0000ffff);
m_bg_tilemap->set_scrollx((y + ((m_bgscroll[0x0 / 4] & 0xffff0000) >> 16)) & 0x3ff, ((m_bgscroll[0x0 / 4] & 0x0000ffff) >> 0) + linescroll); m_bg_tilemap->set_scrollx((y + ((m_bgscroll[0x0 / 4] & 0xffff0000) >> 16)) & 0x3ff, ((m_bgscroll[0x0 / 4] & 0x0000ffff) >> 0) + linescroll);
} }
const pen_t *paldata = m_bg_palette->pens(); const pen_t *paldata = m_bg_palette->pens();
bitmap.fill(paldata[0], cliprect); // are there any places bg pen is showing so we know what it should be? bitmap.fill(paldata[0], cliprect); // are there any places bg pen is showing so we know what it should be?
m_screen->priority().fill(0, cliprect);
draw_sprites(screen, cliprect, m_spritebufferram.get()); m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 2);
draw_sprites(bitmap, cliprect, m_spritebufferram.get());
copy_sprites_from_bitmap(screen, bitmap, cliprect, 1);
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
copy_sprites_from_bitmap(screen, bitmap, cliprect, 0);
m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
return 0; return 0;
} }
WRITE_LINE_MEMBER(pgm2_state::screen_vblank_pgm2) WRITE_LINE_MEMBER(pgm2_state::screen_vblank)
{ {
// rising edge // rising edge
if (state) if (state)
{ {
memcpy(m_spritebufferram.get(), m_sp_videoram, 0x2000); memcpy(m_spritebufferram.get(), m_sp_videoram, 0x2000);
m_arm_aic->set_irq(12, ASSERT_LINE);
} }
} }
@ -348,9 +321,9 @@ WRITE32_MEMBER(pgm2_state::fg_videoram_w)
TILE_GET_INFO_MEMBER(pgm2_state::get_fg_tile_info) TILE_GET_INFO_MEMBER(pgm2_state::get_fg_tile_info)
{ {
int tileno = (m_fg_videoram[tile_index] & 0x0003ffff) >> 0; u32 const tileno = (m_fg_videoram[tile_index] & 0x0003ffff) >> 0;
int colour = (m_fg_videoram[tile_index] & 0x007c0000) >> 18; // 5 bits u8 const colour = (m_fg_videoram[tile_index] & 0x007c0000) >> 18; // 5 bits
int flipxy = (m_fg_videoram[tile_index] & 0x01800000) >> 23; u8 const flipxy = (m_fg_videoram[tile_index] & 0x01800000) >> 23;
SET_TILE_INFO_MEMBER(0, tileno, colour, TILE_FLIPXY(flipxy)); SET_TILE_INFO_MEMBER(0, tileno, colour, TILE_FLIPXY(flipxy));
} }
@ -363,9 +336,9 @@ WRITE32_MEMBER(pgm2_state::bg_videoram_w)
TILE_GET_INFO_MEMBER(pgm2_state::get_bg_tile_info) TILE_GET_INFO_MEMBER(pgm2_state::get_bg_tile_info)
{ {
int tileno = (m_bg_videoram[tile_index] & 0x0003ffff) >> 0; u32 const tileno = (m_bg_videoram[tile_index] & 0x0003ffff) >> 0;
int colour = (m_bg_videoram[tile_index] & 0x003c0000) >> 18; // 4 bits u8 const colour = (m_bg_videoram[tile_index] & 0x003c0000) >> 18; // 4 bits
int flipxy = (m_bg_videoram[tile_index] & 0x01800000) >> 23; u8 const flipxy = (m_bg_videoram[tile_index] & 0x01800000) >> 23;
SET_TILE_INFO_MEMBER(0, tileno, colour, TILE_FLIPXY(flipxy)); SET_TILE_INFO_MEMBER(0, tileno, colour, TILE_FLIPXY(flipxy));
} }
@ -379,13 +352,8 @@ void pgm2_state::video_start()
m_bg_tilemap->set_transparent_pen(0); m_bg_tilemap->set_transparent_pen(0);
m_bg_tilemap->set_scroll_rows(32 * 32); m_bg_tilemap->set_scroll_rows(32 * 32);
m_spritebufferram = make_unique_clear<uint32_t[]>(0x2000 / 4); m_spritebufferram = make_unique_clear<u32[]>(0x2000 / 4);
m_screen->register_screen_bitmap(m_sprite_bitmap);
save_pointer(NAME(m_spritebufferram), 0x2000 / 4); save_pointer(NAME(m_spritebufferram), 0x2000 / 4);
m_sprites_mask_mask = memregion("sprites_mask")->bytes() - 1;
m_sprites_colour_mask = memregion("sprites_colour")->bytes() - 1;
} }