; ; MSXMBC - MS-DOS KERMIT MODULE FOR SANYO MBC-55x ; ; THIS MODULE WAS CREATED BY EDITING THE GENERIC MS-DOS MODULE ; MSXGEN AND ADDING THE SANYO SPECIFIC CODE TO PERFORM THE NEEDED ; FUNCTIONS, MANY OF WHICH WERE GRACEFULLY BORROWED FROM THE MSXIBM ; MODULE. PLEASE NOTE THAT THE SANYO "AUX" DEVICE HARDWARE CONSISTS OF: ; ; 8251A SERIAL COMMUNICATIONS DEVICE (DOES RS-232 STUFF) ; 8259A SYSTEM INTERRUPT CONTROLLER ; 8253 TIMER DEVICE (FED TO 8251A AS BAUD RATE) ; ; DEFUALT SETTINGS ARE: ; ; BAUD RATE = 300 ; CHAR LENGTH = 8 BITS ; PARITY = NONE ; STOP BITS = 1 ; ; JOE SMILEY 1-5-85 ; ; ; GLOBALLY ACCESSIBLE SUBROUTINES ; PUBLIC SERINI ; INITIALIZE AUX DEVICE FOR INPUT PUBLIC SERRST ; RESTORE AUX DEVICE TO CALM STATE PUBLIC CLRBUF ; CLEAR AUX DEVICE INPUT BUFFERS PUBLIC OUTCHR ; OUTPUT CHARACTER ON AUX DEVICE PUBLIC COMS ; SET COMM PORT (ONLY ONE ON SANYO) PUBLIC VTS ; HEATH-19 NOT IMPLEMENTED PUBLIC DODEL ; DELETE CHARACTER FROM SCREEN PUBLIC CTLU ; ERASE CURRENT LINE PUBLIC CMBLNK ; BLANK THE ENTIRE VIDEO SCREEN PUBLIC LOCATE ; HOME CURSOR PUBLIC LCLINI ; LOCAL SYSTEM INITIALIZATION PUBLIC PRTCHR ; GET A CHARACTER (IF ONE) FROM AUX PUBLIC DOBAUD ; SET AUX DEVICE BAUD RATE PUBLIC CLEARL ; CLEAR A LINE ON VIDEO SCREEN PUBLIC DODISK ; GET NO. OF SYSTEM DISK DRIVES PUBLIC GETBAUD ; GET DEFAULT BAUD RATE PUBLIC BEEP ; OUTPUT BEEP ON PC PUBLIC PUTHLP ; DISPLAY HELP MESSAGE ON SCREEN PUBLIC PUTMOD ; PUT MODE STRING ON LINE 24 PUBLIC CLRMOD ; CLEAR MODE LINE PUBLIC POSCUR ; POSITION CURSOR ON VIDEO SCREEN PUBLIC SENDBR ; SEND BREAK SIGNAL ON AUX DEVICE PUBLIC TERM ; PERFORM TERMINAL EMULATION PUBLIC SHOWKEY ; NOT IMPLEMENTED ; ; GLOBALLY ACCESSIBLE DATA ; PUBLIC COUNT ; NO. OF CHARACTERS IN INPUT BUFFER PUBLIC XOFSNT ; FLAG INDICATING XOFF SENT OUT AUX PUBLIC MACHNAM ; ASCII STRING CONTAINING MACHINE NAME PUBLIC SETKTAB ; NOT USED PUBLIC SETKHLP ; NOT USED ; ; INCLUDE STANDARD MS-DOS DEFINITIONS ; INCLUDE MSDEFS.H ; ; ADDITIONAL EQUATES ; FALSE EQU 0 ; BOOLEAN FALSE VALUE TRUE EQU 1 ; BOOLEAN TRUE VALUE MNTRGH EQU (BUFSIZ * 3) / 4 ; HIGH POINT OF BUFFER FULL VIDEO EQU 010H ; VIDEO INTERRUPT ; ; EXTERNAL VARIABLES USED ; ; DRIVES - NO. OF DISK DRIVES ON SYSTEM ; FLAGS - GLOBAL FLAGS AS PER FLGINFO STRUCTURE ; PORTVAL - POINTER TO CURRENT PORTINFO STRUCTURE (ALWAYS PORT1) ; PORT1 - PORTINFO STRUCTURE USED FOR SANYO ; ; ; DEFINE DATA SEGMENT ; DATAS SEGMENT PUBLIC 'DATAS' EXTRN DRIVES:BYTE ; NO. OF DISK DRIVES ON SYSTEM EXTRN FLAGS:BYTE ; GLOBAL FLAGS USED EXTRN PORTVAL:WORD ; POINTER TO PORTINFO STRUCTURE EXTRN PORT1:BYTE ; PORTINFO STRUCTURE USED BY SANYO ; ; SANYO DEVICE DEFINITIONS (AND BAUD RATE TABLE) ; ; ; 8251A serial communications device ; BUF8251 EQU 028H ; I/O address of 8251A in/out buffer CMD8251 EQU 02aH ; I/O address of 8251A command buffer STS8251 EQU 02aH ; I/O address of 8251A status buffer VEC8251 EQU 03e8H ; 8251A interrupt vector location INT8251 EQU 0fbH ; 8259A interrupt enable mask (int 2) ; ; 8251A Command Intruction Formats ; TxEN EQU 001H ; 8251A transmit enable DTR EQU 002H ; 8251A data terminal ready high RxEN EQU 004H ; 8251A receiver enable SBRK EQU 008H ; 8251A send break character ER EQU 010H ; 8251A error reset (must when RxEN) RTS EQU 020H ; 8251A request to send high IR EQU 040H ; 8251A internal reset ; ; 8251A Status Read Formats ; TxRDY EQU 001H ; 8251A transmitter ready RxRDY EQU 002H ; 8251A receiver ready TxEMPTY EQU 004H ; 8251A transmit buffer empty PE EQU 008H ; 8251A parity error OE EQU 010H ; 8251A overrun error FE EQU 020H ; 8251A framing error BRKDET EQU 040H ; 8251A break detect DSR EQU 080H ; 8251A data set ready at zero level ; ; 8253 timer device ; CKA8253 EQU 020H ; I/O address of 8253 counter #0 CKB8253 EQU 022H ; I/O address of 8253 counter #1 CKC8253 EQU 024H ; I/O address of 8253 counter #2 CMD8253 EQU 026H ; I/O address of 8253 command buffer ; ; 8253 Timer baud rate tables ; ; Note: ; the 8251a is normally (by default) set up to a clock multiplier ; of 16x rather than 1x or 64x. this is OK for most of the popular baud ; rates, however, the values programmed below may not work for some of the ; less popular rates without resetting the clock multiplier on the 8251a, ; and reprogramming the timer values below. ; ; in other words, i was too lazy to verify that all of the timer ; values mentioned below would work for the specified baud rates. ; BDDAT LABEL WORD DW (29829/((45/30)*8)) ; Timer value for baud rate 45.5 DW (29829/((50/30)*8)) ; Timer value for baud rate 50 DW (29829/((75/30)*8)) ; Timer value for baud rate 75 DW (29829/((110/30)*8)) ; Timer value for baud rate 110 DW (29829/((134/30)*8)) ; Timer value for baud rate 134.5 DW (29829/((150/30)*8)) ; Timer value for baud rate 150 DW (29829/((300/30)*8)) ; Timer value for baud rate 300 DW (29829/((600/30)*8)) ; Timer value for baud rate 600 DW (29829/((1200/30)*8)) ; Timer value for baud rate 1200 DW (29829/((1800/30)*8)) ; Timer value for baud rate 1800 DW (29829/((2000/30)*8)) ; Timer value for baud rate 2000 DW (29829/((2400/30)*8)) ; Timer value for baud rate 2400 DW (29829/((4800/30)*8)) ; Timer value for baud rate 4800 DW (29829/((9600/30)*8)) ; Timer value for baud rate 9600 DW (29829/((19200/30)*8)) ; Timer value for baud rate 19200 DW (29829/((38400/30)*8)) ; Timer value for baud rate 38400 ; ; 8259A interrupt controller ; CMA8259 EQU 000H ; I/O address of 8259A command buff 1 CMB8259 EQU 002H ; I/O address of 8259A command buff 2 ; ; ASCII MESSAGES ; MACHNAM DB 'Sanyo MBC-55x MS-DOS v2.11$' ERMS20 DB CR,LF,'?Warning: System has no disk drives$' ERMS40 DB CR,LF,'?Warning: Unrecognized baud rate$' BADBD DB CR,LF,'Unimplemented baud rate$' NOIMP DB CR,LF,'Command not implemented.$' SHKMSG DB 'Not implemented.' SHKLEN EQU $-SHKMSG SETKTAB DB 0 SETKHLP DB 0 DELSTR DB BS,' ',BS,'$' CLRLIN DB CR,'$' RBTRN DB 7FH ; RUBOUT CODE ; ; ADDITIONAL DATA STRUCTURES ; TELFLG DB 0 ; TERMINAL EMULATION FLAG XOFSNT DB 0 ; XOFF JUST SENT FLAG XOFRCV DB 0 ; XOFF JUST RECEIVED FLAG PORTIN DB 0 ; AUX PORT INITIALIZED FLAG SAVSCI DW ? ; SAVED AUX PORT INTERRUPT VECTOR SAVSCS DW ? ; SAVED AUX PORT INTERRUPT VECTOR SOURCE DB BUFSIZ DUP(?) ; INPUT DATA BUFFER (FROM AUX) SRCPNT DW 0 ; INPUT BUFFER POINTER COUNT DW 0 ; NO. OF CHARACTERS IN BUFFER SAVESI DW 0 ; SAVE SI REGISTER HERE OURARG TERMARG <> ; TERMINAL EMULATOR ARG STORAGE DATAS ENDS ; END OD DATA SEGMENT ; ; START OF CODE SEGMENT ; CODE SEGMENT PUBLIC EXTRN DEFKEY:NEAR ; DEFINE A TRANSLATION ROUTINE EXTRN PRSERR:NEAR ; EXTERNAL PRINT ERROR ROUTINE ASSUME CS:CODE, DS:DATAS ; ASSUME CODE AND DATA SEGMENTS ; ; DODISK - SET THE NUMBER OF DISK DRIVES ON THE HOST SYSTEM ; ; OUTPUTS: ; DRIVES - GLOBAL BYTE VARIABLE SET TO THE NUMBER OF DISK DRIVES ; ; NOTES: ; RETURNS NORMALLY. ; DODISK PROC NEAR MOV AH,GCURDSK ; SET CODE TO GET CURRENT DISK DRIVE INT DOS ; GET THE CURRENT DISK DRIVE MOV DL,AL ; SET CURRENT DISK DRIVE MOV AH,SELDSK ; SET CODE TO SELECT CURRENT DISK INT DOS ; SELECT AND GET NO. OF DRIVES MOV DRIVES,AL ; SET GLOBAL VARIABLE RET ; AND RETURN DODISK ENDP ; ; CLRBUF - CLEAR 8251A (AUX DEVICE) INPUT BUFFER ; ; THIS ROUTINE CLEARS THE AUX DEVICE INPUT BUFFER SO THAT NO ; ACCUMULATED CHARACTERS (ESPECIALLY IMPORTANT WHEN TALKING TO ; SERVER KERMITS) INTEREFER WITH COMMUNICATION. IT ALSO SETS UP THE ; CIRCULAR INPUT BUFFER USED BY THE INPUT INTERRUPT ROUTINE. ; ; NOTES: ; THIS ROUTINE RETURNS NORMALLY. ; CLRBUF PROC NEAR PUSHF ; SAVE FLAGS CLI ; LOCK OUT INTERRUPTS PUSH AX ;;; SAVE REGISTER IN AL,STS8251 ;;; READ STATUS REGISTER IN AL,BUF8251 ;;; READ INPUT BUFFER IN AL,BUF8251 ;;; READ AGAIN (DOUBLE BUFFERED INPUT) MOV AX,OFFSET SOURCE ;;; GET START OF INPUT DATA BUFFER ; ; RESET CIRCULAR INPUT BUFFER POINTERS AND COUNT ; MOV SRCPNT,AX ;;; SET DATA BUFFER POINTER MOV SAVESI,AX ;;; AND SET INITIAL SI POINTER MOV COUNT,0 ;;; INITIALIZE NO. OF CHARS IN BUFFER POP AX ;;; RESTORE REGISTER POPF ;;; RESTORE FLAGS (RE-ENABLE INTS) RET ; RETURN CLRBUF ENDP ; ; CLEARL - CLEAR TO THE END OF THE CURRENT LINE ON THE VIDEO SCREEN ; CLEARL PROC NEAR MOV AH,3 ; SET CODE TO GET CURSOR POSITION MOV BH,0 ; SET PAGE 0 INT VIDEO ; GET CURRENT CURSOR POSITION MOV CX,DX ; COPY CURSOR POSITION MOV DL,79 ; SET COLUMN POSITION OF SCROLL MOV AH,7 ; SET CODE TO SCROLL PAGE DOWN MOV AL,0 ; SET NUMBER OF LINES (WHOLE WINDOW) MOV BH,7 ; BLANK LINE ATTRIBUTE INT VIDEO ; AND NOW BLANK THE LINES RET ; AND RETURN CLEARL ENDP ; ; OUTCHR - OUTPUT CHARACTER TO AUX DEVICE DOING FLOW CONTROL ; ; THIS SUBROUTINE WILL OUTPUT THE SPECIFIED CHARACTER ON THE AUX ; DEVICE WHILE HONORING XON/XOFF FLOW CONTROL. ; ; INPUTS: ; AH - CONTAINS CHARACTER TO BE OUTPUT ; ; NOTES: ; THIS ROUTINE SKIPS RETURN ON SUCCESS. ; OUTCHR: MOV BP,PORTVAL ; GET POINTER TO CURRENT PORT STRUCTURE CMP DS:[BP].FLOFLG,FALSE ; DOING FLOW CONTROL? JE OUTCH2 ; IF E NO, JUST CONTINUE XOR CX,CX ; CLEAR COUNTER REGISTER OUTCH1: CMP XOFRCV,TRUE ; CURRENTLY BEING HELD? JNE OUTCH2 ; IF NE NO, OK TO PROCEED LOOP OUTCH1 ; ELSE WAIT A WHILE MOV XOFRCV,FALSE ; TIMED OUT, FORCE XOFF OFF AND GO ON ; ; OUTCH2 - OUTPUT CHARACTER TO AUX DEVICE ; ; NOTES: ; - DESTROYS CONTENTS OF AX REGISTER ; - 8251A DEVICE HANDLES PARITY IN HARDWARE (SEE SETUP BELOW) ; OUTCH2: PUSHF ; SAVE FLAGS CLI ; LOCK OUT INTERRUPTS PUSH AX ;;; SAVE REGISTER MOV AL,(TxEN+DTR+RxEN+ER+RTS) ;;; GET OUTPUT ENABLE COMMAND OUT CMD8251,AL ;;; COMMAND 8251 FOR OUTPUT CALL DUMRET ;;; KILL SOME TIME OUTCH3: IN AL,STS8251 ;;; READ DEVICE STATUS TEST AL,TxRDY ;;; TRANSMITTER READY? JZ OUTCH3 ;;; IF ZERO NO POP AX ;;; RESTORE REGISTER MOV AL,AH ;;; GET CHARACTER TO OUTPUT OUT BUF8251,AL ;;; OUTPUT CHARACTER CALL DUMRET ;;; KILL SOME TIME MOV AL,(DTR+RxEN+ER+RTS) ;;; GET INPUT ENABLE COMMAND OUT CMD8251,AL ;;; RE-COMMAND 8251A FOR INPUT POPF ;;; RESTORE FLAGS (RE-ENABLE INTS) JMP RSKP ; RETURN DUMRET: RET ; DUMMY RETURN ; ; CMBLNK - BLANK THE VIDEO SCREEN ; ; NOTES: ; RETURN NORMALLY. ; CMBLNK PROC NEAR MOV CX,0 ; SET HOME POSITION MOV DX,0184FH ; SET LOWER RIGHT CORNER OF SCREEN MOV BH,7 ; SET BLANK ATTRIBUTE MOV AX,0600H ; SET CODE FOR SCROLL PAGE UP INT VIDEO ; AND CLEAR THE SCREEN RET ; AND RETURN CMBLNK ENDP ; ; LOCATE - HOME THE CURSOR ; ; NOTES: ; RETURNS NORMALLY. ; LOCATE PROC NEAR MOV DX,0 ; SET HOME POSITION JMP POSCUR ; AND GO TO POSITION LOCATE ENDP ; ; PUTMOD - WRITE A LINE AT THE BOTTOM OF THE VIDEO SCREEN ; ; INPUTS: ; DX - ADDRESS OF LINE, TERMINATED BY '$' ; ; NOTES: ; RETURNS NORMALLY. ; PUTMOD PROC NEAR PUSH DX ; SAVE REGISTER MOV CX,01800H ; SET START ADDRESS MOV DX,0184FH ; AND END ADDRESS MOV AX,0600H ; SET CODE TO SCROLL PAGE UP MOV BH,07H ; SET ATTRIBUTE INT VIDEO ; CLEAR LINE MOV DX,01800H ; RE-ADDRESS LINE 24 CALL POSCUR ; POSITION THE CURSOR POP DX ; GET STRING ADDRESS MOV AH,PRSTR ; SET CODE TO PRINT STRING INT DOS ; PRINT THE STRING RET ; AND RETURN PUTMOD ENDP ; ; CLRMOD - CLEAR THE LINE WRITTEN BY PUTMOD ; ; NOTES: ; RETURNS NORMALLY. ; CLRMOD PROC NEAR MOV CX,01800H ; ADDRESS START OF LINE 24 MOV DX,0184FH ; AND END ADDRESS MOV AX,0600H ; SET CODE TO SCROLL PAGE UP MOV BH,07H ; NORMAL ATTRIBUTE INT VIDEO ; AND CLEAR LINE RET ; AND RETURN CLRMOD ENDP ; ; PUTHLP - PUT A HELP MESSAGE ON THE SCREEN ; ; INPUTS: ; AX - ADDRESS OF MESSAGE, TERMINATED BY NUL ; ; NOTES: ; RETURNS NORMALLY. ; PUTHLP PROC NEAR PUSH AX ; SAVE THE STRING ADDRESS MOV SI,AX ; SET STRING ADDRESS MOV DH,1 ; INITIALIZE COUNTER PUTHL1: LODSB ; GET NEXT BYTE CMP AL,LF ; GET A LINE FEED? JNE PUTHL2 ; IF NE NO, CONTINUE INC DH ; ELSE COUNT IT JMP PUTHL1 ; AND CONTINUE PUTHL2: CMP AL,0 ; AT END OF STRING? JNE PUTHL1 ; IF NE NO, CONTINUE COUNTING MOV AX,0600H ; SET CODE TO SCROLL ACTIVE PAGE UP XOR CX,CX ; SET HOME POSITION MOV DL,04FH ; TO BOTTOM RIGHT OF NEEDED PIECE MOV BH,070H ; SET INVERSE VIDEO ATTRIBUTE INT VIDEO ; CLEAR SCREEN AREA CALL LOCATE ; HOME CURSOR POP SI ; RESTORE STRING ADDRESS PUTHL3: LODSB ; GET NEXT BYTE CMP AL,0 ; END OF STRING? JE PUTHL4 ; IF E YES MOV AH,14 ; SET CODE TO WRITE TO VIDEO INT VIDEO ; AND DO IT JMP PUTHL3 ; AND DO NEXT CHARACTER PUTHL4: MOV DX,24 * 100H ; SET ADDRESS OF LAST LINE JMP POSCUR ; AND POSITION CURSOR THERE PUTHLP ENDP ; ; DOBAUD SET THE CURRENT BAUD RATE ; ; NOTES: ; RETURNS NORMALLY. ; DOBAUD PROC NEAR PUSH AX ; SAVE REGISTER PUSH BX ; SAVE REGISTER PUSH BP ; SAVE REGISTER MOV BP,PORTVAL ; ADDRESS PORT STRUCTURE MOV AX,DS:[BP].BAUD ; GET BAUD RATE INDEX SHL AX,1 ; CONVERT TO WORD INDEX MOV BX,AX ; RE-GET OFFSET ADDRESS ADD BX,OFFSET BDDAT ; ADD IN BASE ADDRESS OF TABLE ; ; SET TIMER VALUE FOR BAUD RATE GENERATION BY 8253 TIMER CHIP ; MOV AX,[BX] ; GET 8253 TIME COUNT FOR THIS RATE OUT CKC8253,AL ; OUTPUT LOW BYTE OF VALUE MOV AL,AH ; GET HIGH BYTE OUT CKC8253,AL ; OUTPUT HIGH BYTE OF VALUE POP BP ; RESTORE REGISTER POP BX ; RESTORE REGISTER POP AX ; RETSORE REGISTER RET ; AND RETURN DOBAUD ENDP ; ; GETBAUD - SET DEFAULT BAUD RATE TO 300 ; GETBAUD PROC NEAR PUSH AX ; SAVE REGISTER PUSH BP ; SAVE REGISTER MOV AX,6 ; GET INDEX FOR BAUD RATE OF 300 MOV BP,PORTVAL ; GET PORT INFO STRUCTURE MOV DS:[BP].BAUD,AX ; SET INDEX POP BP ; RESTORE REGISTER POP AX ; RESTORE REGISTER RET GETBAUD ENDP ; ; SERINI - SERIAL (AUX) DEVICE INITIALIZATION ; ; THIS FUNCTION IS CALLED TO SET UP THE SERIAL DEVICE INPUT ; INTERRUPT AND INITIALIZE THE SERIAL DEVICE BEFORE COMMUNICATIONS. ; NOTE THAT THIS FUNCTION SHOULD BE ABLE TO BE CALLED TWICE IN ; SUCCESSION WITHOUT DISASTEROUS RESULTS. ; ; "SERRST" IS THE OPPOSITE OF THIS FUNCTION AND SHOULD RETURN ; THE DEVICE TO A QUESCIENT STATE. ; ; NOTES: ; THE AUX DEVICE IS SET UP BY DEFAULT FOR 300 BAUD, 8 BITS ; PER CHARACTER, 1 STOP BIT, AND NO PARITY. ; ; THIS FUNCTION RETURNS NORMALLY. ; SERINI PROC NEAR CMP PORTIN,0 ; DEVICE ALREADY INITIALIZED? JNE SERIN0 ; IF NE YES ; ; RESET 8251A DEVICE AND SET DEFAULT OPERATING MODE ; CLI ; DISABLE INTERRUPTS MOV AL,IR ;;; GET 8251A INTERNAL RESET COMMAND OUT CMD8251,AL ;;; RESET 8251A DEVICE CALL DUMRET ;;; KILL SOME TIME MOV AL,04EH ;;; GET MODE (8 BITS PER CHAR, NO ;;; PARITY, 1 STOP BIT, 16X CLOCK) OUT CMD8251,AL ;;; SET OPERATING MODE ON 8251A CALL DUMRET ;;; KILL SOME TIME MOV AL,(DTR+RxEN+ER+RTS) ;;; GET INPUT ENABLE COMMAND OUT CMD8251,AL ;;; ENABLE INPUT ON 8251A ; ; SET NEW INTERRUPT VECTOR AND UNMASK 8251A INTERRUPT LINE ON 8259A ; PUSH ES ;;; SAVE SEGMENT REGISTER MOV AX,0000 ;;; GET SEGMENT OF VECTOR SPACE MOV ES,AX ;;; SET SEGMENT ADDRESS MOV BX,VEC8251 ;;; GET ADDRESS OF AUX INT VECTOR MOV AX,ES:[BX] ;;; GET OLD VECTOR OFFSET MOV SAVSCI,AX ;;; AND SAVE IT MOV AX,OFFSET SERINT ;;; GET NEW VECTOR OFFSET MOV ES:[BX],AX ;;; AND SET IT ADD BX,2 ;;; GET TO NEXT WORD IN VECTOR MOV AX,ES:[BX] ;;; AND GET IT MOV SAVSCS,AX ;;; AND SAVE SECOND WORD MOV ES:[BX],CS ;;; SET OUR SEGMENT ADDRESS IN AL,CMB8259 ;;; GET CURRENT INTERRUPT MASK AND AL,INT8251 ;;; UNMASK 8251A INTERRUPT OUT CMB8259,AL ;;; SET NEW MASK VALUE POP ES ;;; RESTORE SEGMENT REGISTER ; ; CLEAR THE INPUT DEVICE AND SET UP CIRCULAR INPUT BUFFER ; CALL CLRBUF ;;; CLEAR THE INPUT BUFFER CALL DOBAUD ;;; SET BAUD RATE LOCALLY ; ; INITIALIZATION DONE. ; MOV PORTIN,1 ;;; SET PORT IS INITIALIZED STI ;;; ENABLE INTERRUPTS SERIN0: RET ; RETURN SERINI ENDP ; ; SERRST - RESTORE SERIAL PORT INTERRUPT ; SERRST PROC NEAR CMP PORTIN,0 ; NEED TO RESET? JE SERRS0 ; IF EQUAL NO CLI ; DISABLE INTERRUPTS PUSH ES ;;; SAVE SEGMENT REGISTER MOV AX,0000 ;;; GET SEGMENT OF VECTOR SPACE MOV ES,AX ;;; SET SEGMENT ADDRESS MOV BX,VEC8251 ;;; GET ADDRESS OF AUX INT VECTOR MOV AX,SAVSCI ;;; GET OLD VECTOR OFFSET MOV ES:[BX],AX ;;; AND SET IT ADD BX,2 ;;; GET TO NEXT WORD IN VECTOR MOV AX,SAVSCS ;;; GET SECOND WORD SAVED MOV ES:[BX],AX ;;; SET OLD SEGMENT ADDRESS POP ES ;;; RESTORE SEGMENT REGISTER STI ;;; RE-ENABLE INTERRUPTS MOV PORTIN,0 ; SET DEVICE NOT INITIALIZED SERRS0: RET ; RETURN SERRST ENDP ; ; SERINT - SERIAL PORT (AUX DEVICE) INPUT INTERRUPT SERVICE ROUTINE ; SERINT PROC NEAR PUSH AX ;;; SAVE REGISTER PUSH BX ;;; SAVE REGISTER PUSH CX ;;; SAVE REGISTER PUSH DX ;;; SAVE REGISTER PUSH DI ;;; SAVE REGISTER PUSH BP ;;; SAVE FRAME POINTER PUSH DS ;;; SAVE SEGMENT REGISTER PUSH ES ;;; SAVE SEGMENT REGISTER CLD ;;; DO AUTO-INCREMENT ON STRINGS MOV AX,SEG DATAS ;;; GET DATA SEGEMENT ADDRESS MOV DS,AX ;;; SET DATA SEGMENT ADDRESS MOV ES,AX ;;; AND SET AS EXTRA SEGMENT MOV DI,SRCPNT ;;; GET POINTER TO INPUT DATA BUFFER IN AL,STS8251 ;;; GET 8251A STATUS TEST AL,RxRDY ;;; RECEIVER READY (GOT A CHARACTER)? JZ RETINT ;;; IF Z NO IN AL,BUF8251 ;;; ELSE GET CHARACTER INPUT CMP TELFLG,0 ;;; TERMINAL EMULATION MODE? JZ SRINT0 ;;; IF Z NO AND AL,07FH ;;; ELSE TERMINAL MODE 7 BITS ONLY SRINT0: OR AL,AL ;;; IS THIS A NUL CHARACTER? JZ RETINT ;;; IF Z YES, IGNORE NULS CMP AL,07FH ;;; CHARACTER A RUBOUT? JZ RETINT ;;; IF Z YES, IGNORE THEM TOO MOV BP,PORTVAL ;;; GET ADDRESS OF PORT STRUCTURE CMP DS:[BP].FLOFLG,0 ;;; ARE WE DOING FLOW CONTROL? JE SRINT2 ;;; IF E NO MOV BX,DS:[BP].FLOWC ;;; FLOW CONTROL (BH = XON, BL = XOFF) CMP AL,BL ;;; IS INPUT CHARACTER AN XOFF? JNE SRINT1 ;;; IF NE NO, SO CONTINUE MOV XOFRCV,TRUE ;;; SET RECEIVED XOFF JMP RETINT ;;; AND EXIT FOR NOW SRINT1: CMP AL,BH ;;; GET AN XON? JNE SRINT2 ;;; IF NE NO, CONTINUE MOV XOFRCV,FALSE ;;; CANCEL XOFF JMP RETINT ;;; AND EXIT INTERRUPT SRINT2: STOSB ;;; STORE CHARACTER IN BUFFER CMP DI,OFFSET SOURCE + BUFSIZ ;;; TIME TO WRAP BUFFER BACK TO START JB SRINT3 ;;; IF B NO MOV DI,OFFSET SOURCE ;;; ELSE WRAP BUFFER BACK TO START SRINT3: INC COUNT ;;; COUNT CHARACTER INPUT CMP DS:[BP].FLOFLG,0 ;;; DOING FLOW CONTROL? JE RETINT ;;; IF E NO, JUST LEAVE INTERRUPT CMP XOFSNT,TRUE ;;; HAVE WE SENT AN XOFF? JE RETINT ;;; IF E YES, JUST EXIT CMP COUNT,MNTRGH ;;; PAST THE HIGH TRIGGER POINT? JBE RETINT ;;; IF BE NO, WITHIN LIMIT MOV AH,BL ;;; GET THE XOFF CHARACTER CALL OUTCHR ;;; AND SEND IT NOP ;;; ALLOW FOR RSKP RETURN ON ERROR NOP ;;; " NOP ;;; " MOV XOFSNT,TRUE ;;; SET SENT XOFF CHARACTER RETINT: MOV SRCPNT,DI ;;; SAVE UPDATED BUFFER POINTER POP ES ;;; RESTORE SEGMENT REGISTER POP DS ;;; RESTORE SEGMENT REGISTER POP BP ;;; RESTORE FRAME POINTER POP DI ;;; RESTORE REGISTER POP DX ;;; RESTORE REGISTER POP CX ;;; RESTORE REGISTER POP BX ;;; RESTORE REGISTER POP AX ;;; RESTORE REGISTER INTRET: IRET ;;; RETURN FROM INTERRUPT SERINT ENDP ; ; PRTCHR - CHECK FOR CHARACTER AT AUX DEVICE ; ; OUTPUTS: ; AL - CHARACTER IF ONE AVAILABLE ; DX - NUMBER OF CHARACTERS IN BUFFER ; NOTES: ; SKIPS RETURN IF NO CHARACTER AVAILABLE. ; PRTCHR PROC NEAR CALL CHKXON ; CHECK TO SEE IF XON NEEDED CMP COUNT,0 ; ANY CHARACTERS IN BUFFER? JNZ PRTCH1 ; IF NZ YES JMP RSKP ; ELSE NO DATA, JUST RETURN PRTCH1: MOV SI,SAVESI ; GET SAVED BUFFER POINTER LODSB ; GET NEXT BYTE FROM BUFFER CMP SI,OFFSET SOURCE + BUFSIZ ; TIME TO WRAP BUFFER? JB PRTCH2 ; IF B NO MOV SI,OFFSET SOURCE ; WRAP BUFFER BACK TO START PRTCH2: DEC COUNT ; COUNT CHARACTER REMOVED MOV SAVESI,SI ; SAVE BUFFER POINTER MOV DX,COUNT ; RETURN NO. OF CHARS IN BUFFER RET ; AND RETURN PRTCHR ENDP ; ; CHKXON - CHECK TO SEE IF AN XON IS NEEDED ; CHKXON PROC NEAR PUSH BX ; SAVE REGISTER MOV BX,PORTVAL ; GET ADDRESS OF PORT STRUCTURE CMP [BX].FLOFLG,FALSE ; ARE WE DOING FLOW CONTROL? JE CHKXO1 ; IF E NO, JUST RETURN CMP XOFSNT,FALSE ; HAVE WE ALREADY SENT AN XOFF? JE CHKXO1 ; IF E NO, JUST RETURN CMP COUNT,MNTRGH ; ARE WE BELOW THE TRIGGER? JAE CHKXO1 ; IF AE NO, JUST RETURN MOV AX,[BX].FLOWC ; GET XON INTO AH CALL OUTCHR ; AND OUTPUT CHARACTER NOP ; IGNORE ERROR RETURN NOP ; " NOP ; " MOV XOFSNT,FALSE ; SAY WE SENT AN XON NOW CHKXO1: POP BX ; RESTORE REGISTER RET ; AND RETURN CHKXON ENDP ; ; SENDBR - SEND A BREAK OUT THE AUX DEVICE (SERIAL PORT) ; SENDBR PROC NEAR PUSH AX ; SAVE REGISTER PUSH CX ; SAVE REGISTER XOR CX,CX ; CLEAR LOOP VALUE MOV AL,(TxEN+DTR+RxEN+RTS) ; GET OUTPUT 8251A ENABLE BYTE OUT CMD8251,AL ; AND ENABLE 8251A MOV AL,(TxEN+DTR+RxEN+SBRK+RTS) ; GET SEND BREAK ENABLE BYTE OUT CMD8251,AL ; AND SEND BREAK PAUSE: LOOP PAUSE ; KILL SOME TIME MOV AL,(TxEN+DTR+RxEN+RTS) ; GET OUTPUT 8251A ENABLE BYTE OUT CMD8251,AL ; STOP BREAK MOV AL,(DTR+RxEN+ER+RTS) ; GET INPUT ENABLE BYTE OUT CMD8251,AL ; AND RE-ENABLE INPUT POP CX ; RESTORE REGISTER POP AX ; RESTORE REGISTER RET ; RETURN SENDBR ENDP ; ; POSCUR - POSITION THE CURSOR ; ; INPUTS: ; DH - CONTAINS THE ROW ; DL - CONTAINS THE COLUMN ; ; NOTES: ; RETURNS NORMALLY. ; POSCUR PROC NEAR MOV AH,2 ; SET CODE TO POSITION CURSOR MOV BH,0 ; SET PAGE NUMBER INT VIDEO ; AND POSITION THE CURSOR RET ; AND RETURN POSCUR ENDP ; ; DODEL - DELETE A CHARACTER FROM VIDEO SCREEN ; ; NOTES: ; RETURNS NORMALLY. ; DODEL PROC NEAR MOV AH,PRSTR ; SET CODE TO PRINT STRING MOV DX,OFFSET DELSTR ; SET ERASE STRING INT DOS ; AND ERASE CHARACTER RET ; AND RETURN DODEL ENDP ; ; CTLU - CLEAR CURRENT LINE ; ; NOTES: ; RETURNS NORMALLY. ; CTLU PROC NEAR MOV AH,PRSTR ; SET CODE TO PRINT STRING MOV DX,OFFSET CLRLIN ; SET STRING ADDRESS INT DOS ; OUTPUT STRING CALL CLEARL ; NOW CLEAR THE LINE RET ; AND RETURN CTLU ENDP ; ; COMS - SET THE CURRENT PORT (ONLY ONE ON SANYO) ; COMS PROC NEAR MOV AX,OFFSET PORT1 ; GET ADDRESS OF PORT STRUCTURE MOV PORTVAL,AX ; AND SET IT RET ; WE'RE DONE COMS ENDP ; ; VTS - WE DON'T DO HEATH EMULATION, SANYO BIOS DOES VT-100 (SOMEWHAT) ; VTS PROC NEAR MOV AH,PRSTR ; SET CODE TO PRINT STRING MOV DX,OFFSET NOIMP ; SET ADDRESS OF ERROR MESSAGE INT DOS ; AND PRINT IT JMP PRSERR ; AND EXIT VTS ENDP ; ; LCLINI - DO LOCAL INITIALIZATION ; LCLINI: MOV FLAGS.VTFLG,0 ; DON'T KNOW EXACTLY WHAT THIS DOES MOV AX,0EH ; SET SCAN CODE FOR ARROW KEY MOV SI,OFFSET RBTRN ; SET TRANSLATED CODE ADDRESS MOV CX,1 ; SET SIZE OF TRANSLATION CALL DEFKEY ; AND DEFINE THE KEY RET ; AND RETURN ; ; SHOWKEY - DON'T DO THIS EITHER ; SHOWKEY: MOV AX,OFFSET SHKMSG ; SET ADDRESS OF MESSAGE MOV CX,SHKLEN ; AND LENGTH OF MESSAGE RET ; ; BEEP - PRODUCE A BEEP ; BEEP PROC NEAR MOV DL,BELL ; SET ADDRESS OF BELL MOV AH,DCONIO ; SET CODE FOR OUPUT INT DOS ; OUTPUT BELL RET ; AND RETURN BEEP ENDP ; ; TERM - TERMINAL EMULATOR (DUMB) ; ; INPUTS: ; AX - POINTER TO ARGUMENT BLOCK ; ; NOTES: ; THE SANYO BIOS WILL EMULATE (SOMEWHAT) A VT-100. ; TERM PROC NEAR MOV TELFLG,1 ; SET TERMINAL EMULATION MODE MOV SI,AX ; SET ADDRESS OF ARGUMENT BLOCK MOV DI,OFFSET OURARG ; PLACE TO STORE ARGUMENTS MOV AX,DS ; GET DATA SEGMENT ADDRESS MOV ES,AX ; AND SET IN EXTRA SEGMENT MOV CX,SIZE TERMARG ; AND SET SIZE OF MOVE REP MOVSB ; COPY ARGUMENT BLOCK TO LOCAL STORE TERM1: CALL PRTCHR ; GET NEXT CHAR FROM AUX, ABLE? JMP SHORT TERM2 ; YES, WE HAVE A CHAR NOP ; SPACE FOR RSKP RETURN NOP ; " JMP SHORT TERM3 ; NO CHARACTER, SO CONTINUE TERM2: PUSH AX ; SAVE CHARACTER MOV DL,AL ; COPY CHARACTER MOV AH,CONOUT ; SET CODE FOR CONSOLE OUTPUT INT DOS ; AND GO PRINT IT POP AX ; RESTORE REGISTER TEST OURARG.FLGS,CAPT ; CAPTURING OUTPUT? JZ TERM3 ; IF Z NO, CONTINUE CALL OURARG.CAPTR ; ELSE CALL THE CAPTURE ROUTINE TERM3: MOV AH,DCONIO ; SET CODE FOR INPUT MOV DL,0FFH ; AND CODE INT DOS ; CHECK FOR CHARACTER, WELL? JZ TERM1 ; IF Z NO CHARACTER, GO ON CMP AL,OURARG.ESCC ; ESCAPE CHARACTER? JE TERM4 ; YES, EXIT PUSH AX ; SAVE CHARACTER MOV AH,AL ; COPY THE CHARACTER CALL OUTCHR ; OUTPUT CHARACTER TO AUX DEVICE NOP ; IGNORE ERRORS NOP ; " NOP ; " POP AX ; RESTORE CHARACTER TEST OURARG.FLGS,LCLECHO ; LOCAL ECHO REQUIRED? JZ TERM1 ; IF Z NO, CONTINUE MOV DL,AL ; ELSE COPY CHARACTER MOV AH,DCONIO ; SET CODE INT DOS ; AND ECHO IT JMP TERM1 ; AND CONTINUE TERM4: MOV TELFLG,0 ; CLEAR TERMINAL EMULATION MODE RET TERM ENDP ; ; RSKP - JUMP RETURN WITH SKIPPING ; RSKP PROC NEAR POP BP ; GET TOP OF STACK ADD BP,3 ; ADD SKIP RANGE PUSH BP ; AND RESTORE IT RET RSKP ENDP CODE ENDS END