/*************************************************************************** machine.c Functions to emulate general aspects of the machine (RAM, ROM, interrupts, I/O ports) ***************************************************************************/ #include #include "driver.h" #include "cpu/z80/z80.h" #include "includes/jupiter.h" #include "sound/speaker.h" #include "image.h" #define JUPITER_NONE 0 #define JUPITER_ACE 1 #define JUPITER_TAP 2 static struct { UINT8 hdr_type; UINT8 hdr_name[10]; UINT16 hdr_len; UINT16 hdr_addr; UINT8 hdr_vars[8]; UINT8 hdr_3c4c; UINT8 hdr_3c4d; UINT16 dat_len; } jupiter_tape; static UINT8 *jupiter_data = NULL; static int jupiter_data_type = JUPITER_NONE; static void jupiter_machine_stop(running_machine *machine); /* only gets called at the start of a cpu time slice */ OPBASE_HANDLER( jupiter_opbaseoverride ) { int loop; unsigned short tmpword; if (address == 0x059d) { if (jupiter_data_type == JUPITER_ACE) { for (loop = 0; loop < 0x6000; loop++) program_write_byte(loop + 0x2000, jupiter_data[loop]); } else if (jupiter_data_type == JUPITER_TAP) { for (loop = 0; loop < jupiter_tape.dat_len; loop++) program_write_byte(loop + jupiter_tape.hdr_addr, jupiter_data[loop]); program_write_byte(0x3c27, 0x01); for (loop = 0; loop < 8; loop++) program_write_byte(loop + 0x3c31, jupiter_tape.hdr_vars[loop]); program_write_byte(0x3c39, 0x00); program_write_byte(0x3c3a, 0x00); tmpword = program_read_byte(0x3c3b) + program_read_byte(0x3c3c) * 256 + jupiter_tape.hdr_len; program_write_byte(0x3c3b, tmpword & 0xff); program_write_byte(0x3c3c, (tmpword >> 8) & 0xff); program_write_byte(0x3c45, 0x0c); /* ? */ program_write_byte(0x3c4c, jupiter_tape.hdr_3c4c); program_write_byte(0x3c4d, jupiter_tape.hdr_3c4d); if (!program_read_byte(0x3c57) && !program_read_byte(0x3c58)) { program_write_byte(0x3c57, 0x49); program_write_byte(0x3c58, 0x3c); } } } return (-1); } static int jupiter_ramsize = 2; MACHINE_START( jupiter ) { logerror("jupiter_init\r\n"); logerror("data: %p\n", jupiter_data); if (readinputport(8) != jupiter_ramsize) { jupiter_ramsize = readinputport(8); switch (jupiter_ramsize) { case 03: case 02: memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8800, 0xffff, 0, 0, MWA8_RAM); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8800, 0xffff, 0, 0, MRA8_RAM); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4800, 0x87ff, 0, 0, MWA8_RAM); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4800, 0x87ff, 0, 0, MRA8_RAM); break; case 01: memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8800, 0xffff, 0, 0, MWA8_NOP); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8800, 0xffff, 0, 0, MRA8_NOP); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4800, 0x87ff, 0, 0, MWA8_RAM); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4800, 0x87ff, 0, 0, MRA8_RAM); break; case 00: memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8800, 0xffff, 0, 0, MWA8_NOP); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8800, 0xffff, 0, 0, MRA8_NOP); memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4800, 0x87ff, 0, 0, MWA8_NOP); memory_install_read8_handler(0, ADDRESS_SPACE_PROGRAM, 0x4800, 0x87ff, 0, 0, MRA8_NOP); break; } } if (jupiter_data) { logerror("data: %p. type: %d.\n", jupiter_data, jupiter_data_type); memory_set_opbase_handler(0, jupiter_opbaseoverride); } add_exit_callback(machine, jupiter_machine_stop); } static void jupiter_machine_stop(running_machine *machine) { if (jupiter_data) { free(jupiter_data); jupiter_data = NULL; jupiter_data_type = JUPITER_NONE; } } /* Load in .ace files. These are memory images of 0x2000 to 0x7fff and compressed as follows: ED 00 : End marker ED 01 ED : 0xED ED : repeat count times : */ DEVICE_LOAD( jupiter_ace ) { unsigned char jupiter_repeat, jupiter_byte, loop; int done, jupiter_index; if (jupiter_data_type != JUPITER_NONE) return (0); done = 0; jupiter_index = 0; if ((jupiter_data = malloc(0x6000))) { logerror("Loading file %s.\r\n", image_filename(image)); while (!done && (jupiter_index < 0x6001)) { image_fread(image, &jupiter_byte, 1); if (jupiter_byte == 0xed) { image_fread(image, &jupiter_byte, 1); switch (jupiter_byte) { case 0x00: logerror("File loaded!\r\n"); done = 1; break; case 0x01: image_fread(image, &jupiter_byte, 1); jupiter_data[jupiter_index++] = jupiter_byte; break; case 0x02: logerror("Sequence 0xED 0x02 found in .ace file\r\n"); break; default: image_fread(image, &jupiter_repeat, 1); for (loop = 0; loop < jupiter_byte; loop++) jupiter_data[jupiter_index++] = jupiter_repeat; break; } } else jupiter_data[jupiter_index++] = jupiter_byte; } } if (!done) { logerror("file not loaded\r\n"); return (1); } logerror("Decoded %d bytes.\r\n", jupiter_index); jupiter_data_type = JUPITER_ACE; logerror("data: %p\n", jupiter_data); return (0); } DEVICE_LOAD( jupiter_tap ) { UINT8 inpbyt; int loop; UINT16 hdr_len; if (jupiter_data_type != JUPITER_NONE) return (0); logerror("Loading file %s.\r\n", image_filename(image)); image_fread(image, &inpbyt, 1); hdr_len = inpbyt; image_fread(image, &inpbyt, 1); hdr_len += (inpbyt * 256); /* Read header block */ image_fread(image, &jupiter_tape.hdr_type, 1); image_fread(image, jupiter_tape.hdr_name, 10); image_fread(image, &inpbyt, 1); jupiter_tape.hdr_len = inpbyt; image_fread(image, &inpbyt, 1); jupiter_tape.hdr_len += (inpbyt * 256); image_fread(image, &inpbyt, 1); jupiter_tape.hdr_addr = inpbyt; image_fread(image, &inpbyt, 1); jupiter_tape.hdr_addr += (inpbyt * 256); image_fread(image, &jupiter_tape.hdr_3c4c, 1); image_fread(image, &jupiter_tape.hdr_3c4d, 1); image_fread(image, jupiter_tape.hdr_vars, 8); if (hdr_len > 0x19) for (loop = 0x19; loop < hdr_len; loop++) image_fread(image, &inpbyt, 1); /* Read data block */ image_fread(image, &inpbyt, 1); jupiter_tape.dat_len = inpbyt; image_fread(image, &inpbyt, 1); jupiter_tape.dat_len += (inpbyt * 256); if ((jupiter_data = malloc(jupiter_tape.dat_len))) { image_fread(image, jupiter_data, jupiter_tape.dat_len); jupiter_data_type = JUPITER_TAP; logerror("File loaded\r\n"); } if (!jupiter_data) { logerror("file not loaded\r\n"); return (1); } return (0); } DEVICE_UNLOAD( jupiter_tap ) { logerror("jupiter_tap_unload\n"); if (jupiter_data) { free(jupiter_data); jupiter_data = NULL; jupiter_data_type = JUPITER_NONE; } } READ8_HANDLER ( jupiter_port_fefe_r ) { return (readinputport (0)); } READ8_HANDLER ( jupiter_port_fdfe_r ) { return (readinputport (1)); } READ8_HANDLER ( jupiter_port_fbfe_r ) { return (readinputport (2)); } READ8_HANDLER ( jupiter_port_f7fe_r ) { return (readinputport (3)); } READ8_HANDLER ( jupiter_port_effe_r ) { return (readinputport (4)); } READ8_HANDLER ( jupiter_port_dffe_r ) { return (readinputport (5)); } READ8_HANDLER ( jupiter_port_bffe_r ) { return (readinputport (6)); } READ8_HANDLER ( jupiter_port_7ffe_r ) { speaker_level_w(0,0); return (readinputport (7)); } WRITE8_HANDLER ( jupiter_port_fe_w ) { speaker_level_w(0,1); }