summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/intv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/intv.c')
-rw-r--r--src/mess/machine/intv.c475
1 files changed, 47 insertions, 428 deletions
diff --git a/src/mess/machine/intv.c b/src/mess/machine/intv.c
index d35c7a95782..f3c0bbc6d9d 100644
--- a/src/mess/machine/intv.c
+++ b/src/mess/machine/intv.c
@@ -2,10 +2,7 @@
#include "video/stic.h"
#include "includes/intv.h"
#include "cpu/cp1610/cp1610.h"
-#include "hashfile.h"
-#define INTELLIVOICE_MASK 0x02
-#define ECS_MASK 0x01
WRITE16_MEMBER( intv_state::intvkbd_dualport16_w )
@@ -288,25 +285,6 @@ WRITE16_MEMBER( intv_state::intv_ram8_w )
m_ram8[offset] = data&0xff;
}
-READ16_MEMBER( intv_state::intv_ecs_ram8_r )
-{
- return (int)m_ecs_ram8[offset];
-}
-
-WRITE16_MEMBER( intv_state::intv_ecs_ram8_w )
-{
- m_ecs_ram8[offset] = data&0xff;
-}
-
-READ16_MEMBER( intv_state::intv_cart_ram8_r )
-{
- return (int)m_cart_ram8[offset];
-}
-WRITE16_MEMBER( intv_state::intv_cart_ram8_w )
-{
- m_cart_ram8[offset] = data&0xff;
-}
-
READ16_MEMBER( intv_state::intv_ram16_r )
{
//logerror("%x = ram16_r(%x)\n",state->m_ram16[offset],offset);
@@ -320,289 +298,16 @@ WRITE16_MEMBER( intv_state::intv_ram16_w )
m_ram16[offset] = data & 0xffff;
}
-// ECS and Wsmlb bank switching register handlers
-WRITE16_MEMBER( intv_state::ecs_bank1_page_select )
-{
- if (offset == 0xfff)
- {
- if (data == 0x2a50)
- {
- m_ecs_bank_src[0] = 0;
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- }
- else if (data == 0x2a51)
- {
- m_ecs_bank_src[0] = 1;
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- }
- }
-}
-
-WRITE16_MEMBER( intv_state::ecs_bank2_page_select )
-{
- if (offset == 0xfff)
- {
- if (data == 0x7a50)
- {
- m_ecs_bank_src[1] = 1;
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1)); // ECS ROM at 0x7000 is on page 1
- }
- else if (data == 0x7a51 )
- {
- m_ecs_bank_src[1] = 0;
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1));
- }
- }
-}
-
-WRITE16_MEMBER( intv_state::ecs_bank3_page_select )
-{
- if (offset == 0xfff)
- {
- if (data == 0xea50)
- {
- m_ecs_bank_src[2] = 0;
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- }
- else if (data == 0xea51)
- {
- m_ecs_bank_src[2] = 1;
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- }
- }
-}
-
-WRITE16_MEMBER( intv_state::wsmlb_bank_page_select )
-{
- logerror("offset %x data %x\n", offset, data);
- if (offset == 0xfff)
- {
- if (data == 0xfa50)
- {
- m_ecs_bank_src[3] = 0;
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
- }
- else if (data == 0xfa51)
- {
- m_ecs_bank_src[3] = 1;
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
- }
- }
-}
-
-int intv_state::intv_load_rom_file(device_image_interface &image)
+READ8_MEMBER( intv_state::intvkb_iocart_r )
{
- int i,j;
-
- UINT8 temp;
- UINT8 num_segments;
- UINT8 start_seg;
- UINT8 end_seg;
-
- UINT32 current_address;
- UINT32 end_address;
-
- UINT8 high_byte;
- UINT8 low_byte;
-
- UINT8 *memory = m_region_maincpu->base();
- address_space &program = m_maincpu->space(AS_PROGRAM);
- const char *filetype = image.filetype();
-
- /* if it is in .rom format, we enter here */
- if (!core_stricmp (filetype, "rom"))
- {
- image.fread( &temp, 1); /* header */
- if (temp != 0xa8)
- {
- return IMAGE_INIT_FAIL;
- }
-
- image.fread( &num_segments, 1);
-
- image.fread( &temp, 1);
- if (temp != (num_segments ^ 0xff))
- {
- return IMAGE_INIT_FAIL;
- }
-
- for (i = 0; i < num_segments; i++)
- {
- image.fread( &start_seg, 1);
- current_address = start_seg * 0x100;
-
- image.fread( &end_seg, 1);
- end_address = end_seg * 0x100 + 0xff;
-
- while (current_address <= end_address)
- {
- image.fread( &low_byte, 1);
- memory[(current_address << 1) + 1] = low_byte;
- image.fread( &high_byte, 1);
- memory[current_address << 1] = high_byte;
- current_address++;
- }
-
- /* Here we should calculate and compare the CRC16... */
- image.fread( &temp, 1);
- image.fread( &temp, 1);
- }
-
- /* Access tables and fine address restriction tables are not supported ATM */
- for (i = 0; i < (16 + 32 + 2); i++)
- {
- image.fread( &temp, 1);
- }
- return IMAGE_INIT_PASS;
- }
- /* otherwise, we load it as a .bin file, using extrainfo from intv.hsi in place of .cfg */
+ if (m_iocart1->exists())
+ return m_iocart1->read_rom(space, offset, mem_mask);
+ else if (m_iocart2->exists())
+ return m_iocart2->read_rom(space, offset, mem_mask);
else
- {
- /* This code is a blatant hack, due to impossibility to load a separate .cfg file in MESS. */
- /* It shall be eventually replaced by the .xml loading */
-
- /* extrainfo format */
- // 1. mapper number (to deal with bankswitch). no bankswitch is mapper 0 (most games).
- // 2.->5. current images have at most 4 chunks of data. we store here block size and location to load
- // (value & 0xf0) >> 4 is the location / 0x1000
- // (value & 0x0f) is the size / 0x800
- // 6. some images have a ram chunk. as above we store location and size in 8 bits
- // 7. extra = 1 ECS, 2 Intellivoice
- int start, size;
- int mapper, rom[5], ram, extra;
- astring extrainfo;
- if (!hashfile_extrainfo(image, extrainfo))
- {
- /* If no extrainfo, we assume a single 0x2000 chunk at 0x5000 */
- for (i = 0; i < 0x2000; i++ )
- {
- image.fread( &low_byte, 1);
- memory[((0x5000 + i) << 1) + 1] = low_byte;
- image.fread( &high_byte, 1);
- memory[(0x5000 + i) << 1] = high_byte;
- }
- }
- else
- {
- sscanf(extrainfo.cstr() ,"%d %d %d %d %d %d %d", &mapper, &rom[0], &rom[1], &rom[2],
- &rom[3], &ram, &extra);
-
-// logerror("extrainfo: %d %d %d %d %d %d %d \n", mapper, rom[0], rom[1], rom[2],
-// rom[3], ram, extra);
-
- if (mapper)
- {
- logerror("Bankswitch not yet implemented! \n");
- }
-
- if (ram)
- {
- start = (( ram & 0xf0 ) >> 4) * 0x1000;
- size = ( ram & 0x0f ) * 0x800;
-
- program.install_readwrite_handler(start, start + size,
- read16_delegate( FUNC( intv_state::intv_cart_ram8_r ), this),
- write16_delegate( FUNC( intv_state::intv_cart_ram8_w ), this));
- }
- /* For now intellivoice always active
- if (extra & INTELLIVOICE_MASK)
- {
- // tbd
- }
- */
-
- if (extra & ECS_MASK)
- {
- logerror("Requires ECS Module\n");
- }
-
- for (j = 0; j < 4; j++)
- {
- start = (( rom[j] & 0xf0 ) >> 4) * 0x1000;
- size = ( rom[j] & 0x0f ) * 0x800;
-
- /* some cart has to be loaded to 0x4800, but none goes to 0x4000. Hence, we use */
- /* 0x04 << 4 in extrainfo (to reduce the stored values) and fix the value here. */
- if (start == 0x4000) start += 0x800;
-
-// logerror("step %d: %d %d \n", j, start / 0x1000, size / 0x1000);
-
- for (i = 0; i < size; i++ )
- {
- image.fread( &low_byte, 1);
- memory[((start + i) << 1) + 1] = low_byte;
- image.fread( &high_byte, 1);
- memory[(start + i) << 1] = high_byte;
- }
- }
- }
-
- return IMAGE_INIT_PASS;
- }
+ return m_region_keyboard->u8(offset + 0xe000);
}
-DEVICE_IMAGE_LOAD_MEMBER( intv_state, intv_cart )
-{
- if (image.software_entry() == NULL)
- return intv_load_rom_file(image);
- else
- {
- UINT16 offset[] = {0x4800, 0x5000, 0x6000, 0x7000, 0x9000, 0xa000, 0xc000, 0xd000, 0xf000};
- const char* region_name[] = {"4800", "5000", "6000", "7000", "9000", "A000", "C000", "D000", "F000"};
- UINT8 *memory = m_region_maincpu->base();
- address_space &program = m_maincpu->space(AS_PROGRAM);
-
- UINT32 size=0;
- UINT16 address = 0;
- UINT8 *region;
- for(int i = 0; i < 9; i++)
- {
- address = offset[i];
- size = image.get_software_region_length(region_name[i]);
- if (size)
- {
- region = image.get_software_region(region_name[i]);
- for (int j = 0; j < (size>>1); j++)
- {
- memory[((address + j) << 1) + 1] = region[2*j];
- memory[(address + j) << 1] = region[2*j+1];
- }
- }
- }
- // deal with wsmlb paged rom
-
- size = image.get_software_region_length("F000_bank1");
- if (size && m_region_ecs_rom) // only load if ecs is plugged in (should probably be done a different way)
- {
- UINT8 *ecs_rom_region = m_region_ecs_rom->base();
-
- region = image.get_software_region("F000_bank1");
- for (int j = 0; j < (size>>1); j++)
- {
- ecs_rom_region[((address + j) << 1) + 1] = region[2*j];
- ecs_rom_region[(address + j) << 1] = region[2*j+1];
- }
- }
-
- // Cartridge 8bit ram support
- size = image.get_software_region_length("D000_RAM8");
- if (size)
- {
- program.install_readwrite_handler(0xD000, 0xD000 + size,
- read16_delegate( FUNC( intv_state::intv_cart_ram8_r ), this),
- write16_delegate( FUNC( intv_state::intv_cart_ram8_w ), this));
- }
-
- size = image.get_software_region_length("8800_RAM8");
- if (size)
- {
- program.install_readwrite_handler(0x8800, 0x8800 + size,
- read16_delegate( FUNC( intv_state::intv_cart_ram8_r ), this),
- write16_delegate( FUNC( intv_state::intv_cart_ram8_w ), this));
- }
- return IMAGE_INIT_PASS;
- }
-}
/* Set Reset and INTR/INTRM Vector */
void intv_state::machine_reset()
@@ -615,21 +320,6 @@ void intv_state::machine_reset()
/* Set initial PC */
m_maincpu->set_state_int(CP1610_R7, 0x1000);
-
- if (m_is_ecs)
- {
- // ECS can switch between the maincpu and the ecs roms
- m_ecs_bank_src[0] = 0; // CPU
- m_ecs_bank_src[1] = 1; // ECS
- m_ecs_bank_src[2] = 0; // CPU
- m_ecs_bank_src[3] = 0; // CPU
- m_bank_base[0] = m_region_maincpu->base();
- m_bank_base[1] = m_region_ecs_rom->base();
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1));
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
- }
}
void intv_state::machine_start()
@@ -661,30 +351,7 @@ void intv_state::machine_start()
save_item(NAME(m_ram16));
save_item(NAME(m_sr1_int_pending));
save_item(NAME(m_ram8));
- save_item(NAME(m_cart_ram8));
-
- // ecs
- if (m_is_ecs)
- {
- for (int i = 0; i < 7; i++)
- {
- char str[9];
- sprintf(str, "ECS_ROW%i", i);
- m_ecs_keyboard[i] = ioport(str);
- }
- for (int i = 0; i < 7; i++)
- {
- char str[15];
- sprintf(str, "ECS_SYNTH_ROW%i", i);
- m_ecs_synth[i] = ioport(str);
- }
-
- save_item(NAME(m_ecs_ram8));
- save_item(NAME(m_ecs_psg_porta));
- save_item(NAME(m_ecs_bank_src));
- machine().save().register_postload(save_prepost_delegate(FUNC(intv_state::ecs_banks_restore), this));
- }
-
+
// intvkbd
if (m_is_keybd)
{
@@ -706,14 +373,47 @@ void intv_state::machine_start()
save_item(NAME(m_tms9927_cursor_row));
save_item(NAME(m_tms9927_last_row));
}
-}
-void intv_state::ecs_banks_restore()
-{
- m_bank1->set_base(m_bank_base[m_ecs_bank_src[0]] + (0x2000 << 1));
- m_bank2->set_base(m_bank_base[m_ecs_bank_src[1]] + (0x7000 << 1));
- m_bank3->set_base(m_bank_base[m_ecs_bank_src[2]] + (0xe000 << 1));
- m_bank4->set_base(m_bank_base[m_ecs_bank_src[3]] + (0xf000 << 1));
+ if (m_cart && m_cart->exists())
+ {
+ // RAM
+ switch (m_cart->get_type())
+ {
+ case INTV_RAM:
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xd000, 0xd7ff, read16_delegate(FUNC(intv_cart_slot_device::read_ram),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ram),(intv_cart_slot_device*)m_cart));
+ break;
+ case INTV_GFACT:
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x8800, 0x8fff, read16_delegate(FUNC(intv_cart_slot_device::read_ram),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ram),(intv_cart_slot_device*)m_cart));
+ break;
+ case INTV_VOICE:
+ m_cart->late_subslot_setup();
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0080, 0x0081, read16_delegate(FUNC(intv_cart_slot_device::read_speech),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_speech),(intv_cart_slot_device*)m_cart));
+
+ // passthru for RAM-equipped carts
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x8800, 0x8fff, write16_delegate(FUNC(intv_cart_slot_device::write_88),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xd000, 0xd7ff, write16_delegate(FUNC(intv_cart_slot_device::write_d0),(intv_cart_slot_device*)m_cart));
+ break;
+ case INTV_ECS:
+ m_cart->late_subslot_setup();
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x00f0, 0x00ff, read16_delegate(FUNC(intv_cart_slot_device::read_ay),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ay),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x4000, 0x47ff, read16_delegate(FUNC(intv_cart_slot_device::read_ram),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_ram),(intv_cart_slot_device*)m_cart));
+
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x2000, 0x2fff, write16_delegate(FUNC(intv_cart_slot_device::write_rom20),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x7000, 0x7fff, write16_delegate(FUNC(intv_cart_slot_device::write_rom70),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xe000, 0xefff, write16_delegate(FUNC(intv_cart_slot_device::write_rome0),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xf000, 0xffff, write16_delegate(FUNC(intv_cart_slot_device::write_romf0),(intv_cart_slot_device*)m_cart));
+
+ // passthru for Intellivoice expansion
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x0080, 0x0081, read16_delegate(FUNC(intv_cart_slot_device::read_speech),(intv_cart_slot_device*)m_cart), write16_delegate(FUNC(intv_cart_slot_device::write_speech),(intv_cart_slot_device*)m_cart));
+
+ // passthru for RAM-equipped carts
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0x8800, 0x8fff, write16_delegate(FUNC(intv_cart_slot_device::write_88),(intv_cart_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_write_handler(0xd000, 0xd7ff, write16_delegate(FUNC(intv_cart_slot_device::write_d0),(intv_cart_slot_device*)m_cart));
+ break;
+ }
+
+ m_cart->save_ram();
+ }
}
@@ -828,84 +528,3 @@ READ8_MEMBER( intv_state::intv_right_control_r )
{
return intv_control_r(1);
}
-
-READ8_MEMBER( intv_state::intv_ecs_porta_r )
-{
- if (m_io_ecs_cntrlsel->read() == 0)
- return intv_control_r(2);
- else
- return 0xff; // not sure what to return here, maybe it should be last output?
-}
-
-READ8_MEMBER( intv_state::intv_ecs_portb_r )
-{
- switch (m_io_ecs_cntrlsel->read())
- {
- case 0x00: // hand controller
- {
- return intv_control_r(3);
- }
- case 0x01: // synthesizer keyboard
- {
- UINT8 rv = 0xff;
- // return correct result if more than one bit of 0xFE is set
- for (int i = 0; i < 7; i++)
- {
- if (BIT(m_ecs_psg_porta, i))
- rv &= m_ecs_synth[i]->read();
- }
- return rv;
- }
- case 0x02: // ecs keyboard
- {
- UINT8 rv = 0xff;
- // return correct result if more than one bit of 0xFE is set
- for (int i = 0; i < 7; i++)
- {
- if (BIT(m_ecs_psg_porta, i))
- rv &= m_ecs_keyboard[i]->read();
- }
- return rv;
- }
- default:
- return 0xff;
- }
-}
-
-WRITE8_MEMBER( intv_state::intv_ecs_porta_w )
-{
- m_ecs_psg_porta = (~data) & 0xff;
-}
-
-/* Intellivision console + keyboard component */
-
-DEVICE_IMAGE_LOAD_MEMBER( intv_state,intvkbd_cart )
-{
- if (strcmp(image.device().tag(),":cart1") == 0) /* Legacy cartridge slot */
- {
- /* First, initialize these as empty so that the intellivision
- * will think that the playcable is not attached */
- UINT8 *memory = m_region_maincpu->base();
-
- /* assume playcable is absent */
- memory[0x4800 << 1] = 0xff;
- memory[(0x4800 << 1) + 1] = 0xff;
-
- if (image.software_entry() == NULL)
- {
- return intv_load_rom_file(image);
- }
- // Shouldn't we report failure here???
- }
-
- if (strcmp(image.device().tag(),":cart2") == 0) /* Keyboard component cartridge slot */
- {
- UINT8 *memory = m_region_keyboard->base();
-
- /* Assume an 8K cart, like BASIC */
- image.fread(&memory[0xe000], 0x2000);
- }
-
- return IMAGE_INIT_PASS;
-
-}