; refreshml.dsm ; L. Stewart, January 21, 1983 10:47 AM SPACE SEGMENT C←GROUP GROUP SPACE, C←CODE, C←DATA ; DB 2 DUP(?) SPACE ENDS C←CODE SEGMENT $INCLUDE(Lark.d) ; stack initial value SPIN EQU 0DFF0H deiploc EQU 000H decsloc EQU 002H triploc EQU 004H trcsloc EQU 006H nmiploc EQU 008H nmcsloc EQU 00AH bkiploc EQU 00CH bkcsloc EQU 00EH oviploc EQU 010H ovcsloc EQU 012H ; boot reasons ; interrupts of various sorts are of types 0 up through 255 cDIVERR EQU 0 cTRACE EQU 1 cNMI EQU 2 cBREAK EQU 3 cOVERR EQU 4 cSWAT EQU 5 cMONRET EQU 0FFFCH cRUNERR EQU 0FFFDH cEXTINT EQU 0FFFEH cRESET EQU 0FFFFH C←DATA SEGMENT ; save area for machine state ←mstate LABEL BYTE rax DW ? rbx DW ? rcx DW ? rdx DW ? rsp DW ? rbp DW ? rsi DW ? rdi DW ? rcs DW ? rds DW ? rss DW ? res DW ? rip DW ? rfl DW ? ←lip DW ? ; single step use ←cmklo DW 00H ←cmkhi DW 00H savea DW 0 ←lnmi DW ? ←eitype DW ? C←DATA ENDS EXTRN ←MonMain:NEAR EXTRN ←PortStr:NEAR ASSUME CS:C←CODE, DS:C←DATA ; if code happens to execute into the monitor from lower ; addresses, a trap of type cRUNERR happens ; address = E000 JMP runerr ; 3 bytes ; address = E003 JMP cstart ; 3 bytes ; address = E006 possnmi: JMP pnmib ; 3 bytes ; address = E009 RefA: NOP ; drain IFU NOP NOP NOP ; total 4 DW 0C706H ; 2 bytes DW nmiploc ; 2 bytes DW 0E049H ; OFFSET RefB NOP ; drain IFU NOP NOP NOP ; total 14 ADD ←cmklo,1 ; 5 bytes NOP ; drain IFU NOP NOP NOP ; total 23 ADC ←cmkhi,0 ; 5 bytes NOP ; drain IFU NOP NOP NOP ; total 32 MOV savea,AX ; 3 bytes NOP ; drain IFU NOP NOP NOP ; total 39 IN AL,pioc ; 2 bytes NOP ; drain IFU NOP NOP NOP ; total 45 TEST AL,1 ; 2 bytes NOP ; drain IFU NOP NOP NOP ; total 51 JZ possnmi ; 2 bytes wasntnmi: NOP ; drain IFU NOP NOP NOP ; total 57 MOV AX,savea ; 3 bytes NOP NOP NOP ; total 63 IRET RefB: NOP ; drain IFU NOP NOP NOP NOP ; total 5 DW 0C706H DW nmiploc DW 0E089H ; OFFSET RefC NOP ; drain IFU NOP NOP NOP NOP ; total 16 ADD ←cmklo,1 NOP ; drain IFU NOP NOP NOP NOP ; total 26 ADC ←cmkhi,0 NOP ; total 32 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 42 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 52 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 62 NOP IRET RefC: NOP ; drain IFU NOP NOP NOP NOP ; total 5 DW 0C706H DW nmiploc DW 0E0C9H ; OFFSET RefD NOP ; drain IFU NOP NOP NOP NOP ; total 16 ADD ←cmklo,1 NOP ; drain IFU NOP NOP NOP NOP ; total 26 ADC ←cmkhi,0 NOP ; total 32 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 42 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 52 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 62 NOP IRET RefD: NOP ; drain IFU NOP NOP NOP NOP ; total 5 DW 0C706H DW nmiploc DW 0E009H ; OFFSET RefA NOP ; drain IFU NOP NOP NOP NOP ; total 16 ADD ←cmklo,1 NOP ; drain IFU NOP NOP NOP NOP ; total 26 ADC ←cmkhi,0 NOP ; total 32 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 42 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 52 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP ; total 62 NOP IRET ; io device initialization strings ; The format of this stuff is <port address><byte count><bytes> ; port FF terminates the list ; first set up the 8255 and reset all its outputs ←I8255 LABEL BYTE DB pioctl DB 1 DB 083H ; Port A, C[4..7] output, B, C[0..3] input, all mode 0 DB pioa DB 1 DB 0E1H DB piob DB 1 DB 000H DB pioc DB 1 DB 030H DB apioctl DB 1 DB 088H ; Port A, B, C0-3 Out, Port C4-7 In, mode 0 DB apioa DB 1 DB 0C0H ; revert and off-hook relays OFF DB 0FFH ←I8237 LABEL BYTE ; reset DMA controller DB dmamask DB 1 DB 00FH DB dmaclr DB 1 DB 000H ; Set up SLC controller only in cascade mode DB dmastat DB 1 DB 020H DB dmamode DB 1 DB 0C1H DB dmamask DB 1 DB 00DH DB 0FFH ; See Lark9513.txt for explanations ←I9513 DB TimCtl DB 5 DB 0FFH DB 05FH DB 001H DB 0E0H DB 017H DB TimData DB 2 DB 0C0H DB 088H DB TimCtl DB 6 DB 0E9H ; set SLCHoldoff' high (was E1) DB 0E2H ; everyone else low DB 0E3H DB 0E4H DB 0E5H DB 001H ; SLCHoldoff DB TimData DB 30 ;new DB 062H ; mode L, toggle DB 0DBH ; active high edge gate N, F1 DB 059H ; delay 192/2 -7 DB 000H DB 02EH ; low for 46 DB 000H ;old ; DB 062H ; mode J ; DB 01BH ; DB 02EH ; DB 000H ; DB 092H ; DB 000H ; TSN ; new DB 062H ; mode J, free run DB 01BH ; no gate, F1 DB 058H ; low for 88 DB 000H DB 008H ; high for 8 DB 000H ; old ; DB 062H ; mode L ; DB 0FBH ; DB 007H ; delay 7 ; DB 000H ; DB 008H ; high for 8 ; DB 000H ; Framesync DB 0A5H ; Mode R DB 0FBH ; active low edge gate N, F1 DB 005H ; delay 5 DB 000H DB 000H DB 000H ; 8274 ch. B baud rate, 1200 baud DB 062H ; Mode J DB 01BH DB 028H DB 000H DB 028H DB 000H ; Refresh generator ; Programmable timer, set up for toggling every 8 ticks of SynTSN ; It triggers nmi on the low to high transition of output DB 022H ; Mode D DB 014H DB 008H DB 000H DB 000H DB 000H DB TimCtl DB 2 DB 05FH DB 03FH DB 0FFH ←I8274 DB sioctla DB 2 DB 018H ; channel reset DB 0F0H ; reset Tx underrun, error reset DB sioctlb DB 2 DB 018H ; channel reset DB 0F0H ; reset Tx underrun, error reset DB sioctla DB 14 DB 004H ; WR 4 next DB 04CH ; 16 x clock, 2 stop, no parity DB 001H ; WR 1 next DB 004H ; no interrupts, variable vector ; DB 01EH ; rx int all chars, variable vector, txint, no ext int DB 002H ; WR 2 next DB 014H ; 8088 mode, non-vector int. rx high pri., both int. DB 003H ; WR 3 next DB 0C0H ; 8 bits/rxchar DB 005H ; WR 5 next DB 060H ; 8 bits/txchar DB 006H ; WR 6 next DB 000H ; junk DB 007H ; WR 7 next DB 000H ; junk DB sioctlb DB 14 DB 004H ; WR 4 next DB 04CH ; 16 x clock, 2 stop, no parity DB 001H ; WR 1 next DB 004H ; no interrupts, variable vector ; DB 01EH ; rx int all chars, variable vector, txint, no ext int DB 002H ; WR 2 next DB 000H ; base vector DB 003H ; WR 3 next DB 0C0H ; 8 bits/rxchar DB 005H ; WR 5 next DB 060H ; 8 bits/txchar DB 006H ; WR 6 next DB 000H ; junk DB 007H ; WR 7 next DB 000H ; junk ; now enable 8274 DB sioctla DB 4 DB 003H DB 0C1H ; 8 bits/rxchar, rx enable DB 005H DB 068H ; 8 bits/txchar, tx enable DB sioctlb DB 4 DB 003H DB 0C1H ; 8 bits/rxchar, rx enable DB 005H DB 068H ; 8 bits/txchar, tx enable DB 0FFH ; set up 8259 ; Mask all interrupts ←I8259 DB intctl DB 1 DB 01BH DB intdata DB 3 DB 070H DB 001H DB 0FFH ; end of string DB 0FFH ; jump targets for jumps at top of this file ; runerr may catch sequential execution into EPROM space runerr: MOV rbx,BX MOV BX,cRUNERR JMP intcom ; NMI button pushed wasnmi: MOV rbx,BX MOV BX,cNMI JMP intcom ; possible NMI button push pnmib: ; if old, juggle stack MOV AX,1 XCHG AX,←lnmi OR AL,AL JZ pnmic JMP wasntnmi pnmic: ; if we reach here, fix stack so IRET from refresh code ; "returns" to wasnmi, saving client state MOV BX,0F000H PUSH BX ; push flags for monitor execution XOR BX,BX PUSH BX ; push cs for this routine MOV BX,OFFSET wasnmi PUSH BX ; push ip for this routine JMP wasntnmi ; execution starts here on a system reset cstart: MOV BX,cRESET ; callable from C: CStart(reason) ; initializes ←CStart: MOV AL,0FFH OUT TimCtl,AL MOV AL,083H ; Port A, C4-7 Out, Port B, C0-3 In, mode 0 OUT pioctl,AL MOV AL,068H OUT pioa,AL MOV AL,0E1H OUT pioa,AL MOV AL,030H ; A and HS relays OFF OUT pioc,AL MOV AL,000H OUT piob,AL MOV AL,088H ; Port A, B, C0-3 Out, Port C4-7 In, mode 0 OUT apioctl,AL MOV AL,0C0H ; revert and off-hook relays OFF OUT apioa,AL ; all traps, etc. come here with different codes in BX ←CRestart: MOV AX,SPIN MOV SP,AX MOV AX,CS MOV SS,AX MOV ES,AX MOV DS,AX CALL ←MonMain ; ; if the monitor returns, start it again ; MOV BX,cMONRET JMP ←CStart ←StartM LABEL NEAR CMP rsp,020H JAE sok MOV rsp,01F0H sok: MOV AX,rip MOV ←lip,AX ; save current ip MOV AX,rss MOV SS,AX MOV AX,rsp MOV SP,AX PUSH rfl PUSH rcs PUSH rip MOV BX,rbx MOV CX,rcx MOV DX,rdx MOV SI,rsi MOV DI,rdi MOV BP,rbp MOV AX,rax PUSH res PUSH rds POP DS POP ES IRET brkpt LABEL NEAR MOV rbx,BX MOV BX,cBREAK intcom: MOV rax,AX MOV rcx,CX MOV rdx,DX MOV rsi,SI MOV rdi,DI MOV rbp,BP PUSH DS POP rds PUSH ES POP res POP rip POP rcs POP rfl MOV AX,SS MOV rss,AX MOV AX,SP MOV rsp,AX JMP ←CRestart trace LABEL NEAR ; determine if interrupt happened first! ; if trace flag is off in the flags on the stack then reorder. MOV rax,AX MOV rbx,BX MOV rcx,CX MOV rdx,DX POP DX ; pop ip POP CX ; pop cs POP AX ; pop flags PUSH AX ; push them back ; note: asm bug, TEST AH,1 doesn't work! TEST AX,0100H ; tf set? JNZ trok ; if so, this is the trace trap XOR BX,BX ; otherwise PUSH BX ; push cs for this routine MOV BX,OFFSET trace ; push ip for this routine PUSH BX PUSH AX ; push original flags PUSH CX ; push original cs PUSH DX ; push original ip MOV AX,rax ; restore registers MOV BX,rbx MOV CX,rcx MOV DX,rdx IRET trok: PUSH CX ; push original cs PUSH DX ; push original ip MOV AX,rax ; restore registers MOV CX,rcx ; except BX MOV DX,rdx MOV BX,cTRACE JMP intcom cmov LABEL NEAR MOV rbx,BX MOV BX,cOVERR JMP intcom cmde LABEL NEAR MOV rbx,BX MOV BX,cDIVERR JMP intcom ; All other interrupts UnkInt: ; in principle, CS contains the interrupt type and IP has ; whatever it takes to get control here. PUSH BX MOV BX,CS MOV ←eitype,BX POP BX MOV AL,020H ; 8259 eoi OUT intctl,AL MOV rbx,BX MOV BX,cEXTINT DB 0EAH ; long jump to DW OFFSET intcom ; intcom DW 0 ; the monitor calls this to initialize the machine ←Setup PROC NEAR ; ; set up first refresh interrupt handler XOR BX,BX XOR AX,AX MOV [nmcsloc+BX],AX MOV AX,OFFSET RefA MOV [nmiploc+BX],AX ; ; initialize IO devices ; MOV BX,OFFSET ←I8255 CALL ←PortStr MOV BX,OFFSET ←I9513 CALL ←PortStr MOV BX,OFFSET ←I8237 CALL ←PortStr MOV BX,OFFSET ←I8274 CALL ←PortStr MOV BX,OFFSET ←I8259 CALL ←PortStr ; now set up single step and breakpoint XOR AX,AX XOR BX,BX MOV ←lnmi,AX MOV [trcsloc+BX],AX MOV [bkcsloc+BX],AX MOV [decsloc+BX],AX MOV [ovcsloc+BX],AX MOV [triploc+BX],OFFSET trace MOV [bkiploc+BX],OFFSET brkpt MOV [deiploc+BX],OFFSET cmde MOV [oviploc+BX],OFFSET cmov ; set up all interrupts to point to UnkInt ; The idea is that the interrupt type is encoded in the CS:IP pair ; so that CS holds the type and IP holds UnkInt-16*CS MOV CX,251 MOV DI,014H MOV BX,5 MOV DX,OFFSET UnkInt SUB DX,050H CLD suih: MOV AX,DX STOSW MOV AX,BX STOSW INC BX SUB DX,010H LOOP suih ; initialize save area MOV rip,0200H MOV rsp,01F0H XOR AX,AX MOV rcs,AX MOV res,AX MOV rds,AX MOV rss,AX MOV rfl,0F000H ; interrupts off RET ←Setup ENDP PUBLIC ←cmklo PUBLIC ←cmkhi PUBLIC ←mstate PUBLIC ←CRestart PUBLIC ←StartM PUBLIC ←Setup PUBLIC ←lip PUBLIC ←lnmi PUBLIC ←eitype C←CODE ENDS END