From 640354ad9efa2b8c0027c0bce444e652cb593333 Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Tue, 13 May 2014 11:46:02 +0000 Subject: Big Amiga cleanup and reorganizaton. CDTV temporarily broken. Lots of work still to do. All basic Amiga models are now supported to varying degrees. --- src/mess/machine/amigacrt.c | 464 -------------------------------------------- 1 file changed, 464 deletions(-) delete mode 100644 src/mess/machine/amigacrt.c (limited to 'src/mess/machine/amigacrt.c') diff --git a/src/mess/machine/amigacrt.c b/src/mess/machine/amigacrt.c deleted file mode 100644 index dd1ab1bed0d..00000000000 --- a/src/mess/machine/amigacrt.c +++ /dev/null @@ -1,464 +0,0 @@ -/*************************************************************************** - - Amiga cartridge emulation - -TODO: -- Investigate why the AR2/3 sometimes garble the video on exit from the cart -- Add Nordic Power and similar carts -- Add HRTMon A1200 cart - -***************************************************************************/ - - -#include "emu.h" -#include "includes/amiga.h" -#include "cpu/m68000/m68000.h" -#include "machine/amigacrt.h" - -enum -{ - /* supported cartridges */ - ACTION_REPLAY = 0, - ACTION_REPLAY_MKII, - ACTION_REPLAY_MKIII -}; - -struct amigacrt_t -{ - int cart_type; - int ar1_spurious; - UINT16 ar23_mode; -}; -static amigacrt_t amigacrt; - -/*************************************************************************** - - Utilities - -***************************************************************************/ - -static int check_kickstart_12_13( running_machine &machine, const char *cart_name ) -{ - UINT16 * ksmem = (UINT16 *)(*machine.root_device().memregion( "user1" )); - - if ( ksmem[2] == 0x00FC ) - return 1; - - logerror( "%s requires Kickstart version 1.2 or 1.3 - Cart not installed\n", cart_name ); - - return 0; -} - -/*************************************************************************** - - Amiga Action Replay 1 - - Whenever you push the button, an NMI interrupt is generated. - - The cartridge protects itself from being removed from memory by - generating an interrupt whenever either the spurious interrupt - vector is written at $60, or the nmi interrupt vector is written at - $7c. If the spurious interrupt vector at $60 is written, then - a NMI is generated, and the spurious irq vector is restored. If the - NMI vector at $7c is written, then a spurious interrupt is generated, - and the NMI vector is restored. - - When breakpoints are set, the target address is replaced by a trap - instruction, and the original contents of the address are kept in - the cartridge's RAM. A trap handler is installed pointing to $40 - in RAM, where code that clears memory address $60 followed by two - nops are written. There seems to be a small delay between the write - to $60 and until the actual NMI is generated, since the cart expects - the PC to be at $46 (at the second nop). - -***************************************************************************/ - -IRQ_CALLBACK_MEMBER(amiga_state::amiga_ar1_irqack) -{ - if ( irqline == 7 && amigacrt.ar1_spurious ) - { - return M68K_INT_ACK_SPURIOUS; - } - - return (24+irqline); -} - -static TIMER_CALLBACK( amiga_ar1_delayed_nmi ) -{ - (void)param; - machine.device("maincpu")->execute().set_input_line(7, PULSE_LINE); -} - -static void amiga_ar1_nmi( running_machine &machine ) -{ - amiga_state *state = machine.driver_data(); - /* get the cart's built-in ram */ - UINT16 *ar_ram = (UINT16 *)(state->m_maincpu_program_space->get_write_ptr(0x9fc000)); - - if ( ar_ram != NULL ) - { - int i; - - /* copy custom register values */ - for( i = 0; i < 256; i++ ) - ar_ram[0x1800+i] = CUSTOM_REG(i); - - /* trigger NMI irq */ - amigacrt.ar1_spurious = 0; - machine.scheduler().timer_set(machine.device("maincpu")->cycles_to_attotime(28), FUNC(amiga_ar1_delayed_nmi)); - } -} - -WRITE16_MEMBER( amiga_state::amiga_ar1_chipmem_w ) -{ - int pc = space.device().safe_pc(); - - /* see if we're inside the AR1 rom */ - if ( ((pc >> 16) & 0xff ) != 0xf0 ) - { - /* if we're not, see if either the Spurious IRQ vector - or the NMI vector are being overwritten */ - if ( offset == (0x60/2) || offset == (0x7c/2) ) - { - /* trigger an NMI or spurious irq */ - amigacrt.ar1_spurious = (offset == 0x60/2) ? 0 : 1; - space.machine().scheduler().timer_set(space.machine().device("maincpu")->cycles_to_attotime(28), FUNC(amiga_ar1_delayed_nmi)); - } - } - - (*m_chip_ram_w)(this, offset * 2, data ); -} - -static void amiga_ar1_check_overlay( running_machine &machine ) -{ - amiga_state *state = machine.driver_data(); - - state->m_maincpu_program_space->install_write_handler(0x000000, 0x00007f, write16_delegate(FUNC(amiga_state::amiga_ar1_chipmem_w),state)); -} - -static void amiga_ar1_init( running_machine &machine ) -{ - amiga_state *state = machine.driver_data(); - void *ar_ram; - - /* check kickstart version */ - if ( !check_kickstart_12_13( machine, "Amiga Action Replay" ) ) - { - amigacrt.cart_type = -1; - return; - } - - /* setup the cart ram */ - ar_ram = auto_alloc_array(machine, UINT8, 0x4000); - memset(ar_ram, 0, 0x4000); - - /* Install ROM */ - state->m_maincpu_program_space->install_read_bank(0xf00000, 0xf7ffff, "bank2"); - state->m_maincpu_program_space->unmap_write(0xf00000, 0xf7ffff); - - /* Install RAM */ - state->m_maincpu_program_space->install_readwrite_bank(0x9fc000, 0x9fffff, "bank3"); - - /* Configure Banks */ - state->membank("bank2")->set_base(machine.root_device().memregion("user2")->base()); - state->membank("bank3")->set_base(ar_ram); - - amigacrt.ar1_spurious = 0; - - /* Install IRQ ACK callback */ - device_execute_interface::static_set_irq_acknowledge_callback(*machine.device("maincpu"), device_irq_acknowledge_delegate(FUNC(amiga_state::amiga_ar1_irqack), state)); -} - -/*************************************************************************** - - Amiga Action Replay MKII/MKIII - - Whenever you push the button, an overlay of the cartridge appears - in RAM and an NMI interrupt is generated. Only reads are overlayed. - Writes go directly to chipmem (so that the CPU can write the stack - information for the NMI). Once the interrupt is taken, the cart - disables the ROM overlay and checks it's internal mode register - to see why it was invoked. - - When a breakpoint is set the cart replaces the target instruction - with a trap, and adds a trap handler that it locates in the $100-$120 - area. The handler simply has one instruction: TST.B $BFE001. This cia - access is monitored, and the conditions match (PC < 120 and a previous - command requested the monitoring of the cia) then the cart is invoked. - -***************************************************************************/ - -static void amiga_ar23_freeze( running_machine &machine ); - -READ16_MEMBER( amiga_state::amiga_ar23_cia_r ) -{ - int pc = space.device().safe_pc(); - - if ( ACCESSING_BITS_0_7 && offset == 2048 && pc >= 0x40 && pc < 0x120 ) - { - amiga_ar23_freeze(space.machine()); - } - - return amiga_cia_r( space, offset, mem_mask ); -} - -WRITE16_MEMBER( amiga_state::amiga_ar23_mode_w ) -{ - if ( data & 2 ) - { - space.install_read_handler(0xbfd000, 0xbfefff, read16_delegate(FUNC(amiga_state::amiga_ar23_cia_r), this)); - } - else - { - space.install_read_handler(0xbfd000, 0xbfefff, read16_delegate(FUNC(amiga_state::amiga_cia_r), this)); - } - - amigacrt.ar23_mode = (data&0x3); - if ( amigacrt.ar23_mode == 0 ) - amigacrt.ar23_mode = 1; - -} - -READ16_MEMBER( amiga_state::amiga_ar23_mode_r ) -{ - amiga_state *state = space.machine().driver_data(); - UINT16 *mem = (UINT16 *)(*state->memregion( "user2" )); - - if ( ACCESSING_BITS_0_7 ) - { - if ( offset < 2 ) - return (mem[offset] | (amigacrt.ar23_mode&3)); - - if ( offset == 0x03 ) /* disable cart overlay on chip mem */ - { - UINT32 mirror_mask = state->m_chip_ram.bytes(); - - state->membank("bank1")->set_entry(0); - - while( (mirror_mask<<1) < 0x100000 ) - { - mirror_mask |= ( mirror_mask << 1 ); - } - - /* overlay disabled, map RAM on 0x000000 */ - space.install_write_bank(0x000000, state->m_chip_ram.bytes() - 1, 0, mirror_mask, "bank1"); - } - } - - return mem[offset]; -} - -WRITE16_MEMBER( amiga_state::amiga_ar23_chipmem_w ) -{ - if ( offset == (0x08/2) ) - { - if ( amigacrt.ar23_mode & 1 ) - amiga_ar23_freeze(space.machine()); - } - - (*m_chip_ram_w)(this, offset * 2, data ); -} - -static void amiga_ar23_freeze( running_machine &machine ) -{ - amiga_state *state = machine.driver_data(); - int pc = machine.device("maincpu")->safe_pc(); - - /* only freeze if we're not inside the cart's ROM */ - if ( ((pc >> 16) & 0xfe ) != 0x40 ) - { - /* get the cart's built-in ram */ - UINT16 *ar_ram = (UINT16 *)state->m_maincpu_program_space->get_write_ptr(0x440000); - - if ( ar_ram != NULL ) - { - int i; - - for( i = 0; i < 0x100; i++ ) - ar_ram[0x7800+i] = CUSTOM_REG(i); - } - - /* overlay the cart rom's in chipram */ - state->membank("bank1")->set_entry(2); - - /* writes go to chipram */ - state->m_maincpu_program_space->install_write_handler(0x000000, state->m_chip_ram.bytes() - 1, write16_delegate(FUNC(amiga_state::amiga_ar23_chipmem_w),state)); - - /* trigger NMI irq */ - machine.device("maincpu")->execute().set_input_line(7, PULSE_LINE); - } -} - -static void amiga_ar23_nmi( running_machine &machine ) -{ - amigacrt.ar23_mode = 0; - amiga_ar23_freeze(machine); -} - -#if 0 -static WRITE16_HANDLER( amiga_ar23_custom_w ) -{ - int pc = space.device().safe_pc(); - - /* see if we're inside the AR2 rom */ - if ( ((pc >> 16) & 0xfe ) != 0x40 ) - { - /* get the cart's built-in ram */ - UINT16 *ar_ram = (UINT16 *)memory_get_write_ptr(0, AS_PROGRAM, 0x440000); - - if ( ar_ram != NULL ) - { - ar_ram[0x7800+offset] = data; - } - } - - amiga_custom_w( offset, data, mem_mask ); -} - -static READ16_HANDLER( amiga_ar23_custom_r ) -{ - UINT16 data = amiga_custom_r( offset, mem_mask ); - - int pc = space.device().safe_pc(); - - /* see if we're inside the AR2 rom */ - if ( ((pc >> 16) & 0xfe ) != 0x40 ) - { - /* get the cart's built-in ram */ - UINT16 *ar_ram = (UINT16 *)memory_get_write_ptr(0, AS_PROGRAM, 0x440000); - - if ( ar_ram != NULL ) - { - ar_ram[0x7800+offset] = data; - } - } - - return data; -} -#endif - -static void amiga_ar23_check_overlay( running_machine &machine ) -{ - amiga_state *state = machine.driver_data(); - amigacrt.ar23_mode = 3; - state->m_maincpu_program_space->install_write_handler(0x000000, 0x00000f, write16_delegate(FUNC(amiga_state::amiga_ar23_chipmem_w),state)); -} - -void amiga_state::amiga_ar23_init( running_machine &machine, int ar3 ) -{ - amiga_state *state = machine.driver_data(); - UINT32 mirror = 0x20000, size = 0x1ffff; - void *ar_ram; - - /* check kickstart version */ - if ( !check_kickstart_12_13( machine, "Action Replay MKII or MKIII" ) ) - { - amigacrt.cart_type = -1; - return; - } - - /* setup the cart ram */ - ar_ram = auto_alloc_array_clear(machine, UINT8,0x10000); - - if ( ar3 ) - { - mirror = 0; - size = 0x3ffff; - } - - /* Install ROM */ - state->m_maincpu_program_space->install_read_bank(0x400000, 0x400000+size, 0, mirror, "bank2"); - state->m_maincpu_program_space->unmap_write(0x400000, 0x400000+size, 0, mirror); - - /* Install RAM */ - state->m_maincpu_program_space->install_read_bank(0x440000, 0x44ffff, "bank3"); - state->m_maincpu_program_space->install_write_bank(0x440000, 0x44ffff, "bank3"); - - /* Install Custom chip monitor */ -// state->m_maincpu_program_space->install_legacy_read_handler(0xdff000, 0xdff1ff, FUNC(amiga_ar23_custom_r)); -// state->m_maincpu_program_space->install_legacy_write_handler(0xdff000, 0xdff1ff, FUNC(amiga_ar23_custom_w)); - - /* Install status/mode handlers */ - state->m_maincpu_program_space->install_read_handler( 0x400000, 0x400007, 0, mirror, read16_delegate( FUNC(amiga_state::amiga_ar23_mode_r), this)); - state->m_maincpu_program_space->install_write_handler(0x400000, 0x400003, 0, mirror, write16_delegate(FUNC(amiga_state::amiga_ar23_mode_w), this)); - - /* Configure Banks */ - state->membank("bank2")->set_base(machine.root_device().memregion("user2")->base()); - state->membank("bank3")->set_base(ar_ram); - - state->membank("bank1")->configure_entries(0, 2, state->m_chip_ram, 0); - state->membank("bank1")->configure_entries(1, 2, machine.root_device().memregion("user1")->base(), 0); - state->membank("bank1")->configure_entries(2, 2, machine.root_device().memregion("user2")->base(), 0); - - amigacrt.ar23_mode = 3; -} - -/*************************************************************************** - - MAME/MESS hooks - -***************************************************************************/ - -void amiga_cart_init( running_machine &machine ) -{ - /* see what is there */ - UINT16 *mem = (UINT16 *)(*machine.root_device().memregion( "user2" )); - amiga_state *state = machine.driver_data(); - - amigacrt.cart_type = -1; - - if ( mem != NULL ) - { - if ( mem[0x00] == 0x1111 ) - { - amigacrt.cart_type = ACTION_REPLAY; - amiga_ar1_init(machine); - } - else if ( mem[0x0C] == 0x4D6B ) - { - amigacrt.cart_type = ACTION_REPLAY_MKII; - state->amiga_ar23_init(machine, 0); - } - else if ( mem[0x0C] == 0x4D4B ) - { - amigacrt.cart_type = ACTION_REPLAY_MKIII; - state->amiga_ar23_init(machine, 1); - } - } -} - -void amiga_cart_check_overlay( running_machine &machine ) -{ - if ( amigacrt.cart_type < 0 ) - return; - - switch( amigacrt.cart_type ) - { - case ACTION_REPLAY: - amiga_ar1_check_overlay(machine); - break; - - case ACTION_REPLAY_MKII: - case ACTION_REPLAY_MKIII: - amiga_ar23_check_overlay(machine); - break; - } -} - -void amiga_cart_nmi( running_machine &machine ) -{ - if ( amigacrt.cart_type < 0 ) - return; - - switch( amigacrt.cart_type ) - { - case ACTION_REPLAY: - amiga_ar1_nmi(machine); - break; - - case ACTION_REPLAY_MKII: - case ACTION_REPLAY_MKIII: - amiga_ar23_nmi(machine); - break; - } -} -- cgit v1.2.3-70-g09d2