src/mess/drivers/ql.c
| r1370 | r1371 | |
| 3 | 3 | #include "cpu/m68000/m68000.h" |
| 4 | 4 | #include "devices/cartslot.h" |
| 5 | 5 | #include "includes/serial.h" |
| 6 | #include "sound/speaker.h" |
| 6 | 7 | #include "video/generic.h" |
| 7 | 8 | #include "video/zx8301.h" |
| 8 | 9 | #include "inputx.h" |
| r1370 | r1371 | |
| 17 | 18 | |
| 18 | 19 | TODO: |
| 19 | 20 | |
| 21 | - unicode for port char macros |
| 22 | - get rid of keyboard not 100% prompt |
| 23 | - microdrive simulation |
| 20 | 24 | - RTC register write |
| 21 | | - proper pound key code (£) |
| 22 | | - speaker sound |
| 23 | | - microdrive simulation |
| 24 | | - M68008 opcode reading interface |
| 25 | 25 | - serial data latching? |
| 26 | 26 | - transmit interrupt timing |
| 27 | 27 | - interface interrupt |
| 28 | 28 | - accurate screen timings |
| 29 | - ZX8301 cycle stealing |
| 29 | 30 | - emulate COMCTL properly |
| 30 | | - ZX8301 cycle stealing |
| 31 | 31 | |
| 32 | 32 | */ |
| 33 | 33 | |
| r1370 | r1371 | |
| 82 | 82 | int ser2_txd, ser2_dtr; |
| 83 | 83 | int netout, netin; |
| 84 | 84 | int mdrdw, mdselck, mdseld, erase, raw1, raw2; |
| 85 | int mdv_motor; |
| 85 | 86 | } zx8302; |
| 86 | 87 | |
| 87 | 88 | static emu_timer *zx8302_txd_timer, *zx8302_ipc_timer, *zx8302_rtc_timer, *zx8302_gap_timer; |
| r1370 | r1371 | |
| 158 | 159 | |
| 159 | 160 | static TIMER_CALLBACK( zx8302_gap_tick ) |
| 160 | 161 | { |
| 161 | | zx8302_interrupt(ZX8302_INT_GAP); |
| 162 | if (zx8302.mdv_motor) |
| 163 | { |
| 164 | zx8302_interrupt(ZX8302_INT_GAP); |
| 165 | } |
| 162 | 166 | } |
| 163 | 167 | |
| 164 | 168 | static READ8_HANDLER( zx8302_rtc_r ) |
| r1370 | r1371 | |
| 229 | 233 | timer_set(ATTOTIME_IN_NSEC(480), NULL, data, zx8302_delayed_ipc_command); |
| 230 | 234 | } |
| 231 | 235 | |
| 236 | /* |
| 237 | static int zx8302_get_selected_microdrive(void) |
| 238 | { |
| 239 | int i; |
| 240 | |
| 241 | for (i = 0; i < 8; i++) |
| 242 | { |
| 243 | if (BIT(zx8302.mdv_motor, i)) return 8 - i; |
| 244 | } |
| 245 | |
| 246 | return 0; |
| 247 | } |
| 248 | */ |
| 249 | |
| 232 | 250 | static WRITE8_HANDLER( zx8302_mdv_control_w ) |
| 233 | 251 | { |
| 234 | 252 | /* |
| 253 | |
| 254 | bit description |
| 255 | |
| 256 | 0 MDSELDH |
| 257 | 1 MDSELCKH |
| 258 | 2 MDRDWL |
| 259 | 3 ERASE |
| 260 | 4 |
| 261 | 5 |
| 262 | 6 |
| 263 | 7 |
| 264 | |
| 265 | */ |
| 266 | |
| 267 | /* |
| 235 | 268 | MDV control |
| 236 | 269 | at reset; and after data transfer of any mdv |
| 237 | 270 | (02 00) 8 times stop all motors |
| r1370 | r1371 | |
| 256 | 289 | get 4 bytes |
| 257 | 290 | (02 02) indication to skip PLL sequence: 6*00,2*ff |
| 258 | 291 | */ |
| 292 | |
| 293 | zx8302.mdseld = BIT(data, 0); |
| 294 | zx8302.mdselck = BIT(data, 1); |
| 295 | zx8302.mdrdw = BIT(data, 2) ? 0 : 1; |
| 296 | zx8302.erase = BIT(data, 3); |
| 297 | |
| 298 | // Microdrive selection shift register |
| 299 | |
| 300 | if (zx8302.mdselck) |
| 301 | { |
| 302 | zx8302.mdv_motor >>= 1; |
| 303 | zx8302.mdv_motor |= (zx8302.mdseld << 7); |
| 304 | |
| 305 | // logerror("MDV selected %u\n", zx8302_get_selected_microdrive()); |
| 306 | } |
| 307 | |
| 308 | // logerror("MDV control %x\n", data); |
| 259 | 309 | } |
| 260 | 310 | |
| 261 | 311 | static READ8_HANDLER( zx8302_irq_status_r ) |
| r1370 | r1371 | |
| 412 | 462 | break; |
| 413 | 463 | } |
| 414 | 464 | |
| 465 | speaker_level_w(0, BIT(data, 1)); |
| 466 | |
| 415 | 467 | ipc.ser2_cts = BIT(data, 4); |
| 416 | 468 | ipc.ser1_dtr = BIT(data, 5); |
| 417 | 469 | |
| r1370 | r1371 | |
| 807 | 859 | MDRV_PALETTE_INIT(zx8301) |
| 808 | 860 | MDRV_VIDEO_START(zx8301) |
| 809 | 861 | MDRV_VIDEO_UPDATE(zx8301) |
| 862 | |
| 863 | // sound hardware |
| 864 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 865 | MDRV_SOUND_ADD(SPEAKER, 0) |
| 866 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 810 | 867 | MACHINE_DRIVER_END |
| 811 | 868 | |
| 812 | 869 | static MACHINE_DRIVER_START( ql_ntsc ) |
| r1370 | r1371 | |
| 1043 | 1100 | /* Computer Drivers */ |
| 1044 | 1101 | |
| 1045 | 1102 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT CONFIG COMPANY FULLNAME FLAGS */ |
| 1046 | | COMP( 1984, ql, 0, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (UK)", GAME_NO_SOUND ) |
| 1047 | | COMP( 1985, ql_us, ql, 0, ql_ntsc, ql, 0, ql, "Sinclair Research Ltd", "QL (USA)", GAME_NO_SOUND ) |
| 1048 | | COMP( 1985, ql_es, ql, 0, ql, ql_es, 0, ql, "Sinclair Research Ltd", "QL (Spain)", GAME_NO_SOUND ) |
| 1049 | | COMP( 1985, ql_fr, ql, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (France)", GAME_NO_SOUND ) |
| 1050 | | COMP( 1985, ql_de, ql, 0, ql, ql_de, 0, ql, "Sinclair Research Ltd", "QL (Germany)", GAME_NO_SOUND ) |
| 1051 | | COMP( 1985, ql_it, ql, 0, ql, ql_it, 0, ql, "Sinclair Research Ltd", "QL (Italy)", GAME_NO_SOUND ) |
| 1052 | | COMP( 1985, ql_se, ql, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (Sweden)", GAME_NO_SOUND ) |
| 1103 | COMP( 1984, ql, 0, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (UK)", GAME_SUPPORTS_SAVE ) |
| 1104 | COMP( 1985, ql_us, ql, 0, ql_ntsc, ql, 0, ql, "Sinclair Research Ltd", "QL (USA)", GAME_SUPPORTS_SAVE ) |
| 1105 | COMP( 1985, ql_es, ql, 0, ql, ql_es, 0, ql, "Sinclair Research Ltd", "QL (Spain)", GAME_SUPPORTS_SAVE ) |
| 1106 | COMP( 1985, ql_fr, ql, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (France)", GAME_SUPPORTS_SAVE ) |
| 1107 | COMP( 1985, ql_de, ql, 0, ql, ql_de, 0, ql, "Sinclair Research Ltd", "QL (Germany)", GAME_SUPPORTS_SAVE ) |
| 1108 | COMP( 1985, ql_it, ql, 0, ql, ql_it, 0, ql, "Sinclair Research Ltd", "QL (Italy)", GAME_SUPPORTS_SAVE ) |
| 1109 | COMP( 1985, ql_se, ql, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (Sweden)", GAME_SUPPORTS_SAVE ) |
| 1053 | 1110 | COMP( 1985, ql_dk, ql, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (Denmark)", GAME_NOT_WORKING ) |
| 1054 | | COMP( 1985, ql_gr, ql, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (Greece)", GAME_NO_SOUND ) |
| 1111 | COMP( 1985, ql_gr, ql, 0, ql, ql, 0, ql, "Sinclair Research Ltd", "QL (Greece)", GAME_SUPPORTS_SAVE ) |