// license:BSD-3-Clause // copyright-holders:Jonathan Gevaryahu /****************************************************************************** * * Telesensory Systems Inc./Speech Plus * 1500 and 2000 series * Prose 2020 * Copyright (C) 2011-2013 Jonathan Gevaryahu AKA Lord Nightmare and Kevin 'kevtris' Horton * * The Prose 2000 card is an IEEE 796 Multibus card, with additional connectors to facilitate power and serial input other than via multibus. * There are two hardware versions of the card: * - The 1981 Telesensory Systems Inc copyrighted version * (lacks U82, has some rework on the power input to add a bypass capacitor and an extra power line to the 8086) * - The 1986 Speech Plus copyrighted version * (adds U82 as an extra buffer for status (not sure)? integrates the greenwire fixes from the above board, minor reorganizations of passives) * Both versions encountered have been in non-multibus enclosures: * - The 1981 Version appeared on a 'Voice V4' Speech board scrapped from a "Kurzweil Reading Machine" Talking Scanner (predecessor to the TSI/Kurzweil/Xerox 'Reading Edge' scanner which is SPARC based) [I'm very sorry I didn't get the OCR computing guts of the scanner itself too :( ] * - The 1986 Version appeared in a 'Prose 2020' under-monitor RS232 speech unit. * * DONE: * Skeleton Written * Load cpu and dsp ROMs and mapper PROMs * Successful compile * Successful run * Correctly Interleave 8086 CPU ROMs * Debug LEDs hooked to popmessage * Correctly load UPD7720 ROMs as UPD7725 data - done; this is utterly disgusting code, but appears to work. * Attached i8251a uart at u15 * Added dipswitch array S4 * Attached 8259 PIC * IR0 = upd7720 p0 pin masked by (probably peripheral bit 8) * IR1 = i8251 rxrdy * IR2 = i8251 txempty * IR3 = i8251 txrdy * IR4,5,6,7 unknown so far, not hooked up yet * Hooked the terminal to the i8251a uart at u15 * Hooked up upd7720 reset line * Verified CPU and DSP clocks * * TODO: * UPD7720: hook up serial output and SCK, and hook SO to the DAC; this requires fixing the upd7725 core to actually support SCK and serial output/SO! * Attach the other i8251a uart (assuming it is hooked to the main hardware at all!) * Correctly implement UPD7720 cpu core to avoid needing revolting conversion code; this probably involves overriding and duplicating much of the exec_xx sections of the 7725 core * Correct memory maps and io maps, and figure out what all the PROMs do - mostly done * 8259 PIC: figure out where IR4-7 come from, if anywhere. * UPD7720 and 8259: hook up p0 and p1 as outputs, and figure out how 8259 IR0 is masked from 7720 p0. * Add other dipswitches and jumpers (these may actually just control clock dividers for the two 8251s) * Older v1.1 set gets stuck forever waiting for upd7720 status port to equal 0x20, which never happens. * Everything else * * Notes: * Text in ROM indicates there is a test mode 'activated by switch s4 dash 7' * When switch s4-7 is switched on, the hardware says, over and over: * "This is version 3.4.1 test mode, activated by switch s4 dash 7" * * 0x03400: the peripheral register * the low 8 bits (7-0) are Sw4 * the high 8 bits: * Bit F E D C B A 9 8 * | | | | | | | \- unknown but used, probably control (1=allow 0=mask?) 7720 p0 int to 8259 ir0? * | | | | | | \--- LED 6 control (0 = on) * | | | | | \----- LED 5 control (0 = on) * | | | | \------- LED 4 control (0 = on) * | | | \--------- LED 3 control (0 = on) * | | \----------- unknown, possibly unused? * | \------------- UPD7720 RESET line (0 = high/in reset, 1 = low/running) * \--------------- unknown, possibly unused? but might possibly related to 7720 p0->8259 as well? * * When the unit is idle, leds 5 and 3 are on and upd7720 reset is low (write of 0b?1?0101?. * On all character writes from i8251, bit 8 is unset, then set again, possibly to avoid interrupt clashes? * * Bootup notes v3.4.1: * D3109: checks if 0x80 (S4-8) is set: if set, continue, else jump to D3123 * D3123: write 0x1C (0 0 0 [1 1 1 0] 0) to 3401 * then jump to D32B0 * D32B0: memory test routine: * This routine flood-fills memory from 0000-2FFF with 0xFF, * then, bytewise starting from 0000, shifts the value progresively * right by one, writes it and checks that it still matches, * i.e. read 0xFF, write 0x7f, read 0x7f, write 0x3f... etc. * Loop at D32E4. * D32E6: similar to D32B0, but rotates in 1 bits to 16 bit words, * though only the low byte is written, and only fills the 2BFF * down to 0000 region. (seems rather redundant, actually) * Loop at D3301. * D3311: write 0x0A (0 0 0 [0 1 0 1] 0) to 3401 * then jump to D3330 * D3330: jump back to D312E * D312E: this is some unknown conditional code, usually goes to D314E * if BP is not 1, go to D314E and don't update leds (usually taken?) * if BP is 1 and SI is 0, delay for 8*65536 cycles. no delay if si!=0 * write 0x0C (0 0 0 [0 1 1 0] 0) to 3401 * D314E: floodfill 0000-2BFF with 0x55 (rep at D315C) * check if bp was 1 and jump to D318F if it was * write 0x14 (0 0 0 [1 0 1 0] 0) to 3401 * call E3987: initialize UPD7720, return * D33D2: checksum the ROMs in 5? passes, loop at D33DA, test at D33E6 (which passes) * if test DID fail: write 0x10 (0 0 0 [1 0 0 0] 0) to 3401 * more stuff * write 0xFF to 3401 * more stuff * set up word table? not sure what its doing here... * if test does NOT fail (and it doesn't): * D3414: write 0x08 (0 0 0 [0 1 0 0] 0) to 3400 * D5E14: initialize PIC8259 * * D338A: write 0x12 0 0 0 [1 0 0 1] 0 to 3401 * * F44B4: general in-operation LED status write ******************************************************************************/ /* Core includes */ #include "emu.h" #include "includes/tsispch.h" #include "bus/rs232/rs232.h" #include "cpu/i86/i86.h" #include "machine/clock.h" #include "machine/i8251.h" #include "sound/dac.h" #include "sound/volt_reg.h" #include "speaker.h" // defines #define DEBUG_PARAM 1 #undef DEBUG_DSP #undef DEBUG_DSP_W /* Devices and handlers */ /***************************************************************************** USART 8251 and Terminal stuff *****************************************************************************/ WRITE_LINE_MEMBER(tsispch_state::i8251_rxrdy_int) { m_pic->ir1_w(state); } WRITE_LINE_MEMBER(tsispch_state::i8251_txempty_int) { m_pic->ir2_w(state); } WRITE_LINE_MEMBER(tsispch_state::i8251_txrdy_int) { m_pic->ir3_w(state); } /***************************************************************************** LED/dipswitch stuff *****************************************************************************/ READ8_MEMBER( tsispch_state::dsw_r ) { /* the only dipswitch I'm really sure about is s4-7 which enables the test mode * The switches are, for normal operation on my unit (and the older unit as well): * 1 2 3 4 5 6 7 8 * ON ON OFF OFF OFF OFF OFF OFF * which makes this register read 0xFC * When s4-7 is turned on, it reads 0xBC */ return ioport("s4")->read(); } WRITE8_MEMBER( tsispch_state::peripheral_w ) { /* This controls the four LEDS, the RESET line for the upd77p20, and (probably) the p0-to-ir0 masking of the upd77p20; there are two unknown and seemingly unused bits as well. see the top of the file for more info. */ m_paramReg = data; m_dsp->set_input_line(INPUT_LINE_RESET, BIT(data,6)?CLEAR_LINE:ASSERT_LINE); #ifdef DEBUG_PARAM //fprintf(stderr,"8086: Parameter Reg written: UNK7: %d, DSPRST6: %d; UNK5: %d; LED4: %d; LED3: %d; LED2: %d; LED1: %d; DSPIRQMASK: %d\n", BIT(data,7), BIT(data,6), BIT(data,5), BIT(data,4), BIT(data,3), BIT(data,2), BIT(data,1), BIT(data,0)); logerror("8086: Parameter Reg written: UNK7: %d, DSPRST6: %d; UNK5: %d; LED4: %d; LED3: %d; LED2: %d; LED1: %d; DSPIRQMASK: %d\n", BIT(data,7), BIT(data,6), BIT(data,5), BIT(data,4), BIT(data,3), BIT(data,2), BIT(data,1), BIT(data,0)); #endif popmessage("LEDS: 6/Talking:%d 5:%d 4:%d 3:%d\n", 1-BIT(data,1), 1-BIT(data,2), 1-BIT(data,3), 1-BIT(data,4)); } /***************************************************************************** UPD77P20 stuff *****************************************************************************/ READ16_MEMBER( tsispch_state::dsp_data_r ) { #ifdef DEBUG_DSP uint8_t temp = m_dsp->snesdsp_read(true); fprintf(stderr, "dsp data read: %02x\n", temp); return temp; #else return m_dsp->snesdsp_read(true); #endif } WRITE16_MEMBER( tsispch_state::dsp_data_w ) { #ifdef DEBUG_DSP_W fprintf(stderr, "dsp data write: %02x\n", data); #endif m_dsp->snesdsp_write(true, data); } READ16_MEMBER( tsispch_state::dsp_status_r ) { #ifdef DEBUG_DSP uint8_t temp = m_dsp->snesdsp_read(false); fprintf(stderr, "dsp status read: %02x\n", temp); return temp; #else return m_dsp->snesdsp_read(false); #endif } WRITE16_MEMBER( tsispch_state::dsp_status_w ) { fprintf(stderr, "warning: upd772x status register should never be written to!\n"); m_dsp->snesdsp_write(false, data); } WRITE_LINE_MEMBER( tsispch_state::dsp_to_8086_p0_w ) { fprintf(stderr, "upd772x changed p0 state to %d!\n",state); //TODO: do stuff here! } WRITE_LINE_MEMBER( tsispch_state::dsp_to_8086_p1_w ) { fprintf(stderr, "upd772x changed p1 state to %d!\n",state); //TODO: do stuff here! } /***************************************************************************** Reset and Driver Init *****************************************************************************/ void tsispch_state::machine_reset() { fprintf(stderr,"machine reset\n"); m_dsp->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); // starts in reset } void tsispch_state::init_prose2k() { uint8_t *dspsrc = (uint8_t *)(memregion("dspprgload")->base()); uint32_t *dspprg = (uint32_t *)(memregion("dspprg")->base()); fprintf(stderr,"driver init\n"); // unpack 24 bit 7720 data into 32 bit space and shuffle it so it can run as 7725 code // data format as-is in dspsrc: (L = always 0, X = doesn't matter) // source upd7720 dest upd7725 // bit 7 6 5 4 3 2 1 0 bit 7 6 5 4 3 2 1 0 // for OP/RT: // b1 15 16 17 18 19 20 21 22 -> 22 21 20 19 18 17 16 15 // b2 L 8 9 10 11 12 13 14 -> 14 13 12 L 11 10 9 8 // b3 0 1 2 3 4 5 6 7 -> 7 6 5 4 3 2 1 0 // for JP: // b1 15 16 17 18 19 20 21 22 -> 22 21 20 19 18 17 16 15 // b2 L 8 9 10 11 12 13 14 -> 14 13 L L L 12 11 10 // b3 0 1 2 3 4 5 6 7 -> 9 8 7 6 5 4 X X // for LD: // b1 15 16 17 18 19 20 21 22 -> 22 21 20 19 18 17 16 15 // b2 L 8 9 10 11 12 13 14 -> 14 13 12 11 10 9 8 7 // b3 0 1 2 3 4 5 6 7 -> 6 5 X X 3 2 1 0 for (int i = 0; i < 0x600; i+= 3) { uint8_t byte1t = bitswap<8>(dspsrc[0+i], 0, 1, 2, 3, 4, 5, 6, 7); uint16_t byte23t; // here's where things get disgusting: if the first byte was an OP or RT, do the following: if ((byte1t&0x80) == 0x00) // op or rt instruction { byte23t = bitswap<16>( (((uint16_t)dspsrc[1+i]<<8)|dspsrc[2+i]), 8, 9, 10, 15, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7); } else if ((byte1t&0xC0) == 0x80) // jp instruction { byte23t = bitswap<16>( (((uint16_t)dspsrc[1+i]<<8)|dspsrc[2+i]), 8, 9, 15, 15, 15, 10, 11, 12, 13, 14, 0, 1, 2, 3, 6, 7); } else // ld instruction { byte23t = bitswap<16>( (((uint16_t)dspsrc[1+i]<<8)|dspsrc[2+i]), 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 3, 4, 5, 6, 7); } *dspprg = byte1t<<24 | byte23t<<8; dspprg++; } m_paramReg = 0x00; // on power up, all leds on, reset to upd7720 is high } /****************************************************************************** Address Maps ******************************************************************************/ /* The address map of the prose 2020 is controlled by 2 PROMs, see the ROM section for details on those. (x = ignored; * = selects address within this range; s = selects one of a pair of chips) A19 A18 A17 A16 A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 0 0 x x 0 x 0 * * * * * * * * * * * * s 6264*2 SRAM first half 0 0 x x 0 x 1 0 * * * * * * * * * * * s 6264*2 SRAM 3rd quarter 0 0 x x 0 x 1 1 0 0 0 x x x x x x x * x iP8251A @ U15 0 0 x x 0 x 1 1 0 0 1 x x x x x x x * x AMD P8259A PIC 0 0 x x 0 x 1 1 0 1 0 x x x x x x x x * LEDS, dipswitches, and UPD77P20 control lines 0 0 x x 0 x 1 1 0 1 1 x x x x x x x * x UPD77P20 data/status 0 0 x x 0 x 1 1 1 x x Open bus, verified (returns 0x00EA) 0 0 x x 1 x Open bus? (or maybe communication with multibus connector?) (returns 0xFA,B,C,FFF) 0 1 Open bus, verified (returns 0x00EA) 1 0 Open bus, verified (returns 0x00EA) 1 1 0 * * * * * * * * * * * * * * * * s ROMs 2 and 3 1 1 1 * * * * * * * * * * * * * * * * s ROMs 0 and 1 */ void tsispch_state::i8086_mem(address_map &map) { map.unmap_value_high(); map(0x00000, 0x02FFF).mirror(0x34000).ram(); // verified; 6264*2 SRAM, only first 3/4 used map(0x03000, 0x03003).mirror(0x341FC).rw("i8251a_u15", FUNC(i8251_device::read), FUNC(i8251_device::write)).umask16(0x00ff); map(0x03200, 0x03203).mirror(0x341FC).rw(m_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff); // AMD P8259 PIC @ U5 (reads as 04 and 7c, upper byte is open bus) map(0x03400, 0x03400).mirror(0x341FE).r(FUNC(tsispch_state::dsw_r)); // verified, read from dipswitch s4 map(0x03401, 0x03401).mirror(0x341FE).w(FUNC(tsispch_state::peripheral_w)); // verified, write to the 4 leds, plus 4 control bits map(0x03600, 0x03601).mirror(0x341FC).rw(FUNC(tsispch_state::dsp_data_r), FUNC(tsispch_state::dsp_data_w)); // verified; UPD77P20 data reg r/w map(0x03602, 0x03603).mirror(0x341FC).rw(FUNC(tsispch_state::dsp_status_r), FUNC(tsispch_state::dsp_status_w)); // verified; UPD77P20 status reg r map(0xc0000, 0xfffff).rom(); // verified } // Technically the IO line of the i8086 is completely ignored (it is running in 8086 MIN mode,I believe, which may ignore IO) void tsispch_state::i8086_io(address_map &map) { map.unmap_value_high(); } void tsispch_state::dsp_prg_map(address_map &map) { map(0x0000, 0x01ff).rom().region("dspprg", 0); } void tsispch_state::dsp_data_map(address_map &map) { map(0x0000, 0x01ff).rom().region("dspdata", 0); } /****************************************************************************** Input Ports ******************************************************************************/ static INPUT_PORTS_START( prose2k ) PORT_START("s4") // dipswitch array s4 PORT_DIPNAME( 0x01, 0x00, "S4-1") PORT_DIPLOCATION("SW4:1") PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, "S4-2") PORT_DIPLOCATION("SW4:2") PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x04, 0x04, "S4-3") PORT_DIPLOCATION("SW4:3") PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x08, 0x08, "S4-4") PORT_DIPLOCATION("SW4:4") PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x10, 0x10, "S4-5") PORT_DIPLOCATION("SW4:5") PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x20, 0x20, "S4-6") PORT_DIPLOCATION("SW4:6") PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x40, 0x40, "S4-7: Self Test") PORT_DIPLOCATION("SW4:7") PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x80, 0x80, "S4-8") PORT_DIPLOCATION("SW4:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) INPUT_PORTS_END /****************************************************************************** Machine Drivers ******************************************************************************/ void tsispch_state::prose2k(machine_config &config) { /* basic machine hardware */ /* There are two crystals on the board: a 24MHz xtal at Y2 and a 16MHz xtal at Y1 */ I8086(config, m_maincpu, 8000000); /* VERIFIED clock, unknown divider */ m_maincpu->set_addrmap(AS_PROGRAM, &tsispch_state::i8086_mem); m_maincpu->set_addrmap(AS_IO, &tsispch_state::i8086_io); m_maincpu->set_irq_acknowledge_callback("pic8259", FUNC(pic8259_device::inta_cb)); /* TODO: the UPD7720 has a 10KHz clock to its INT pin */ /* TODO: the UPD7720 has a 2MHz clock to its SCK pin */ /* TODO: hook up p0, p1, int */ UPD7725(config, m_dsp, 8000000); /* VERIFIED clock, unknown divider; correct dsp type is UPD77P20 */ m_dsp->set_addrmap(AS_PROGRAM, &tsispch_state::dsp_prg_map); m_dsp->set_addrmap(AS_DATA, &tsispch_state::dsp_data_map); m_dsp->p0().set(FUNC(tsispch_state::dsp_to_8086_p0_w)); m_dsp->p1().set(FUNC(tsispch_state::dsp_to_8086_p1_w)); /* PIC 8259 */ PIC8259(config, m_pic, 0); m_pic->out_int_callback().set_inputline(m_maincpu, 0); /* uarts */ i8251_device &u15(I8251(config, "i8251a_u15", 0)); u15.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); u15.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr)); u15.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); u15.rxrdy_handler().set(FUNC(tsispch_state::i8251_rxrdy_int)); u15.txrdy_handler().set(FUNC(tsispch_state::i8251_txrdy_int)); u15.txempty_handler().set(FUNC(tsispch_state::i8251_txempty_int)); clock_device &clock(CLOCK(config, "baudclock", 153600)); clock.signal_handler().set("i8251a_u15", FUNC(i8251_device::write_txc)); clock.signal_handler().append("i8251a_u15", FUNC(i8251_device::write_rxc)); /* sound hardware */ SPEAKER(config, "speaker").front_center(); DAC_12BIT_R2R(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC (TODO: correctly figure out how the DAC works; apparently it is connected to the serial output of the upd7720, which will be "fun" to connect up) voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref")); vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac", -1.0, DAC_VREF_NEG_INPUT); rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); rs232.rxd_handler().set("i8251a_u15", FUNC(i8251_device::write_rxd)); rs232.dsr_handler().set("i8251a_u15", FUNC(i8251_device::write_dsr)); rs232.cts_handler().set("i8251a_u15", FUNC(i8251_device::write_cts)); } /****************************************************************************** ROM Definitions ******************************************************************************/ ROM_START( prose2k ) ROM_REGION(0x100000,"maincpu", 0) // prose 2000/2020 firmware version 3.4.1 ROMX_LOAD( "v3.4.1__2000__2.u22", 0xc0000, 0x10000, CRC(201d3114) SHA1(549ef1aa28d5664d4198cbc1826b31020d6c4870),ROM_SKIP(1)) ROMX_LOAD( "v3.4.1__2000__3.u45", 0xc0001, 0x10000, CRC(190c77b6) SHA1(2b90b3c227012f2085719e6283da08afb36f394f),ROM_SKIP(1)) ROMX_LOAD( "v3.4.1__2000__0.u21", 0xe0000, 0x10000, CRC(3fae874a) SHA1(e1d3e7ba309b29a9c3edbe3d22becf82eae50a31),ROM_SKIP(1)) ROMX_LOAD( "v3.4.1__2000__1.u44", 0xe0001, 0x10000, CRC(bdbb0785) SHA1(6512a8c2641e032ef6bb0889490d82f5d4399575),ROM_SKIP(1)) // TSI/Speech plus DSP firmware v3.12 8/9/88, NEC UPD77P20 ROM_REGION( 0x600, "dspprgload", 0) // packed 24 bit data ROM_LOAD( "v3.12__8-9-88__dsp_prog.u29", 0x0000, 0x0600, CRC(9e46425a) SHA1(80a915d731f5b6863aeeb448261149ff15e5b786)) ROM_REGION32_BE( 0x800, "dspprg", ROMREGION_ERASEFF) // for unpacking 24 bit data into 32 bit data which cpu core can understand ROM_REGION16_BE( 0x400, "dspdata", 0) ROM_LOAD16_WORD_SWAP( "v3.12__8-9-88__dsp_data.u29", 0x0000, 0x0400, CRC(f4e4dd16) SHA1(6e184747db2f26e45d0e02907105ff192e51baba)) // mapping PROMs: // All are am27s19 32x8 TriState PROMs (equivalent to 82s123/6331) // L - always low; H - always high // U77: unknown (what does this do? likely as to do with multibus and possibly waitstates?) // input is A19 for I4, A18 for I3, A15 for I2, A13 for I1, A12 for I0 // output bits 0bLLLLzyxH (TODO: recheck) // bit - function // 7, 6, 5, 4 - seem unconnected? // 3 - connection unknown, low in the RAM, ROM, and Peripheral memory areas // 2 - connection unknown, low in the RAM and ROM memory areas // 1 - unknown, always high (TODO: recheck) // 0 - unknown, always high // // U79: SRAM and peripheral mapping: // input is A19 for I4, A18 for I3, A15 for I2, A13 for I1, A12 for I0, same as U77 // On the Prose 2000 later board dumped, only bits 3 and 0 are used; // bits 7-4 are always low, bits 2 and 1 are always high. // SRAMS are only populated in U61 and U64. // On the Prose 2000 earlier board dumped, bits 3,2,1,0 are all used; // bits 7-4 are always low. SRAM is in 6 6116s, mapped the same as the 2 6264s on the later board. // output bits 0bLLLL3210 // 7,6,5,4 - seem unconnected? // 3 - to /EN3 (pin 4) of 74S138N at U80 // AND to EN1 (pin 6) of 74S138N at U78 // i.e. one is activated when pin is high and other when pin is low // The 74S138N at U80: [*ENABLED ONLY WITHIN/CONTROLS THE 3000-3FFF AREA*] // /EN2 - pulled to GND // EN1 - pulled to VCC through resistor R5 // inputs: S0 - A9; S1 - A10; S2 - A11 // /Y0 - /CS (pin 11) of iP8251A at U15 [0x3000-0x31FF] // /Y1 - /CS (pin 1) of AMD 8259A at U4 [0x3200-0x33FF] // /Y2 - pins 1, 4, 9 (1A, 2A, 3A inputs) of 74HCT32 Quad OR gate at U58 [0x3400-0x35FF] // /Y3 - pin 26 (/CS) of UPD77P20 at U29 [0x3600-0x37FF] // /Y4 through /Y7 - seem unconnected? [0x3800-0x3FFF] // The 74S138N at U78: [*ENABLED IN ALL AREAS EXCEPT 3000-3FFF*] // /EN3 - ? (TODO: figure these out) // /EN2 - ? // inputs: S0 - A18; S1 - A19; S2 - Pulled to GND // /Y0 - ? // /Y1 - ? // /Y2 - ? // /Y3 - connects somewhere, only active when A18 and A19 are high, possibly a ROM bus buffer enable? (TODO: figure out what this does) // /Y4-/Y7 - never used since S2 is pulled to GND // 2 - to /CS1 on 6264 SRAMs at U63 and U66 // 1 - to /CS1 on 6264 SRAMs at U62 and U65 // 0 - to /CS1 on 6264 SRAMs at U61 and U64 // // U81: (OPTIONAL) maps ROMS: input is A19-A15 for I4,3,2,1,0 // On the Prose 2000 board dumped, only bits 6 and 5 are used, // the rest are always high; maps ROMs 0,1,2,3 to C0000-FFFFF. // The Prose 2000 board has empty unpopulated sockets for ROMs 4-15; // if present these would be driven by a different PROM in this location. // bit - function // 7 - to /CE of ROMs 14(U28) and 15(U51) // 6 - to /CE of ROMs 0(U21) and 1(U44) // 5 - to /CE of ROMs 2(U22) and 3(U45) // 4 - to /CE of ROMs 4(U23) and 5(U46) // 3 - to /CE of ROMs 6(U24) and 7(U47) // 2 - to /CE of ROMs 8(U25) and 9(U48) // 1 - to /CE of ROMs 10(U26) and 11(U49) // 0 - to /CE of ROMs 12(U27) and 13(U50) // // Note U81 is optional; it can be replaced by a 74s138 instead of a PROM, // with A19, A18, A17 as inputs, for decoding the ROMs as: // 7 - to /CE of ROMs 0(U21) and 1(U44) (0xE0000-0xE3FFF) // 6 - to /CE of ROMs 2(U22) and 3(U45) (0xE4000-0xE7FFF) // 5 - to /CE of ROMs 4(U23) and 5(U46) (0xE8000-0xEBFFF) // 4 - to /CE of ROMs 6(U24) and 7(U47) (0xEC000-0xEFFFF) // 3 - to /CE of ROMs 8(U25) and 9(U48) (0xF0000-0xF3FFF) // 2 - to /CE of ROMs 10(U26) and 11(U49) (0xF4000-0xF7FFF) // 1 - to /CE of ROMs 12(U27) and 13(U50) (0xF8000-0xFBFFF) // 0 - to /CE of ROMs 14(U28) and 15(U51) (0xFC000-0xFFFFF) ROM_REGION(0x1000, "proms", 0) ROM_LOAD( "am27s19.u77", 0x0000, 0x0020, CRC(a88757fc) SHA1(9066d6dbc009d7a126d75b8461ca464ddf134412)) ROM_LOAD( "am27s19.u79", 0x0020, 0x0020, CRC(a165b090) SHA1(bfc413c79915c68906033741318c070ad5dd0f6b)) ROM_LOAD( "am27s19.u81", 0x0040, 0x0020, CRC(62e1019b) SHA1(acade372edb08fd0dcb1fa3af806c22c47081880)) ROM_END ROM_START( prose2ko ) // 'Older' prose2k set ROM_REGION(0x100000,"maincpu", 0) // prose 2000 firmware version 1.1 ROMX_LOAD( "v1.1__6__speech__plus__=c=1983.am2764.6.u24", 0xec000, 0x2000, CRC(c881f92d) SHA1(2d4eb96360adac54d4f0110595bfaf682280c1ca),ROM_SKIP(1)) ROMX_LOAD( "v1.1__7__speech__plus__=c=1983.am2764.7.u47", 0xec001, 0x2000, CRC(4d5771cb) SHA1(55ed59ad1cad154804dbeeebed98f062783c33c3),ROM_SKIP(1)) ROMX_LOAD( "v1.1__8__speech__plus__=c=1983.am2764.8.u25", 0xf0000, 0x2000, CRC(adf9bfb8) SHA1(0b73561b52b388b740fabf07ada2d70a52f22037),ROM_SKIP(1)) ROMX_LOAD( "v1.1__9__speech__plus__=c=1983.am2764.9.u48", 0xf0001, 0x2000, CRC(355f97d2) SHA1(7655fc55b577821e0bd8bf81fb74b8a20b1df098),ROM_SKIP(1)) ROMX_LOAD( "v1.1__10__speech__plus__=c=1983.am2764.10.u26", 0xf4000, 0x2000, CRC(949a0344) SHA1(8e33c69dfc413aea95f166b08902ad97b1e3e980),ROM_SKIP(1)) ROMX_LOAD( "v1.1__11__speech__plus__=c=1983.am2764.11.u49", 0xf4001, 0x2000, CRC(ad9a0670) SHA1(769f2f8696c7b6907706466aa9ab7a897ed9f889),ROM_SKIP(1)) ROMX_LOAD( "v1.1__12__speech__plus__=c=1983.am2764.12.u27", 0xf8000, 0x2000, CRC(9eaf9378) SHA1(d296b1d347c03e6123c38c208ead25b1f43b9859),ROM_SKIP(1)) ROMX_LOAD( "v1.1__13__speech__plus__=c=1983.am2764.13.u50", 0xf8001, 0x2000, CRC(5e173667) SHA1(93230c2fede5095f56e10d20ea36a5a45a1e7356),ROM_SKIP(1)) ROMX_LOAD( "v1.1__14__speech__plus__=c=1983.am2764.14.u28", 0xfc000, 0x2000, CRC(e616bd6e) SHA1(5dfae2c5079d89f791c9d7166f9504231a464203),ROM_SKIP(1)) ROMX_LOAD( "v1.1__15__speech__plus__=c=1983.am2764.15.u51", 0xfc001, 0x2000, CRC(beb1fa19) SHA1(72130fe45c3fd3de7cf794936dc68ed2d4193daf),ROM_SKIP(1)) // TSI/Speech plus DSP firmware v?.? (no sticker, but S140025 printed on chip), unlabeled chip, but clearly a NEC UPD7720C ceramic // NOT DUMPED YET, using the 3.12 dsp firmware as a placeholder, since the dsp on the older board is mask ROM and doesn't dump easily ROM_REGION( 0x600, "dspprgload", 0) // packed 24 bit data ROM_LOAD( "s140025__dsp_prog.u29", 0x0000, 0x0600, NO_DUMP) ROM_LOAD( "v3.12__8-9-88__dsp_prog.u29", 0x0000, 0x0600, CRC(9e46425a) SHA1(80a915d731f5b6863aeeb448261149ff15e5b786)) // temp placeholder ROM_REGION32_BE( 0x800, "dspprg", ROMREGION_ERASEFF) // for unpacking 24 bit data into 32 bit data which cpu core can understand ROM_REGION16_BE( 0x400, "dspdata", 0) ROM_LOAD( "s140025__dsp_data.u29", 0x0000, 0x0400, NO_DUMP) ROM_LOAD16_WORD_SWAP( "v3.12__8-9-88__dsp_data.u29", 0x0000, 0x0400, CRC(f4e4dd16) SHA1(6e184747db2f26e45d0e02907105ff192e51baba)) // temp placeholder ROM_REGION(0x1000, "proms", 0) ROM_LOAD( "dm74s288n.u77", 0x0000, 0x0020, CRC(a88757fc) SHA1(9066d6dbc009d7a126d75b8461ca464ddf134412)) // == am27s19.u77 ROM_LOAD( "dm74s288n.whitespot.u79", 0x0020, 0x0020, CRC(7faee6cb) SHA1(b6dd2a6909dac9e89e7317c006a013ff0866382d)) // no third PROM in this set, a 74S138 is used instead for e0000-fffff ROM mapping ROM_END /****************************************************************************** Drivers ******************************************************************************/ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS COMP( 1987, prose2k, 0, 0, prose2k, prose2k, tsispch_state, init_prose2k, "Telesensory Systems Inc/Speech Plus", "Prose 2000/2020 v3.4.1", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) COMP( 1982, prose2ko, prose2k, 0, prose2k, prose2k, tsispch_state, init_prose2k, "Telesensory Systems Inc/Speech Plus", "Prose 2000/2020 v1.1", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )