rastersp.cpp: Added Football Crazy game. (#9383)

* machine/53c7xx.cpp: DFE bit is not reset when status register is read.
* cpu/i386: Fixed multiple issues with breakpoint emulation.
* machine/bacta_datalogger.cpp: Prevent continuous transmission of 0xff.
* machine/z80scc.cpp: Fixed incorrect setting of baud rate due to uninitialised variables.

New working machines
--------------
Football Crazy (Video Quiz) [Paul-Arnold]
This commit is contained in:
Paul-Arnold 2022-03-29 16:25:03 +01:00 committed by GitHub
parent a6fed48685
commit 209b0bf704
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 828 additions and 189 deletions

View File

@ -2445,6 +2445,7 @@ void i386_device::zero_state()
m_opcode_bytes_length = 0;
memset(m_opcode_addrs, 0, sizeof(m_opcode_addrs));
m_opcode_addrs_index = 0;
m_dri_changed_active = false;
}
void i386_device::device_reset()

View File

@ -276,6 +276,7 @@ protected:
memory_passthrough_handler m_dr_breakpoints[4];
util::notifier_subscription m_notifier;
bool m_dri_changed_active;
//386 Debug Register change handlers.
inline void dri_changed();

View File

@ -736,9 +736,10 @@ void i386_device::i386_mov_dr_r32() // Opcode 0x0f 23
case 6: CYCLES(CYCLES_MOV_DR6_7_REG); m_dr[dr] = LOAD_RM32(modrm); break;
case 7:
{
dr7_changed(m_dr[7], rm32);
CYCLES(CYCLES_MOV_DR6_7_REG);
uint32_t old_dr7 = m_dr[7];
m_dr[dr] = rm32;
dr7_changed(old_dr7, m_dr[7]);
CYCLES(CYCLES_MOV_DR6_7_REG);
break;
}
default:

View File

@ -2479,7 +2479,11 @@ void i386_device::i386_protected_mode_iret(int operand32)
inline void i386_device::dri_changed()
{
int dr;
if(!(m_dr[7] & 0xff)) return;
if(m_dri_changed_active)
return;
m_dri_changed_active = true;
for(dr = 0; dr < 4; dr++)
{
m_dr_breakpoints[dr].remove();
@ -2490,48 +2494,65 @@ inline void i386_device::dri_changed()
int breakpoint_length = (m_dr[7] >> ((dr << 2) + 16 + 2)) & 3;
uint32_t phys_addr = m_dr[dr];
uint32_t error;
phys_addr = translate_address(m_CPL, TRANSLATE_READ, &phys_addr, &error);
phys_addr &= ~3; // According to CUP386, data breakpoints are only reliable on dword-aligned addresses, so align this to a dword.
uint32_t true_mask = 0;
switch(breakpoint_length)
if(translate_address(m_CPL, TRANSLATE_READ, &phys_addr, &error))
{
case 0: true_mask = 0xff; break;
case 1: true_mask = 0xffff; break;
// Case 2 is invalid on a real 386.
case 3: true_mask = 0xffffffff; break;
phys_addr &= ~3; // According to CUP386, data breakpoints are only reliable on dword-aligned addresses, so align this to a dword.
uint32_t true_mask = 0;
switch(breakpoint_length)
{
case 0: true_mask = 0xff; break;
case 1: true_mask = 0xffff; break;
// Case 2 is invalid on a real 386.
case 3: true_mask = 0xffffffff; break;
}
if(true_mask == 0)
{
logerror("i386: Unknown breakpoint length value\n");
}
else if(breakpoint_type == 1)
{
m_dr_breakpoints[dr] = m_program->install_write_tap(
phys_addr,
phys_addr + 3,
"i386_debug_write_breakpoint",
[this, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
{
if(true_mask & mem_mask)
{
m_dr[6] |= 1 << dr;
i386_trap(1,1,0);
}
},
&m_dr_breakpoints[dr]);
}
else if(breakpoint_type == 3)
{
m_dr_breakpoints[dr] = m_program->install_readwrite_tap(
phys_addr,
phys_addr + 3,
"i386_debug_readwrite_breakpoint",
[this, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
{
if(true_mask & mem_mask)
{
m_dr[6] |= 1 << dr;
i386_trap(1,1,0);
}
},
[this, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
{
if(true_mask & mem_mask)
{
m_dr[6] |= 1 << dr;
i386_trap(1,1,0);
}
},
&m_dr_breakpoints[dr]);
}
}
if(true_mask == 0)
{
logerror("i386: Unknown breakpoint length value\n");
}
else if(breakpoint_type == 1) m_dr_breakpoints[dr] = m_program->install_write_tap(phys_addr, phys_addr + 3, "i386_debug_write_breakpoint",
[&, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
{
if(true_mask & mem_mask)
{
m_dr[6] |= 1 << dr;
i386_trap(1,0,0);
}
}, &m_dr_breakpoints[dr]);
else if(breakpoint_type == 3) m_dr_breakpoints[dr] = m_program->install_readwrite_tap(phys_addr, phys_addr + 3, "i386_debug_readwrite_breakpoint",
[this, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
{
if(true_mask & mem_mask)
{
m_dr[6] |= 1 << dr;
i386_trap(1,0,0);
}
},
[this, dr, true_mask](offs_t offset, u32& data, u32 mem_mask)
{
if(true_mask & mem_mask)
{
m_dr[6] |= 1 << dr;
i386_trap(1,0,0);
}
}, &m_dr_breakpoints[dr]);
}
}
m_dri_changed_active = false;
}
inline void i386_device::dr7_changed(uint32_t old_val, uint32_t new_val)

View File

@ -292,7 +292,8 @@ uint32_t ncr53c7xx_device::read(offs_t offset, uint32_t mem_mask)
if (ACCESSING_BITS_0_7)
{
ret = m_dstat;
m_dstat = 0;
// DFE isn't cleared on read
m_dstat &= DSTAT_DFE;
update_irqs();
}
if (ACCESSING_BITS_8_15)

View File

@ -1077,6 +1077,9 @@ void z80scc_channel::device_start()
m_tx_fifo_sz = (m_uart->m_variant & z80scc_device::SET_ESCC) ? 4 : 1;
m_tx_fifo_wp = m_tx_fifo_rp = 0;
m_rxc = 0x00;
m_txc = 0x00;
#if Z80SCC_USE_LOCAL_BRG
// baudrate clocks and timers
baudtimer = timer_alloc(TIMER_ID_BAUD);
@ -1137,6 +1140,11 @@ void z80scc_channel::device_start()
save_item(NAME(m_rts));
save_item(NAME(m_tx_int_disarm));
save_item(NAME(m_sync_pattern));
save_item(NAME(m_rxd));
save_item(NAME(m_rcv_mode));
save_item(NAME(m_index));
save_item(NAME(m_brg_rate));
save_item(NAME(m_delayed_tx_brg_change));
}

File diff suppressed because it is too large Load Diff

View File

@ -68,11 +68,11 @@ void bacta_datalogger_device::tx_queue()
{
if (is_transmit_register_empty())
{
if (m_output_char != -1)
if (m_output_char != 255)
{
set_tra_rate(1200);
transmit_register_setup(m_output_char);
m_output_char = -1;
m_output_char = 255;
}
}
}