name msxmbc ; File MSXMBC.ASM ; Last modification: 19 May 1986 ; ; 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 ; ; Add global entry point vtstat for use by Status in mssset. ; Joe R. Doupnik 12 March 1986 ; Add global procedures ihosts and ihostr to handle host initialization ; when packets are to be sent or received by us,resp. 24 March 1986 ; Add global procedure dtrlow (without worker serhng) to force DTR & RTS low ; in support of Kermit command Hangup. Says Not Yet Implemented. [jrd] ; Add global procedure Dumpscr, called by Ter in file msster, to dump screen ; to a file. Just does a beep for now. 13 April 1986 [jrd] ; In proc Outchr add override of xon from chkxon sending routine. ; This makes a hand typed Xoff supress the xon flow control character sent ; automatically as the receiver buffer empties. 20 April 1986 [jrd] ; Fix missing Ret in Puthlp. 3 May 1986 [jrd] ; Redo ascii string for Delete a character on screen: back over DEL code, back ; over unwanted char, replace both by spaces, backup to 1st char. This is the ; general form when the Bios does not interpret DEL. 19 May 86 [jrd] ; Move code to set default baud rate from GETBAUD to LCLINI. 24 June 86 [rwb] ; - Bob Babcock ; ; 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 baud rate from hardware [rwb] 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 public vtstat ; Status for mssset. [jrd] public ihosts, ihostr, dtrlow, dumpscr ;new global entry points [jrd] ; ; 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 MSSDEF.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 extrn dmpname:byte ; [jrd] ; ; 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,' ',BS,BS,'$' ; [jrd] CLRLIN DB CR,'$' RBTRN DB 7FH ; RUBOUT CODE hngmsg db cr,lf,' The phone should have hungup.',cr,lf,'$' ; [jrd] hnghlp db cr,lf,' The modem control lines DTR and RTS for the current' db ' port are forced low (off)' db cr,lf,' to hangup the phone. Normally, Kermit leaves them' db ' high (on) when it exits.' db cr,lf,'$' ; [jrd] rdbuf db 80 dup (?) ; temp buf [jrd] ; ; 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 'code' EXTRN DEFKEY:NEAR ; DEFINE A TRANSLATION ROUTINE EXTRN PRSERR:NEAR ; EXTERNAL PRINT ERROR ROUTINE extrn comnd:near, sleep:near ; [jrd] 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 push ax ; save regs. [jrd] push bx push cx push dx 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 pop dx ; [jrd] pop cx pop bx pop ax 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 cmp ah,byte ptr [bp].flowc ; sending xoff? [jrd] jne outch1 ; ne = no mov xofsnt,false ; supress xon from chkxon buffer routine 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 push ax ; save regs. [jrd] push bx push cx push dx 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 pop dx ; [jrd] pop cx pop bx pop ax 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 bx ; save regs. [jrd] push cx 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 pop cx ; [jrd] pop bx RET ; AND RETURN PUTMOD ENDP ; ; CLRMOD - CLEAR THE LINE WRITTEN BY PUTMOD ; ; NOTES: ; RETURNS NORMALLY. ; CLRMOD PROC NEAR push ax ; save regs. [jrd] push bx push cx push dx 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 pop dx ; [jrd] pop cx pop bx pop ax 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 bx ; save regs. [jrd] push cx push dx push si 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 ; [jrd] JMP POSCUR ; AND POSITION CURSOR THERE call poscur ; position cursor [jrd] pop si ; [jrd] pop dx pop cx pop bx ret 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 is supposed to read the baud rate which the hardware is [rwb] ; programmed for and set the program variable to match. [rwb] ; Since the Sanyo hardware doesn't allow this, we simply [rwb] ; return. [rwb] ; GETBAUD PROC NEAR 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 bx ; save reg. [jrd] 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 pop bx ; [jrd] ; ; 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 push bx ; save reg. [jrd] 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 bx ; [jrd] 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 ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit ; else repeat cycle. Requires that the port be initialized before hand. ; Ihosts is used by the local send-file routine just after initializing ; the serial port. ; 22 March 1986 [jrd] IHOSTS PROC NEAR push ax ; save the registers push bx push cx push dx mov bx,portval ; port indicator mov ax,[bx].flowc ; put Go-ahead flow control char in ah call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop ihosts1:call clrbuf ; clear out interrupt buffer mov ax,1 ; sleep for 1 second call sleep ; procedure sleep is in msscom.asm call prtchr ; check for char at port jmp ihosts1 ; have a char in al, repeat wait/read cycle nop ; prtchr does skip return on empty buffer pop dx ; empty buffer. we are done here. pop cx pop bx pop ax ret IHOSTS ENDP ; IHOSTR - initialize the remote host for our reception of a file by ; sending the flow-on character (XON typically) to release any held ; data. Called by receive-file code just after initializing the serial ; port. 22 March 1986 [jrd] IHOSTR PROC NEAR push ax ; save regs push bx push cx mov bx,portval ; port indicator mov ax,[bx].flowc ; put Go-ahead flow control char in ah call outchr ; send it (release Host's output queue) nop ; outchr can do skip return nop nop pop cx pop bx pop ax ret IHOSTR ENDP DTRLOW PROC NEAR ; Global proc to Hangup the Phone by making ; DTR and RTS low. mov ah,cmtxt ; allow text to be able to display help mov bx,offset rdbuf ; dummy buffer mov dx,offset hnghlp ; help message call comnd ; get a confirm jmp r ; not yet imp. call serhng ; drop DTR and RTS mov ah,prstr ; give a nice message ; not yet imp. mov dx,offset hngmsg mov dx,offset noimp ; for now int dos jmp rskp DTRLOW ENDP ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low ; to terminate the connection. 29 March 1986 [jrd] ; Calling this twice without intervening calls to serini should be harmless. ; Returns normally. ; SERHNG is Not Yet Implemented. ; ; 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 push ax ; save regs. [jrd] push bx MOV AH,2 ; SET CODE TO POSITION CURSOR MOV BH,0 ; SET PAGE NUMBER INT VIDEO ; AND POSITION THE CURSOR pop bx ; [jrd] pop ax 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 VTSTAT PROC NEAR ; For Status display [jrd] ret ; no emulator status to display VTSTAT ENDP ; Save the screen to a buffer and then append buffer to a disk file. [jrd] ; Default filename is Kermit.scn; actual file can be a device too. Filename ; is determined by mssset and is passed as pointer dmpname. DUMPSCR PROC NEAR ; Dumps screen contents to a file. Just Beeps here call beep ; [jrd] ret DUMPSCR ENDP ; ; LCLINI - DO LOCAL INITIALIZATION ; flags.vtflg holds terminal emulation type (0 = none). [jrd] LCLINI: MOV FLAGS.VTFLG,0 ; DON'T KNOW EXACTLY WHAT THIS DOES ; ; set baud rate variable to indicate 300 baud [rwb] ; (port programmed elsewhere) [rwb] ; 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 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 R PROC NEAR ; [jrd] ret R ENDP CODE ENDS END