; cmonml.dsm ; L. Stewart, September 24, 1982 10:30 AM ; clkxx -> cmkxx , September 10, 1982 11:42 AM ; L. Stewart, December 3, 1982 3:02 PM, new initial I/O setup code ; L. Stewart, January 21, 1983 1:04 PM, initial I/O fixup 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 cDIVERR EQU 0 cTRACE EQU 1 cNMI EQU 2 cBREAK EQU 3 cOVERR EQU 4 cEXTINT EQU 254 cRESET EQU 255 C←DATA SEGMENT ←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 ←refa DW ? ←refb DW ? ←refc DW ? ←refd DW ? ←savea DW ? ←saveb DW ? ←lnmi DW ? ←eitype DW ? C←DATA ENDS EXTRN ←main:NEAR EXTRN ←portstr:NEAR ASSUME CS:C←CODE, DS:C←DATA ←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 XOR BX,BX cmmt: IN AL,pioc TEST AL,4 JNZ cmst IN AL,piob MOV [BX+0AA55H],AL MOV AL,[BX+0AA55H] MOV [BX+055AAH],AL MOV AL,[BX+055AAH] JMP cmmt cmst: MOV BX,cRESET ←crestart: MOV AX,SPIN MOV SP,AX MOV AX,CS MOV SS,AX MOV ES,AX MOV DS,AX CALL ←main JMP DWORD PTR JHUNK JHUNK DW 00H DW 0FFFFH ; set timer, address of timer in BX, interval in CX ; call is settmr(interval, &timer) ; interval is in 1000ths of a second ←settmr PROC NEAR ADD CX,←cmklo MOV WORD PTR [BX],CX RET ←settmr ENDP ; has timer expired? Address of timer in BX ; returns BX=1 if so, BX=0 if not ; call is if (tmrexp(&timer)) { ... } ←tmrexp PROC NEAR MOV AX,WORD PTR [BX] XOR BX,BX CMP AX,←cmklo ; expired will leave sign bit set JS teret RET teret: INC BX RET ←tmrexp ENDP ; Enable interrupts ←inton PROC NEAR STI RET ←inton ENDP ; Disable interrupts ←intoff PROC NEAR CLI RET ←intoff ENDP wasnmi: MOV rbx,BX MOV BX,cNMI JMP intcom possnmi: ; if old, juggle stack MOV AX,1 XCHG AX,←lnmi OR AL,AL JNZ wasntnmi ; if we reach here, fix stack so IRET returns to secret place! MOV BX,0F000H PUSH BX ; push flags XOR BX,BX PUSH BX ; push cs for this routine MOV BX,OFFSET wasnmi PUSH BX ; push ip for this routine JMP wasntnmi ; Refresh Interrupt RefA: MOV ←savea,AX ; 3 bytes MOV ←saveb,BX ; 4 bytes XOR BX,BX ; 2 bytes MOV AX,←refb ; 3 bytes MOV [nmiploc+BX],AX ; 4 bytes MOV AX,←cmklo ; 3 bytes ADD AX,1 ; 3 bytes MOV ←cmklo,AX ; 3 bytes MOV AX,←cmkhi ; 3 bytes ADC AX,0 ; 3 bytes MOV ←cmkhi,AX ; 3 bytes IN AL,pioc ; 2 bytes check for NMI TEST AL,1 ; 2 bytes JZ possnmi ; 2 bytes wasntnmi: MOV AX,←savea ; 3 bytes MOV BX,←saveb ; 3 bytes ; total 46, we need 18 more, counting IRET NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP IRET RefB: MOV ←savea,AX ; 3 bytes MOV ←saveb,BX ; 4 bytes XOR BX,BX ; 2 bytes MOV AX,←refc ; 3 bytes MOV [nmiploc+BX],AX ; 4 bytes MOV AX,←cmklo ; 3 bytes ADD AX,1 ; 3 bytes MOV ←cmklo,AX ; 3 bytes MOV AX,←cmkhi ; 3 bytes ADC AX,0 ; 3 bytes MOV ←cmkhi,AX ; 3 bytes MOV AX,←savea ; 3 bytes MOV BX,←saveb ; 3 bytes ; total 40, we need 24 more, counting IRET NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP IRET RefC: MOV ←savea,AX ; 3 bytes MOV ←saveb,BX ; 4 bytes XOR BX,BX ; 2 bytes MOV AX,←refd ; 3 bytes MOV [nmiploc+BX],AX ; 4 bytes MOV AX,←cmklo ; 3 bytes ADD AX,1 ; 3 bytes MOV ←cmklo,AX ; 3 bytes MOV AX,←cmkhi ; 3 bytes ADC AX,0 ; 3 bytes MOV ←cmkhi,AX ; 3 bytes MOV AX,←savea ; 3 bytes MOV BX,←saveb ; 3 bytes ; total 50, we need 24 more, counting IRET NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP IRET RefD: MOV ←savea,AX ; 3 bytes MOV ←saveb,BX ; 4 bytes XOR BX,BX ; 2 bytes MOV AX,←refa ; 3 bytes MOV [nmiploc+BX],AX ; 4 bytes MOV AX,←cmklo ; 3 bytes ADD AX,1 ; 3 bytes MOV ←cmklo,AX ; 3 bytes MOV AX,←cmkhi ; 3 bytes ADC AX,0 ; 3 bytes MOV ←cmkhi,AX ; 3 bytes MOV AX,←savea ; 3 bytes MOV BX,←saveb ; 3 bytes ; total 50, we need 24 more, counting IRET NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP IRET ; initialize interrupt vectors ←intinit PROC NEAR MOV AX,OFFSET RefA MOV ←refa,AX MOV AX,OFFSET RefB MOV ←refb,AX MOV AX,OFFSET RefC MOV ←refc,AX MOV AX,OFFSET RefD MOV ←refd,AX XOR BX,BX XOR AX,AX MOV [nmcsloc+BX],AX MOV AX,←refa MOV [nmiploc+BX],AX RET ←intinit ENDP ; 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 ←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 ←setup PROC NEAR CALL ←intinit 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 ←settmr PUBLIC ←tmrexp ; PUBLIC ←inton ; PUBLIC ←intoff PUBLIC ←cmklo PUBLIC ←cmkhi PUBLIC ←mstate PUBLIC ←startm PUBLIC ←setup PUBLIC ←lip PUBLIC ←lnmi PUBLIC ←eitype C←CODE ENDS END