summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/drivers/ti990_10.c
blob: 6f9b90afaa02582410b17eb72e5192630759b4f7 (plain) (tree)






































































                                                                                           
                                 
                       

                                 






                                                                                        
                                                     


                                            


                                      

                                     
 

                                                    
                                                    






                                                     
 
                                              

                          


  

























                                                                                                      
 
                                      

 






























































































                                                                                                                                 
                                    
 
                          

 
  
                                   
 
                           
 
                                                

 
                                   
 
               
                      
 
  






                                            
                                  
 
                                                

 
                                                
 
                            







                                                                          

                                                                                  
                                                                                                                      
                                                               
                                                                                                                   

                                                               








                                                                

                                                                        





                                                                        


               
  


                                                 
 

                           



                                                       
                                                                                     
 
                           
                                            

                                                                              
 
                    

                                                                               
 


                                                                              




































                                                                                                                   
                             














                                                                               
                                                                                                                  
      

 
                                                                                                               
                                                                                                                                                                       
/*
    TI990/10 driver

    This driver boots the DX10 build tape and build a bootable system disk.
    I have been able to run a few programs (including most games from the
    "fun and games" tape), but I have been unable to perform system generation
    and install BASIC/COBOL/PASCAL.

TODO :
* programmer panel
* emulate TILINE fully: timings, tiline timeout, possibly memory error
* finish tape emulation (write support)
* add additional devices as need appears (931 VDT, FD800, card reader, ASR/KSR, printer)
* emulate 990/10A and 990/12 CPUs?
* find out why the computer locks when executing ALGS and BASIC/COBOL/PASCAL installation
*/

/*
    CRU map:

    990/10 CPU board:
    1fa0-1fbe: map file CRU interface
    1fc0-1fde: error interrupt register
    1fe0-1ffe: control panel

    optional hardware (default configuration):
    0000-001e: 733 ASR
    0020-003e: PROM programmer
    0040-005e: card reader
    0060-007e: line printer
    0080-00be: FD800 floppy disc
    00c0-00ee: 913 VDT, or 911 VDT
    0100-013e: 913 VDT #2, or 911 VDT
    0140-017e: 913 VDT #3, or 911 VDT
    1700-177e (0b00-0b7e, 0f00-0f7e): CI402 serial controller #0 (#1, #2) (for 931/940 VDT)
        (note that CRU base 1700 is used by the integrated serial controller in newer S300,
        S300A, 990/10A (and 990/5?) systems)
    1f00-1f1e: CRU expander #1 interrupt register
    1f20-1f3e: CRU expander #2 interrupt register
    1f40-1f5e: TILINE coupler interrupt control #1-8


    TPCS map:
    1ff800: disk controller #1 (system disk)
    1ff810->1ff870: extra disk controllers #2 through #8
    1ff880 (1ff890): tape controller #1 (#2)
    1ff900->1ff950: communication controllers #1 through #6
    1ff980 (1ff990, 1ff9A0): CI403/404 serial controller #1 (#2, #3) (for 931/940 VDT)
    1ffb00, 1ffb04, etc: ECC memory controller #1, #2, etc, diagnostic
    1ffb10, 1ffb14, etc: cache memory controller #1, #2, etc, diagnostic


    interrupt map (default configuration):
    0,1,2: CPU board
    3: free
    4: card reader
    5: line clock
    6: 733 ASR/KSR
    7: FD800 floppy (or FD1000 floppy)
    8: free
    9: 913 VDT #3
    10: 913 VDT #2
    11: 913 VDT
    12: free
    13: hard disk
    14 line printer
    15: PROM programmer (actually not used)
*/

#include "emu.h"

#include "cpu/tms9900/ti990_10.h"
#include "sound/beep.h"
#include "machine/ti99/990_hd.h"
#include "machine/ti99/990_tap.h"
#include "video/911_vdt.h"


class ti990_10_state : public driver_device
{
public:
	ti990_10_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag) ,
		m_maincpu(*this, "maincpu"),
		m_intlines(0),
		m_ckon_state(0) { }

	device_t *m_terminal;
	DECLARE_DRIVER_INIT(ti990_10);
	virtual void machine_reset();
	virtual void video_start();

	DECLARE_WRITE_LINE_MEMBER( key_interrupt );
	DECLARE_WRITE_LINE_MEMBER( line_interrupt );
	DECLARE_WRITE_LINE_MEMBER( tape_interrupt );
	void ti990_set_int_line(int line, int state);
	WRITE_LINE_MEMBER(ti990_set_int13);
	TIMER_CALLBACK_MEMBER(clear_load);
	void ti990_hold_load();
	WRITE_LINE_MEMBER(ti990_ckon_ckof_callback);
	READ8_MEMBER( ti990_panel_read );
	WRITE8_MEMBER( ti990_panel_write );

	required_device<cpu_device> m_maincpu;
	UINT16 m_intlines;
	int m_ckon_state;
};


/*
    Interrupt priority encoder.  Actually part of the CPU board.
*/

void ti990_10_state::ti990_set_int_line(int line, int state)
{
	int level;


	if (state)
		m_intlines |= (1 << line);
	else
		m_intlines &= ~ (1 << line);

	if (m_intlines)
	{
		for (level = 0; ! (m_intlines & (1 << level)); level++)
			;
		m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, level);  /* interrupt it, baby */
	}
	else
		m_maincpu->set_input_line(0, CLEAR_LINE);
}


WRITE_LINE_MEMBER(ti990_10_state::ti990_set_int13)
{
	ti990_set_int_line(13, state);
}

/*
    hold and debounce load line (emulation is inaccurate)
*/

TIMER_CALLBACK_MEMBER(ti990_10_state::clear_load)
{
	m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
}

void ti990_10_state::ti990_hold_load()
{
	m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
	machine().scheduler().timer_set(attotime::from_msec(100), timer_expired_delegate(FUNC(ti990_10_state::clear_load),this));
}

/*
    line interrupt
*/

/* m_ckon_state: 1 if line clock active (RTCLR flip-flop on TI990/10 schematics -
SMI sheet 4) */
WRITE_LINE_MEMBER(ti990_10_state::line_interrupt)
{
	// set_int10(state);
	if (m_ckon_state)
		ti990_set_int_line(5, 1);
}

WRITE_LINE_MEMBER(ti990_10_state::ti990_ckon_ckof_callback)
{
	m_ckon_state = state;
	if (! m_ckon_state)
		ti990_set_int_line(5, 0);
}



/*
    Control panel emulation

    three panel types
    * operator panel
    * programmer panel
    * MDU (external unit connected instead of the control panel, as seen in
      945401-9701 p. 2-5 though 2-15)

    Operator panel:
    * Power led
    * Fault led
    * Off/On/Load switch

    Programmer panel:
    * 16 status light, 32 switches, IDLE, RUN leds
    * interface to a low-level debugger in ROMs

    * MDU:
    * includes a programmer panel, a tape unit, and a few parts
      (diagnostic tape, diagnostic ROMs, etc.)

    CRU output:
    0-7: lights 0-7
    8: increment scan
    9: clear scan (according to 990 handbook)
    A: run light (additionally sets all data LEDs to 1s, the scan count to 0b10 and enables the HALT/SIE switch)
    B: fault light
    C: Memory Error Interrupt clear
    D: Start panel timer
    E: Set SIE function (interrupt after 2 instructions are executed)
    F: flag (according to 990 handbook)

    input :
    0-7: switches 0-7 (or data from MDU tape)
    8: scan count bit 1
    9: scan count bit 0
    A: timer active
    B: programmer panel not present or locked
    C: char in MDU tape unit buffer?
    D: unused?
    E: if 0, MDU unit present
    F: flag (according to 990 handbook)
*/

READ8_MEMBER( ti990_10_state::ti990_panel_read )
{
	if (offset == 1)
		return 0x48;

	return 0;
}

WRITE8_MEMBER( ti990_10_state::ti990_panel_write )
{
}


void ti990_10_state::machine_reset()
{
	ti990_hold_load();
}

/*
void ti990_10_state::rset_callback)
{
    ti990_cpuboard_reset();

    // clear controller panel and smi fault LEDs
}

void ti990_10_state::lrex_callback)
{
    // right???
    ti990_hold_load();
}
*/

/*
    TI990/10 video emulation.

    We emulate a single VDT911 CRT terminal.
*/

void ti990_10_state::video_start()
{
	m_terminal = machine().device("vdt911");
}

WRITE_LINE_MEMBER(ti990_10_state::key_interrupt)
{
	// set_int10(state);
}

/*
  Memory map - see description above
*/

static ADDRESS_MAP_START(ti990_10_memmap, AS_PROGRAM, 16, ti990_10_state )

	AM_RANGE(0x000000, 0x0fffff) AM_RAM     /* let's say we have 1MB of RAM */
	AM_RANGE(0x100000, 0x1ff7ff) AM_NOP     /* free TILINE space */
	AM_RANGE(0x1ff800, 0x1ff81f) AM_DEVREADWRITE("hdc", ti990_hdc_device, read, write)  /* disk controller TPCS */
	AM_RANGE(0x1ff820, 0x1ff87f) AM_NOP     /* free TPCS */
	AM_RANGE(0x1ff880, 0x1ff89f) AM_DEVREADWRITE("tpc", tap_990_device, read, write) /* tape controller TPCS */
	AM_RANGE(0x1ff8a0, 0x1ffbff) AM_NOP     /* free TPCS */
	AM_RANGE(0x1ffc00, 0x1fffff) AM_ROM     /* LOAD ROM */

ADDRESS_MAP_END


/*
  CRU map
*/

static ADDRESS_MAP_START(ti990_10_io, AS_IO, 8, ti990_10_state )
	AM_RANGE(0x10, 0x11) AM_DEVREAD("vdt911", vdt911_device, cru_r)
	AM_RANGE(0x80, 0x8f) AM_DEVWRITE("vdt911", vdt911_device, cru_w)
	AM_RANGE(0x1fa, 0x1fb) AM_NOP // AM_READ(ti990_10_mapper_cru_r)
	AM_RANGE(0x1fc, 0x1fd) AM_NOP // AM_READ(ti990_10_eir_cru_r)
	AM_RANGE(0x1fe, 0x1ff) AM_READ(ti990_panel_read)
	AM_RANGE(0xfd0, 0xfdf) AM_NOP // AM_WRITE(ti990_10_mapper_cru_w)
	AM_RANGE(0xfe0, 0xfef) AM_NOP // AM_WRITE(ti990_10_eir_cru_w)
	AM_RANGE(0xff0, 0xfff) AM_WRITE(ti990_panel_write)

ADDRESS_MAP_END

/*
    Callback from the tape controller.
*/
WRITE_LINE_MEMBER(ti990_10_state::tape_interrupt)
{
	// set_int9(state);
}

static MACHINE_CONFIG_START( ti990_10, ti990_10_state )
	/* basic machine hardware */
	/* TI990/10 CPU @ 4.0(???) MHz */
	MCFG_TMS99xx_ADD("maincpu", TI990_10, 4000000, ti990_10_memmap, ti990_10_io )

	// VDT 911 terminal
	MCFG_DEVICE_ADD("vdt911", VDT911, 0)
	MCFG_VDT911_KEYINT_HANDLER(WRITELINE(ti990_10_state, key_interrupt))
	MCFG_VDT911_LINEINT_HANDLER(WRITELINE(ti990_10_state, line_interrupt))

	// Hard disk
	MCFG_DEVICE_ADD("hdc", TI990_HDC, 0)
	MCFG_TI990_HDC_INT_CALLBACK(WRITELINE(ti990_10_state, ti990_set_int13))

	// Tape controller
	MCFG_DEVICE_ADD("tpc", TI990_TAPE_CTRL, 0)
	MCFG_TI990_TAPE_INT_HANDLER(WRITELINE(ti990_10_state, tape_interrupt))
MACHINE_CONFIG_END


/*
  ROM loading
*/
ROM_START(ti990_10)

	/*CPU memory space*/
#if 0

	ROM_REGION16_BE(0x200000, "maincpu",0)

	/* TI990/10 : older boot ROMs for floppy-disk */
	ROM_LOAD16_BYTE("975383.31", 0x1FFC00, 0x100, CRC(64fcd040))
	ROM_LOAD16_BYTE("975383.32", 0x1FFC01, 0x100, CRC(64277276))
	ROM_LOAD16_BYTE("975383.29", 0x1FFE00, 0x100, CRC(af92e7bf))
	ROM_LOAD16_BYTE("975383.30", 0x1FFE01, 0x100, CRC(b7b40cdc))

#elif 1

	ROM_REGION16_BE(0x200000, "maincpu",0)

	/* TI990/10 : newer "universal" boot ROMs  */
	ROM_LOAD16_BYTE("975383.45", 0x1FFC00, 0x100, CRC(391943c7) SHA1(bbd4da60b221d146542a6b547ae1570024e41b8a))
	ROM_LOAD16_BYTE("975383.46", 0x1FFC01, 0x100, CRC(f40f7c18) SHA1(03613bbf2263a4335c25dfc63cf2878c06bfe280))
	ROM_LOAD16_BYTE("975383.47", 0x1FFE00, 0x100, CRC(1ba571d8) SHA1(adaa18f149b643cc842fea8d7107ee868d6ffaf4))
	ROM_LOAD16_BYTE("975383.48", 0x1FFE01, 0x100, CRC(8852b09e) SHA1(f0df2abb438716832c16ab111e475da3ae612673))

#else

	ROM_REGION16_BE(0x202000, "maincpu",0)

	/* TI990/12 ROMs - actually incompatible with TI990/10, but I just wanted to disassemble them. */
	ROM_LOAD16_BYTE("ti2025-7", 0x1FFC00, 0x1000, CRC(4824f89c))
	ROM_LOAD16_BYTE("ti2025-8", 0x1FFC01, 0x1000, CRC(51fef543))
	/* the other half of this ROM is not loaded - it makes no sense as TI990/12 machine code, as
	it is microcode... */

#endif


	/* VDT911 character definitions */
	ROM_REGION(vdt911_chr_region_len, vdt911_chr_region, ROMREGION_ERASEFF)

ROM_END

DRIVER_INIT_MEMBER(ti990_10_state,ti990_10)
{
#if 0
	/* load specific ti990/12 rom page */
	const int page = 3;

	memmove(memregion("maincpu")->base()+0x1FFC00, memregion("maincpu")->base()+0x1FFC00+(page*0x400), 0x400);
#endif
}

/*    YEAR  NAME        PARENT  COMPAT  MACHINE     INPUT       INIT        COMPANY                 FULLNAME */
COMP( 1975, ti990_10,   0,      0,      ti990_10,   0, ti990_10_state,   ti990_10,   "Texas Instruments",    "TI Model 990/10 Minicomputer System" , GAME_NOT_WORKING )