home *** CD-ROM | disk | FTP | other *** search
- ; Kermit system dependent module for IBM-PC
-
- public serini, serrst, clrbuf, outchr, coms, vts, dodel,
- public ctlu, cmblnk, locate, prtchr, dobaud, clearl,
- public dodisk, getbaud, beep,
- public count, xofsnt, puthlp, putmod, clrmod, poscur
- public sendbr, machnam, setktab, setkhlp, lclini, showkey
- include msdefs.h
-
- false equ 0
- true equ 1
- mntrgh equ bufsiz*3/4 ; High point = 3/4 of buffer full.
-
- ; constants used by serial port handler
-
- BRKBIT EQU 040H ; Send-break bit.
- TIMER EQU 40H ; Use to issue short beep.
- PORT_B EQU 61H ; Port B address.
- MCONF EQU 11H ; Machine configuration.
- KEYB EQU 16H
- BIOS EQU 10H
-
- MDMDAT1 EQU 03F8H ; Address of modem port (data). [19b]
- MDMSTS1 EQU 03FDH ; Address of modem port status. [19b]
- MDMCOM1 EQU 03FBH ; Address of modem port command. [19b]
- MDMDAT2 EQU 02F8H ; Port 2 address. [19b]
- MDMSTS2 EQU 02FDH ; Port 2 status. [19b]
- MDMCOM2 EQU 02FBH ; Port 2 command. [19b]
- MDMINP EQU 1 ; Input ready bit.
-
- MDMINTV EQU 0030H ; Address of modem port interrupt vector.
- MDINTV2 EQU 002CH ; Address for port 2. [19b]
- MDMINTO EQU 0EFH ; Mask to enable interrupt for modem port.
- MDINTO2 EQU 0F7H ; Enable interrupt level 3. [19b]
- MDMINTC EQU 010H ; Bit to set to disable interrupts for modem.
- MDINTC2 EQU 008H ; Disable IRQ3. [19b]
-
- INTCONT EQU 0021H ; Address of 8259 interrupt controller ICW2-3.
- INTCON1 EQU 0020H ; Address of 8259 ICW1.
- EOICOM EQU 0064H ; End of interrupt.
- EOICOM2 EQU 0063H ; End of interrupt for COM2. [19b]
-
- ; external variables used:
- ; drives - # of disk drives on system
- ; flags - global flags as per flginfo structure defined in pcdefs
- ; trans - global transmission parameters, trinfo struct defined in pcdefs
- ; portval - pointer to current portinfo structure (currently either port1
- ; or port2)
- ; port1, port2 - portinfo structures for the corresponding ports
-
- ; global variables defined in this module:
- ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
- ; setktab - keyword table for redefining keys (should contain a 0 if
- ; not implemented)
- ; setkhlp - help for setktab.
-
- datas segment public 'datas'
- extrn drives:byte,flags:byte, trans:byte
- extrn portval:word, port1:byte, port2:byte
-
- setktab db 12
- mkeyw 'BACKSPACE',0eh
- mkeyw 'F1',3bh
- mkeyw 'F2',3ch
- mkeyw 'F3',3dh
- mkeyw 'F4',3eh
- mkeyw 'F5',3fh
- mkeyw 'F6',40h
- mkeyw 'F7',41h
- mkeyw 'F8',42h
- mkeyw 'F9',43h
- mkeyw 'F10',44h
- mkeyw 'SCAN',-1
-
- setkhlp db cr,lf,'Keyname: backspace, f1, ... f10, or "SCAN" follwed by '
- db 'decimal scan code$'
- brkval db 0 ; What to send for a break.
- brkadr dw 0 ; Where to send it.
- modem mdminfo <MDMDAT1,MDMSTS1,MDMCOM1,MDMINTO,MDMINTC,EOICOM,MDMINTV>
- erms20 db cr,lf,'?Warning: System has no disk drives$' ; [21a]
- erms40 db cr,lf,'?Warning: Unrecognized baud rate$'
- badbd db cr,lf,'Unimplemented baud rate$'
- machnam db 'IBM-PC$'
- crlf db cr,lf,'$'
- delstr db BS,' ',BS,'$' ; Delete string. [21d]
- clrlin db cr,'$' ; Clear line (just the cr part).
- savsci dw ? ; Save for serial port interrupt vector. [14]
- savscs dw ? ; Ditto. [14]
- savbr1 dw ? ; "Break" interrupt vector. [25]
- savbr2 dw ? ; Ditto. [25]
- portin db 0 ; Has comm port been initialized. [21c]
- xofsnt db 0 ; Say if we sent an XOFF.
- xofrcv db 0 ; Say if we received an XOFF.
- tmp db ?,'$'
- temp dw 0
- temp1 dw ? ; Temporary storage.
- temp2 dw ? ; Temporary storage.
-
- ontab db 02H ; Two entries.
- db 03H,'OFF$' ; Should be alphabetized. [19a]
- dw 00H
- db 02H,'ON$'
- dw 01H
-
- comptab db 04H
- db 01H,'1$'
- dw 01H
- db 01H,'2$'
- dw 00H
- db 04H,'COM1$'
- dw 01H
- db 04H,'COM2$'
- dw 00H
-
- ; this table is indexed by the baud rate definitions given in
- ; pcdefs. Unsupported baud rates should contain FF.
- bddat label word
- dw 0FFH ; 45.5 baud -- Not supported.
- dw 900H ; 50 baud
- dw 600H ; 75 baud
- dw 417H ; 110 baud
- dw 359H ; 134.5 baud
- dw 300H ; 150 baud
- dw 180H ; 300 baud
- dw 0C0H ; 600 baud
- dw 60H ; 1200 baud
- dw 40H ; 1800 baud
- dw 3AH ; 2000 baud
- dw 30H ; 2400 baud
- dw 18H ; 4800 baud
- dw 0CH ; 9600 baud
- dw 0FFH ; 19200 baud -- Not supported.
- dw 0FFH ; 38400 baud -- Not supported.
-
- ; variables for serial interrupt handler
-
- source db bufsiz DUP(?) ; Buffer for data from port.
- srcpnt dw 0 ; Pointer in buffer (DI).
- count dw 0 ; Number of chars in int buffer.
- savesi dw 0 ; Save SI register here.
- telflg db 0 ; Are we acting as a terminal.
- mst dw 0 ; Modem status address.
- mdat dw 0 ; Modem data address.
- mdeoi db 0 ; End-of-Interrupt value.
-
- rbtrn db 7fH ; rubout
-
- shkbuf db 300 dup (?) ; room for definition
- shkmsg db ' Scan code: '
- shkmln equ $-shkmsg
- shkms1 db cr,lf,' Definition: '
- shkm1ln equ $-shkms1
- datas ends
-
- code segment public
- extrn comnd:near, dopar:near, defkey:near, gss:near
- assume cs:code,ds:datas
-
- ; local initialization
-
- lclini proc near
- mov ax,0eH ; scan code for arrow key
- mov si,offset rbtrn ; translate to rubout
- mov cx,1 ; one char translation
- call defkey
- mov brkval,BRKBIT ; What to send for a break.
- mov ax,modem.mdcom ; Where to send it.
- mov brkadr,ax
- ret
- lclini endp
-
- ; this is called by Kermit initialization. It checks the
- ; number of disks on the system, sets the drives variable
- ; appropriately. Returns normally.
-
- DODISK PROC NEAR
- int mconf ; Get equipment configuration.
- mov ah,al ; Store AL value for a bit.
- and al,01H ; First, look at bit 0.
- jz dodsk0 ; No disk drives -- forget it.
- mov al,ah ; Get back original value.
- mov cl,6 ; Shift over bits 6 and 7.
- shr al,cl ; To positions 0 and 1.
- inc al ; Want 1 thru 4 (not 0 thru 3).
- mov drives,al ; Remember how many.
- ret
- dodsk0: mov ah,prstr ; Print a warning message.
- mov dx,offset erms20 ; I'm not sure if things will
- int dos ; work with only a cassette.
- mov drives,0 ; Say there aren't any drives.
- ret
- DODISK ENDP
-
- ; show the definition of a key. The terminal argument block (which contains
- ; the address and length of the definition tables) is passed in ax.
- ; Returns a string to print in AX, length of same in CX.
- ; Returns normally.
- showkey proc near
- push es
- push ax ; save the ptr
- mov bx,ds
- mov es,bx ; address data segment
- cld
- showk1: xor ah,ah
- int keyb ; read a char
- push ax ; save the character
- call gss ; get shift state
- pop bx
- mov ah,al ; shift state to ah
- mov al,bh ; scan code to al
- push ax ; remember scan code
- mov di,offset shkbuf
- mov si,offset shkmsg
- mov cx,shkmln
- rep movsb ; copy in initial message
- call nout ; write out scan code
- mov si,offset shkms1
- mov cx,shkm1ln ; second message
- rep movsb
- pop ax ; get scan code back
- pop bx ; and terminal arg block
- mov cx,[bx].klen ; and length
- jcxz showk2 ; no table, not defined
- push di ; remember output ptr
- mov di,[bx].ktab ; get key table
- repne scasw ; search for a definition for this
- mov si,di ; remember result ptr
- pop di ; get output ptr back
- jne showk2 ; not defined, forget it
- sub si,[bx].ktab ; compute offset from beginning
- sub si,2 ; minus 2 for pre-increment
- add si,[bx].krpl ; get index into replacement table
- mov si,[si] ; pick up replacement
- mov cl,[si] ; get length
- mov ch,0
- inc si
- rep movsb ; copy into buffer
- showk2: mov ax,offset shkbuf ; this is buffer
- mov cx,di
- sub cx,ax ; length
- pop es
- ret ; and return
- showkey endp
-
- ; Clear the input buffer. This throws away all the characters in the
- ; serial interrupt buffer. This is particularly important when
- ; talking to servers, since NAKs can accumulate in the buffer.
- ; Returns normally.
-
- CLRBUF PROC NEAR
- cli
- mov ax,offset source
- mov srcpnt,ax
- mov savesi,ax
- mov count,0
- sti
- ret
- CLRBUF ENDP
-
- ; Clear to the end of the current line. Returns normally.
-
- CLEARL PROC NEAR
- mov ah,3 ; Clear to end of line.
- mov bh,0
- int bios ; Get current cursor position
- mov cx,dx
- mov dl,79
- mov ah,7
- mov al,0
- mov bh,7
- int bios
- ret
- CLEARL ENDP
-
- ; Put the char in AH to the serial port. This assumes the
- ; port has been initialized. Should honor xon/xoff. Skip returns on
- ; success, returns normally if the character cannot be written.
-
- outchr: mov bp,portval
- cmp ds:[bp].floflg,0 ; Are we doing flow control.
- je outch2 ; No, just continue.
- xor cx,cx ; clear counter
- outch1: cmp xofrcv,true ; Are we being held?
- jne outch2 ; No - it's OK to go on.
- loop outch1 ; held, try for a while
- mov xofrcv,false ; timed out, force it off and fall thru.
- outch2: push dx ; Save register.
- sub cx,cx
- mov al,ah ; Parity routine works on AL.
- call dopar ; Set parity appropriately.
- mov ah,al ; Don't overwrite character with status.
- mov dx,modem.mdstat ; Get port status.
- outch3: in al,dx
- test al,20H ; Transmitter ready?
- jnz outch4 ; Yes
- loop outch3
- jmp outch5 ; Timeout
- outch4: mov al,ah ; Now send it out
- mov dx,modem.mddat
- out dx,al
- pop dx
- jmp rskp
- outch5: pop dx
- ret
-
- ; This routine blanks the screen. Returns normally.
-
- CMBLNK PROC NEAR ; This is stolen from the IBM example.
- mov cx,0
- mov dx,184FH
- mov bh,7
- mov ax,600H
- int bios
- ret
- CMBLNK ENDP
-
- ; Locate: homes the cursor. Returns normally.
-
- LOCATE PROC NEAR
- mov dx,0 ; Go to top left corner of screen.
- jmp poscur
- LOCATE ENDP
-
- ; write a line in inverse video at the bottom of the screen...
- ; the line is passed in dx, terminated by a $. Returns normally.
- putmod proc near
- push dx ; preserve message
- mov cx,1800h
- mov dx,184fh
- mov ax,600h ; scroll to clear the line
- mov bh,70h ; inverse video
- int bios
- mov dx,1800h ; now address line 24
- call poscur
- pop dx ; get message back
- mov ah,prstr
- int dos ; write it out
- ret ; and return
- putmod endp
-
- ; clear the mode line written by putmod. Returns normally.
- clrmod proc near
- mov cx,1800h
- mov dx,184fh
- mov ax,600h
- mov bh,7h
- int bios
- ret
- clrmod endp
-
- ; put a help message on the screen. This one uses reverse video...
- ; pass the message in ax, terminated by a null. Returns normally.
- puthlp proc near
- push ax ; preserve this
- mov si,ax ; point to it
- mov dh,1 ; init counter
- puthl1: lodsb ; get a byte
- cmp al,lf ; linefeed?
- jne puthl2 ; no, keep going
- inc dh ; count it
- jmp puthl1 ; and keep looping
- puthl2: cmp al,0 ; end of string?
- jne puthl1 ; no, keep going
- mov ax,600h ; scroll to clear window
- xor cx,cx ; from top left
- mov dl,4fh ; to bottom right of needed piece
- mov bh,70h ; inverse video
- int bios
- call locate ; home cursor
- pop si ; point to string again
- puthl3: lodsb ; get a byte
- cmp al,0 ; end of string?
- je puthl4 ; yes, stop
- mov ah,14
- int bios ; else write to screen
- jmp puthl3 ; and keep going
- puthl4: mov dx,24 * 100H ; go to last line
- jmp poscur ; position and return
- puthlp endp
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns normally.
-
- DOBAUD PROC NEAR
- mov bp,portval
- mov temp1,ax ; Don't overwrite previous rate. [25]
- mov ax,ds:[bp].baud ; Check if new rate is valid. [25]
- mov tmp,2
- mul tmp ; Get index into baud table.
- mov bx,offset bddat ; Start of table.
- add bx,ax
- mov ax,[bx] ; The data to output to port.
- cmp ax,0FFH ; Unimplemented baud rate.
- jne dobd0
- mov ax,temp1 ; Get back orginal value.
- mov ds:[bp].baud,ax ; Leave baud rate as is.
- mov ah,prstr
- mov dx,offset badbd ; Give an error message.
- int dos
- ret
- dobd0: mov temp1,ax ; Remember value to output. [25]
- mov dx,modem.mdcom ; LCR -- Initialize baud rate. [19b]
- in al,dx
- mov bl,al
- or ax,80H
- out dx,al
- mov dx,modem.mddat ; [19b]
- mov ax,temp1
- out dx,al
- inc dx
- mov al,ah
- out dx,al
- mov dx,modem.mdcom ; [19b]
- mov al,bl
- out dx,al
- ret
- DOBAUD ENDP
-
- ; Get the current baud rate from the serial card and set it
- ; in the portinfo structure for the current port. Returns normally.
- ; This is used during initialization.
-
- GETBAUD PROC NEAR
- mov dx,modem.mdcom ; Get current Line Control Register value.
- in al,dx
- mov bl,al ; Save it.
- or ax,80H ; Turn on to access baud rate generator.
- out dx,al
- mov dx,modem.mddat ; Divisor latch.
- inc dx
- in al,dx ; Get hi order byte.
- mov ah,al ; Save here.
- dec dx
- in al,dx ; Get lo order byte.
- push ax
- mov dx,modem.mdcom
- mov al,bl ; Restore old value.
- out dx,al
- pop ax
- cmp ax,0FFFFH ; Who knows what this is.
- je getb2
- mov bx,offset bddat ; Find rate's offset into table.
- mov cl,0 ; Keep track of index.
- getb0: cmp ax,[bx]
- je getb1
- inc cl
- cmp cl,baudsiz ; At the end of the list.
- jge getb2
- add bx,2
- jmp getb0
- getb1: mov ch,0
- mov bp,portval
- mov ds:[bp].baud,cx ; Set baud rate.
- ret
- getb2: mov ah,prstr
- mov dx,offset erms40
- int dos
- ret
- GETBAUD ENDP
-
- ; skip returns if no character available at port,
- ; otherwise returns with char in al, # of chars in buffer in dx.
- PRTCHR PROC NEAR
- call chkxon ; see if we need to xon
- cmp count,0
- jnz prtch2
- jmp rskp ; No data - check console.
- prtch2: mov si,savesi
- lodsb ; get a byte
- cmp si,offset source + bufsiz ; bigger than buffer?
- jb prtch1 ; no, keep going
- mov si,offset source ; yes, wrap around
- prtch1: dec count
- mov savesi,si
- mov dx,count ; return # of chars in buffer
- ret
- PRTCHR ENDP
-
- ; local routine to see if we have to transmit an xon
- chkxon proc near
- push bx
- mov bx,portval
- cmp [bx].floflg,0 ; doing flow control?
- je chkxo1 ; no, skip all this
- cmp xofsnt,false ; have we sent an xoff?
- je chkxo1 ; no, forget it
- cmp count,mntrgh ; below trigger?
- jae chkxo1 ; no, forget it
- mov ax,[bx].flowc ; ah gets xon
- call outchr ; send it
- nop
- nop
- nop ; in case it skips
- mov xofsnt,false ; remember we've sent the xon.
- chkxo1: pop bx ; restore register
- ret ; and return
- chkxon endp
-
- ; Send a break out the current serial port. Returns normally.
- SENDBR PROC NEAR
- push cx
- push dx
- push ax
- xor cx,cx ; Clear loop counter.
- mov dx,brkadr ; Port address. [19b]
- in al,dx ; Get current setting.
- or al,brkval ; Set send-break bit(s).
- out dx,al ; Start the break.
- pause: loop pause ; Wait a while.
- xor al,brkval ; Clear send-break bit(s).
- out dx,al ; Stop the break.
- pop ax
- pop dx
- pop cx
- ret ; And return.
- SENDBR ENDP
-
- ; Position the cursor according to contents of DX:
- ; DH contains row, DL contains column. Returns normally.
-
- POSCUR PROC NEAR
- mov ah,2 ; Position cursor.
- mov bh,0
- int bios
- ret
- POSCUR ENDP
-
- ; Delete a character from the terminal. This works by printing
- ; backspaces and spaces. Returns normally.
-
- DODEL PROC NEAR
- mov ah,prstr
- mov dx,offset delstr ; Erase weird character.
- int dos
- ret
- DODEL ENDP
-
- ; Move the cursor to the left margin, then clear to end of line.
- ; Returns normally.
-
- CTLU PROC NEAR
- mov ah,prstr
- mov dx,offset clrlin
- int dos
- call clearl
- ret
- CTLU ENDP
-
- ; set the current port.
-
- COMS PROC NEAR
- mov dx,offset comptab
- mov bx,0
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp comx ; Didn't get a confirm.
- nop
- pop bx
- mov flags.comflg,bl ; Set the comm port flag.
- cmp flags.comflg,1 ; Using Com 1?
- jne coms0 ; Nope.
- mov ax,offset port1
- mov portval,ax
- mov modem.mddat,MDMDAT1 ; Set COM1 defaults.
- mov modem.mdstat,MDMSTS1
- mov modem.mdcom,MDMCOM1
- mov modem.mddis,MDMINTC
- mov modem.mden,MDMINTO
- mov modem.mdmeoi,EOICOM
- mov modem.mdintv,MDMINTV
- mov brkadr,MDMCOM1
- ret
- coms0: mov ax,offset port2
- mov portval,ax
- mov modem.mddat,MDMDAT2 ; Set COM2 defaults.
- mov modem.mdstat,MDMSTS2
- mov modem.mdcom,MDMCOM2
- mov modem.mddis,MDINTC2
- mov modem.mden,MDINTO2
- mov modem.mdmeoi,EOICOM2
- mov modem.mdintv,MDINTV2
- mov brkadr,MDMCOM2
- ret
- comx: pop bx
- ret
- COMS ENDP
-
- ; Set heath emulation on/off.
-
- VTS PROC NEAR
- mov dx,offset ontab
- mov bx,0
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp vt0 ; Didn't get a confirm.
- nop
- pop bx
- mov flags.vtflg,bl ; Set the VT52 emulation flag.
- ret
- vt0: pop bx
- ret
- VTS ENDP
-
- ; initialization for using serial port. This routine performs
- ; any initialization necessary for using the serial port, including
- ; setting up interrupt routines, setting buffer pointers, etc.
- ; Doing this twice in a row should be harmless (this version checks
- ; a flag and returns if initialization has already been done).
- ; SERRST below should restore any interrupt vectors that this changes.
- ; Returns normally.
-
- SERINI PROC NEAR
- push es
- cmp portin,0 ; Did we initialize port already? [21c]
- jne serin0 ; Yes, so just leave. [21c]
- cli ; Disable interrupts
- cld ; Do increments in string operations
- xor ax,ax ; Address low memory
- mov es,ax
- mov bx,modem.mdintv ; Save serial card interrupt vector. [19b]
- mov ax,es:[bx]
- mov savsci,ax
- mov ax,offset serint ; And point it to my routine
- mov es:[bx],ax
- add bx,2 ; Save CS register too. [19b]
- mov ax,es:[bx]
- mov savscs,ax
- mov es:[bx],cs
- mov portin,1 ; Remember port has been initialize.
- call clrbuf ; Clear input buffer.
- mov ax,modem.mdstat
- mov mst,ax ; Use this address for status.
- mov ax,modem.mddat
- mov mdat,ax ; Use this address for data.
- mov al,modem.mdmeoi
- mov mdeoi,al ; Use to signify end-of-interrupt.
- in al,21H ; Set up 8259 interrupt controller
- and al,modem.mden ; Enable INT3 or INT4.
- out 21H,al
- mov dx,modem.mdcom ; Set up the serial card.
- mov al,3
- out dx,al
- mov dl,0F9H
- mov al,1 ; Set up interrupt enable register
- out dx,al
- mov dl,0FCH ; Enable interrupts from serial card
- mov al,0BH
- out dx,al
- sti ; Allow interrupts
- mov dl,0F8H
- in al,dx
- serin0: pop es
- ret ; We're done.
- SERINI ENDP
-
- ; Reset the serial port. This is the opposite of serini. Calling
- ; this twice without intervening calls to serini should be harmless.
- ; Returns normally.
-
- SERRST PROC NEAR
- push es ; preserve this
- cmp portin,0 ; Reset already?
- je srst1 ; Yes, just leave.
- cli ; Disable interrupts
- mov dx,03FCH ; Disable modem interrupts
- cmp flags.comflg,1 ; Using port 1 ?
- je srst0 ; Yes - continue.
- mov dh,02 ; Set for port 2.
- srst0: mov al,3
- out dx,al
- in al,21H ; Interrupt controller
- or al,modem.mddis ; Inhibit IRQ3 or IRQ4.
- out 21H,al
- xor bx,bx ; Address low memory
- mov es,bx
- mov bx,modem.mdintv ; Restore the serial card int vector
- mov ax,savsci
- mov es:[bx],ax
- add bx,2 ; Restore CS too.
- mov ax,savscs
- mov es:[bx],ax
- mov portin,0 ; Reset flag.
- sti
- srst1: pop es
- ret ; All done.
- SERRST ENDP
-
- ; serial port interrupt routine. This is not accessible outside this
- ; module, handles serial port receiver interrupts.
-
- SERINT PROC NEAR
- push bx
- push dx
- push ax
- push es
- push di
- push ds
- push bp
- push cx
- cld
- mov ax,seg datas
- mov ds,ax ; address data segment
- mov es,ax
- mov di,srcpnt ; Registers for storing data.
- mov dx,mst ; Asynch status port. [19b]
- in al,dx
- test al,mdminp ; Data available?
- jz retint ; Nope.
- mov dx,mdat ; [19b]
- in al,dx
- cmp telflg,0 ; File transfer or terminal mode? [17c]
- jz srint0
- and al,7FH ; Terminal mode (7 bits only).
- srint0: or al,al
- jz retint ; Ignore nulls.
- mov ah,al
- and ah,7fH ; strip parity temporarily
- cmp ah,7FH ; Ignore rubouts, too.
- jz retint
- mov bp,portval
- cmp ds:[bp].floflg,0 ; Doing flow control?
- je srint2 ; Nope.
- mov bx,ds:[bp].flowc ; Flow control char (BH = XON, BL = XOFF).
- cmp al,bl ; Is it an XOFF?
- jne srint1 ; Nope, go on.
- mov xofrcv,true ; Set the flag.
- jmp retint
- srint1: cmp al,bh ; Get an XON?
- jne srint2 ; No, go on.
- mov xofrcv,false ; Clear our flag.
- jmp retint
- srint2: stosb
- cmp di,offset source + bufsiz
- jb srint3 ; not past end...
- mov di,offset source ; wrap buffer around
- srint3: inc count
- cmp ds:[bp].floflg,0 ; Doing flow control?
- je retint ; No, just leave.
- cmp xofsnt,true ; Have we sent an XOFF?
- je retint ; Yes.
- cmp count,mntrgh ; Past the high trigger point?
- jbe retint ; No, we're within our limit.
- mov ah,bl ; Get the XOFF.
- call outchr ; Send it.
- nop
- nop
- nop ; ignore failure.
- mov xofsnt,true ; Remember we sent it.
- retint: mov srcpnt,di
- sti
- mov al,mdeoi ; [19b]
- out intcon1,al ; Send End-of-Interrupt to 8259.
- pop cx
- pop bp
- pop ds
- pop di
- pop es
- pop ax
- pop dx
- pop bx
- intret: iret
- SERINT ENDP
-
- ; Produce a short beep. The PC DOS bell is long enough to cause a loss
- ; of data at the port. Returns normally.
-
- BEEP PROC NEAR
- mov al,10110110B ; Gen a short beep (long one losses data.)
- out timer+3,al ; Code snarfed from Technical Reference.
- mov ax,533H
- out timer+2,al
- mov al,ah
- out timer+2,al
- in al,port_b
- mov ah,al
- or al,03
- out port_b,al
- sub cx,cx
- mov bl,1
- beep0: loop beep0
- dec bl
- jnz beep0
- mov al,ah
- out port_b,al
- ret
- BEEP ENDP
-
- ; put the number in ax into the buffer pointed to by di. Di is updated
- nout proc near
- mov dx,0 ; high order is always 0.
- mov bx,10
- div bx ; divide to get digit
- push dx ; save remainder digit
- or ax,ax ; test quotient
- jz nout1 ; zero, no more of number
- call nout ; else call for rest of number
- nout1: pop ax ; get digit back
- add al,'0' ; make printable
- stosb ; drop it off
- ret ; and return
- nout endp
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr.
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret.
-
- R PROC NEAR
- ret
- R ENDP
-
- code ends
- end