src/mess/drivers/spectrum.c
| r7486 | r7487 | |
| 120 | 120 | 128K/+2 Bank switches with port 7ffd only. |
| 121 | 121 | +3/+2a Bank switches with both ports. |
| 122 | 122 | |
| 123 | | Notes: |
| 124 | | 1. No contented memory. |
| 125 | | 2. No hi-res colour effects (need contended memory first for accurate timing). |
| 126 | | 3. Multiface 1 and Interface 1 not supported. |
| 127 | | 4. Horace and the Spiders cartridge doesn't run properly. |
| 128 | | 5. Tape images not supported: |
| 129 | | .TZX, .SPC, .ITM, .PAN, .TAP(Warajevo), .VOC, .ZXS. |
| 130 | | 6. Snapshot images not supported: |
| 131 | | .ACH, .PRG, .RAW, .SEM, .SIT, .SNX, .ZX, .ZXS, .ZX82. |
| 132 | | 7. 128K emulation is not perfect - the 128K machines crash and hang while |
| 123 | TODO: (the best resource for ZX Spectrum HW informations is the http://www.zxdesign.info/ |
| 124 | blog, a project devored to reverse-engineer the ZX Spectrum in h/w). |
| 125 | |
| 126 | 1. No contended memory. The different Spectrum models have different contention timings |
| 127 | Updated info can be found here: http://scratchpad.wikia.com/wiki/Contended_memory |
| 128 | Of course, neither "late timing" contention effects are emulated. |
| 129 | |
| 130 | 2. Russian models (at least Pentagon and Scorpion) reportedly don't have contended memory. |
| 131 | Information about screen timings are here: http://www.worldofspectrum.org/rusfaq/ |
| 132 | |
| 133 | 3. Similarly, contended I/O is not emulated: http://scratchpad.wikia.com/wiki/Contended_IO |
| 134 | |
| 135 | 4. Finally, the Floating Bus implementation is incomplete: http://scratchpad.wikia.com/wiki/Floating_bus |
| 136 | The page hosts a couple of testing programs. |
| 137 | |
| 138 | 5. A NTSC model exists: it's not the Timex, but a plain ZX Spectrum made for the Chilean market: |
| 139 | http://scratchpad.wikia.com/wiki/NTSC_Spectrum |
| 140 | |
| 141 | 6. No hi-res colour effects (need contended memory first for accurate timing). |
| 142 | |
| 143 | 7. Keyboard autorepeat is broken. |
| 144 | |
| 145 | 8. Port decoding on all models needs to be checked and, in case, corrected. |
| 146 | |
| 147 | 9. The actual Issue 2/3 effect is a bit more complicated than implemented: |
| 148 | http://piters.tripod.com/cassport.htm for an explanation/test suite. |
| 149 | |
| 150 | 10. Tape formats not supported: |
| 151 | .001, .CSW, .LTP, .PZX, .SPC, .STA, .ITM/.PAN, .TAP(Warajevo), .VOC, .ZXS, .ZXT |
| 152 | |
| 153 | 11. Disk formats not supported: |
| 154 | .CPD, .DSK, .FDD, .FDI, .HDF, .IMG, .MDR, .MGT, .SCL, .TRD, .ZXD |
| 155 | |
| 156 | 12. 128K emulation is not perfect - the 128K machines crash and hang while |
| 133 | 157 | running quite a lot of games. |
| 134 | | 8. Disk errors occur on some +3 games. |
| 135 | | 9. Video hardware of all machines is timed incorrectly. |
| 136 | | 10. EXROM and HOME cartridges are not emulated. |
| 137 | | 11. The TK90X and TK95 roms output 0 to port #df on start up. |
| 138 | | 12. The purpose of this port is unknown (probably display mode as TS2068) and |
| 139 | | thus is not emulated. |
| 140 | 158 | |
| 159 | 13. Disk errors occur on some +3 games. |
| 160 | |
| 161 | 14. EXROM and HOME cartridges are not emulated on Timex machines. |
| 162 | |
| 163 | 15. The TK90X and TK95 roms output 0 to port #df on start up. The purpose of this port is unknown |
| 164 | (probably display mode as TS2068) and thus is not emulated. |
| 165 | |
| 141 | 166 | Very detailed infos about the ZX Spectrum +3e can be found at |
| 167 | http://www.worldofspectrum.org/zxplus3e/ |
| 142 | 168 | |
| 143 | | http://www.z88forever.org.uk/zxplus3e/ |
| 144 | | |
| 145 | 169 | *******************************************************************************/ |
| 146 | 170 | |
| 147 | 171 | #include "emu.h" |
| r7486 | r7487 | |
| 153 | 177 | #include "devices/snapquik.h" |
| 154 | 178 | #include "devices/cartslot.h" |
| 155 | 179 | #include "devices/cassette.h" |
| 180 | #include "devices/messram.h" |
| 156 | 181 | #include "formats/tzx_cas.h" |
| 157 | 182 | #include "formats/spec_snqk.h" |
| 158 | 183 | |
| 184 | |
| 159 | 185 | /****************************************************************************************************/ |
| 160 | 186 | /* Spectrum 48k functions */ |
| 161 | 187 | |
| r7486 | r7487 | |
| 208 | 234 | return address; |
| 209 | 235 | } |
| 210 | 236 | |
| 211 | | MACHINE_RESET( spectrum ) |
| 212 | | { |
| 213 | | spectrum_state *state = (spectrum_state *)machine->driver_data; |
| 214 | | const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 215 | | |
| 216 | | memory_set_direct_update_handler(space, spectrum_direct); |
| 217 | | state->port_7ffd_data = -1; |
| 218 | | state->port_1ffd_data = -1; |
| 219 | | } |
| 220 | | |
| 221 | | static ADDRESS_MAP_START (spectrum_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 222 | | AM_RANGE(0x0000, 0x3fff) AM_ROM |
| 223 | | AM_RANGE(0x4000, 0x5aff) AM_RAM AM_BASE_MEMBER(spectrum_state,video_ram) |
| 224 | | AM_RANGE(0x5b00, 0xffff) AM_RAM |
| 225 | | ADDRESS_MAP_END |
| 226 | | |
| 227 | 237 | /* KT: more accurate keyboard reading */ |
| 228 | 238 | /* DJR: Spectrum+ keys added */ |
| 229 | 239 | READ8_HANDLER(spectrum_port_fe_r) |
| r7486 | r7487 | |
| 313 | 323 | return input_port_read(space->machine, "MIKROGEN") | (0xff^0x1f); |
| 314 | 324 | } |
| 315 | 325 | |
| 316 | | static READ8_HANDLER ( spectrum_port_ula_r ) |
| 326 | static READ8_HANDLER ( spectrum_port_ula_r ) |
| 317 | 327 | { |
| 318 | 328 | spectrum_state *state = (spectrum_state *)space->machine->driver_data; |
| 319 | 329 | int vpos = video_screen_get_vpos(space->machine->primary_screen); |
| r7486 | r7487 | |
| 321 | 331 | return vpos<193 ? state->video_ram[(vpos&0xf8)<<2]:0xff; |
| 322 | 332 | } |
| 323 | 333 | |
| 334 | /* Memory Maps */ |
| 335 | |
| 336 | static ADDRESS_MAP_START (spectrum_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 337 | AM_RANGE(0x0000, 0x3fff) AM_ROM |
| 338 | AM_RANGE(0x4000, 0x5aff) AM_RAM AM_BASE_MEMBER(spectrum_state,video_ram) |
| 339 | // AM_RANGE(0x5b00, 0x7fff) AM_RAM |
| 340 | // AM_RANGE(0x8000, 0xffff) AM_RAM |
| 341 | ADDRESS_MAP_END |
| 342 | |
| 324 | 343 | /* ports are not decoded full. |
| 325 | 344 | The function decodes the ports appropriately */ |
| 326 | 345 | static ADDRESS_MAP_START (spectrum_io, ADDRESS_SPACE_IO, 8) |
| r7486 | r7487 | |
| 331 | 350 | AM_RANGE(0x01, 0x01) AM_READ(spectrum_port_ula_r) AM_MIRROR(0xfffe) |
| 332 | 351 | ADDRESS_MAP_END |
| 333 | 352 | |
| 353 | /* Input ports */ |
| 354 | |
| 334 | 355 | /****************************************************************************************************/ |
| 335 | 356 | |
| 336 | 357 | static INPUT_PORTS_START( spec_joys ) |
| r7486 | r7487 | |
| 497 | 518 | PORT_BIT(0xf3, IP_ACTIVE_LOW, IPT_UNUSED) |
| 498 | 519 | INPUT_PORTS_END |
| 499 | 520 | |
| 521 | /* Machine initialization */ |
| 500 | 522 | |
| 523 | DRIVER_INIT( spectrum ) |
| 524 | { |
| 525 | const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 526 | UINT8 *ram = messram_get_ptr(devtag_get_device(machine, "messram")); |
| 527 | |
| 528 | switch (messram_get_size(devtag_get_device(machine, "messram"))) |
| 529 | { |
| 530 | case 48*1024: |
| 531 | memory_install_ram(space, 0x8000, 0xffff, 0, 0, ram); // Fall through |
| 532 | case 16*1024: |
| 533 | memory_install_ram(space, 0x5b00, 0x7fff, 0, 0, ram); |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | MACHINE_RESET( spectrum ) |
| 538 | { |
| 539 | spectrum_state *state = (spectrum_state *)machine->driver_data; |
| 540 | const address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 541 | |
| 542 | memory_set_direct_update_handler(space, spectrum_direct); |
| 543 | state->port_7ffd_data = -1; |
| 544 | state->port_1ffd_data = -1; |
| 545 | } |
| 546 | |
| 501 | 547 | /* F4 Character Displayer */ |
| 502 | 548 | static const gfx_layout spectrum_charlayout = |
| 503 | 549 | { |
| r7486 | r7487 | |
| 529 | 575 | (cassette_state)(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED) |
| 530 | 576 | }; |
| 531 | 577 | |
| 532 | | MACHINE_DRIVER_START( spectrum ) |
| 578 | MACHINE_DRIVER_START( spectrum_common ) |
| 533 | 579 | |
| 534 | 580 | MDRV_DRIVER_DATA( spectrum_state ) |
| 535 | 581 | |
| 536 | 582 | /* basic machine hardware */ |
| 537 | | MDRV_CPU_ADD("maincpu", Z80, 3500000) /* 3.5 MHz */ |
| 583 | MDRV_CPU_ADD("maincpu", Z80, X1 / 4) /* This is verified only for the ZX Spectum. Other clones are reported to have different clocks */ |
| 538 | 584 | MDRV_CPU_PROGRAM_MAP(spectrum_mem) |
| 539 | 585 | MDRV_CPU_IO_MAP(spectrum_io) |
| 540 | 586 | MDRV_CPU_VBLANK_INT("screen", spec_interrupt) |
| r7486 | r7487 | |
| 565 | 611 | |
| 566 | 612 | /* devices */ |
| 567 | 613 | MDRV_SNAPSHOT_ADD("snapshot", spectrum, "ach,frz,plusd,prg,sem,sit,sna,snp,snx,sp,z80,zx", 0) |
| 568 | | MDRV_QUICKLOAD_ADD("quickload", spectrum, "scr", 0) |
| 614 | MDRV_QUICKLOAD_ADD("quickload", spectrum, "raw,scr", 2) // The delay prevents the screen from being cleared by the RAM test at boot |
| 569 | 615 | MDRV_CASSETTE_ADD( "cassette", spectrum_cassette_config ) |
| 570 | 616 | |
| 571 | 617 | /* cartridge */ |
| r7486 | r7487 | |
| 574 | 620 | MDRV_CARTSLOT_NOT_MANDATORY |
| 575 | 621 | MACHINE_DRIVER_END |
| 576 | 622 | |
| 623 | MACHINE_DRIVER_START( spectrum ) |
| 624 | MDRV_IMPORT_FROM( spectrum_common ) |
| 625 | |
| 626 | /* internal ram */ |
| 627 | MDRV_RAM_ADD("messram") // This configuration is verified only for the original ZX Spectrum. |
| 628 | MDRV_RAM_DEFAULT_SIZE("48K") // It's likely, but still to be checked, that many clones were produced only |
| 629 | MDRV_RAM_EXTRA_OPTIONS("16K") // in the 48k configuration, while others have extra memory (80k, 128K, 1024K) |
| 630 | MDRV_RAM_DEFAULT_VALUE(0xff) // available via bankswitching. |
| 631 | MACHINE_DRIVER_END |
| 632 | |
| 577 | 633 | /*************************************************************************** |
| 578 | 634 | |
| 579 | 635 | Game driver(s) |
| r7486 | r7487 | |
| 827 | 883 | ROM_END |
| 828 | 884 | |
| 829 | 885 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ |
| 830 | | COMP( 1982, spectrum, 0, 0, spectrum, spectrum, 0, "Sinclair Research", "ZX Spectrum" , 0) |
| 831 | | COMP( 1987, spec80k, spectrum, 0, spectrum, spectrum, 0, "", "ZX Spectrum 80K" , GAME_UNOFFICIAL) |
| 832 | | COMP( 1995, specide, spectrum, 0, spectrum, spectrum, 0, "", "ZX Spectrum IDE" , GAME_UNOFFICIAL) |
| 833 | | COMP( 1986, inves, spectrum, 0, spectrum, spec_plus, 0, "Investronica", "Inves Spectrum 48K+" , 0) |
| 834 | | COMP( 1985, tk90x, spectrum, 0, spectrum, spectrum, 0, "Micro Digital", "TK 90X Color Computer" , 0) |
| 835 | | COMP( 1986, tk95, spectrum, 0, spectrum, spec_plus, 0, "Micro Digital", "TK 95 Color Computer" , 0) |
| 836 | | COMP( 1985, hc85, spectrum, 0, spectrum, spectrum, 0, "ICE-Felix", "HC-85" , 0) |
| 837 | | COMP( 1988, hc88, spectrum, 0, spectrum, spectrum, 0, "ICE-Felix", "HC-88" , GAME_NOT_WORKING) |
| 838 | | COMP( 1990, hc90, spectrum, 0, spectrum, spectrum, 0, "ICE-Felix", "HC-90" , 0) |
| 839 | | COMP( 1991, hc91, spectrum, 0, spectrum, spec_plus, 0, "ICE-Felix", "HC-91" , 0) |
| 840 | | COMP( 1988, cobra, spectrum, 0, spectrum, spectrum, 0, "ITCI", "Cobra" , GAME_NOT_WORKING) |
| 841 | | COMP( 1988, cobra80, spectrum, 0, spectrum, spectrum, 0, "ITCI", "Cobra 80K" , GAME_NOT_WORKING) |
| 842 | | COMP( 1987, cip01, spectrum, 0, spectrum, spectrum, 0, "Electronica", "CIP-01" , 0) // keyboard should be spectrum, but image was not clear |
| 843 | | COMP( 1988, cip03, spectrum, 0, spectrum, spectrum, 0, "Electronica", "CIP-03" , 0) // keyboard should be spectrum, but image was not clear |
| 844 | | COMP( 1990, jet, spectrum, 0, spectrum, spectrum, 0, "Electromagnetica", "JET" , 0) // keyboard should be spectrum, but image was not clear |
| 845 | | COMP( 1987, dgama87, spectrum, 0, spectrum, spectrum, 0, "Didaktik Skalica", "Didaktik Gama 87" , 0) |
| 846 | | COMP( 1988, dgama88, spectrum, 0, spectrum, spectrum, 0, "Didaktik Skalica", "Didaktik Gama 88" , 0) |
| 847 | | COMP( 1989, dgama89, spectrum, 0, spectrum, spectrum, 0, "Didaktik Skalica", "Didaktik Gama 89" , 0) |
| 848 | | COMP( 1990, didakt90, spectrum, 0, spectrum, spectrum, 0, "Didaktik Skalica", "Didaktik 90" , 0) |
| 849 | | COMP( 1991, didakm91, spectrum, 0, spectrum, spec_plus, 0, "Didaktik Skalica", "Didaktik M 91" , 0) |
| 850 | | COMP( 1992, didaktk, spectrum, 0, spectrum, spec_plus, 0, "Didaktik Skalica", "Didaktik Kompakt" , 0) |
| 851 | | COMP( 1993, didakm93, spectrum, 0, spectrum, spec_plus, 0, "Didaktik Skalica", "Didaktik M 93" , 0) |
| 852 | | COMP( 1988, mistrum, spectrum, 0, spectrum, spectrum, 0, "Amaterske RADIO", "Mistrum" , 0) // keyboard could be spectrum in some models (since it was a build-yourself design) |
| 853 | | COMP( 1990, blitz, spectrum, 0, spectrum, spectrum, 0, "", "Blic" , 0) // no keyboard images found |
| 854 | | COMP( 1990, byte, spectrum, 0, spectrum, spectrum, 0, "", "Byte" , 0) // no keyboard images found |
| 855 | | COMP( 199?, orizon, spectrum, 0, spectrum, spectrum, 0, "", "Orizon-Micro" , 0) // no keyboard images found |
| 856 | | COMP( 1993, quorum48, spectrum, 0, spectrum, spectrum, 0, "", "Kvorum 48K" , GAME_NOT_WORKING) |
| 857 | | COMP( 1993, magic6, spectrum, 0, spectrum, spectrum, 0, "", "Magic 6" , GAME_NOT_WORKING) // keyboard should be spectrum, but image was not clear |
| 858 | | COMP( 1990, compani1, spectrum, 0, spectrum, spectrum, 0, "", "Kompanion 1" , 0) // no keyboard images found |
| 859 | | COMP( 1990, spektrbk, spectrum, 0, spectrum, spectrum, 0, "", "Spektr BK-001" , 0) |
| 860 | | COMP( 1990, zvezda, spectrum, 0, spectrum, spectrum, 0, "", "Zvezda" , 0) |
| 886 | COMP( 1982, spectrum, 0, 0, spectrum, spectrum, spectrum, "Sinclair Research", "ZX Spectrum" , 0) |
| 887 | COMP( 1987, spec80k, spectrum, 0, spectrum, spectrum, spectrum, "", "ZX Spectrum 80K" , GAME_UNOFFICIAL) |
| 888 | COMP( 1995, specide, spectrum, 0, spectrum, spectrum, spectrum, "", "ZX Spectrum IDE" , GAME_UNOFFICIAL) |
| 889 | COMP( 1986, inves, spectrum, 0, spectrum, spec_plus, spectrum, "Investronica", "Inves Spectrum 48K+" , 0) |
| 890 | COMP( 1985, tk90x, spectrum, 0, spectrum, spectrum, spectrum, "Micro Digital", "TK 90X Color Computer" , 0) |
| 891 | COMP( 1986, tk95, spectrum, 0, spectrum, spec_plus, spectrum, "Micro Digital", "TK 95 Color Computer" , 0) |
| 892 | COMP( 1985, hc85, spectrum, 0, spectrum, spectrum, spectrum, "ICE-Felix", "HC-85" , 0) |
| 893 | COMP( 1988, hc88, spectrum, 0, spectrum, spectrum, spectrum, "ICE-Felix", "HC-88" , GAME_NOT_WORKING) |
| 894 | COMP( 1990, hc90, spectrum, 0, spectrum, spectrum, spectrum, "ICE-Felix", "HC-90" , 0) |
| 895 | COMP( 1991, hc91, spectrum, 0, spectrum, spec_plus, spectrum, "ICE-Felix", "HC-91" , 0) |
| 896 | COMP( 1988, cobra, spectrum, 0, spectrum, spectrum, spectrum, "ITCI", "Cobra" , GAME_NOT_WORKING) |
| 897 | COMP( 1988, cobra80, spectrum, 0, spectrum, spectrum, spectrum, "ITCI", "Cobra 80K" , GAME_NOT_WORKING) |
| 898 | COMP( 1987, cip01, spectrum, 0, spectrum, spectrum, spectrum, "Electronica", "CIP-01" , 0) // keyboard should be spectrum, but image was not clear |
| 899 | COMP( 1988, cip03, spectrum, 0, spectrum, spectrum, spectrum, "Electronica", "CIP-03" , 0) // keyboard should be spectrum, but image was not clear |
| 900 | COMP( 1990, jet, spectrum, 0, spectrum, spectrum, spectrum, "Electromagnetica", "JET" , 0) // keyboard should be spectrum, but image was not clear |
| 901 | COMP( 1987, dgama87, spectrum, 0, spectrum, spectrum, spectrum, "Didaktik Skalica", "Didaktik Gama 87" , 0) |
| 902 | COMP( 1988, dgama88, spectrum, 0, spectrum, spectrum, spectrum, "Didaktik Skalica", "Didaktik Gama 88" , 0) |
| 903 | COMP( 1989, dgama89, spectrum, 0, spectrum, spectrum, spectrum, "Didaktik Skalica", "Didaktik Gama 89" , 0) |
| 904 | COMP( 1990, didakt90, spectrum, 0, spectrum, spectrum, spectrum, "Didaktik Skalica", "Didaktik 90" , 0) |
| 905 | COMP( 1991, didakm91, spectrum, 0, spectrum, spec_plus, spectrum, "Didaktik Skalica", "Didaktik M 91" , 0) |
| 906 | COMP( 1992, didaktk, spectrum, 0, spectrum, spec_plus, spectrum, "Didaktik Skalica", "Didaktik Kompakt" , 0) |
| 907 | COMP( 1993, didakm93, spectrum, 0, spectrum, spec_plus, spectrum, "Didaktik Skalica", "Didaktik M 93" , 0) |
| 908 | COMP( 1988, mistrum, spectrum, 0, spectrum, spectrum, spectrum, "Amaterske RADIO", "Mistrum" , 0) // keyboard could be spectrum in some models (since it was a build-yourself design) |
| 909 | COMP( 1990, blitz, spectrum, 0, spectrum, spectrum, spectrum, "", "Blic" , 0) // no keyboard images found |
| 910 | COMP( 1990, byte, spectrum, 0, spectrum, spectrum, spectrum, "", "Byte" , 0) // no keyboard images found |
| 911 | COMP( 199?, orizon, spectrum, 0, spectrum, spectrum, spectrum, "", "Orizon-Micro" , 0) // no keyboard images found |
| 912 | COMP( 1993, quorum48, spectrum, 0, spectrum, spectrum, spectrum, "", "Kvorum 48K" , GAME_NOT_WORKING) |
| 913 | COMP( 1993, magic6, spectrum, 0, spectrum, spectrum, spectrum, "", "Magic 6" , GAME_NOT_WORKING) // keyboard should be spectrum, but image was not clear |
| 914 | COMP( 1990, compani1, spectrum, 0, spectrum, spectrum, spectrum, "", "Kompanion 1" , 0) // no keyboard images found |
| 915 | COMP( 1990, spektrbk, spectrum, 0, spectrum, spectrum, spectrum, "", "Spektr BK-001" , 0) |
| 916 | COMP( 1990, zvezda, spectrum, 0, spectrum, spectrum, spectrum, "", "Zvezda" , 0) |