src/mess/drivers/x1.c
| r5502 | r5503 | |
| 1 | | /*************************************************************************** |
| 1 | /************************************************************************************************ |
| 2 | 2 | |
| 3 | | Sharp X1 |
| 3 | Sharp X1 (c) 1983 Sharp Corporation |
| 4 | 4 | |
| 5 | | 05/2009 Skeleton driver. |
| 5 | preliminary driver by Angelo Salese |
| 6 | 6 | |
| 7 | | ============= X1 series ============= |
| 7 | TODO: |
| 8 | - Understand how keyboard works and decap/dump the keyboard MCU if possible; |
| 9 | - Hook-up image formats; |
| 10 | - Video part is bare minimum, chances are that's probably a tilemap/bitmap nightmare; |
| 11 | - Sort out / redump the gfx roms; |
| 8 | 12 | |
| 13 | ================================================================================================= |
| 14 | |
| 9 | 15 | X1 (CZ-800C) - November, 1982 |
| 10 | 16 | * CPU: z80A @ 4MHz, 80C49 x 2 (one for key scan, the other for TV & Cas Ctrl) |
| 11 | 17 | * ROM: IPL (4KB) + chargen (2KB) |
| r5502 | r5503 | |
| 104 | 110 | BASIC has to be loaded from external media (tape or disk), the |
| 105 | 111 | computer only has an Initial Program Loader (IPL) |
| 106 | 112 | |
| 107 | | TODO: everything, in particular to sort out the BIOS dumps |
| 108 | | (especially CGROM dumps). Also, notice this is a color computer, |
| 109 | | despite the skeleton code says it's black ad white |
| 113 | ************************************************************************************************/ |
| 110 | 114 | |
| 111 | | ****************************************************************************/ |
| 112 | | |
| 113 | 115 | #include "driver.h" |
| 114 | 116 | #include "cpu/z80/z80.h" |
| 115 | 117 | #include "machine/8255ppi.h" |
| r5502 | r5503 | |
| 123 | 125 | |
| 124 | 126 | static VIDEO_UPDATE( x1 ) |
| 125 | 127 | { |
| 126 | | const gfx_element *gfx = screen->machine->gfx[0]; |
| 127 | | int count = 0; |
| 128 | | |
| 129 | 128 | int y,x; |
| 130 | 129 | |
| 131 | 130 | for (y=0;y<25;y++) |
| 132 | 131 | { |
| 133 | 132 | for (x=0;x<40;x++) |
| 134 | 133 | { |
| 135 | | int tile = videoram[count]; |
| 136 | | int color = colorram[count]; |
| 134 | int tile = videoram[x+(y*40)]; |
| 135 | int color = colorram[x+(y*40)] & 0x3f; |
| 136 | int width = (colorram[x+(y*40)] & 0x80)>>7; |
| 137 | 137 | |
| 138 | | //int colour = tile>>12; |
| 139 | | drawgfx_opaque(bitmap,cliprect,gfx,tile,color,0,0,x*8,y*8); |
| 140 | | |
| 141 | | count++; |
| 138 | drawgfx_opaque(bitmap,cliprect,screen->machine->gfx[width],tile,color,0,0,(x/(width+1))*8*(width+1),y*8); |
| 142 | 139 | } |
| 143 | 140 | } |
| 144 | 141 | |
| 145 | 142 | return 0; |
| 146 | 143 | } |
| 147 | 144 | |
| 145 | |
| 146 | |
| 147 | static UINT8 sub_cmd,sub_val; |
| 148 | |
| 149 | /* |
| 150 | Keyboard MCU simulation |
| 151 | */ |
| 152 | |
| 153 | static READ8_HANDLER( sub_io_r ) |
| 154 | { |
| 155 | //printf("R\n"); |
| 156 | return sub_val; |
| 157 | } |
| 158 | |
| 159 | static WRITE8_HANDLER( sub_io_w ) |
| 160 | { |
| 161 | static UINT32 test; |
| 162 | |
| 163 | /* TODO: check sub-routine at $10e */ |
| 164 | /* $17a -> floppy? */ |
| 165 | /* $094 -> ROM */ |
| 166 | /* $0c0 -> timer*/ |
| 167 | /* $052 -> cmt */ |
| 168 | /* $0f5 -> reload sub-routine? */ |
| 169 | test = input_code_pressed(KEYCODE_C) ? 0x02 : 0x00; //temp kludge |
| 170 | |
| 171 | switch(data) |
| 172 | { |
| 173 | case 0xe6: sub_val = 0; break; //RTC timer? |
| 174 | case 0xe8: sub_val = sub_cmd; break; |
| 175 | case 0xeb: sub_val = test; break; //used on device select |
| 176 | //case 0xed: sub_val = test; break; |
| 177 | //case 0xef: sub_val = test; break; //used on timer select? |
| 178 | #if 0 |
| 179 | default: |
| 180 | { |
| 181 | if(data > 0xe0 && data <= 0xef) |
| 182 | printf("%02x CMD\n",data); |
| 183 | } |
| 184 | #endif |
| 185 | } |
| 186 | sub_cmd = data; |
| 187 | } |
| 188 | |
| 189 | static UINT8 rom_index[3]; |
| 190 | |
| 191 | static READ8_HANDLER( x1_rom_r ) |
| 192 | { |
| 193 | //UINT8 *ROM = memory_region(space->machine, "rom"); |
| 194 | |
| 195 | // popmessage("%06x",rom_index[0]<<16|rom_index[1]<<8|rom_index[2]<<0); |
| 196 | |
| 197 | return 0; //ROM[rom_index[0]<<16|rom_index[1]<<8|rom_index[2]<<0]; |
| 198 | } |
| 199 | |
| 200 | static WRITE8_HANDLER( x1_rom_w ) |
| 201 | { |
| 202 | rom_index[offset] = data; |
| 203 | } |
| 204 | |
| 205 | static WRITE8_HANDLER( rom_bank_0_w ) |
| 206 | { |
| 207 | UINT8 *ROM = memory_region(space->machine, "maincpu"); |
| 208 | |
| 209 | memory_set_bankptr(space->machine, 1, &ROM[0x10000]); |
| 210 | } |
| 211 | |
| 212 | static WRITE8_HANDLER( rom_bank_1_w ) |
| 213 | { |
| 214 | UINT8 *ROM = memory_region(space->machine, "maincpu"); |
| 215 | |
| 216 | memory_set_bankptr(space->machine, 1, &ROM[0x00000]); |
| 217 | } |
| 218 | |
| 219 | static WRITE8_HANDLER( rom_data_w ) |
| 220 | { |
| 221 | UINT8 *ROM = memory_region(space->machine, "maincpu"); |
| 222 | |
| 223 | ROM[0x10000+offset] = data; |
| 224 | } |
| 225 | |
| 226 | |
| 148 | 227 | static ADDRESS_MAP_START( x1_mem, ADDRESS_SPACE_PROGRAM, 8 ) |
| 149 | 228 | ADDRESS_MAP_UNMAP_HIGH |
| 150 | | AM_RANGE(0x0000, 0x0fff) AM_ROM |
| 229 | AM_RANGE(0x0000, 0x7fff) AM_ROMBANK(1) AM_WRITE(rom_data_w) |
| 151 | 230 | AM_RANGE(0x8000, 0xffff) AM_RAM |
| 152 | 231 | ADDRESS_MAP_END |
| 153 | 232 | |
| r5502 | r5503 | |
| 155 | 234 | ADDRESS_MAP_UNMAP_HIGH |
| 156 | 235 | // AM_RANGE(0x0700, 0x0701) AM_WRITENOP //YM-2151 reg/data |
| 157 | 236 | // AM_RANGE(0x0704, 0x0707) AM_NOP //ctc regs |
| 237 | AM_RANGE(0x0e00, 0x0e02) AM_WRITE(x1_rom_w) |
| 238 | AM_RANGE(0x0e03, 0x0e03) AM_READ(x1_rom_r) |
| 158 | 239 | // AM_RANGE(0x0e80, 0x0e82) AM_WRITENOP //kanji registers? |
| 159 | 240 | // AM_RANGE(0x0ff8, 0x0fff) AM_WRITENOP //fdc registers |
| 160 | 241 | // AM_RANGE(0x1000, 0x12ff) AM_RAM //paletteram |
| r5502 | r5503 | |
| 162 | 243 | // AM_RANGE(0x1400, 0x17ff) AM_RAM //pcg? |
| 163 | 244 | AM_RANGE(0x1800, 0x1800) AM_DEVWRITE("crtc", mc6845_address_w) |
| 164 | 245 | AM_RANGE(0x1801, 0x1801) AM_DEVWRITE("crtc", mc6845_register_w) |
| 165 | | // AM_RANGE(0x1900, 0x19ff) AM_NOP //sub port, mirrored |
| 246 | AM_RANGE(0x1900, 0x19ff) AM_READWRITE(sub_io_r,sub_io_w) //sub port comms, mirrored |
| 166 | 247 | AM_RANGE(0x1a00, 0x1a03) AM_MIRROR(0xfc) AM_DEVREADWRITE("ppi8255_0", ppi8255_r, ppi8255_w) //8255, mirrored |
| 167 | 248 | AM_RANGE(0x1b00, 0x1bff) AM_DEVWRITE("ay", ay8910_data_w) //PSG / ay-3-8910 data port |
| 168 | 249 | AM_RANGE(0x1c00, 0x1cff) AM_DEVWRITE("ay", ay8910_address_w) //PSG / ay-3-8910 reg port |
| 169 | | // AM_RANGE(0x1d00, 0x1dff) AM_WRITENOP //ROM bankswitch = 1 |
| 170 | | // AM_RANGE(0x1e00, 0x1eff) AM_WRITENOP //ROM bankswitch = 0 |
| 250 | AM_RANGE(0x1d00, 0x1dff) AM_WRITE(rom_bank_1_w) //ROM bankswitch = 1 |
| 251 | AM_RANGE(0x1e00, 0x1eff) AM_WRITE(rom_bank_0_w) //ROM bankswitch = 0 |
| 171 | 252 | // AM_RANGE(0x1f80, 0x1f8f) AM_WRITENOP //dma |
| 172 | 253 | // AM_RANGE(0x1f90, 0x1f93) AM_NOP //sio |
| 173 | 254 | // AM_RANGE(0x1fa0, 0x1fa3) AM_NOP //ctc regs |
| r5502 | r5503 | |
| 189 | 270 | 8*8 |
| 190 | 271 | }; |
| 191 | 272 | |
| 273 | static const gfx_layout x1_chars_8wx8 = |
| 274 | { |
| 275 | 16,8, |
| 276 | RGN_FRAC(1,1), |
| 277 | 1, |
| 278 | { 0 }, |
| 279 | { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 }, |
| 280 | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, |
| 281 | 8*8 |
| 282 | }; |
| 283 | |
| 192 | 284 | static const gfx_layout x1_chars_16x16 = |
| 193 | 285 | { |
| 194 | 286 | 16,16, |
| r5502 | r5503 | |
| 203 | 295 | /* TODO: separe the different x1 decodings accordingly */ |
| 204 | 296 | static GFXDECODE_START( x1 ) |
| 205 | 297 | GFXDECODE_ENTRY( "cgrom", 0x00000, x1_chars_8x8, 0, 0x40 ) |
| 206 | | GFXDECODE_ENTRY( "cgrom", 0x00000, x1_chars_16x16, 0, 0x40 ) //only x1turboz uses this so far |
| 298 | GFXDECODE_ENTRY( "cgrom", 0x00000, x1_chars_8wx8, 0, 0x40 ) |
| 299 | GFXDECODE_ENTRY( "cgrom", 0x01800, x1_chars_16x16, 0, 0x40 ) //only x1turboz uses this so far |
| 207 | 300 | GFXDECODE_ENTRY( "kanji", 0x27000, x1_chars_16x16, 0, 0x40 ) //needs to be checked when the ROM will be redumped |
| 208 | 301 | GFXDECODE_END |
| 209 | 302 | |
| r5502 | r5503 | |
| 225 | 318 | palette_set_color_rgb(machine, 0x200+i, pal1bit(i >> 2), pal1bit(i >> 1), pal1bit(i >> 0)); |
| 226 | 319 | } |
| 227 | 320 | |
| 228 | | static MACHINE_RESET( x1 ) |
| 229 | | { |
| 230 | | } |
| 321 | static UINT8 hres_320,io_switch; |
| 231 | 322 | |
| 232 | | |
| 233 | | static UINT8 hres_320, io_switch; |
| 234 | | |
| 235 | 323 | static READ8_DEVICE_HANDLER( x1_porta_r ) |
| 236 | 324 | { |
| 237 | 325 | //printf("PPI Port A read\n"); |
| r5502 | r5503 | |
| 241 | 329 | /* this port is system related */ |
| 242 | 330 | static READ8_DEVICE_HANDLER( x1_portb_r ) |
| 243 | 331 | { |
| 332 | static UINT8 sub_obf; |
| 244 | 333 | //printf("PPI Port B read\n"); |
| 245 | 334 | /* |
| 246 | 335 | x--- ---- "v disp" |
| r5502 | r5503 | |
| 252 | 341 | ---- --x- "cmt read" |
| 253 | 342 | ---- ---x "cmt test" (active low) |
| 254 | 343 | */ |
| 255 | | return input_port_read(device->machine, "SYSTEM"); |
| 344 | sub_obf^=0x20; |
| 345 | return (input_port_read(device->machine, "SYSTEM") & ~0x60) | sub_obf; |
| 256 | 346 | } |
| 257 | 347 | |
| 258 | 348 | /* I/O system port */ |
| r5502 | r5503 | |
| 363 | 453 | PORT_DIPSETTING( 0x00, DEF_STR( On ) ) |
| 364 | 454 | INPUT_PORTS_END |
| 365 | 455 | |
| 456 | static MACHINE_RESET( x1 ) |
| 457 | { |
| 458 | UINT8 *ROM = memory_region(machine, "maincpu"); |
| 459 | |
| 460 | memory_set_bankptr(machine, 1, &ROM[0x00000]); |
| 461 | } |
| 462 | |
| 463 | |
| 366 | 464 | static MACHINE_DRIVER_START( x1 ) |
| 367 | 465 | /* basic machine hardware */ |
| 368 | 466 | MDRV_CPU_ADD("maincpu", Z80, XTAL_4MHz) |
| r5502 | r5503 | |
| 402 | 500 | |
| 403 | 501 | /* ROM definition */ |
| 404 | 502 | ROM_START( x1 ) |
| 405 | | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) |
| 503 | ROM_REGION( 0x20000, "maincpu", ROMREGION_ERASEFF ) |
| 406 | 504 | ROM_SYSTEM_BIOS( 0, "default", "X1 IPL" ) |
| 407 | 505 | ROMX_LOAD( "ipl.x1", 0x0000, 0x1000, CRC(7b28d9de) SHA1(c4db9a6e99873808c8022afd1c50fef556a8b44d), ROM_BIOS(1) ) |
| 408 | 506 | ROM_SYSTEM_BIOS( 1, "alt", "X1 IPL (alt)" ) |
| 409 | 507 | ROMX_LOAD( "ipl_alt.x1", 0x0000, 0x1000, CRC(e70011d3) SHA1(d3395e9aeb5b8bbba7654dd471bcd8af228ee69a), ROM_BIOS(2) ) |
| 410 | 508 | |
| 411 | | ROM_REGION(0x0800, "cgrom", 0) |
| 412 | | ROM_LOAD("fnt0808.x1", 0x0000, 0x0800, CRC(e3995a57) SHA1(1c1a0d8c9f4c446ccd7470516b215ddca5052fb2) ) |
| 509 | ROM_REGION(0x1000, "mcu", ROMREGION_ERASEFF) //MCU for the Keyboard, "sub cpu" |
| 510 | ROM_LOAD( "80c48", 0x0000, 0x1000, NO_DUMP ) |
| 413 | 511 | |
| 512 | ROM_REGION(0x4c600, "cgrom", 0) |
| 513 | ROM_LOAD("fnt0808.x1", 0x00000, 0x00800, CRC(e3995a57) SHA1(1c1a0d8c9f4c446ccd7470516b215ddca5052fb2) ) |
| 514 | |
| 414 | 515 | ROM_REGION(0x4ac00, "kanji", ROMREGION_ERASEFF) |
| 415 | 516 | ROM_END |
| 416 | 517 | |
| 417 | 518 | ROM_START( x1ck ) |
| 418 | | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) |
| 519 | ROM_REGION( 0x20000, "maincpu", ROMREGION_ERASEFF ) |
| 419 | 520 | ROM_SYSTEM_BIOS( 0, "default", "X1 IPL" ) |
| 420 | 521 | ROMX_LOAD( "ipl.x1", 0x0000, 0x1000, CRC(7b28d9de) SHA1(c4db9a6e99873808c8022afd1c50fef556a8b44d), ROM_BIOS(1) ) |
| 421 | 522 | ROM_SYSTEM_BIOS( 1, "alt", "X1 IPL (alt)" ) |
| 422 | 523 | ROMX_LOAD( "ipl_alt.x1", 0x0000, 0x1000, CRC(e70011d3) SHA1(d3395e9aeb5b8bbba7654dd471bcd8af228ee69a), ROM_BIOS(2) ) |
| 423 | 524 | |
| 525 | ROM_REGION(0x1000, "mcu", ROMREGION_ERASEFF) //MCU for the Keyboard, "sub cpu" |
| 526 | ROM_LOAD( "80c48", 0x0000, 0x1000, NO_DUMP ) |
| 527 | |
| 424 | 528 | ROM_REGION(0x0800, "cgrom", 0) |
| 425 | 529 | ROM_LOAD("fnt0808.x1", 0x0000, 0x0800, CRC(e3995a57) SHA1(1c1a0d8c9f4c446ccd7470516b215ddca5052fb2) ) |
| 426 | 530 | |
| r5502 | r5503 | |
| 430 | 534 | ROM_END |
| 431 | 535 | |
| 432 | 536 | ROM_START( x1turbo ) |
| 433 | | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) |
| 537 | ROM_REGION( 0x20000, "maincpu", ROMREGION_ERASEFF ) |
| 434 | 538 | ROM_LOAD( "ipl.x1t", 0x0000, 0x8000, CRC(2e8b767c) SHA1(44620f57a25f0bcac2b57ca2b0f1ebad3bf305d3) ) |
| 435 | 539 | |
| 540 | ROM_REGION(0x1000, "mcu", ROMREGION_ERASEFF) //MCU for the Keyboard, "sub cpu" |
| 541 | ROM_LOAD( "80c48", 0x0000, 0x1000, NO_DUMP ) |
| 542 | |
| 436 | 543 | ROM_REGION(0x0800, "cgrom", 0) |
| 437 | 544 | /* This should be larger... hence, we are missing something (maybe part of the other fnt roms?) */ |
| 438 | 545 | ROM_LOAD("fnt0808.x1", 0x0000, 0x0800, CRC(84a47530) SHA1(06c0995adc7a6609d4272417fe3570ca43bd0454) ) |
| r5502 | r5503 | |
| 446 | 553 | Many emulators come with fnt0816.x1 & fnt1616.x1 but I am not sure about what was present on the real |
| 447 | 554 | X1 Turbo / Turbo Z */ |
| 448 | 555 | ROM_START( x1turboz ) |
| 449 | | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) |
| 556 | ROM_REGION( 0x20000, "maincpu", ROMREGION_ERASEFF ) |
| 450 | 557 | ROM_LOAD( "ipl.x1t", 0x0000, 0x8000, CRC(2e8b767c) SHA1(44620f57a25f0bcac2b57ca2b0f1ebad3bf305d3) ) |
| 451 | 558 | |
| 559 | ROM_REGION(0x1000, "mcu", ROMREGION_ERASEFF) //MCU for the Keyboard, "sub cpu" |
| 560 | ROM_LOAD( "80c48", 0x0000, 0x1000, NO_DUMP ) |
| 561 | |
| 452 | 562 | ROM_REGION(0x4c600, "cgrom", 0) |
| 453 | 563 | ROM_LOAD("fnt0808.x1", 0x0000, 0x0800, CRC(84a47530) SHA1(06c0995adc7a6609d4272417fe3570ca43bd0454) ) |
| 454 | 564 | ROM_SYSTEM_BIOS( 0, "font1", "Font set 1" ) |