; 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 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