;Console I/O for MS-DOS 2.0 INCLUDE IODEF.ASM IO GROUP CODE,INITSEG INITSEG SEGMENT BYTE PUBLIC 'IOSYS' ASSUME CS:IO, DS:IO IF INTINP ; SS and BP are zero CLI ; Set up keyboard interrupt vector. MOV WORD PTR [BP+64H],OFFSET IO:KBINT MOV [BP+66H],CS STI ELSE MOV AL,0FFH OUT BASE+3,AL ; Mask all interrupts ENDIF ;Set up vector 29H for fast console output MOV WORD PTR [BP+0A4H],OFFSET IO:CON$INT MOV [BP+0A6H],CS INITSEG ENDS CODE SEGMENT BYTE PUBLIC 'IOSYS' ASSUME CS:IO, DS:IO PUBLIC CONTBL,RDNDEXIT EXTRN EXIT:NEAR, CMDERR:NEAR, BUS$EXIT:NEAR, PTRSAV:DWORD ; Command table CONTBL: DW EXIT ; Init DW EXIT DW EXIT DW CMDERR DW CON$READ DW CON$RDND DW EXIT DW CON$FLSH DW CON$WRIT DW CON$WRIT DW CON$WRST ; Console keyboard interrupt handler. KBINT PROC FAR PUSH AX PUSH SI MOV AL,20H ;End of Interrupt command OUT BASE+2,AL ;Send to slave IN AL,DATA ;Get the character AND AL,7FH CMP AL,"C"-"@" JZ FLSH CMP AL,"S"-"@" JZ FLSH CMP AL,"F"-"@" JNZ SAVKY FLSH: CALL FLUSH ; Call I/O system keyboard buffer flush. SAVKY: MOV SI,CS:[REAR] ;Pointer to rear of queue CALL INCQ CMP SI,CS:[FRONT] ;Any room in queue? JZ QFULL MOV CS:[SI],AL ;Put character in queue MOV CS:[REAR],SI ;Save pointer LEAVINT: POP SI POP AX IRET KBINT ENDP QFULL: MOV AL,7 ; BELL character. CALL OUTCHR ; Call I/O system console output function. JMP SHORT LEAVINT BUSEXIT:JMP BUS$EXIT CON$RDND: CALL CSTATUS JZ BUSEXIT RDNDEXIT: LES DI,[PTRSAV] MOV ES:[DI.MEDIA],AL JMP EXIT CSTATUS: IF INTINP-1 IN AL,STAT AND AL,DAV JZ REPEAT PUSHF ;Look like an INT CALL KBINT REPEAT: ENDIF PUSH SI CLI ; Disable interrupts while checking queue. MOV SI,[FRONT] CMP SI,[REAR] ; Anything in queue? JZ NOCHR ; Jump if nothing in queue. CALL INCQ LODSB ;Get character (if there is one) OR SI,SI NOCHR: STI POP SI RET CON$READ: CALL INP STOSB LOOP CON$READ JMP EXIT INP: CALL CSTATUS ; Get I/O system console input status. JZ INP PUSH SI CLI ; Disable interrupts while changing queue pointers. MOV SI,[FRONT] CALL INCQ ; Permanently remove char from queue MOV [FRONT],SI STI POP SI RET CON$FLSH: CALL FLUSH JMP EXIT FLUSH: CLI MOV CS:[REAR],OFFSET IO:QUEUE MOV CS:[FRONT],OFFSET IO:QUEUE STI RET INCQ: INC SI CMP SI,OFFSET IO:ENDQ ;Exceeded length of queue? JB RET1 MOV SI,OFFSET IO:QUEUE RET1: RET FRONT DW OFFSET IO:QUEUE REAR DW OFFSET IO:QUEUE QUEUE DB QSIZE DUP(?) ENDQ LABEL BYTE ; ************ Console Output ************ CON$WRST: IN AL,STAT AND AL,TBMT JZ BUS$EXITV JMP EXIT BUS$EXITV: JMP BUS$EXIT CON$INT: STI ;INTS back on PUSH AX PUSH CX PUSH DX PUSH DI PUSH DS PUSH CS POP DS CALL CONOUT POP DS POP DI POP DX POP CX POP AX IRET CON$WRIT: MOV SI,DI CONOUTLP: LODS BYTE PTR ES:[SI] PUSH CX CALL CONOUT POP CX LOOP CONOUTLP JMP EXIT ESC EQU 1BH STATE DW ST1 PRMPNT DW PARMS PARMS DB 0,0,0,0,0,0,0 LASTPRM DB 0 BUFF DB 0,0,0,0,0,0,0,0,0,0 ; Cursor control table CMDTABL DB 'A' ;Cursor up DW CUU DB 'B' ;Cursor down DW CUD DB 'C' ;Cursor forward DW CUF DB 'D' ;Cursor backward DW CUB DB 'H' ;Cursor position DW CUP DB 'J' ;Erase display DW ED DB 'K' ;Erase line DW EL DB 'f' ;Cursor position DW CUP DB 'm' ;Exit/Enter reverse video mode DW SGR DB 's' ;Save cursor position DW PSCP DB 'u' ;Set cursor to saved position DW PRCP DB 00 CONOUT: MOV DI,OFFSET IO:STATE JMP WORD PTR [DI] ;JUMP TO THE CURRENT ANSI STATE ST1: CMP AL,ESC JNZ OUTCHR MOV WORD PTR [DI],OFFSET IO:ST2 RET OUTCHR: PUSH AX OUTLP: IN AL,STAT AND AL,TBMT JZ OUTLP POP AX OUT DATA,AL MOV [STATE],OFFSET IO:ST1 RET SENDESC: PUSH AX MOV AL,ESC CALL OUTCHR JMP OUTLP ST2: CMP AL,'[' JNZ SENDESC MOV BX,OFFSET IO:PARMS MOV [BX],BYTE PTR 31H MOV WORD PTR [PRMPNT],BX MOV IO:[STATE],OFFSET IO:ST3 RET ST3: CMP AL,';' JNZ ST3A INC WORD PTR [PRMPNT] RET ST3A: CMP AL,'0' JB ST3B CMP AL,'9' JA ST3B PUSH DI MOV DI,[PRMPNT] MOV [DI],AL POP DI RET ST4: PUSH AX MOV AL,ESC CALL OUTCHR MOV AL,'[' CALL OUTCHR JMP OUTLP ST3B: MOV DI,OFFSET IO:CMDTABL-3 ST3C: ADD DI,3 CMP BYTE PTR [DI],0 JZ ST4 ;Output characters in buffer CMP AL,[DI] JNZ ST3C INC DI ;Point to translate characters MOV BX,WORD PTR [DI] MOV SI,OFFSET IO:BUFF ;Set up temp buffer MOV CX,1 ;Set counter to at least 1 time MOV DL,0 ;Set # of characters TLOOP: MOV AL,[BX] ;Fetch xlate char CMP AL,0 JZ TEXIT ;End of characters TEST AL,80H ;Test for special character JZ NEXTCHR CMP AL,0F1H ;Is it 1st parm JNZ SCHR MOV AL,IO:[PARMS] ;Fetch it JMP NEXTCHR SCHR: CMP AL,0F2H ;Is it 2nd parm JNZ TCHR MOV AL,IO:[PARMS+1] JMP NEXTCHR TCHR: CMP AL,0FEH ;Use special driver ? JZ TDRIV CMP AL,0FFH ;Is it count char JNZ NEXTCHR MOV CL,IO:[PARMS] CMP CL,31H JAE TCHR1 MOV CL,31H TCHR1: SUB CL,30H INC BX JMP TLOOP NEXTCHR: MOV [SI],AL ;Put to buffer INC SI ;Temp buffer INC BX ;Xlate table INC DL ;# of char in BUFF JMP TLOOP ;Get next character TEXIT: ;All charcters are fetched MOV SI,OFFSET IO:BUFF MOV DH,DL ;Save # of char TEXITL: MOV AL,[SI] CALL OUTCHR INC SI DEC DH JNZ TEXITL ;Output until empty DEC CL ;Do CX count JNZ TEXIT RET TDRIV: ;User defined driver for SGR CMP WORD PTR [DI],OFFSET IO:SGR JZ DRIVOUT MOV AL,0 ;Dummy char JMP OUTCHR DRIVOUT: MOV BX,OFFSET IO:PARMS CMP BYTE PTR [BX],37H ;Is it enter mode JZ SGRN MOV AL,'q' ;Heath exit video mode JMP SENDESC SGRN: MOV AL,'p' JMP SENDESC ;Heath enter video mode ; ; Cursor controls translation table. This table below contains that ; actual ASCII code sequences used by your terminal to perform basic ; cursor control commands. MS-DOS 2.0 normally expects to see ANSI ; standard sequences for these commands, however this table is set ; up so that the user can re-define the ASCII codes for his specific ; terminal. The table has some specifiers that will tell the code ; to use certain parameters that are passed, such as row or column ; number, or the number of moves. ; ; Specifer action ; 0F1H Use parameter #1 here (the row or line #) ; 0F2H Use parameter #2 here (the column #) ; 0FEH Use special driver routine (User defined) ; 0FFH Use parameter #1 as a count ; 00H end of code ; ESC Outputs the 'esc' character HEATH: CUP: DB ESC ;Cursor position DB 'Y' DB 0F1H DB 0F2H DB 0 CUU: DB ESC ;Cursor up DB 'A' DB 0FFH DB 0 CUD: DB ESC ;Cursor down DB 'B' DB 0FFH DB 0 CUF: DB ESC ;Cursor forward DB 'C' DB 0FFH DB 0 CUB: DB ESC ;Cursor backward DB 'D' DB 0FFH DB 0 ED: DB ESC ;Erase display DB 'E' DB 0 EL: DB ESC ;Erase line DB 'L' DB 0 PSCP: DB ESC ;Save cursor position DB 'j' DB 0 PRCP: DB ESC ;Set cursor to saved position DB 'k' DB 0 SGR: DB 0FEH ;User defined driver DB 0 CODE ENDS END