/*************************************************************************** Tandy 2000 Skeleton driver. ****************************************************************************/ /* TODO: - CRT9007 - CRT9212 Double Row Buffer - CRT9021B Attribute Generator - 80186 - keyboard ROM - hires graphics board - floppy 720K DSQD - DMA - WD1010 - hard disk - mouse */ #include "includes/tandy2k.h" #include "formats/mfi_dsk.h" enum { LPINEN = 0, KBDINEN, PORTINEN }; // Read/Write Handlers void tandy2k_state::dma_request(int line, int state) { } void tandy2k_state::speaker_update() { int level = !(m_spkrdata & m_outspkr); speaker_level_w(m_speaker, level); } READ8_MEMBER( tandy2k_state::videoram_r ) { address_space &program = m_maincpu->space(AS_PROGRAM); offs_t addr = (m_vram_base << 15) | (offset << 1); UINT16 data = program.read_word(addr); // character m_drb0->write(space, 0, data & 0xff); // attributes m_drb1->write(space, 0, data >> 8); return data & 0xff; } READ8_MEMBER( tandy2k_state::enable_r ) { /* bit signal description 0 RS-232 ring indicator 1 RS-232 carrier detect 2 3 4 5 6 7 _ACLOW */ return 0x80; } WRITE8_MEMBER( tandy2k_state::enable_w ) { /* bit signal description 0 KBEN keyboard enable 1 EXTCLK external baud rate clock 2 SPKRGATE enable periodic m_speaker output 3 SPKRDATA direct output to m_speaker 4 RFRQGATE enable refresh and baud rate clocks 5 FDCRESET* reset 8272 6 TMRIN0 enable 80186 timer 0 7 TMRIN1 enable 80186 timer 1 */ // keyboard enable m_kb->power_w(BIT(data, 0)); // external baud rate clock m_extclk = BIT(data, 1); // m_speaker gate pit8253_gate0_w(m_pit, BIT(data, 2)); // m_speaker data m_spkrdata = BIT(data, 3); speaker_update(); // refresh and baud rate clocks pit8253_gate1_w(m_pit, BIT(data, 4)); pit8253_gate2_w(m_pit, BIT(data, 4)); // FDC reset if(BIT(data, 5)) m_fdc->reset(); // timer 0 enable m_maincpu->set_input_line(INPUT_LINE_TMRIN0, BIT(data, 6)); // timer 1 enable m_maincpu->set_input_line(INPUT_LINE_TMRIN1, BIT(data, 7)); } WRITE8_MEMBER( tandy2k_state::dma_mux_w ) { /* bit description 0 DMA channel 0 enable 1 DMA channel 1 enable 2 DMA channel 2 enable 3 DMA channel 3 enable 4 DMA channel 0 select 5 DMA channel 1 select 6 DMA channel 2 select 7 DMA channel 3 select */ m_dma_mux = data; // check for DMA error int drq0 = 0; int drq1 = 0; for (int ch = 0; ch < 4; ch++) { if (BIT(data, ch)) { if (BIT(data, ch + 4)) drq1++; else drq0++; } } int dme = (drq0 > 2) || (drq1 > 2); m_pic1->ir6_w(dme); } READ8_MEMBER( tandy2k_state::kbint_clr_r ) { if (m_pb_sel == KBDINEN) { m_kb->busy_w(1); m_pic1->ir0_w(CLEAR_LINE); } return 0xff; } READ16_MEMBER( tandy2k_state::vpac_r ) { if (ACCESSING_BITS_0_7) { return m_vpac->read(space, offset); } else { return 0xff00; } } WRITE16_MEMBER( tandy2k_state::vpac_w ) { if (ACCESSING_BITS_0_7) { m_vpac->write(space, offset, data & 0xff); } else { addr_ctrl_w(space, offset, data >> 8); } } READ8_MEMBER( tandy2k_state::fldtc_r ) { m_fdc->tc_w(true); m_fdc->tc_w(false); return 0; } WRITE8_MEMBER( tandy2k_state::fldtc_w ) { m_fdc->tc_w(true); m_fdc->tc_w(false); } WRITE8_MEMBER( tandy2k_state::addr_ctrl_w ) { /* bit signal description 8 A15 A15 of video access 9 A16 A16 of video access 10 A17 A17 of video access 11 A18 A18 of video access 12 A19 A19 of video access 13 CLKSPD clock speed (0 = 22.4 MHz, 1 = 28 MHz) 14 CLKCNT dots/char (0 = 10 [800x400], 1 = 8 [640x400]) 15 VIDOUTS selects the video source for display on monochrome monitor */ // video access m_vram_base = data & 0x1f; // dots per char int character_width = BIT(data, 6) ? 8 : 10; if (m_clkcnt != BIT(data, 6)) { m_vpac->set_hpixels_per_column(character_width); m_clkcnt = BIT(data, 6); } // video clock speed if (m_clkspd != BIT(data, 5)) { float pixel_clock = BIT(data, 5) ? XTAL_16MHz*28/16 : XTAL_16MHz*28/20; float character_clock = pixel_clock / character_width; m_vpac->set_unscaled_clock(pixel_clock); m_vac->set_unscaled_clock(character_clock); m_clkspd = BIT(data, 5); } // video source select m_vidouts = BIT(data, 7); logerror("Address Control %02x\n", data); } // Memory Maps static ADDRESS_MAP_START( tandy2k_mem, AS_PROGRAM, 16, tandy2k_state ) ADDRESS_MAP_UNMAP_HIGH // AM_RANGE(0x00000, 0xdffff) AM_RAM AM_RANGE(0xe0000, 0xf7fff) AM_RAM AM_SHARE("hires_ram") AM_RANGE(0xf8000, 0xfbfff) AM_RAM AM_SHARE("char_ram") AM_RANGE(0xfc000, 0xfdfff) AM_MIRROR(0x2000) AM_ROM AM_REGION(I80186_TAG, 0) ADDRESS_MAP_END static ADDRESS_MAP_START( tandy2k_io, AS_IO, 16, tandy2k_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000, 0x00001) AM_READWRITE8(enable_r, enable_w, 0x00ff) AM_RANGE(0x00002, 0x00003) AM_WRITE8(dma_mux_w, 0x00ff) AM_RANGE(0x00004, 0x00005) AM_READWRITE8(fldtc_r, fldtc_w, 0x00ff) AM_RANGE(0x00010, 0x00013) AM_DEVREADWRITE8(I8251A_TAG, i8251_device, data_r, data_w, 0x00ff) AM_RANGE(0x00030, 0x00033) AM_DEVICE8(I8272A_TAG, i8272a_device, map, 0x00ff) AM_RANGE(0x00040, 0x00047) AM_DEVREADWRITE8_LEGACY(I8253_TAG, pit8253_r, pit8253_w, 0x00ff) AM_RANGE(0x00052, 0x00053) AM_READ8(kbint_clr_r, 0x00ff) AM_RANGE(0x00050, 0x00057) AM_DEVREADWRITE8(I8255A_TAG, i8255_device, read, write, 0x00ff) AM_RANGE(0x00060, 0x00063) AM_DEVREADWRITE8_LEGACY(I8259A_0_TAG, pic8259_r, pic8259_w, 0x00ff) AM_RANGE(0x00070, 0x00073) AM_DEVREADWRITE8_LEGACY(I8259A_1_TAG, pic8259_r, pic8259_w, 0x00ff) AM_RANGE(0x00080, 0x00081) AM_DEVREADWRITE8(I8272A_TAG, i8272a_device, mdma_r, mdma_w, 0x00ff) // AM_RANGE(0x00100, 0x0017f) AM_DEVREADWRITE8(CRT9007_TAG, crt9007_device, read, write, 0x00ff) AM_WRITE8(addr_ctrl_w, 0xff00) AM_RANGE(0x00100, 0x0017f) AM_READWRITE(vpac_r, vpac_w) // AM_RANGE(0x00180, 0x00180) AM_READ8(hires_status_r, 0x00ff) // AM_RANGE(0x00180, 0x001bf) AM_WRITE(hires_palette_w) // AM_RANGE(0x001a0, 0x001a0) AM_READ8(hires_plane_w, 0x00ff) // AM_RANGE(0x0ff00, 0x0ffff) AM_READWRITE(i186_internal_port_r, i186_internal_port_w) ADDRESS_MAP_END static ADDRESS_MAP_START( tandy2k_hd_io, AS_IO, 16, tandy2k_state ) AM_IMPORT_FROM(tandy2k_io) // AM_RANGE(0x000e0, 0x000ff) AM_WRITE8(hdc_dack_w, 0x00ff) // AM_RANGE(0x0026c, 0x0026d) AM_DEVREADWRITE8_LEGACY(WD1010_TAG, hdc_reset_r, hdc_reset_w, 0x00ff) // AM_RANGE(0x0026e, 0x0027f) AM_DEVREADWRITE8_LEGACY(WD1010_TAG, wd1010_r, wd1010_w, 0x00ff) ADDRESS_MAP_END static ADDRESS_MAP_START( vpac_mem, AS_0, 8, tandy2k_state ) AM_RANGE(0x0000, 0x3fff) AM_READ(videoram_r) ADDRESS_MAP_END // Input Ports static INPUT_PORTS_START( tandy2k ) // defined in machine/tandy2kb.c INPUT_PORTS_END // Video UINT32 tandy2k_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { if (m_vidouts) { m_vac->screen_update(screen, bitmap, cliprect); } return 0; } /* static CRT9007_DRAW_SCANLINE( tandy2k_crt9007_display_pixels ) { tandy2k_state *state = device->machine().driver_data(); address_space &program = state->m_maincpu->space(AS_PROGRAM); for (int sx = 0; sx < x_count; sx++) { UINT32 videoram_addr = ((state->m_vram_base << 15) | (va << 1)) + sx; UINT8 videoram_data = program.read_word(videoram_addr); UINT16 charram_addr = (videoram_data << 4) | sl; UINT8 charram_data = state->m_char_ram[charram_addr] & 0xff; for (int bit = 0; bit < 10; bit++) { if (BIT(charram_data, 7)) { bitmap.pix16(y, x + (sx * 10) + bit) = 1; } charram_data <<= 1; } } } */ WRITE_LINE_MEMBER( tandy2k_state::vpac_vlt_w ) { m_drb0->clrcnt_w(state); m_drb1->clrcnt_w(state); } WRITE_LINE_MEMBER( tandy2k_state::vpac_drb_w ) { m_drb0->tog_w(state); m_drb1->tog_w(state); } static CRT9007_INTERFACE( vpac_intf ) { SCREEN_TAG, 10, DEVCB_DEVICE_LINE_MEMBER(I8259A_1_TAG, pic8259_device, ir1_w), DEVCB_NULL, // DMAR 80186 HOLD DEVCB_DEVICE_LINE_MEMBER(CRT9021B_TAG, crt9021_device, vsync_w), // VS DEVCB_NULL, // HS DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, vpac_vlt_w), // VLT DEVCB_DEVICE_LINE_MEMBER(CRT9021B_TAG, crt9021_device, cursor_w), // CURS DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, vpac_drb_w), // DRB DEVCB_DEVICE_LINE_MEMBER(CRT9021B_TAG, crt9021_device, retbl_w), // CBLANK DEVCB_DEVICE_LINE_MEMBER(CRT9021B_TAG, crt9021_device, slg_w), // SLG DEVCB_DEVICE_LINE_MEMBER(CRT9021B_TAG, crt9021_device, sld_w) // SLD }; static CRT9212_INTERFACE( drb0_intf ) { DEVCB_NULL, // ROF DEVCB_NULL, // WOF DEVCB_DEVICE_LINE_MEMBER(CRT9007_TAG, crt9007_device, vlt_r), // REN DEVCB_DEVICE_LINE_MEMBER(CRT9007_TAG, crt9007_device, wben_r), // WEN DEVCB_LINE_VCC // WEN2 }; static CRT9212_INTERFACE( drb1_intf ) { DEVCB_NULL, // ROF DEVCB_NULL, // WOF DEVCB_DEVICE_LINE_MEMBER(CRT9007_TAG, crt9007_device, vlt_r), // REN DEVCB_DEVICE_LINE_MEMBER(CRT9007_TAG, crt9007_device, wben_r), // WEN DEVCB_LINE_VCC // WEN2 }; static CRT9021_INTERFACE( vac_intf ) { SCREEN_TAG, DEVCB_DEVICE_MEMBER(CRT9212_0_TAG, crt9212_device, read), // data DEVCB_DEVICE_MEMBER(CRT9212_1_TAG, crt9212_device, read), // attributes DEVCB_LINE_VCC // ATTEN }; // Intel 8251A Interface WRITE_LINE_MEMBER( tandy2k_state::rxrdy_w ) { m_rxrdy = state; m_pic0->ir2_w(m_rxrdy || m_txrdy); } WRITE_LINE_MEMBER( tandy2k_state::txrdy_w ) { m_txrdy = state; m_pic0->ir2_w(m_rxrdy || m_txrdy); } static const i8251_interface usart_intf = { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, rxrdy_w), DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, txrdy_w), DEVCB_NULL, DEVCB_NULL }; // Intel 8253 Interface WRITE_LINE_MEMBER( tandy2k_state::outspkr_w ) { m_outspkr = state; speaker_update(); } WRITE_LINE_MEMBER( tandy2k_state::intbrclk_w ) { if (!m_extclk && state) { m_uart->transmit_clock(); m_uart->receive_clock(); } } WRITE_LINE_MEMBER( tandy2k_state::rfrqpulse_w ) { } static const struct pit8253_config pit_intf = { { { XTAL_16MHz/16, DEVCB_NULL, DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, outspkr_w) }, { XTAL_16MHz/8, DEVCB_NULL, DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, intbrclk_w) }, { XTAL_16MHz/8, DEVCB_NULL, DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, rfrqpulse_w) } } }; // Intel 8255A Interface READ8_MEMBER( tandy2k_state::ppi_pb_r ) { /* bit signal description 0 LPRIN0 auxiliary input 0 1 LPRIN1 auxiliary input 1 2 LPRIN2 auxiliary input 2 3 _LPRACK acknowledge 4 _LPRFLT fault 5 _LPRSEL select 6 LPRPAEM paper empty 7 LPRBSY busy */ UINT8 data = 0; switch (m_pb_sel) { case LPINEN: // printer acknowledge data |= m_centronics->ack_r() << 3; // printer fault data |= m_centronics->fault_r() << 4; // printer select data |= m_centronics->vcc_r() << 5; // paper empty data |= m_centronics->pe_r() << 6; // printer busy data |= m_centronics->busy_r() << 7; break; case KBDINEN: // keyboard data data = m_kbdin; break; case PORTINEN: // PCB revision data = 0x03; break; } return data; } WRITE8_MEMBER( tandy2k_state::ppi_pc_w ) { /* bit signal description 0 port A direction 1 port B input select bit 0 2 port B input select bit 1 3 LPRINT13 interrupt 4 STROBE IN 5 INBUFFULL 6 _LPRACK 7 _LPRDATSTB */ // input select m_pb_sel = (data >> 1) & 0x03; // interrupt m_pic1->ir3_w(BIT(data, 3)); // printer strobe m_centronics->strobe_w(BIT(data, 7)); } static I8255A_INTERFACE( ppi_intf ) { DEVCB_NULL, // Port A read DEVCB_DEVICE_MEMBER(CENTRONICS_TAG, centronics_device, write), // Port A write DEVCB_DRIVER_MEMBER(tandy2k_state, ppi_pb_r), // Port B write DEVCB_NULL, // Port B write DEVCB_NULL, // Port C read DEVCB_DRIVER_MEMBER(tandy2k_state, ppi_pc_w) // Port C write }; // Intel 8259 Interfaces /* IR0 MEMINT00 IR1 TMOINT01 IR2 SERINT02 IR3 BUSINT03 IR4 FLDINT04 IR5 BUSINT05 IR6 HDCINT06 IR7 BUSINT07 */ static const struct pic8259_interface pic0_intf = { DEVCB_CPU_INPUT_LINE(I80186_TAG, INPUT_LINE_INT0), DEVCB_LINE_VCC, DEVCB_NULL }; /* IR0 KBDINT10 IR1 VIDINT11 IR2 RATINT12 IR3 LPRINT13 IR4 MCPINT14 IR5 MEMINT15 IR6 DMEINT16 IR7 BUSINT17 */ static const struct pic8259_interface pic1_intf = { DEVCB_CPU_INPUT_LINE(I80186_TAG, INPUT_LINE_INT1), DEVCB_LINE_VCC, DEVCB_NULL }; // Intel 8272 Interface void tandy2k_state::fdc_irq(bool state) { m_pic0->ir4_w(state); } void tandy2k_state::fdc_drq(bool state) { dma_request(0, state); } static SLOT_INTERFACE_START( tandy2k_floppies ) SLOT_INTERFACE( "525qd", FLOPPY_525_QD ) SLOT_INTERFACE_END // Centronics Interface static const centronics_interface centronics_intf = { DEVCB_DEVICE_LINE_MEMBER(I8255A_TAG, i8255_device, pc6_w), // ACK output DEVCB_NULL, // BUSY output DEVCB_NULL // NOT BUSY output }; // Keyboard WRITE_LINE_MEMBER( tandy2k_state::kbdclk_w ) { if (!m_kbdclk && state) { m_kbdin >>= 1; m_kbdin |= m_kb->data_r() << 7; } m_kbdclk = state; } WRITE_LINE_MEMBER( tandy2k_state::kbddat_w ) { if (!m_kbddat && state) { m_kb->busy_w(m_kbdclk); m_pic1->ir0_w(!m_kbdclk); } m_kbddat = state; } static TANDY2K_KEYBOARD_INTERFACE( kb_intf ) { DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, kbdclk_w), DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, kbddat_w) }; // Machine Initialization void tandy2k_state::machine_start() { // memory banking address_space &program = m_maincpu->space(AS_PROGRAM); UINT8 *ram = m_ram->pointer(); int ram_size = m_ram->size(); program.install_ram(0x00000, ram_size - 1, ram); m_fdc->setup_intrq_cb(i8272a_device::line_cb(FUNC(tandy2k_state::fdc_irq), this)); m_fdc->setup_drq_cb(i8272a_device::line_cb(FUNC(tandy2k_state::fdc_drq), this)); // patch out i186 relocation register check UINT8 *rom = memregion(I80186_TAG)->base(); rom[0x1f16] = 0x90; rom[0x1f17] = 0x90; // register for state saving save_item(NAME(m_dma_mux)); save_item(NAME(m_kbdclk)); save_item(NAME(m_kbddat)); save_item(NAME(m_kbdin)); save_item(NAME(m_extclk)); save_item(NAME(m_rxrdy)); save_item(NAME(m_txrdy)); save_item(NAME(m_pb_sel)); save_item(NAME(m_vidouts)); save_item(NAME(m_clkspd)); save_item(NAME(m_clkcnt)); save_item(NAME(m_outspkr)); save_item(NAME(m_spkrdata)); } // Machine Driver static MACHINE_CONFIG_START( tandy2k, tandy2k_state ) // basic machine hardware MCFG_CPU_ADD(I80186_TAG, I80186, XTAL_16MHz) MCFG_CPU_PROGRAM_MAP(tandy2k_mem) MCFG_CPU_IO_MAP(tandy2k_io) // video hardware MCFG_SCREEN_ADD(SCREEN_TAG, RASTER) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // not accurate MCFG_SCREEN_UPDATE_DRIVER(tandy2k_state, screen_update) MCFG_SCREEN_SIZE(640, 480) MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) MCFG_CRT9007_ADD(CRT9007_TAG, XTAL_16MHz*28/16, vpac_intf, vpac_mem) MCFG_CRT9212_ADD(CRT9212_0_TAG, drb0_intf) MCFG_CRT9212_ADD(CRT9212_1_TAG, drb1_intf) MCFG_CRT9021_ADD(CRT9021B_TAG, XTAL_16MHz*28/16/8, vac_intf) // sound hardware MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) // devices MCFG_I8255A_ADD(I8255A_TAG, ppi_intf) MCFG_I8251_ADD(I8251A_TAG, usart_intf) MCFG_PIT8253_ADD(I8253_TAG, pit_intf) MCFG_PIC8259_ADD(I8259A_0_TAG, pic0_intf) MCFG_PIC8259_ADD(I8259A_1_TAG, pic1_intf) MCFG_I8272A_ADD(I8272A_TAG, true) MCFG_FLOPPY_DRIVE_ADD(I8272A_TAG ":0", tandy2k_floppies, "525qd", 0, floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD(I8272A_TAG ":1", tandy2k_floppies, "525qd", 0, floppy_image_device::default_floppy_formats) MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics) MCFG_TANDY2K_KEYBOARD_ADD(kb_intf) // software lists MCFG_SOFTWARE_LIST_ADD("flop_list", "tandy2k") // internal ram MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("128K") MCFG_RAM_EXTRA_OPTIONS("256K,384K,512K,640K,768K,896K") MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( tandy2k_hd, tandy2k ) // basic machine hardware MCFG_CPU_MODIFY(I80186_TAG) MCFG_CPU_IO_MAP(tandy2k_hd_io) // Tandon TM502 hard disk MCFG_HARDDISK_ADD("harddisk0") //MCFG_WD1010_ADD(WD1010_TAG, wd1010_intf) //MCFG_WD1100_11_ADD(WD1100_11_TAG, wd1100_11_intf) MACHINE_CONFIG_END // ROMs ROM_START( tandy2k ) ROM_REGION( 0x2000, I80186_TAG, 0 ) ROM_LOAD16_BYTE( "484a00.u48", 0x0000, 0x1000, CRC(a5ee3e90) SHA1(4b1f404a4337c67065dd272d62ff88dcdee5e34b) ) ROM_LOAD16_BYTE( "474600.u47", 0x0001, 0x1000, CRC(345701c5) SHA1(a775cbfa110b7a88f32834aaa2a9b868cbeed25b) ) ROM_REGION( 0x100, "plds", 0 ) ROM_LOAD( "82s153.u62", 0x000, 0x100, NO_DUMP ) // interrupt/DMA ROM_LOAD( "82s153.u68", 0x000, 0x100, NO_DUMP ) // video ROM_LOAD( "82s153.u95", 0x000, 0x100, NO_DUMP ) // memory timing ROM_LOAD( "pal10l8.u82", 0x000, 0x100, NO_DUMP ) // video ROM_LOAD( "pal16l8a.u102", 0x000, 0x100, NO_DUMP ) // bus interface ROM_LOAD( "pal16l8a.u103", 0x000, 0x100, NO_DUMP ) // bus interface ROM_LOAD( "pal20l8.u103", 0x000, 0x100, NO_DUMP ) // bus interface, alternate ROM_LOAD( "pal16r6a.u16", 0x000, 0x100, NO_DUMP ) // HDC ROM_END #define rom_tandy2khd rom_tandy2k // System Drivers // YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS COMP( 1983, tandy2k, 0, 0, tandy2k, tandy2k, driver_device, 0, "Tandy Radio Shack", "Tandy 2000", GAME_NOT_WORKING) COMP( 1983, tandy2khd, tandy2k, 0, tandy2k_hd, tandy2k, driver_device, 0, "Tandy Radio Shack", "Tandy 2000HD", GAME_NOT_WORKING)