diff options
Diffstat (limited to 'src/mess/machine/jupiter.c')
-rw-r--r-- | src/mess/machine/jupiter.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/mess/machine/jupiter.c b/src/mess/machine/jupiter.c new file mode 100644 index 00000000000..e81c712bca4 --- /dev/null +++ b/src/mess/machine/jupiter.c @@ -0,0 +1,119 @@ +/*************************************************************************** + + machine.c + + Functions to emulate general aspects of the machine (RAM, ROM, interrupts, + I/O ports) + +***************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "imagedev/snapquik.h" +#include "includes/jupiter.h" + + + +/* Load in .ace files. These are memory images of 0x2000 to 0x7fff + and compressed as follows: + + ED 00 : End marker + ED <cnt> <byt> : repeat <byt> count <cnt:1-240> times + <byt> : <byt> +*/ + + +/****************************************************************************** + Snapshot Handling +******************************************************************************/ + +SNAPSHOT_LOAD(jupiter) +{ + UINT8 *RAM = image.device().machine().root_device().memregion("maincpu")->base(); + device_t *cpu = image.device().machine().device("maincpu"); + address_space *space = image.device().machine().device("maincpu")->memory().space(AS_PROGRAM); + unsigned char jupiter_repeat, jupiter_byte, loop; + int done=0, jupiter_index=0x2000; + + if (space->machine().root_device().ioport("CFG")->read()==0) + { + image.seterror(IMAGE_ERROR_INVALIDIMAGE, "At least 16KB RAM expansion required"); + image.message("At least 16KB RAM expansion required"); + return IMAGE_INIT_FAIL; + } + + logerror("Loading file %s.\r\n", image.filename()); + while (!done && (jupiter_index < 0x8001)) + { + image.fread( &jupiter_byte, 1); + if (jupiter_byte == 0xed) + { + image.fread(&jupiter_byte, 1); + switch (jupiter_byte) + { + case 0x00: + logerror("File loaded!\r\n"); + done = 1; + break; + case 0x01: + image.fread(&jupiter_byte, 1); + RAM[jupiter_index++] = jupiter_byte; + break; + default: + image.fread(&jupiter_repeat, 1); + for (loop = 0; loop < jupiter_byte; loop++) + RAM[jupiter_index++] = jupiter_repeat; + break; + } + } + else + RAM[jupiter_index++] = jupiter_byte; + } + + logerror("Decoded %X bytes.\r\n", jupiter_index-0x2000); + + if (!done) + { + image.seterror(IMAGE_ERROR_INVALIDIMAGE, "EOF marker not found"); + image.message("EOF marker not found"); + return IMAGE_INIT_FAIL; + } + + // patch CPU registers + // Some games do not follow the standard, and have rubbish in the CPU area. So, + // we check that some other bytes are correct. + // 2080 = memory size of original machine, should be 0000 or 8000 or C000. + // 2118 = new stack pointer, do not use if between 8000 and FF00. + + jupiter_index = RAM[0x2080] | (RAM[0x2081] << 8); + + if ((jupiter_index & 0x3FFF)==0) + { + cpu_set_reg(cpu, Z80_AF, RAM[0x2100] | (RAM[0x2101] << 8)); + cpu_set_reg(cpu, Z80_BC, RAM[0x2104] | (RAM[0x2105] << 8)); + cpu_set_reg(cpu, Z80_DE, RAM[0x2108] | (RAM[0x2109] << 8)); + cpu_set_reg(cpu, Z80_HL, RAM[0x210c] | (RAM[0x210d] << 8)); + cpu_set_reg(cpu, Z80_IX, RAM[0x2110] | (RAM[0x2111] << 8)); + cpu_set_reg(cpu, Z80_IY, RAM[0x2114] | (RAM[0x2115] << 8)); + cpu_set_reg(cpu, STATE_GENPC, RAM[0x211c] | (RAM[0x211d] << 8)); + cpu_set_reg(cpu, Z80_AF2, RAM[0x2120] | (RAM[0x2121] << 8)); + cpu_set_reg(cpu, Z80_BC2, RAM[0x2124] | (RAM[0x2125] << 8)); + cpu_set_reg(cpu, Z80_DE2, RAM[0x2128] | (RAM[0x2129] << 8)); + cpu_set_reg(cpu, Z80_HL2, RAM[0x212c] | (RAM[0x212d] << 8)); + cpu_set_reg(cpu, Z80_IM, RAM[0x2130]); + cpu_set_reg(cpu, Z80_IFF1, RAM[0x2134]); + cpu_set_reg(cpu, Z80_IFF2, RAM[0x2138]); + cpu_set_reg(cpu, Z80_I, RAM[0x213c]); + cpu_set_reg(cpu, Z80_R, RAM[0x2140]); + + if ((RAM[0x2119] < 0x80) || !jupiter_index) + cpu_set_reg(cpu, STATE_GENSP, RAM[0x2118] | (RAM[0x2119] << 8)); + } + + /* Copy data to the address space */ + for (jupiter_index = 0x2000; jupiter_index < 0x8000; jupiter_index++) + space->write_byte(jupiter_index, RAM[jupiter_index]); + + return IMAGE_INIT_PASS; +} + |