trunk/src/mess/drivers/cat.c
| r25398 | r25399 | |
| 162 | 162 | Board name: 950-0001C |
| 163 | 163 | "INFORMATION APPLIANCE INC. COPYRIGHT 1985" |
| 164 | 164 | _________________|||||||||_____________________________________________________________________________ |
| 165 | | | video out [unknown IDC connector]____ | |
| 165 | | video out [Floppy connector] ____ | |
| 166 | 166 | | / \ | |
| 167 | 167 | <4 pin edge) 74LS107 |PB1 | uA339 MC3403 | |
| 168 | 168 | | 7407 \____/ | |
| r25398 | r25399 | |
| 185 | 185 | | TMS4256 74F153 74LS393 |__________| || UM95089 Y2 | U = |
| 186 | 186 | |_____________________________________(j9)________________________________________________________|_T___= |
| 187 | 187 | |
| 188 | *Devices of interest: |
| 189 | J1: breakout of joystick, serial/rs232, hex-keypad, parallel port, and forth switch (and maybe cassette?) pins |
| 190 | J4: keyboard ribbon cable |
| 191 | R6522P (upper): parallel port via |
| 192 | R6522P (lower): keyboard via |
| 193 | UM95089: Tone Dialer chip |
| 194 | |
| 195 | |
| 196 | *Pals: |
| 188 | 197 | "TIMING B" - AMPAL16R4APC (marked on silkscreen "TIMING PAL") |
| 189 | 198 | "DECODE E" - AMPAL16L8PC (marked on silkscreen "DECODE PAL") |
| 190 | 199 | "VIDEO 2B" - AMPAL16R4APC (marked on silkscreen "VIDEO PAL") |
| 191 | 200 | "DISK 3.5C" - AMPAL16R4PC (marked on silkscreen "DISK PAL") |
| 201 | |
| 202 | *Deviations from silkscreen: |
| 192 | 203 | 4N37 (marked on silkscreen "4N35") |
| 193 | 204 | 74F153 (marked on silkscreen "74ALS153") |
| 205 | |
| 206 | *Other Devices: |
| 194 | 207 | TMS4256-15NL - 262144 x 1 DRAM |
| 195 | 208 | PB1 - piezo speaker |
| 209 | |
| 196 | 210 | Crystals: |
| 197 | 211 | Y1: 15.8976Mhz, main clock? |
| 198 | 212 | Y2: 3.579545Mhz, used by the DTMF generator chip UM95089? |
| r25398 | r25399 | |
| 252 | 266 | - Figure out the keyboard (interrupts are involved? or maybe an NMI on a |
| 253 | 267 | timer/vblank? It iss possible this uses the same DUART+IP2 'keyboard read |
| 254 | 268 | int' stuff as the cat does) |
| 255 | | - Beeper |
| 256 | | - Communications port (Duart? or some other plain UART?) |
| 269 | - get the keyboard scanning actually working |
| 270 | - Beeper (on one of the vias?) |
| 271 | - vblank/hblank stuff |
| 272 | - Get the 6850 ACIA working for communications |
| 257 | 273 | - Floppy (probably similar to the Cat) |
| 258 | | - Centronics port (probably similar to the Cat) |
| 259 | | - Joystick port |
| 260 | | - Forth button (keep in mind shift-usefront-space ALWAYS enables forth on a swyft) |
| 274 | - Centronics port (attached to one of the VIAs) |
| 275 | - Joystick port (also likely on a via) |
| 276 | - Keypad? (also likely on a via done as a grid scan?) |
| 277 | - Forth button (on the port on the back; keep in mind shift-usefront-space ALWAYS enables forth on a swyft) |
| 261 | 278 | - Multple undumped firmware revisions exist |
| 262 | 279 | |
| 263 | 280 | ****************************************************************************/ |
| r25398 | r25399 | |
| 282 | 299 | #undef DEBUG_DUART_OUTPUT_LINES |
| 283 | 300 | #undef DEBUG_DUART_INPUT_LINES |
| 284 | 301 | #undef DEBUG_DUART_TXD |
| 285 | | // TODO: the duart irq handler doesn't work becuase there is no easy way to strobe the duart to force it to check its inputs yet |
| 302 | // TODO: the duart irq handler doesn't work because there was no easy way to strobe the duart to force it to check its inputs; now with devcb there is, but it hasn't been hooked up yet |
| 286 | 303 | #undef DEBUG_DUART_IRQ_HANDLER |
| 287 | 304 | |
| 288 | 305 | #undef DEBUG_TEST_W |
| 289 | 306 | |
| 307 | #define DEBUG_SWYFT_VIA0 1 |
| 308 | #define DEBUG_SWYFT_VIA1 1 |
| 309 | |
| 310 | |
| 290 | 311 | // Includes |
| 291 | 312 | #include "emu.h" |
| 292 | 313 | #include "cpu/m68000/m68000.h" |
| r25398 | r25399 | |
| 314 | 335 | m_via1(*this, "via6522_1"), |
| 315 | 336 | //m_speaker(*this, "speaker"), |
| 316 | 337 | m_svram(*this, "svram"), // nvram |
| 317 | | m_p_videoram(*this, "p_videoram"), |
| 338 | m_p_cat_videoram(*this, "p_cat_vram"), |
| 339 | m_p_swyft_videoram(*this, "p_swyft_vram"), |
| 318 | 340 | m_y0(*this, "Y0"), |
| 319 | 341 | m_y1(*this, "Y1"), |
| 320 | 342 | m_y2(*this, "Y2"), |
| r25398 | r25399 | |
| 338 | 360 | DECLARE_WRITE8_MEMBER(cat_duart_output); |
| 339 | 361 | //required_device<speaker_sound_device> m_speaker; |
| 340 | 362 | optional_shared_ptr<UINT16> m_svram; |
| 341 | | required_shared_ptr<UINT16> m_p_videoram; |
| 363 | optional_shared_ptr<UINT16> m_p_cat_videoram; |
| 364 | optional_shared_ptr<UINT8> m_p_swyft_videoram; |
| 342 | 365 | optional_ioport m_y0; |
| 343 | 366 | optional_ioport m_y1; |
| 344 | 367 | optional_ioport m_y2; |
| r25398 | r25399 | |
| 381 | 404 | DECLARE_READ16_MEMBER(cat_2e80_r); |
| 382 | 405 | DECLARE_READ16_MEMBER(cat_0080_r); |
| 383 | 406 | DECLARE_READ16_MEMBER(cat_0000_r); |
| 407 | |
| 408 | DECLARE_READ8_MEMBER(swyft_d0000); |
| 409 | |
| 410 | DECLARE_READ8_MEMBER(swyft_via0_r); |
| 411 | DECLARE_WRITE8_MEMBER(swyft_via0_w); |
| 412 | DECLARE_READ8_MEMBER(via0_pa_r); |
| 413 | DECLARE_WRITE8_MEMBER(via0_pa_w); |
| 414 | DECLARE_READ_LINE_MEMBER(via0_ca1_r); |
| 415 | DECLARE_WRITE_LINE_MEMBER(via0_ca1_w); |
| 416 | DECLARE_READ_LINE_MEMBER(via0_ca2_r); |
| 417 | DECLARE_WRITE_LINE_MEMBER(via0_ca2_w); |
| 418 | DECLARE_READ8_MEMBER(via0_pb_r); |
| 419 | DECLARE_WRITE8_MEMBER(via0_pb_w); |
| 420 | DECLARE_READ_LINE_MEMBER(via0_cb1_r); |
| 421 | DECLARE_WRITE_LINE_MEMBER(via0_cb1_w); |
| 422 | DECLARE_READ_LINE_MEMBER(via0_cb2_r); |
| 423 | DECLARE_WRITE_LINE_MEMBER(via0_cb2_w); |
| 424 | DECLARE_WRITE_LINE_MEMBER(via0_int_w); |
| 425 | |
| 426 | DECLARE_READ8_MEMBER(swyft_via1_r); |
| 427 | DECLARE_WRITE8_MEMBER(swyft_via1_w); |
| 428 | DECLARE_READ8_MEMBER(via1_pa_r); |
| 429 | DECLARE_WRITE8_MEMBER(via1_pa_w); |
| 430 | DECLARE_READ_LINE_MEMBER(via1_ca1_r); |
| 431 | DECLARE_WRITE_LINE_MEMBER(via1_ca1_w); |
| 432 | DECLARE_READ_LINE_MEMBER(via1_ca2_r); |
| 433 | DECLARE_WRITE_LINE_MEMBER(via1_ca2_w); |
| 434 | DECLARE_READ8_MEMBER(via1_pb_r); |
| 435 | DECLARE_WRITE8_MEMBER(via1_pb_w); |
| 436 | DECLARE_READ_LINE_MEMBER(via1_cb1_r); |
| 437 | DECLARE_WRITE_LINE_MEMBER(via1_cb1_w); |
| 438 | DECLARE_READ_LINE_MEMBER(via1_cb2_r); |
| 439 | DECLARE_WRITE_LINE_MEMBER(via1_cb2_w); |
| 440 | DECLARE_WRITE_LINE_MEMBER(via1_int_w); |
| 384 | 441 | |
| 385 | 442 | UINT8 m_duart_inp; |
| 386 | 443 | /* gate array 2 has a 16-bit counter inside which counts at 10mhz and |
| 387 | | rolls over at FFFF->0000; on rollover (or maybe at FFFF terminal count) |
| 444 | rolls over at FFFF->0000; on roll-over (or maybe at FFFF terminal count) |
| 388 | 445 | it triggers the KTOBF output. It does this every 6.5535ms, which causes |
| 389 | 446 | a 74LS74 d-latch at IC100 to switch the state of the DUART IP2 line; |
| 390 | 447 | this causes the DUART to fire an interrupt, which makes the 68000 read |
| r25398 | r25399 | |
| 539 | 596 | * ||\------- /INDEX: 0 = index sensor active, 1 = index sensor inactive (verified) |
| 540 | 597 | * |\-------- ? this bit may indicate which drive is selected, i.e. same as floppy control bit 7; low on drive 1, high on drive 0? |
| 541 | 598 | * \--------- ? this bit may indicate 'data separator overflow'; it is usually low but becomes high if you manually select the floppy drive |
| 542 | | ALL of these bits except bit 7 seem to be reset when the selected drive in floppy control is switched |
| 599 | ALL of these bits except bit F seem to be reset when the selected drive in floppy control is switched |
| 543 | 600 | */ |
| 544 | 601 | READ16_MEMBER( cat_state::cat_floppy_status_r ) |
| 545 | 602 | { |
| r25398 | r25399 | |
| 581 | 638 | // 0x80000e-0x80000f read |
| 582 | 639 | READ16_MEMBER( cat_state::cat_battery_r ) |
| 583 | 640 | { |
| 641 | /* |
| 642 | * FEDCBA98 (76543210 is open bus) |
| 643 | * |||||||\-- ? |
| 644 | * ||||||\--- ? |
| 645 | * |||||\---- ? |
| 646 | * ||||\----- ? |
| 647 | * |||\------ ? |
| 648 | * ||\------- ? |
| 649 | * |\-------- ? |
| 650 | * \--------- Battery status (0 = good, 1 = bad) |
| 651 | */ |
| 584 | 652 | /* just return that battery is full, i.e. bit 15 is 0 */ |
| 585 | 653 | /* to make the cat think the battery is bad, return 0x8080 instead of 0x0080 */ |
| 586 | 654 | // TODO: hook this to a dipswitch |
| r25398 | r25399 | |
| 684 | 752 | } |
| 685 | 753 | |
| 686 | 754 | |
| 687 | | /* Canon cat memory map, based on a 16MB dump of the entire address space of a running unit using forth "1000000 0 do i c@ semit loop" |
| 755 | /* Canon cat memory map, based on testing and a 16MB dump of the entire address space of a running unit using forth "1000000 0 do i c@ semit loop" |
| 688 | 756 | 68k address map: |
| 689 | 757 | a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 (a0 via UDS/LDS) |
| 690 | 758 | *i *i * x x * * * x x x x x x x x x x x x x x x x *GATE ARRAY 2 DECODES THESE LINES TO ENABLE THIS AREA* (a23 and a22 are indirectly decoded via the /RAMROMCS and /IOCS lines from gate array 1) |
| r25398 | r25399 | |
| 732 | 800 | AM_RANGE(0x000000, 0x03ffff) AM_ROM AM_MIRROR(0x180000) // 256 KB ROM |
| 733 | 801 | AM_RANGE(0x040000, 0x043fff) AM_RAM AM_SHARE("svram") AM_MIRROR(0x18C000)// SRAM powered by battery |
| 734 | 802 | AM_RANGE(0x200000, 0x27ffff) AM_ROM AM_REGION("svrom",0x0000) AM_MIRROR(0x180000) // SV ROM |
| 735 | | AM_RANGE(0x400000, 0x47ffff) AM_RAM AM_SHARE("p_videoram") AM_MIRROR(0x180000) // 512 KB RAM |
| 803 | AM_RANGE(0x400000, 0x47ffff) AM_RAM AM_SHARE("p_cat_vram") AM_MIRROR(0x180000) // 512 KB RAM |
| 736 | 804 | AM_RANGE(0x600000, 0x67ffff) AM_READWRITE(cat_2e80_r,cat_video_control_w) AM_MIRROR(0x180000) // Gate Array #1: Video |
| 737 | 805 | AM_RANGE(0x800000, 0x800001) AM_READWRITE(cat_floppy_control_r, cat_floppy_control_w) AM_MIRROR(0x18FFE0) // floppy control lines and readback |
| 738 | 806 | AM_RANGE(0x800002, 0x800003) AM_READWRITE(cat_0080_r, cat_keyboard_w) AM_MIRROR(0x18FFE0) // keyboard col write |
| r25398 | r25399 | |
| 754 | 822 | AM_RANGE(0xC00000, 0xC00001) AM_READ(cat_2e80_r) AM_MIRROR(0x3FFFFE) // Open bus/vme? |
| 755 | 823 | ADDRESS_MAP_END |
| 756 | 824 | |
| 757 | | /* Swyft Memory map, based on watching the infoapp roms do their thing: |
| 758 | | 68k address map: |
| 759 | | a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 (a0 via UDS/LDS) |
| 760 | | ? ? ? ? 0 0 ? ? * * * * * * * * * * * * * * * a R ROM (a=0 is low, a=1 is high) |
| 761 | | ? ? ? ? 0 1 * * * * * * * * * * * * * * * * * a RW RAM |
| 762 | | ? ? ? ? 1 1 ?0? ?1? ? ? ? ? ? ? ? ? ? ? ? ? * * * * R ? status of something? floppy? |
| 763 | | ? ? ? ? 1 1 ?1? ?0? ? 0 0 1 ? ? ? ? ? ? ? ? ? ? ? ? ?R?W 6850 acia control reg lives here, gets 0x55 steadystate and 0x57 written to it to reset it |
| 764 | | ? ? ? ? 1 1 ?1? ?0? ? 0 1 0 ? ? * * * * ?*? ? ? ? ? ? RW VIA 0 |
| 765 | | ? ? ? ? 1 1 ?1? ?0? ? 1 0 0 ? ? * * * * ?*? ? ? ? ? ? RW VIA 1 |
| 766 | | ^ ^ ^ ^ ^ |
| 767 | | */ |
| 768 | | |
| 769 | | static ADDRESS_MAP_START(swyft_mem, AS_PROGRAM, 16, cat_state) |
| 770 | | ADDRESS_MAP_UNMAP_HIGH |
| 771 | | AM_RANGE(0x000000, 0x00ffff) AM_ROM AM_MIRROR(0xF00000) // 64 KB ROM |
| 772 | | AM_RANGE(0x040000, 0x07ffff) AM_RAM AM_MIRROR(0xF00000) AM_SHARE("p_videoram") // 256 KB RAM |
| 773 | | //AM_RANGE(0x0d0000, 0x0d000f) AM_READ(unknown_d0004) // status of something? reads from d0000, d0004, d0008, d000a, d000e |
| 774 | | AM_RANGE(0x0e1000, 0x0e1001) AM_DEVWRITE8("acia6850", acia6850_device, control_write, 0xFF00) // 6850 ACIA lives here |
| 775 | | // where are the other 3 acia registers? e1002-e1003, and read/write for each? |
| 776 | | //AM_RANGE(0x0e2000, 0x0e2fff) AM_READWRITE(unknown_e2000) // io area with selector on a9 a8 a7 a6? |
| 777 | | //AM_RANGE(0x0e4000, 0x0e4fff) AM_READWRITE(unknown_e4000) // there's likely a modem chip mapped around somewhere |
| 778 | | ADDRESS_MAP_END |
| 779 | | |
| 780 | 825 | /* Input ports */ |
| 781 | 826 | |
| 782 | 827 | /* 2009-07 FP |
| r25398 | r25399 | |
| 886 | 931 | INPUT_PORTS_END |
| 887 | 932 | |
| 888 | 933 | static INPUT_PORTS_START( swyft ) |
| 934 | // insert dwight and sandy's swyft keyboard map here once we figure out the byte line order |
| 889 | 935 | INPUT_PORTS_END |
| 890 | 936 | |
| 891 | 937 | |
| r25398 | r25399 | |
| 956 | 1002 | int horpos = 0; |
| 957 | 1003 | for (x = 0; x < 42; x++) |
| 958 | 1004 | { |
| 959 | | code = m_p_videoram[addr++]; |
| 1005 | code = m_p_cat_videoram[addr++]; |
| 960 | 1006 | for (b = 15; b >= 0; b--) |
| 961 | 1007 | { |
| 962 | 1008 | bitmap.pix16(y, horpos++) = ((code >> b) & 0x01) ^ m_video_invert; |
| r25398 | r25399 | |
| 970 | 1016 | return 0; |
| 971 | 1017 | } |
| 972 | 1018 | |
| 973 | | MACHINE_START_MEMBER(cat_state,swyft) |
| 974 | | { |
| 975 | | //m_6ms_timer = timer_alloc(TIMER_COUNTER_6MS); // CRUDE HACK |
| 976 | | } |
| 977 | | |
| 978 | | MACHINE_RESET_MEMBER(cat_state,swyft) |
| 979 | | { |
| 980 | | //m_maincpu->set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(cat_state::cat_int_ack),this)); |
| 981 | | //m_6ms_timer->adjust(attotime::zero, 0, attotime::from_hz((XTAL_19_968MHz/2)/65536)); // horrible hack |
| 982 | | } |
| 983 | | |
| 984 | | VIDEO_START_MEMBER(cat_state,swyft) |
| 985 | | { |
| 986 | | } |
| 987 | | |
| 988 | | UINT32 cat_state::screen_update_swyft(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 989 | | { |
| 990 | | UINT16 code; |
| 991 | | int y, x, b; |
| 992 | | |
| 993 | | int addr = 0; |
| 994 | | for (y = 0; y < 242; y++) |
| 995 | | { |
| 996 | | int horpos = 0; |
| 997 | | for (x = 0; x < 20; x++) |
| 998 | | { |
| 999 | | code = m_p_videoram[addr++]; |
| 1000 | | for (b = 15; b >= 0; b--) |
| 1001 | | { |
| 1002 | | bitmap.pix16(y, horpos++) = (code >> b) & 0x01; |
| 1003 | | } |
| 1004 | | } |
| 1005 | | } |
| 1006 | | return 0; |
| 1007 | | } |
| 1008 | | |
| 1009 | 1019 | /* TODO: the duart is the only thing actually connected to the cpu IRQ pin |
| 1010 | 1020 | * The KTOBF output of the gate array 2 (itself the terminal count output |
| 1011 | 1021 | * of a 16-bit counter clocked at ~10mhz, hence 6.5536ms period) goes to a |
| r25398 | r25399 | |
| 1097 | 1107 | MCFG_NVRAM_ADD_0FILL("nvram") |
| 1098 | 1108 | MACHINE_CONFIG_END |
| 1099 | 1109 | |
| 1110 | |
| 1111 | /* Swyft Memory map, based on watching the infoapp roms do their thing: |
| 1112 | 68k address map: |
| 1113 | (a23,a22,a21,a20 lines don't exist on the 68008 so are considered unconnected) |
| 1114 | a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 (a0 via UDS/LDS) |
| 1115 | x x x x 0 0 ? ? * * * * * * * * * * * * * * * a R ROM (a=0 is low, a=1 is high) |
| 1116 | x x x x 0 1 * * * * * * * * * * * * * * * * * a RW RAM |
| 1117 | x x x x 1 1 ?0? ?1? ? ? ? ? ? ? ? ? ? ? ? ? * * * * R ? status of something? floppy? |
| 1118 | x x x x 1 1 ?1? ?0? ? 0 0 1 ? ? ? ? ? ? ? ? ? ? ? ? ?R?W 6850 acia control reg lives here, gets 0x55 steadystate and 0x57 written to it to reset it |
| 1119 | x x x x 1 1 ?1? ?0? ? 0 1 0 ? ? * * * * ?*? ? ? ? ? ? RW VIA 0 |
| 1120 | x x x x 1 1 ?1? ?0? ? 1 0 0 ? ? * * * * ?*? ? ? ? ? ? RW VIA 1 |
| 1121 | ^ ^ ^ ^ ^ |
| 1122 | */ |
| 1123 | |
| 1124 | /* Swyft rom and ram notes: |
| 1125 | rom: |
| 1126 | **Vectors: |
| 1127 | 0x0000-0x0003: SP boot vector |
| 1128 | 0x0004-0x0007: PC boot vector |
| 1129 | **unknown: |
| 1130 | 0x0009-0x00BF: ? table |
| 1131 | 0x00C0-0x01DF: ? table |
| 1132 | 0x01E0-0x02DF: ? table (may be part of next table) |
| 1133 | 0x02E0-0x03DF: ? table |
| 1134 | 0x03E0-0x0B3F: int16-packed jump table (expanded to int32s at ram at 0x46000-0x46EC0 on boot) |
| 1135 | 0x0B40-0x108F: ?binary code of forth interpreter? |
| 1136 | 0x1090-0xCD3B: tForth bytecode, even the fonts?: |
| 1137 | 0x1090-0x24CF: ? |
| 1138 | **Fonts: |
| 1139 | 0x24D0-0x254F: ? (likely font 1 width lookup table) |
| 1140 | 0x2550-0x2BCF: Font 1 data |
| 1141 | 0x2BD0-0x2C4F: ? (likely font 2 width lookup table) |
| 1142 | 0x2C50-0x32CF: Font 2 data |
| 1143 | **unknown?: |
| 1144 | 0x32D0-0x360F: String data (and control codes?) |
| 1145 | 0x3610-0x364F: ? fill (0x03 0xe8) |
| 1146 | 0x3650-0x369F: ? fill (0x03 0x20) |
| 1147 | 0x36A0-0x384d: ? forth code? |
| 1148 | 0x384e-0x385d: Lookup table for phone keypad |
| 1149 | 0x385e-...: ? |
| 1150 | ...-0xC951: ? |
| 1151 | 0xC952: boot vector |
| 1152 | 0xC952-...: boot code? |
| 1153 | 0xCD26-0xCD3B: ?init forth bytecode? |
| 1154 | 0xCD3C-0xCEBA: 0xFF fill (unused?) |
| 1155 | 0xCEEB-0xFFFE: Forth dictionaries for compiling, with <word> then <3 bytes> afterward? (or before it? most likely afterward) |
| 1156 | |
| 1157 | ram: (system dram ranges from 0x40000-0x7FFFF) |
| 1158 | 0x40000-0x425CF - the screen display ram |
| 1159 | (?0x425D0-0x44BA0 - ?unknown (maybe screen ram page 2?)) |
| 1160 | 0x44DC6 - SP vector |
| 1161 | 0x46000-0x46EC0 - jump tables to instructions for ? (each forth word?) |
| 1162 | |
| 1163 | |
| 1164 | on boot: |
| 1165 | copy/expand packed rom short words 0x3E0-0xB3F to long words at 0x46000-0x46EC0 |
| 1166 | copy 0x24f longwords of zero beyond that up to 0x47800 |
| 1167 | CD26->A5 <?pointer to init stream function?> |
| 1168 | 44DC6->A7 <reset SP... why it does this twice, once by the vector and once here, i'm gonna guess has to do with running the code in a debugger or on a development daughterboard like the cat had, where the 68008 wouldn't get explicitly reset> |
| 1169 | 44F2A->A6 <?pointer to work ram space?> |
| 1170 | EA2->A4 <?function> |
| 1171 | E94->A3 <?function> |
| 1172 | EAE->A2 <?function> |
| 1173 | 41800->D7 <?forth? opcode index base; the '1800' portion gets the opcode type added to it then is multiplied by 4 to produce the jump table offset within the 0x46000-0x46EC0 range> |
| 1174 | 46e3c->D4 <?pointer to more work ram space?> |
| 1175 | CD22->D5 <?pointer to another function?> |
| 1176 | write 0xFFFF to d0004.l |
| 1177 | jump to A4(EA2) |
| 1178 | |
| 1179 | read first stream byte (which is 0x03) from address pointed to by A5 (which is CD26), inc A5, OR the opcode (0x03) to D7 |
| 1180 | (Note: if the forth opcodes are in order in the dictionary, then 0x03 is "!char" which is used to read a char from an arbitrary address) |
| 1181 | copy D7 to A0 |
| 1182 | Add A0 low word to itself |
| 1183 | Add A0 low word to itself again |
| 1184 | move the long word from address pointed to by A0 (i.e. the specific opcode's area at the 46xxx part of ram) to A1 |
| 1185 | Jump to A1(11A4) |
| 1186 | |
| 1187 | 11A4: move 41b00 to D0 (select an opcode "page" 1bxx) |
| 1188 | jump to 118E |
| 1189 | |
| 1190 | 118E: read next stream byte (in this case, 0x8E) from address pointed to by A5 (which is CD27), inc A5, OR the opcode (0x8e) to D7 |
| 1191 | add to 41b00 in d0, for 41b8E |
| 1192 | Add A0 low word to itself |
| 1193 | Add A0 low word to itself again |
| 1194 | move the long word from address pointed to by A0 (i.e. the specific opcode's area at the 46xxx part of ram) to A1 |
| 1195 | Jump to A1(CD06) |
| 1196 | |
| 1197 | CD06: jump to A3 (E94) |
| 1198 | |
| 1199 | E94: subtract D5 from A5 (cd28 - cd22 = 0x0006) |
| 1200 | write 6 to address @A5(44f28) and decrement A5 |
| 1201 | write D4(46e3c) to address @a6(44f26) and decrement a5 |
| 1202 | lea ($2, A1), A5 - i.e. increment A1 by 2, and write that to A5, so write CD06+2=CD08 to A5 |
| 1203 | A1->D5 |
| 1204 | A0->D4 |
| 1205 | read next stream byte (in this case, 0x03) from address pointed to by A5 (which is CD08), inc A5, OR the opcode (0x03) to D7 |
| 1206 | |
| 1207 | */ |
| 1208 | |
| 1209 | static ADDRESS_MAP_START(swyft_mem, AS_PROGRAM, 8, cat_state) |
| 1210 | ADDRESS_MAP_UNMAP_HIGH |
| 1211 | AM_RANGE(0x000000, 0x00ffff) AM_ROM AM_MIRROR(0xF00000) // 64 KB ROM |
| 1212 | AM_RANGE(0x040000, 0x07ffff) AM_RAM AM_MIRROR(0xF00000) AM_SHARE("p_swyft_vram") // 256 KB RAM |
| 1213 | AM_RANGE(0x0d0000, 0x0d000f) AM_READ(swyft_d0000) AM_MIRROR(0xF00000) // status of something? reads from d0000, d0004, d0008, d000a, d000e |
| 1214 | AM_RANGE(0x0e1000, 0x0e1000) AM_DEVWRITE("acia6850", acia6850_device, control_write) AM_MIRROR(0xF00000) // 6850 ACIA lives here |
| 1215 | AM_RANGE(0x0e2000, 0x0e2fff) AM_READWRITE(swyft_via0_r, swyft_via0_w) AM_MIRROR(0xF00000)// io area with selector on a9 a8 a7 a6? |
| 1216 | AM_RANGE(0x0e4000, 0x0e4fff) AM_READWRITE(swyft_via1_r, swyft_via1_w) AM_MIRROR(0xF00000) |
| 1217 | ADDRESS_MAP_END |
| 1218 | |
| 1219 | MACHINE_START_MEMBER(cat_state,swyft) |
| 1220 | { |
| 1221 | //m_6ms_timer = timer_alloc(TIMER_COUNTER_6MS); // CRUDE HACK |
| 1222 | } |
| 1223 | |
| 1224 | MACHINE_RESET_MEMBER(cat_state,swyft) |
| 1225 | { |
| 1226 | //m_maincpu->set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(cat_state::cat_int_ack),this)); |
| 1227 | //m_6ms_timer->adjust(attotime::zero, 0, attotime::from_hz((XTAL_19_968MHz/2)/65536)); // horrible hack |
| 1228 | } |
| 1229 | |
| 1230 | VIDEO_START_MEMBER(cat_state,swyft) |
| 1231 | { |
| 1232 | } |
| 1233 | |
| 1234 | UINT32 cat_state::screen_update_swyft(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 1235 | { |
| 1236 | UINT16 code; |
| 1237 | int y, x, b; |
| 1238 | |
| 1239 | int addr = 0; |
| 1240 | for (y = 0; y < 242; y++) |
| 1241 | { |
| 1242 | int horpos = 0; |
| 1243 | for (x = 0; x < 40; x++) |
| 1244 | { |
| 1245 | code = m_p_swyft_videoram[addr++]; |
| 1246 | for (b = 7; b >= 0; b--) |
| 1247 | { |
| 1248 | bitmap.pix16(y, horpos++) = (code >> b) & 0x01; |
| 1249 | } |
| 1250 | } |
| 1251 | } |
| 1252 | return 0; |
| 1253 | } |
| 1254 | |
| 1100 | 1255 | static const acia6850_interface swyft_acia_config = |
| 1101 | 1256 | { |
| 1102 | 1257 | 3579545, // guess |
| r25398 | r25399 | |
| 1110 | 1265 | |
| 1111 | 1266 | static const via6522_interface swyft_via0_config = |
| 1112 | 1267 | { |
| 1113 | | DEVCB_NULL, |
| 1114 | | DEVCB_NULL, |
| 1115 | | DEVCB_NULL, |
| 1116 | | DEVCB_NULL, |
| 1117 | | DEVCB_NULL, |
| 1118 | | DEVCB_NULL, |
| 1119 | | DEVCB_NULL, |
| 1120 | | DEVCB_NULL, |
| 1121 | | DEVCB_NULL, |
| 1122 | | DEVCB_NULL, |
| 1123 | | DEVCB_NULL, |
| 1124 | | DEVCB_NULL, |
| 1125 | | DEVCB_NULL, |
| 1268 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_pa_r), // PA in |
| 1269 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_pb_r), // PB in |
| 1270 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_ca1_r), // CA1 in callback |
| 1271 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_cb1_r), // CB1 in callback |
| 1272 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_ca2_r), // CA2 in callback |
| 1273 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_cb2_r), // CB2 in callback |
| 1274 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_pa_w), // PA out |
| 1275 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_pb_w), // PB out |
| 1276 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_ca1_w), // CA1 out callback |
| 1277 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_cb1_w), // CA2 out callback |
| 1278 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_ca2_w), // CB1 out callback |
| 1279 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_cb2_w), // CB2 out callback |
| 1280 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via0_int_w), // interrupt callback |
| 1126 | 1281 | }; |
| 1127 | 1282 | |
| 1128 | 1283 | static const via6522_interface swyft_via1_config = |
| 1129 | 1284 | { |
| 1130 | | DEVCB_NULL, |
| 1131 | | DEVCB_NULL, |
| 1132 | | DEVCB_NULL, |
| 1133 | | DEVCB_NULL, |
| 1134 | | DEVCB_NULL, |
| 1135 | | DEVCB_NULL, |
| 1136 | | DEVCB_NULL, |
| 1137 | | DEVCB_NULL, |
| 1138 | | DEVCB_NULL, |
| 1139 | | DEVCB_NULL, |
| 1140 | | DEVCB_NULL, |
| 1141 | | DEVCB_NULL, |
| 1142 | | DEVCB_NULL, |
| 1285 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_pa_r), // PA in |
| 1286 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_pb_r), // PB in |
| 1287 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_ca1_r), // CA1 in callback |
| 1288 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_cb1_r), // CB1 in callback |
| 1289 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_ca2_r), // CA2 in callback |
| 1290 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_cb2_r), // CB2 in callback |
| 1291 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_pa_w), // PA out |
| 1292 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_pb_w), // PB out |
| 1293 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_ca1_w), // CA1 out callback |
| 1294 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_cb1_w), // CA2 out callback |
| 1295 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_ca2_w), // CB1 out callback |
| 1296 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_cb2_w), // CB2 out callback |
| 1297 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, cat_state, via1_int_w), // interrupt callback |
| 1143 | 1298 | }; |
| 1144 | 1299 | |
| 1300 | READ8_MEMBER( cat_state::swyft_d0000 ) |
| 1301 | { |
| 1302 | // wtf is this supposed to be? |
| 1303 | UINT8 byte = 0xD3; // ? |
| 1304 | logerror("mystery device: read from 0x%5X, returning %02X\n", offset+0xD0000, byte); |
| 1305 | return byte; |
| 1306 | } |
| 1307 | |
| 1308 | |
| 1309 | // if bit is 1 enable: (obviously don't set more than one bit or you get bus contention!) |
| 1310 | // acia |
| 1311 | // via0 |
| 1312 | // via1 |
| 1313 | // x x x x 1 1 ?1? ?0? ? ^ ^ ^ ? ? * * * * ?*? ? ? ? ? ? |
| 1314 | // ^ ^ ^ ^ <- these four bits address the VIA registers? is this correct? |
| 1315 | static const char *const swyft_via_regnames[] = { "0: ORB/IRB", "1: ORA/IRA", "2: DDRB", "3: DDRA", "4: T1C-L", "5: T1C-H", "6: T1L-L", "7: T1L-H", "8: T2C-L" "9: T2C-H", "A: SR", "B: ACR", "C: PCR", "D: IFR", "E: IER", "F: ORA/IRA*" }; |
| 1316 | |
| 1317 | READ8_MEMBER( cat_state::swyft_via0_r ) |
| 1318 | { |
| 1319 | if (offset&0x000C3F) fprintf(stderr,"VIA0: read from invalid offset in 68k space: %06X!\n", offset); |
| 1320 | UINT8 data = m_via0->read(space, (offset>>5)&0xF); |
| 1321 | #ifdef DEBUG_SWYFT_VIA0 |
| 1322 | logerror("VIA0 register %s read by cpu: returning %02x\n", swyft_via_regnames[(offset>>5)&0xF], data); |
| 1323 | #endif |
| 1324 | return data; |
| 1325 | } |
| 1326 | |
| 1327 | WRITE8_MEMBER( cat_state::swyft_via0_w ) |
| 1328 | { |
| 1329 | #ifdef DEBUG_SWYFT_VIA0 |
| 1330 | logerror("VIA0 register %s written by cpu with data %02x\n", swyft_via_regnames[(offset>>5)&0xF], data); |
| 1331 | #endif |
| 1332 | if (offset&0x000C3F) fprintf(stderr,"VIA0: write to invalid offset in 68k space: %06X, data: %02X!\n", offset, data); |
| 1333 | m_via1->write(space, (offset>>5)&0xF, data); |
| 1334 | } |
| 1335 | |
| 1336 | READ8_MEMBER( cat_state::swyft_via1_r ) |
| 1337 | { |
| 1338 | if (offset&0x000C3F) fprintf(stderr," VIA1: read from invalid offset in 68k space: %06X!\n", offset); |
| 1339 | UINT8 data = m_via1->read(space, (offset>>5)&0xF); |
| 1340 | #ifdef DEBUG_SWYFT_VIA1 |
| 1341 | logerror(" VIA1 register %s read by cpu: returning %02x\n", swyft_via_regnames[(offset>>5)&0xF], data); |
| 1342 | #endif |
| 1343 | return data; |
| 1344 | } |
| 1345 | |
| 1346 | WRITE8_MEMBER( cat_state::swyft_via1_w ) |
| 1347 | { |
| 1348 | #ifdef DEBUG_SWYFT_VIA1 |
| 1349 | logerror(" VIA1 register %s written by cpu with data %02x\n", swyft_via_regnames[(offset>>5)&0xF], data); |
| 1350 | #endif |
| 1351 | if (offset&0x000C3F) fprintf(stderr," VIA1: write to invalid offset in 68k space: %06X, data: %02X!\n", offset, data); |
| 1352 | m_via0->write(space, (offset>>5)&0xF, data); |
| 1353 | } |
| 1354 | |
| 1355 | // first via |
| 1356 | READ8_MEMBER( cat_state::via0_pa_r ) |
| 1357 | { |
| 1358 | logerror("VIA0: Port A read!\n"); |
| 1359 | return 0xFF; |
| 1360 | } |
| 1361 | |
| 1362 | WRITE8_MEMBER( cat_state::via0_pa_w ) |
| 1363 | { |
| 1364 | logerror("VIA0: Port A written with data of 0x%02x!\n", data); |
| 1365 | } |
| 1366 | |
| 1367 | READ_LINE_MEMBER ( cat_state::via0_ca1_r ) |
| 1368 | { |
| 1369 | logerror("VIA0: CA1 read!\n"); |
| 1370 | return 1; |
| 1371 | } |
| 1372 | |
| 1373 | WRITE_LINE_MEMBER ( cat_state::via0_ca1_w ) |
| 1374 | { |
| 1375 | logerror("VIA0: CA1 written with %d!\n", state); |
| 1376 | } |
| 1377 | |
| 1378 | READ_LINE_MEMBER ( cat_state::via0_ca2_r ) |
| 1379 | { |
| 1380 | logerror("VIA0: CA2 read!\n"); |
| 1381 | return 1; |
| 1382 | } |
| 1383 | |
| 1384 | WRITE_LINE_MEMBER ( cat_state::via0_ca2_w ) |
| 1385 | { |
| 1386 | logerror("VIA0: CA2 written with %d!\n", state); |
| 1387 | } |
| 1388 | |
| 1389 | READ8_MEMBER( cat_state::via0_pb_r ) |
| 1390 | { |
| 1391 | logerror("VIA0: Port B read!\n"); |
| 1392 | return 0xFF; |
| 1393 | } |
| 1394 | |
| 1395 | WRITE8_MEMBER( cat_state::via0_pb_w ) |
| 1396 | { |
| 1397 | logerror("VIA0: Port B written with data of 0x%02x!\n", data); |
| 1398 | } |
| 1399 | |
| 1400 | READ_LINE_MEMBER ( cat_state::via0_cb1_r ) |
| 1401 | { |
| 1402 | logerror("VIA0: CB1 read!\n"); |
| 1403 | return 1; |
| 1404 | } |
| 1405 | |
| 1406 | WRITE_LINE_MEMBER ( cat_state::via0_cb1_w ) |
| 1407 | { |
| 1408 | logerror("VIA0: CB1 written with %d!\n", state); |
| 1409 | } |
| 1410 | |
| 1411 | READ_LINE_MEMBER ( cat_state::via0_cb2_r ) |
| 1412 | { |
| 1413 | logerror("VIA0: CB2 read!\n"); |
| 1414 | return 1; |
| 1415 | } |
| 1416 | |
| 1417 | WRITE_LINE_MEMBER ( cat_state::via0_cb2_w ) |
| 1418 | { |
| 1419 | logerror("VIA0: CB2 written with %d!\n", state); |
| 1420 | } |
| 1421 | |
| 1422 | WRITE_LINE_MEMBER ( cat_state::via0_int_w ) |
| 1423 | { |
| 1424 | logerror("VIA0: INT output set to %d!\n", state); |
| 1425 | } |
| 1426 | |
| 1427 | // second via |
| 1428 | READ8_MEMBER( cat_state::via1_pa_r ) |
| 1429 | { |
| 1430 | logerror(" VIA1: Port A read!\n"); |
| 1431 | return 0xFF; |
| 1432 | } |
| 1433 | |
| 1434 | WRITE8_MEMBER( cat_state::via1_pa_w ) |
| 1435 | { |
| 1436 | logerror(" VIA1: Port A written with data of 0x%02x!\n", data); |
| 1437 | } |
| 1438 | |
| 1439 | READ_LINE_MEMBER ( cat_state::via1_ca1_r ) |
| 1440 | { |
| 1441 | logerror(" VIA1: CA1 read!\n"); |
| 1442 | return 1; |
| 1443 | } |
| 1444 | |
| 1445 | WRITE_LINE_MEMBER ( cat_state::via1_ca1_w ) |
| 1446 | { |
| 1447 | logerror(" VIA1: CA1 written with %d!\n", state); |
| 1448 | } |
| 1449 | |
| 1450 | READ_LINE_MEMBER ( cat_state::via1_ca2_r ) |
| 1451 | { |
| 1452 | logerror(" VIA1: CA2 read!\n"); |
| 1453 | return 1; |
| 1454 | } |
| 1455 | |
| 1456 | WRITE_LINE_MEMBER ( cat_state::via1_ca2_w ) |
| 1457 | { |
| 1458 | logerror(" VIA1: CA2 written with %d!\n", state); |
| 1459 | } |
| 1460 | |
| 1461 | READ8_MEMBER( cat_state::via1_pb_r ) |
| 1462 | { |
| 1463 | logerror(" VIA1: Port B read!\n"); |
| 1464 | return 0xFF; |
| 1465 | } |
| 1466 | |
| 1467 | WRITE8_MEMBER( cat_state::via1_pb_w ) |
| 1468 | { |
| 1469 | logerror(" VIA1: Port B written with data of 0x%02x!\n", data); |
| 1470 | } |
| 1471 | |
| 1472 | READ_LINE_MEMBER ( cat_state::via1_cb1_r ) |
| 1473 | { |
| 1474 | logerror(" VIA1: CB1 read!\n"); |
| 1475 | return 1; |
| 1476 | } |
| 1477 | |
| 1478 | WRITE_LINE_MEMBER ( cat_state::via1_cb1_w ) |
| 1479 | { |
| 1480 | logerror(" VIA1: CB1 written with %d!\n", state); |
| 1481 | } |
| 1482 | |
| 1483 | READ_LINE_MEMBER ( cat_state::via1_cb2_r ) |
| 1484 | { |
| 1485 | logerror(" VIA1: CB2 read!\n"); |
| 1486 | return 1; |
| 1487 | } |
| 1488 | |
| 1489 | WRITE_LINE_MEMBER ( cat_state::via1_cb2_w ) |
| 1490 | { |
| 1491 | logerror(" VIA1: CB2 written with %d!\n", state); |
| 1492 | } |
| 1493 | |
| 1494 | WRITE_LINE_MEMBER ( cat_state::via1_int_w ) |
| 1495 | { |
| 1496 | logerror(" VIA1: INT output set to %d!\n", state); |
| 1497 | } |
| 1498 | |
| 1145 | 1499 | static MACHINE_CONFIG_START( swyft, cat_state ) |
| 1146 | 1500 | |
| 1147 | 1501 | /* basic machine hardware */ |
| 1148 | | //MCFG_CPU_ADD("maincpu",M68008, XTAL_15_8976MHz/2) //MC68008P8, Y1=15.8796Mhz, clock GUESSED at Y1 / 2 |
| 1149 | | MCFG_CPU_ADD("maincpu",M68000, XTAL_15_8976MHz/2) //MC68008P8, Y1=15.8796Mhz, clock GUESSED at Y1 / 2 |
| 1502 | MCFG_CPU_ADD("maincpu",M68008, XTAL_15_8976MHz/2) //MC68008P8, Y1=15.8796Mhz, clock GUESSED at Y1 / 2 |
| 1150 | 1503 | MCFG_CPU_PROGRAM_MAP(swyft_mem) |
| 1151 | 1504 | |
| 1152 | 1505 | MCFG_MACHINE_START_OVERRIDE(cat_state,swyft) |
| r25398 | r25399 | |
| 1166 | 1519 | MCFG_VIDEO_START_OVERRIDE(cat_state,swyft) |
| 1167 | 1520 | |
| 1168 | 1521 | MCFG_ACIA6850_ADD("acia6850", swyft_acia_config) // unknown clock |
| 1522 | MCFG_VIA6522_ADD("via6522_0", XTAL_15_8976MHz/16, swyft_via0_config) // unknown clock, GUESSED |
| 1523 | MCFG_VIA6522_ADD("via6522_1", XTAL_15_8976MHz/16, swyft_via1_config) // unknown clock, GUESSED |
| 1169 | 1524 | MACHINE_CONFIG_END |
| 1170 | 1525 | |
| 1171 | 1526 | /* ROM definition */ |
| 1172 | 1527 | ROM_START( swyft ) |
| 1173 | 1528 | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) |
| 1529 | /* this version of the swyft code identifies itself at 0x3fCB as version 330 */ |
| 1174 | 1530 | ROM_LOAD( "infoapp.lo", 0x0000, 0x8000, CRC(52c1bd66) SHA1(b3266d72970f9d64d94d405965b694f5dcb23bca) ) |
| 1175 | 1531 | ROM_LOAD( "infoapp.hi", 0x8000, 0x8000, CRC(83505015) SHA1(693c914819dd171114a8c408f399b56b470f6be0) ) |
| 1176 | | /* a version of the swyft roms are labeled '331 low' and '331 high' */ |
| 1532 | /* another (yet to be dumped) version of the swyft roms are labeled '331 low' and '331 high' */ |
| 1177 | 1533 | ROM_REGION( 0x1000, "pals", ROMREGION_ERASEFF ) |
| 1178 | 1534 | ROM_LOAD( "timing b.pal16r4", 0x0000, 0x38b, NO_DUMP) |
| 1179 | 1535 | ROM_LOAD( "decode e.pal16l8", 0x0400, 0x38b, NO_DUMP) |