;******************************************************************************* ; ; This module contains the firmware required to initialize the MILSTAR ; test rack computers upon power-up or reset. ; ;******************************************************************************* NAME MSURST ; Non-local declarations. PUBLIC msuSBC_reset ; For jump table. PUBLIC LBXParityErrors ; For parity error interrupt handler. PUBLIC MemoryTestStatus ; For universal firmware. PUBLIC MemoryTestPerformed EXTRN SBC_reset: FAR ; Miscellaneous addresses. EXTRN initialize_SBC: FAR EXTRN memory_test: FAR EXTRN start_of_RMX: FAR EXTRN BREAKENTRY: FAR ; Monitor code addresses. EXTRN RESTORECODE: NEAR EXTRN STEPENTRY: FAR MONITOR_DATA SEGMENT WORD PUBLIC 'DATA' EXTRN MBUFHEAD: WORD ; Monitor data addresses. EXTRN MBUFTAIL: WORD EXTRN MBUFTOP: BYTE EXTRN BRKTBL: BYTE EXTRN CTXTBL: BYTE MONITOR_DATA ENDS ; 8255A Programmable Peripheral Interface (PPI) port definitions. PPI_control EQU 0CEH ; Control register PPI_port_A EQU 0C8H ; Port A. PPI_port_B EQU 0CAH ; Port B. PPI_port_C EQU 0CCH ; Port C. ; Am96/0512L 512K Ram Board port definitions. LBX_error_register_ping EQU 0000H LBX_error_register_pong EQU 0008H ; IOC Clock Board port definitions. clock_board_ID EQU 5000H ; Board ID register. clock_board_configuration EQU 5004H ; Configuration register (ping/pongs memory). $EJECT ;******************************************************************************* ; ; Monitor Data Segment ; ; The variable storage declared here is concatenated with that declared in the ; MTEX-86 monitor (see MSUMON.A86). ; ; Note that variables are declared and allocated using the DB and DW ; directives with indeterminate initialization. Data records for these ; addresses are generated in the absolute (LOCATEd) file but can be ignored. ; ;******************************************************************************* MONITOR_DATA SEGMENT WORD PUBLIC 'DATA' LBXParityErrors DW 2 DUP (?) ; Count (DWORD) of LBX memory parity errors. MemoryTestStatus DW 8 DUP (?) ; Memory test status. MemoryTestPerformed DW ? ; If 55AAH following a reset, then memory ; testing has already been performed. MONITOR_DATA ENDS $EJECT ;******************************************************************************* ; ; This section of the code defines the jump instruction to be placed at ; address FFFF:0; this is the first instruction executed upon power-up ; or after a reset. ; ;******************************************************************************* FFFF0_CODE SEGMENT PARA PUBLIC 'CODE' JMP SBC_reset FFFF0_CODE ENDS $EJECT ;******************************************************************************* ; ; This code is executed upon power-up or after a reset. The following ; functions are performed: ; ; - Initialize the single board computer functions. ; - Test memory. ; - Initialize the monitor data structures. ; - Initialize the interrupt vector table. ; - Initialize the console interface. ; - Start the iRMX root job (which initializes iRMX and starts ; the universal firmware). ; ; This code is largely copied from Lance Jump's reset IORESET routine ; (see MTEX-86 and MON86). ; ;******************************************************************************* MONITOR_CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS: MONITOR_CODE, DS:MONITOR_DATA, ES:NOTHING, SS:NOTHING msuSBC_reset PROC FAR CLI ; Disable interrupts. MOV AX, MONITOR_DATA ; Use the monitor data and stack areas. MOV DS, AX MOV SS, AX MOV SP, OFFSET CTXTBL ; (Top of stack.) CALL initialize_SBC ; Initialize the SBC 286/10 hardware. $EJECT ;******************************************************************************* ; ; On power-up only, test the following blocks of memory: ; ; 00000H - 07FFFH (Lower 32K of dual port RAM) ; 08000H - 0FFFFH (Upper 32K of dual port RAM) ; C0000H - C3FFFH (16K of local RAM) ; 30000H - AFFFFH (512K of LBX RAM) ; ;******************************************************************************* MOV AX, MemoryTestPerformed ; Check if a memory test has CMP AX, 55AAH ; already been performed. JNE test_dual_port_memory JMP memory_test_done ; If yes, then don't test again. ; Move the stack into local memory and test the lower 32K of dual port RAM. ; There is no problem with the temporary variables (see local subroutine ; TEST_MEMORY) being located in the area of memory being tested. test_dual_port_memory: MOV AX, 0C000H MOV SS, AX MOV SP, 0100H ; SS:SP = C000:0100. MOV AX, 0000H ; Start address = 00000H. MOV BX, 07FFH ; Stop address = 07FFFH. CALL test_memory ; Test the memory and MOV MemoryTestStatus+0, AX ; store the test status. ; Restore the stack and test the upper 32K of dual port RAM. This memory is ; only present in the IOC test set. MOV AX, MONITOR_DATA ; Use the monitor stack area. MOV SS, AX MOV SP, OFFSET CTXTBL ; (Top of stack.) MOV AX, 0800H ; Start address = 08000H. MOV BX, 0FFFH ; Stop address = 0FFFFH. CALL test_memory ; Test the memory and MOV MemoryTestStatus+2, AX ; store the test status. ; Test the 16K of local memory. MOV AX, 0C000H ; Start address = C0000H. MOV BX, 0C3FFH ; Stop address = C3FFFH. CALL test_memory ; Test the memory and MOV MemoryTestStatus+4, AX ; store the test status. ; Test 512K of LBX RAM. If this is the IOC test set, then "ping" the memory ; boards (so as to test the first of the two LBX boards). MOV DX, clock_board_ID ; Is this the IOC test set? IN AL, DX CMP AL, 43H JNE test_LBX_memory MOV DX, clock_board_configuration ; Yes, so test the ping memory. MOV AX, 3B8EH OUT DX, AX test_LBX_memory: MOV AL, 00H ; Clear the parity error register. OUT LBX_error_register_ping, AL MOV AX, 3000H ; Start address = 30000H. MOV BX, 0AFFFH ; Stop address = AFFFFH. CALL test_memory ; Test the memory and MOV MemoryTestStatus+6, AX ; store the test status. ; Initialize the remaining memory test statuses to RMX error E$MEM. MOV AX, 0002H MOV MemoryTestStatus+8, AX MOV MemoryTestStatus+10, AX MOV MemoryTestStatus+12, AX MOV MemoryTestStatus+14, AX ; If this is the IOC test set, then "pong" the memory boards and test the ; second of the two LBX boards. MOV DX, clock_board_ID ; Is this the IOC test set? IN AL, DX CMP AL, 43H JNE memory_test_done MOV DX, clock_board_configuration ; Yes, so test the pong memory. MOV AX, 3BAEH OUT DX, AX MOV AL, 00H ; Clear the parity error register. OUT LBX_error_register_pong, AL MOV AX, 3000H ; Start address = 30000H. MOV BX, 0AFFFH ; Stop address = AFFFFH. CALL test_memory ; Test the memory and MOV MemoryTestStatus+8, AX ; store the test status. MOV DX, clock_board_configuration ; Return to the ping memory. MOV AX, 3B8EH OUT DX, AX ; Store a distinctive, seemingly non-random value in memory to indicate that ; memory has been tested. This inhibits memory testing, thus preserving ; downloaded programs if a hardware reset occurs. Initialize the LBX parity ; errors count to zero so that the universal firmware, when it comes up, ; doesn't display an error count message. Clear the timeout light; it might ; have been set by the I/O reference to the IOC clock board. memory_test_done: MOV AX, 55AAH ; Memory has been tested! MOV MemoryTestPerformed, AX XOR AX, AX ; Zero the LBX parity errors count. MOV LBXParityErrors, AX MOV LBXParityErrors+2, AX MOV AL, 06H ; Reset bit 3 of the PPI, clearing the OUT PPI_control, AL ; timeout interrupt and the yellow LED. MOV AL, 07H ; Set bit 3 of the PPI, re-enabling the OUT PPI_control, AL ; timeout interrupt. $EJECT ;******************************************************************************* ; ; Restore any breakpoints that were set, reset the registers in the ; monitor's context table, reset the monitor's macro buffer, initialize ; the interrupt vector table, and start up iRMX. ; ;******************************************************************************* CALL RESTORECODE ; Restore code displaced by breakpoints. MOV AX, DS ; Clear out the breakpoint table. MOV ES, AX MOV DI, OFFSET BRKTBL MOV CX, 8*5 ; 8 breakpoints (pointer and opcode for each). XOR AX, AX CLD REP STOSB MOV DI, OFFSET CTXTBL ; Zero all the registers in the context table. MOV CX, 28 REP STOSB MOV AX, OFFSET MBUFTOP ; Reset the monitor command macro MOV MBUFHEAD, AX ; pointers (but the macro text is MOV MBUFTAIL, AX ; not erased). XOR AX, AX ; Initialize all the interrupt MOV ES, AX ; vectors with the address of MOV DI, AX ; the breakpoint entry in the MOV BX, OFFSET BREAKENTRY ; monitor. MOV DX, SEG BREAKENTRY MOV CX, 256 CLD next_vector: MOV AX, BX ; Offset of BREAKENTRY. STOSW MOV AX, DX ; Selector of BREAKENTRY. STOSW LOOP next_vector MOV DI, 4 ; Initialize the single step MOV AX, OFFSET STEPENTRY ; trap vector with the address STOSW ; of the single step entry in MOV AX, SEG STEPENTRY ; the monitor. STOSW JMP start_of_RMX ; Boot up the iRMX operating system. msuSBC_reset ENDP $EJECT ;******************************************************************************* ; ; TEST_MEMORY is a subroutine local to SBC_RESET; TEST_MEMORY sets up the ; arguments for a call to routine MEMORY_TEST and calls it. TEST_MEMORY ; is passed the selectors of the memory test's start and stop addresses ; in the CPU's registers: ; ; AX - Start Address (Selector) ; BX - Stop Address (Selector) ; ; TEST_MEMORY assumes an offset of 0000H for the start address and an ; offset of 000FH for the stop address. For example, to test locations ; 30000H through AFFFFH, you would pass in selectors 3000H and AFFFH. ; The status of the memory test is returned in AX: ; ; AX - Memory Test Status (0000H = no error) ; ; The LBX parity errors variable is used as a dummy variable to receive ; the bad address and expected value returned by routine MEMORY_TEST. ; ;******************************************************************************* test_memory PROC NEAR PUSH AX ; Start address selector. XOR AX, AX ; Start address offset = 0000H. PUSH AX PUSH BX ; Stop address selector. MOV AX, 000FH ; Stop address offset = 000FH. PUSH AX MOV AX, MONITOR_DATA ; Return bad address to temporary variable. PUSH AX MOV AX, OFFSET LBXParityErrors PUSH AX MOV AX, MONITOR_DATA ; Return expected value to temporary variable. PUSH AX MOV AX, OFFSET LBXParityErrors PUSH AX CALL memory_test ; Test the memory. RET ; Return the memory test status in AX. test_memory ENDP MONITOR_CODE ENDS END