trunk/src/mess/drivers/spc1000.c
| r32090 | r32091 | |
| 1 | // license:MAME |
| 2 | // copyright-holders:Miodrag Milanovic, Robbbert |
| 1 | 3 | /*************************************************************************** |
| 2 | 4 | |
| 3 | 5 | Samsung SPC-1000 driver by Miodrag Milanovic |
| r32090 | r32091 | |
| 11 | 13 | - Find out if any of the unconnected parts of 6000,4000,4001 are used |
| 12 | 14 | |
| 13 | 15 | |
| 16 | NOTE: 2014-09-13: added code from someone's modified MESS driver for floppy |
| 17 | disk. Since it is not to our coding standards, it is |
| 18 | commented out with #if 0/#endif and 3 slashes (///). |
| 19 | It is planned to be converted when time permits. The |
| 20 | author is unknown. |
| 21 | |
| 22 | Hardware details of the fdc: Intelligent device, Z80 CPU, |
| 23 | XTAL_8MHz, PPI 8255, FDC uPD765C, 2 RAM chips, 28 other |
| 24 | small ics. And of course, no schematic. |
| 25 | |
| 26 | |
| 14 | 27 | ****************************************************************************/ |
| 15 | 28 | |
| 16 | 29 | |
| r32090 | r32091 | |
| 44 | 57 | DECLARE_READ8_MEMBER(porta_r); |
| 45 | 58 | DECLARE_READ8_MEMBER(mc6847_videoram_r); |
| 46 | 59 | DECLARE_WRITE8_MEMBER(cass_w); |
| 60 | ///DECLARE_WRITE8_MEMBER(spc1000_sd725_w); |
| 61 | ///DECLARE_READ8_MEMBER(spc1000_sd725_r); |
| 47 | 62 | |
| 48 | 63 | MC6847_GET_CHARROM_MEMBER(get_char_rom) |
| 49 | 64 | { |
| r32090 | r32091 | |
| 56 | 71 | UINT8 m_GMODE; |
| 57 | 72 | UINT16 m_page; |
| 58 | 73 | virtual void machine_reset(); |
| 74 | ///FloppyDisk fdd; |
| 75 | ///void initDisk(void); |
| 59 | 76 | required_device<mc6847_base_device> m_vdg; |
| 60 | 77 | required_device<cpu_device> m_maincpu; |
| 61 | 78 | required_device<ram_device> m_ram; |
| r32090 | r32091 | |
| 140 | 157 | AM_RANGE(0x8008, 0x8008) AM_READ_PORT("LINE8") |
| 141 | 158 | AM_RANGE(0x8009, 0x8009) AM_READ_PORT("LINE9") |
| 142 | 159 | AM_RANGE(0xA000, 0xA000) AM_READWRITE(spc1000_iplk_r, spc1000_iplk_w) |
| 160 | ///AM_RANGE(0xC000, 0xC002) AM_READWRITE(spc1000_sd725_r, spc1000_sd725_w) |
| 143 | 161 | ADDRESS_MAP_END |
| 144 | 162 | |
| 145 | 163 | /* Input ports */ |
| r32090 | r32091 | |
| 226 | 244 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) |
| 227 | 245 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') |
| 228 | 246 | PORT_START("LINE9") |
| 229 | | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) |
| 247 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) /// PORT_NAME("IPL") PORT_CODE(KEYCODE_F6) |
| 230 | 248 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) |
| 231 | 249 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') |
| 232 | 250 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') |
| r32090 | r32091 | |
| 236 | 254 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') |
| 237 | 255 | INPUT_PORTS_END |
| 238 | 256 | |
| 257 | #if 0 |
| 258 | typedef union PC |
| 259 | { |
| 260 | struct { |
| 261 | unsigned char rDAV : 1; |
| 262 | unsigned char rRFD : 1; |
| 263 | unsigned char rDAC : 1; |
| 264 | unsigned char rNON : 1; |
| 265 | unsigned char wDAV : 1; |
| 266 | unsigned char wRFD : 1; |
| 267 | unsigned char wDAC : 1; |
| 268 | unsigned char wATN : 1; |
| 269 | } bits; |
| 270 | unsigned char b; |
| 271 | } pc_t; |
| 239 | 272 | |
| 273 | typedef char byte; |
| 274 | |
| 275 | typedef struct |
| 276 | { |
| 277 | byte rdVal; |
| 278 | byte wrVal; |
| 279 | byte rSize; |
| 280 | UINT16 seq; |
| 281 | byte isCmd; |
| 282 | byte cmd; |
| 283 | UINT8 sdata[6]; |
| 284 | pc_t PC; |
| 285 | char diskfile[1024]; |
| 286 | char diskfile2[1024]; |
| 287 | UINT8 diskdata[80*16*256]; // 80 tracks 16 sectors 256 byte |
| 288 | UINT8 diskdata2[80*16*256]; |
| 289 | byte modified; |
| 290 | byte modified2; |
| 291 | byte write; |
| 292 | byte write2; |
| 293 | byte *buffer; |
| 294 | byte idx; |
| 295 | int datasize; |
| 296 | int dataidx; |
| 297 | } FloppyDisk; |
| 298 | |
| 299 | void spc1000_state::initDisk(void) |
| 300 | { |
| 301 | FILE *f; |
| 302 | strcpy(fdd.diskfile, "system.dsk"); |
| 303 | strcpy(fdd.diskfile2, "disk.dsk"); |
| 304 | printf("ddd\n"); |
| 305 | if (strlen(fdd.diskfile) > 4) |
| 306 | { |
| 307 | f = fopen(fdd.diskfile, "rb"); |
| 308 | if (f > 0) { |
| 309 | fread(fdd.diskdata, 1, sizeof(fdd.diskdata), f); |
| 310 | fclose(f); |
| 311 | } |
| 312 | } |
| 313 | if (strlen(fdd.diskfile2) > 4) |
| 314 | { |
| 315 | f = fopen(fdd.diskfile2, "rb"); |
| 316 | if (f > 0) { |
| 317 | fread(fdd.diskdata2, 1, sizeof(fdd.diskdata2), f); |
| 318 | printf("disk.dsk\n"); |
| 319 | fclose(f); |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | WRITE8_MEMBER(spc1000_state::spc1000_sd725_w) |
| 325 | { |
| 326 | //printf("write 0x%04x=%d\n", (0xc000+offset), data); |
| 327 | if (offset == 0) { |
| 328 | fdd.wrVal = data; |
| 329 | } else if (offset == 2) { |
| 330 | if (data != 0) |
| 331 | { |
| 332 | fdd.PC.b = (data & 0xf0) | (fdd.PC.b & 0xf); |
| 333 | } |
| 334 | else |
| 335 | { |
| 336 | fdd.PC.b = fdd.PC.b & 0xf; |
| 337 | } |
| 338 | if (data & 0x10) // DAV=1 |
| 339 | { |
| 340 | //printf("FDD Data Valid (c000 bit4 on)\n"); |
| 341 | if (fdd.isCmd == 1) // command |
| 342 | { |
| 343 | fdd.isCmd = 0; |
| 344 | printf("FDD Command(Data) = 0h%02x\n", fdd.wrVal); |
| 345 | fdd.cmd = fdd.wrVal; |
| 346 | switch (fdd.wrVal) |
| 347 | { |
| 348 | case 0x00: // FDD Initialization |
| 349 | printf("*FDD Initialization\n"); |
| 350 | break; |
| 351 | case 0x01: // FDD Write |
| 352 | printf("*FDD Write\n"); |
| 353 | fdd.rSize = 4; |
| 354 | fdd.seq = 0; |
| 355 | break; |
| 356 | case 0x02: // FDD Read |
| 357 | printf("*FDD Read\n"); |
| 358 | // fdd.PC.bits.rRFD = 1; |
| 359 | fdd.rSize = 4; |
| 360 | fdd.seq = 0; |
| 361 | break; |
| 362 | case 0x03: // FDD Send Data |
| 363 | //printf("*FDD Send Data\n"); |
| 364 | if (fdd.seq == 4) |
| 365 | { |
| 366 | printf("seq=%d,(%d,%d,%d,%d)\n", fdd.seq, fdd.sdata[0], fdd.sdata[1], fdd.sdata[2], fdd.sdata[3]); |
| 367 | fdd.buffer = (byte*)(fdd.sdata[1] != 0 ? fdd.diskdata2 : fdd.diskdata); |
| 368 | fdd.buffer += (fdd.sdata[2] * 16 + fdd.sdata[3]-1) * 256; |
| 369 | fdd.datasize = fdd.sdata[0] * 256; |
| 370 | fdd.dataidx = 0; |
| 371 | |
| 372 | } |
| 373 | fdd.rdVal = 0; |
| 374 | break; |
| 375 | case 0x04: // FDD Copy |
| 376 | printf("*FDD Copy\n"); |
| 377 | fdd.rSize = 7; |
| 378 | fdd.seq = 0; |
| 379 | break; |
| 380 | case 0x05: // FDD Format |
| 381 | printf("*FDD Format\n"); |
| 382 | break; |
| 383 | case 0x06: // FDD Send Status |
| 384 | printf("*FDD Send Status\n"); |
| 385 | #define DATA_OK 0x40 |
| 386 | fdd.rdVal = 0x80 & DATA_OK; |
| 387 | break; |
| 388 | case 0x07: // FDD Send Drive State |
| 389 | printf("*FDD Send Drive State\n"); |
| 390 | #define DRIVE0 0x10 |
| 391 | fdd.rdVal = 0x0f | DRIVE0; |
| 392 | break; |
| 393 | case 0x08: // FDD RAM Test |
| 394 | printf("*FDD RAM Test\n"); |
| 395 | fdd.rSize = 4; |
| 396 | fdd.seq = 0; |
| 397 | break; |
| 398 | case 0x09: // FDD Transmit 2 |
| 399 | printf("*FDD Transmit 2\n"); |
| 400 | fdd.rSize = 4; |
| 401 | fdd.seq = 0; |
| 402 | break; |
| 403 | case 0x0A: // FDD Action |
| 404 | printf("*FDD No Action\n"); |
| 405 | break; |
| 406 | case 0x0B: // FDD Transmit 1 |
| 407 | printf("*FDD Transmit 1\n"); |
| 408 | fdd.rSize = 4; |
| 409 | fdd.seq = 0; |
| 410 | break; |
| 411 | case 0x0C: // FDD Receive |
| 412 | printf("*FDD Receive\n"); |
| 413 | fdd.rSize = 4; |
| 414 | fdd.seq = 0; |
| 415 | break; |
| 416 | case 0x0D: // FDD Go |
| 417 | printf("*FDD Go\n"); |
| 418 | fdd.rSize = 2; |
| 419 | fdd.seq = 0; |
| 420 | break; |
| 421 | case 0x0E: // FDD Load |
| 422 | printf("*FDD Load\n"); |
| 423 | fdd.rSize = 6; |
| 424 | fdd.seq = 0; |
| 425 | break; |
| 426 | case 0x0F: // FDD Save |
| 427 | printf("FDD Save\n"); |
| 428 | fdd.rSize = 6; |
| 429 | fdd.seq = 0; |
| 430 | break; |
| 431 | case 0x10: // FDD Load and Go |
| 432 | printf("*FDD Load and Go\n"); |
| 433 | break; |
| 434 | |
| 435 | } |
| 436 | } |
| 437 | else |
| 438 | { |
| 439 | if (fdd.rSize-- > 0) |
| 440 | { |
| 441 | fdd.sdata[fdd.seq++] = (char) fdd.wrVal; |
| 442 | printf("seq=%d, data = 0x%02x\n", fdd.seq-1, fdd.sdata[fdd.seq-1]); |
| 443 | // printf("cmd=%d\n", fdd.cmd); |
| 444 | if (fdd.rSize == 0) |
| 445 | { |
| 446 | printf("Fdd Command(%d) Fired\n", fdd.cmd); |
| 447 | if (fdd.cmd == 0x0e) |
| 448 | { |
| 449 | int offset = (int)((int)fdd.sdata[2] * 16 + (int)fdd.sdata[3]-1) * 256; |
| 450 | int size = fdd.sdata[0] * 256; |
| 451 | printf("load(%d,%d,%d,%d),offset=%d, size=%d\n", fdd.sdata[0], fdd.sdata[1], fdd.sdata[2], fdd.sdata[3], offset, size); |
| 452 | fdd.buffer = (byte*)(fdd.sdata[1] != 0 ? fdd.diskdata2 : fdd.diskdata); |
| 453 | //fdd.buffer += offset; |
| 454 | fdd.datasize = size; |
| 455 | unsigned short addr = ((unsigned short)fdd.sdata[4]) * 0x100 + (unsigned short)fdd.sdata[5]; |
| 456 | printf("target addr=%04x, %02x, %02x, size=%d\n", addr, fdd.sdata[4], fdd.sdata[5], fdd.datasize); |
| 457 | UINT8 *mem = m_ram->pointer(); |
| 458 | memcpy(&mem[addr], &fdd.buffer[offset], fdd.datasize); |
| 459 | } |
| 460 | else if (fdd.cmd == 0x0f) |
| 461 | { |
| 462 | int offset = (int)((int)fdd.sdata[2] * 16 + (int)fdd.sdata[3]-1) * 256; |
| 463 | int size = fdd.sdata[0] * 256; |
| 464 | printf("save(%d,%d,%d,%d),offset=%d, size=%d\n", fdd.sdata[0], fdd.sdata[1], fdd.sdata[2], fdd.sdata[3], offset, size); |
| 465 | fdd.buffer = (byte*)(fdd.sdata[1] != 0 ? fdd.diskdata2 : fdd.diskdata); |
| 466 | fdd.buffer += offset; |
| 467 | fdd.datasize = size; |
| 468 | unsigned short addr = ((unsigned short)fdd.sdata[4]) * 0x100 + (unsigned short)fdd.sdata[5]; |
| 469 | printf("target addr=%04x, %02x, %02x, size=%d\n", addr, fdd.sdata[4], fdd.sdata[5], fdd.datasize); |
| 470 | UINT8 *mem = m_ram->pointer(); |
| 471 | memcpy(fdd.buffer, &mem[addr], fdd.datasize); |
| 472 | } |
| 473 | } |
| 474 | } |
| 475 | } |
| 476 | fdd.PC.bits.rDAC = 1; |
| 477 | |
| 478 | } |
| 479 | else if (fdd.PC.bits.rDAC == 1) // DAV=0 |
| 480 | { |
| 481 | //printf("FDD Ouput Data Cleared (c000 bit4 off)\n"); |
| 482 | fdd.wrVal = 0; |
| 483 | // printf("FDD_Read = 0h%02x (cleared)\n", fdd.wrVal); |
| 484 | fdd.PC.bits.rDAC = 0; |
| 485 | } |
| 486 | if (data & 0x20) // RFD=1 |
| 487 | { |
| 488 | // printf("FDD Ready for Data Read (c000 bit5 on)\n"); |
| 489 | fdd.PC.bits.rDAV = 1; |
| 490 | } |
| 491 | else if (fdd.PC.bits.rDAV == 1) // RFD=0 |
| 492 | { |
| 493 | //fdd.rdVal = 0; |
| 494 | //printf("FDD Input Data = 0h%02x\n", fdd.rdVal); |
| 495 | fdd.PC.bits.rDAV = 0; |
| 496 | } |
| 497 | if (data & 0x40) // DAC=1 |
| 498 | { |
| 499 | // printf("FDD Data accepted (c000 bit6 on)\n"); |
| 500 | } |
| 501 | if (data & 0x80) // ATN=1 |
| 502 | { |
| 503 | // printf("FDD Attention (c000 bit7 on)\n"); |
| 504 | //printf("Command = 0x%02x\n", fdd.rdVal); |
| 505 | //printf("FDD Ready for Data\n", fdd.rdVal); |
| 506 | fdd.PC.bits.rRFD = 1; |
| 507 | fdd.isCmd = 1; |
| 508 | } |
| 509 | } |
| 510 | return; |
| 511 | } |
| 512 | |
| 513 | READ8_MEMBER(spc1000_state::spc1000_sd725_r) |
| 514 | { |
| 515 | //printf("read %04x\n", (0xc000+offset)); |
| 516 | if (offset == 1) |
| 517 | { |
| 518 | if (fdd.cmd == 3) |
| 519 | { |
| 520 | fdd.rdVal = *(fdd.buffer + fdd.dataidx++); |
| 521 | } |
| 522 | //printf("FDD_Data > 0h%02x\n", spcsys.fdd.rdVal); |
| 523 | return fdd.rdVal; |
| 524 | } |
| 525 | else if (offset == 2) |
| 526 | { |
| 527 | //printf("FDD_PC > 0h%02x\n", spcsys.fdd.PC.b); |
| 528 | return fdd.PC.b; |
| 529 | } |
| 530 | return 0; |
| 531 | } |
| 532 | #endif |
| 533 | |
| 534 | |
| 240 | 535 | void spc1000_state::machine_reset() |
| 241 | 536 | { |
| 242 | 537 | address_space &space = m_maincpu->space(AS_PROGRAM); |
| r32090 | r32091 | |
| 253 | 548 | membank("bank2")->set_base(ram); |
| 254 | 549 | membank("bank3")->set_base(mem); |
| 255 | 550 | membank("bank4")->set_base(ram + 0x8000); |
| 551 | ///initDisk(); |
| 256 | 552 | |
| 257 | 553 | m_IPLK = 1; |
| 258 | 554 | } |
| r32090 | r32091 | |
| 331 | 627 | ROM_LOAD( "spcall.rom", 0x0000, 0x8000, CRC(19638fc9) SHA1(489f1baa7aebf3c8c660325fb1fd790d84203284)) |
| 332 | 628 | ROM_END |
| 333 | 629 | |
| 630 | #if 0 |
| 631 | ROM_START( spc1000 ) |
| 632 | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) |
| 633 | ROM_LOAD( "spcall.rom", 0x0000, 0x8000, CRC(2FBB6ECA) SHA1(cc9a076b0f00d54b2aec31f1f558b10f43ef61c8)) |
| 634 | /// more roms to come... |
| 635 | ROM_END |
| 636 | #endif |
| 637 | |
| 638 | |
| 334 | 639 | /* Driver */ |
| 335 | 640 | |
| 336 | 641 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ |