|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 34897 (0x8851) Types: TextFile Names: »msxz10.asm«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z« └─⟦31f2d420d⟧ └─⟦this⟧ »msxz10.asm«
name msxz10 ; File MSXZ10.ASM ; Last modification: 27 April 1986 ; Kermit system dependent module for Heath/Zenith Z100 ; major revision of port i/o routines - now directly uses serial ; port interrupt (supports 9600 bps without error) ; implements selection of J1/J2 port ; from Joseph E. Rock, Jr - USAF Academy - 18 April 1986 ; includes fix to SETBAUD from August Treubig of Middle South Services ; via John Voigt, Tulane Univ. Systems Group <SYSBJAV@TCSVM.BITNET> ; 21 April 1986 Geoff Mulligan, USAFA. ; ; Add global entry point vtstat for use by Status in mssset. ; Add a few register saves & restores. ; Also trimmed off trailing commas from publics. 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] ; Correct error in pushing registers in POSCUR. From Greg Elder. 17 April 86 ; 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 bad data structure in comptab; use mkeyw macro. [jrd] ; Replace emulator ontab with termtb for Set Term Heath-19 | none. [jrd] ; Merge these changes with the rewritten code of Geoff Mulligan 27 April 86 public serini, serrst, clrbuf, outchr, coms, vts, vtstat, 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 public ihosts, ihostr, dtrlow, dumpscr ; [jrd] include mssdef.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 048H ; Send-break bit. ; 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 ; monmode - color/monochrome mode of monitor ; 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. BIOS_SEG SEGMENT AT 40H ; Define segment where BIOS really is ORG 4*3 BIOS_PRINT LABEL FAR ORG 6*3 BIOS_CONFUNC LABEL FAR ; CON: function BIOS_SEG ENDS ; Function codes for BIOS_xxxFUNC CHR_WRITE EQU 0 ; Write character CHR_READ EQU 1 ; Read character CHR_STATUS EQU 2 ; Get status CHR_SFGS EQU 0 ; Get status subfunction CHR_SFGC EQU 1 ; Get config subfunction CHR_CONTROL EQU 3 ; Control function CHR_CFSU EQU 0 ; Set new configuration parameters CHR_CFCI EQU 1 ; Clear input buffer ; serial port information TSRE EQU 004H THBE EQU 001H DTR EQU 002H DTROFF EQU 0fdH DCD EQU 040H RDA EQU 002H J1_ADDR EQU 0e8H J2_ADDR EQU 0ecH PDATA EQU 0 PSTATUS EQU 1 PMODE EQU 2 PCOMM EQU 3 TXON EQU 001H TXOFF EQU 0feH RXON EQU 004H RXOFF EQU 0fbH MODE1 EQU 04dH MODE2 EQU 030H ; must be ORed with appropriate baud rate Z8259 EQU 0f2H EOI EQU 020H J1INT EQU 68 J2INT EQU 69 BUFILEN EQU 1200 BUFOLEN EQU 500 datas segment public 'datas' extrn drives:byte, flags:byte, trans:byte extrn portval:word, port1:byte, port2:byte ;[jrd] extrn monmode:byte setktab db 13 mkeyw 'F0',96h mkeyw 'F1',97h mkeyw 'F2',98h mkeyw 'F3',99h mkeyw 'F4',9ah mkeyw 'F5',9bh mkeyw 'F6',9ch mkeyw 'F7',9dh mkeyw 'F8',9eh mkeyw 'F9',9fh mkeyw 'F10',0a0h mkeyw 'F11',0a1h mkeyw 'SCAN',-1 setkhlp db cr,lf,'Keyname: f0, ... f11, "HELP" or "SCAN" follwed by ' db 'decimal scan code$' brkval db 0 ; What to send for a break. brkadr dw 0 ; Where to send it. badbd db cr,lf,'Unimplemented baud rate$' noimp db cr,lf,'Not implemented$' machnam db 'Heath-Zenith Z-100$' 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] crlf db cr,lf,'$' delstr db BS,BS,' ',BS,'$' ; Delete string. [21d] home db ESC,'H$' eeolstr db ESC,'K$' ; Erase to end of line clrstr db ESC,'E$' ; Erase entire display enamod db ESC,'x1$' ; Enable 25th line dismod db ESC,'y1$' ; Disable 25th line enascan db ESC,'y?$' ; Enable scan codes disscan db ESC,'x?$' ; Disable scan codes begrev db ESC,'p$' ; Enter reverse video endrev db ESC,'q$' ; Exit reverse video lin25 db ESC,'Y8 $' ; Column 1 row 25 savcur db ESC,'j$' ; Save current cursor position precur db ESC,'k$' ; Restore cursor to previous position clrlin db cr,'$' ; Clear line (just the cr part). monstr db ESC,'i0$' ; Return montior information xofsnt db 0 ; Say if we sent an XOFF. xofrcv db 0 ; Say if we received an XOFF. tmp db ?,'$' temp1 dw ? ; Temporary storage. termtb db 2 ; two entries. Set Term Heath-19 | none [jrd] mkeyw 'Heath-19',1 ; [jrd] mkeyw 'none',0 ; [jrd] comptab db 04H mkeyw '1',1 ; [jrd] mkeyw '2',0 ; [jrd] mkeyw 'J1',1 ; [jrd] mkeyw 'J2',0 ; [jrd] ; this table is indexed by the baud rate definitions given in ; pcdefs. Unsupported baud rates should contain FF. bddat label word dw 0 ; 45.5 baud dw 1 ; 50 baud dw 2 ; 75 baud dw 3 ; 110 baud dw 4 ; 134.5 baud dw 5 ; 150 baud dw 6 ; 300 baud dw 7 ; 600 baud dw 8 ; 1200 baud dw 9 ; 1800 baud dw 10 ; 2000 baud dw 11 ; 2400 baud dw 12 ; 4800 baud dw 13 ; 9600 baud dw 14 ; 19200 baud dw 15 ; 38400 baud ; variables for serial interrupt handler count dw 0 ; Number of chars in int buffer. buffin db BUFILEN dup(?) ; input buffer bufibeg dw 0 bufiend dw 0 buffout db BUFOLEN dup(?) ; output buffer bufobeg dw 0 bufoend dw 0 portadr dw 0 intin db 0 ; port int installed flag oldseg dw 0 oldoff dw 0 ourarg termarg <> 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 extrn sleep:near ; [jrd] assume cs:code,ds:datas ; local initialization lclini proc near mov brkval,BRKBIT ; What to send for a break. push ax mov ax,offset port2 mov portval,ax call serini mov ax,portadr add ax,PCOMM mov brkadr,ax pop ax mov flags.vtflg,0 ; Turn off true Heath mode (allows key macros) 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 mov ah,gcurdsk ; Current disk value to AL. int dos mov dl,al ; Put current disk in DL. mov ah,seldsk ; Select current disk. int dos mov drives,al ret DODISK ENDP ; retrieve the mode of the monitor (color/monochrome) ; sets "monmode" to 7 for monochrome and 3 for color ;GETMMODE proc near ; push ax ; push dx ; mov ah,prstr ; do it by sending 'ESC i 0' [jer] ; mov dx,offset monstr ; note that this is z-100 specific ; int dos ; mov ah,CONINQ ; z100 responds with ;gm1: int dos ; 'ESC i E Nn where ; cmp al,ESC ; n is 32/64 K VRAM ; je gm1 ; and N is ; int dos ; 1 = monochrome ; mov monmode,7 ; 3 = color ; int dos ; cmp al,'1' ; je gm2 ; mov monmode,3 ;gm2: int dos ; pop dx ; pop ax ; ret ;getmmode 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 bx ; save regs. [jrd] push di push si push es push ax ; save the ptr mov bx,ds mov es,bx ; address data segment cld showk1: mov ah,prstr mov dx,offset enascan ; enable scan codes int dos mov ah,0ch ; char input with buffer flush mov al,7 int dos push ax mov ah,prstr mov dx,offset disscan ; disable scan codes int dos pop ax ; push ax ; save the character ; call gss ; get shift state ; pop bx mov ah,0 ; 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 pop si ; [jrd] pop di pop bx 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 push bx xor bx,bx mov bufoend,bx mov bufobeg,bx mov bufiend,bx mov bufibeg,bx pop bx mov count,0 sti ret CLRBUF ENDP ; Clear to the end of the current line. Returns normally. CLEARL PROC NEAR push ax ; save regs. [jrd] push dx mov ah,prstr mov dx,offset eeolstr ; Erase to end of line int dos pop dx ; [jrd] pop ax 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 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 ; 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 bx ; Save register. mov al,ah ; Parity routine works on AL. call dopar ; Set parity appropriately. mov bx,bufoend ; get pointer to end of que mov byte ptr buffout[bx],al ; put char in it inc bx ; point to next spot in que cmp bx,BUFOLEN ; looking at end of que ? jne outch3 ; no, OK xor bx,bx ; yes, reset pointer outch3: cli mov bufoend,bx ; store new value mov bx,dx mov dx,portadr add dx,PCOMM in al,dx test al,TXON ; TX already on ? jnz outch4 ; yes, OK or al,TXON ; no, turn it on out dx,al ; it's on outch4: mov dx,bx sti ; done with 2661 pop bx jmp rskp ; This routine blanks the screen. Returns normally. CMBLNK PROC NEAR mov ah,prstr mov dx,offset clrstr int dos ret CMBLNK ENDP ; Locate: homes the cursor. Returns normally. LOCATE PROC NEAR mov ah,prstr mov dx,offset home ; Go to top left corner of screen. int dos 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 ah,prstr mov dx,offset savcur int dos mov dx,offset enamod int dos mov dx,offset lin25 int dos mov dx,offset begrev int dos pop dx ; get message back int dos ; write it out mov dx,offset endrev int dos mov dx,offset precur int dos ret ; and return putmod endp ; clear the mode line written by putmod. Returns normally. clrmod proc near mov ah,prstr mov dx,offset dismod int dos ret clrmod endp BEEP PROC NEAR mov dl,BELL ; ASCII BEL mov ah,dconio int dos ; Ring it ret BEEP 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 ah,prstr mov dx,offset crlf int dos pop si ; point to string again puthl3: lodsb ; get a byte cmp al,0 ; end of string? je puthl4 ; yes, stop mov dl,al mov ah,dconio int dos jmp puthl3 ; and keep going puthl4: mov ah,prstr mov dx,offset crlf int dos ret puthlp endp ; Set the baud rate for the current port, based on the value ; in the portinfo structure. Returns normally. DOBAUD PROC NEAR push bx ; save regs. [jrd] push es mov bp,portval mov temp1,ax ; Don't overwrite previous rate. [25] mov ax,ds:[bp].baud ; Check if new rate is valid. [25] shl ax,1 ; Get index into baud table. (times 2) 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 pop es ; [jrd] pop bx ret dobd0: push dx ; need to use it push ax ; save baud rate mov dx,portadr ; get addr to send it add dx,PMODE mov al,MODE1 cli ; none while setting 2661 out dx,al ; mode reg 1/2 pop ax ; get baud back and al,0fH ; make sure it's clean or al,MODE2 ; make complete mode 2/2 command out dx,al ; set mode reg 2/2 sti ; done with 2661 pop dx ; restore it pop es ; [jrd] pop bx 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 push ax push dx mov dx,portadr ; get addr to retrieve mode from add dx,PMODE in al,dx ; read and discard mode 1/2 in al,dx ; mode 2/2 has baud rate and ax,000fH ; clean it up mov bp,portval mov ds:[bp].baud,ax ; put it in portinfo struct pop dx pop ax 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 mov dx,bufiend ; compute number of chars in sub dx,bufibeg ; input que jge prtch1 ; is it wrapped around add dx,BUFILEN ; yes, make it + prtch1: cmp dx,0 ; anything in there ? jne prtch3 ; ne = yes. [jrd] jmp rskp ; no, return skip [jrd] prtch3: push bx ; yes, get the char mov bx,bufibeg ; get the position mov al,byte ptr buffin[bx] ; get the char inc bx ; bump the position ptr cmp bx,BUFILEN ; wrap it ? jne prtch2 xor bx,bx ; yes, reset pointer prtch2: mov bufibeg,bx ; store new value dec dx ; we took one char out mov count,dx ; save (does anyone use this??) pop bx 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 ; 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. ; 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 push ax ; [jrd] push dx mov ah,CONOUT mov dl,ESC int dos mov dl,'Y' int dos pop dx push dx mov dl,dh add dl,' ' int dos pop dx add dl,' ' int dos pop ax ; [jrd] 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 ; jmp notimp mov dx,offset comptab mov bx,0 mov ah,cmkey call comnd jmp r nop 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 J1? jne coms0 ; Nope. mov ax,offset port1 mov portval,ax jmp coms1 coms0: mov ax,offset port2 mov portval,ax coms1: call serini ret comx: pop bx ret COMS ENDP ; Set heath emulation on/off. VTS PROC NEAR mov dx,offset termtb ; [jrd] 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 Heath emulation flag ret vt0: pop bx ret VTS ENDP notimp: mov ah,prstr mov dx,offset noimp int dos jmp rskp 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 ; simple routine to insure that the port has RXON and DTR high ; assumes int are off porton proc near push dx push ax mov dx,portadr add dx,PCOMM in al,dx or al,RXON+DTR out dx,al pop ax pop dx ret porton endp ; routine to retrieve current int vector ; inputs: al = int number ; outputs: cx = seg for current isr ; dx = offset for current isr getivec proc near push es ; save registers push bx mov ah,35H ; Int 21H, function 35H = Get Vector. int dos ; get vector in es:bx mov cx,es ; addr of org vector (seg) mov dx,bx ; and offset pop bx pop es ret getivec endp ; routine to set int vector ; inputs: ah = int number ; cx = seg for isr ; dx = offset for isr setivec proc near push ds ; save ds around next DOS call. mov ds,cx mov ah,25H ; set interrupt address from ds:dx int dos pop ds ret setivec 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 mov ax,portval cmp ax,offset port1 je seri2 ; setup for J1 cmp intin,2 jne seri0 ret ; J2 already set up seri0: cmp intin,1 jne seri1 ; J1 currently installed call serrst ; de-install current int seri1: mov al,J2INT call getivec mov oldseg,cx mov oldoff,dx mov cx,cs mov dx,offset serisr mov al,J2INT call setivec mov portadr,J2_ADDR mov brkadr,J2_ADDR+PCOMM call clrbuf call porton mov intin,2 ; show J2 installed ret seri2: cmp intin,1 jne seri3 ret ; J1 already set up seri3: cmp intin,2 jne seri4 ; J2 currently installed call serrst ; de-install current int seri4: mov al,J1INT call getivec mov oldseg,cx mov oldoff,dx mov cx,cs mov dx,offset serisr mov al,J1INT call setivec mov portadr,J1_ADDR call clrbuf call porton mov intin,1 ; show J1 installed ret 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 dx cmp intin,0 ; is any isr installed je serr2 ; no, all done push ax push cx mov ax,J2INT ; guess it's J2 cmp intin,2 ; yes, je serr1 ; reset it mov ax,J1INT ; no, must be J1 serr1: mov cx,oldseg ; original isr mov dx,oldoff ; address call setivec ; do it mov intin,0 ; show nothing installed pop cx pop ax serr2: pop dx ret ; All done. SERRST 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 ; the serial port interrupt service routine ; this routine does int driven input and output ; once installed, it displaces the Z-100 serial isr serisr: push ax ; Save regs push bx push cx push dx push ds ; save data seg mov ax,seg datas ; set our mov ds,ax ; data seg mov dx,portadr mov cx,dx add dx,PSTATUS in al,dx ; Get port status mov ah,al ; Save it test ah,RDA ; check for data available jz isr2 ; No, skip mov dx,cx in al,dx ; get the data mov bx,bufiend ; get where to put it mov byte ptr buffin[bx],al ; stick it in the que inc bx ; bump que pointer cmp bx,BUFILEN ; pointing to end of que? jne isr1 xor bx,bx ; reset pointer isr1: mov bufiend,bx ; store new pointer isr2: test ah,TSRE+THBE ; ready to send a char? jz isr5 ; no, almost done mov bx,bufobeg ; get pointer to end of output buffer cmp bx,bufoend ; buffer empty? jz isr4 ; yes, turn transmitter off mov al,byte ptr buffout[bx] ; get char to send mov dx,cx out dx,al ; send it inc bx ; point to next char to send cmp bx,BUFOLEN ; pointing to end of que? jne isr3 xor bx,bx ; reset pointer isr3: mov bufobeg,bx ; save it jmp isr5 isr4: mov dx,cx add dx,PCOMM in al,dx ; get current mode and al,TXOFF ; turn xmitter off out dx,al ; do it. isr5: mov al,EOI ; Tell interrupt controller out Z8259,al ; that interrupt serviced pop ds pop dx pop cx pop bx ; restore regs pop ax iret ; 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 ------- -------