; begin kermit8.asm [18]

;       This set of routines provides a user oriented way of parsing
;       commands.  It is similar to that of the COMND JSYS in TOPS-20.
 
 
;       This routine prints the prompt in DE and specifies the reparse
;       address.
 
PROMPT	PROC  NEAR
	pop bx                  ; Get the return address.
        push bx                 ; Put it on the stack again.
        mov cmrprs,bx           ; Save as addr to go to on reparse.
        mov bx,0                        ; Clear out register.
        add bx,sp               ; Get the present stack pointer.
        mov cmostp,bx           ; Save for later restoral.
        mov cmprmp,dx           ; Save pointer to the prompt.
        mov bx,offset cmdbuf
        mov cmcptr,bx           ; Initialize the command pointer.
        mov cmdptr,bx
        mov ah,0
        mov cmaflg,ah           ; Zero the flags.
        mov cmccnt,ah
        mov cmsflg,0FFH
        mov ah,prstr
        mov dx,offset cmcrlf
        int dos
        mov ah,prstr            ; Print the prompt.
        mov dx,cmprmp
        int dos
        ret
PROMPT	ENDP
 
;       This address is jumped to on reparse.

PARSE	PROC NEAR 
repars: mov sp,cmostp           ; new sp <-- old sp
        mov bx,offset cmdbuf
        mov cmdptr,bx
        mov ah,0FFH
        mov cmsflg,ah
        mov bx,cmrprs           ; Get the reparse address.
        call bx                 ; Go there.
 
;       This address can be jumped to on a parsing error.
 
prserr: mov sp,cmostp           ; Set new sp to old one.
        mov bx,offset cmdbuf
        mov cmcptr,bx           ; Initialize the command pointer.
        mov cmdptr,bx
        mov ah,0
        mov cmaflg,ah           ; Zero the flags.
        mov cmccnt,ah
        mov cmsflg,0FFH
        mov ah,prstr
        mov dx,offset cmcrlf
        int dos
        mov ah,prstr            ; Print the prompt.
        mov dx,cmprmp           ; Get the prompt.
        int dos
; Instead return to before the prompt call.
        mov bx,cmrprs
        call bx
PARSE	ENDP
 
;       This routine parses the specified function in AH. Any additional
;       information is in DX and BX.
;       Returns +1 on success
;               +4 on failure (assumes a JMP follows the call)
 
CMND	PROC NEAR
comnd:  mov cmstat,ah           ; Save what we are presently parsing.
        call cminbf             ; Get chars until an action or a erase char.
	mov ah,cmstat		; Restore 'ah' for upcoming checks.
        cmp ah,cmcfm            ; Parse a confirm?
        jz cmcfrm               ; Go get one.
        cmp ah,cmkey            ; Parse a keyword?
	jnz cm1
        jmp cmkeyw               ; Try and get one.
cm1:    cmp ah,cmifi		; Parse an input file spec?
	jnz cm2
	jmp cmifil		; Go get one.
cm2:	cmp ah,cmofi		; Output file spec?
	jnz cm3
	jmp cmofil		; Go get one.
cm3:	cmp ah,cmtxt		; Parse arbitrary text.   [8]
	jnz cm4
	jmp cmtext
cm4:	mov ah,prstr		; Else give error.
	mov dx,offset cmer00	; "?Unrecognized COMND call"
	int dos
	ret

; This routine gets a confirm.

cmcfrm: call cmgtch		; Get a char.
	cmp ah,0		; Is it negative (a terminator; a space or
				; a tab will not be returned here as they
				; will be seen as leading white space.)
        js cmcfr0
        ret                     ; If not, return failure.
cmcfr0: and ah,7FH                      ; Turn off the minus bit.
        cmp ah,esc                      ; Is it an escape?
        jne cmcfr2
        mov ah,conout
        mov dl,bell             ; Get a bell.
        int dos
        mov ah,0
        mov cmaflg,ah           ; Turn off the action flag.
        mov bx,cmcptr           ; Move the pointer to before thee scape.
        dec bx
        mov cmcptr,bx
        mov cmdptr,bx
        dec cmccnt              ; Decremrnt the char count.
        jmp cmcfrm              ; Try again.
cmcfr2: cmp ah,'?'                      ; Curious?
        jne cmcfr3
        mov ah,prstr            ; Print something useful.
        mov dx,offset cmin00
        int dos
        mov ah,prstr
        mov dx,offset cmcrlf            ; Print a crlf.
        int dos
        mov ah,prstr
        mov dx,cmprmp           ; Reprint the prompt.
        int dos
        mov bx,cmdptr           ; Get the pointer into the buffer.
        mov ah,'$'              ; Put a $ there for printing.
        mov [bx],ah
        mov bx,cmcptr
        dec bx                  ; Decrement & save the buffer pointer.
        mov  cmcptr,bx
        mov ah,prstr
        mov dx,offset cmdbuf
        int dos
        mov ah,0                        ; Turn off the action flag.
        mov cmaflg,ah
        jmp repars              ; Reparse everything.
 
cmcfr3: cmp ah,ff                       ; Is it a form feed?
        jne cmcfr4
        call cmblnk             ; If so blank the screen.
cmcfr4: jmp rskp
 
;       This routine parses a keyword from the table pointed
;       to in DX.  The format of the table is as follows:
;
;       addr:   db      n       ; Where n is the # of entries in the table.
;               db      m       ; M is the size of the keyword.
;               db      'string$' ; Where string is the keyword.
;               dw      ab      ; Where ab is data to be returned.
;
;       The keywords must be in alphabetical order.


cmkeyw: mov cmhlp,bx            ; Save the help.
        mov cmptab,dx           ; Save the beginning of keyword table.
        mov bx,dx
        mov ch,[bx]                     ; Get number of entries in table.
        inc bx
	mov dx,cmdptr		; Save command pointer.
	mov cmsptr,dx		; Save pointer's here.
cmky1:  cmp ch,0                ; Any commands left to check?
        jne cmky2
	mov ah,prstr
	mov dx,offset cmer04	; Complain.   [1]      
	int dos
        ret                     ; Fail if not.
cmky2:  dec ch
	mov cl,0		; Keep track of how many chars read in so far.
        call cmgtch             ; Get a char.
        cmp ah,0                ; Do we have a terminator?
        jns cmky2x 
	jmp cmky4               ; Negative number means we do.
cmky2x: inc bx                  ; Point to first letter of keyword.
	inc cl			; Read in another char.
        mov al,[bx]                   
        cmp ah,'a'              ; Less than a?
        jl cmky21               ; If so, don't capitalize.
        cmp ah,'z'+1            ; More than z?
        jns cmky21
        and ah,137O             ; Capitalize the letter.
cmky21: cmp ah,al
	je cmky3
	jg cmky2y
        jmp cmky41              ; Fail if ah preceeds al alphabetically.
cmky2y: jmp cmky6               ; Not this keyword - try the next.
cmky3:  inc bx                  ; We match here, how 'bout next char?
        mov al,[bx]
        cmp al,'$'               ; End of keyword?
	jne cmky3x
        jmp cmky7                ; Succeed.
cmky3x:	mov dl,al		; Save al's char here.
        call cmgtch
	inc cl			; Read in another char.
	mov al,dl
	cmp ah,'a'
	jl cmky31
	cmp ah,'z'+1
	jns cmky31
	and ah,137O
cmky31: cmp ah,9BH		; Escape Recognition (escape w/minus bit on)?
	je cmky3y
	cmp ah,0BFH		; A question mark?    [3]
	je cmky3y
	cmp ah,0A0H		; A space?
	je cmky3y
	cmp ah,8DH		; Carriage return?
	je cmky3y
	jmp cmky38
cmky3y:	mov cmkptr,bx		; Save bx here.
	mov cmsiz,cx		; Save size info.
	mov cmchr,ah		; Save char for latter.
	call cmambg		; See if input is ambiguous or not.
	 jmp cmky32		; Succeeded (not ambiguous).
	mov ah,cmchr
	cmp ah,9BH		; Escape?
	je cmky3z
	jmp cmky41		; Fail.
cmky3z:	mov ah,conout		; Else, ring a bell.
	mov dl,bell
	int dos
	mov bx,cmcptr		; Move pointer to before the escape.
	dec bx
	mov cmcptr,bx
	mov cmdptr,bx
	dec cmccnt		; Decrement char count.
	mov bx,cmkptr		; Failed - pretend user never typed ....
	mov cx,cmsiz		; ... in a char.
	dec cl			; Don't count the escape.
	dec bx
	mov cmaflg,0		; Reset the action flag.
	jmp cmky3		; Keep checking.
cmky32: mov cx,cmsiz		; Restore info.
	mov bx,cmkptr		; Our place in the keyword table.
	cmp cmchr,0A0H		; Space?
	je cmky35
	cmp cmchr,0BFH		; Question mark?     [3]
	je cmky35
	cmp cmchr,8DH		; Carriage return?
	je cmky35
	dec cmcptr		; Pointer into buffer of input.
	mov dx,cmcptr
cmky33:	mov ah,[bx]		; Get next char in keyword.
	cmp ah,'$'		; Are we done yet?
	jz cmky34
	mov di,dx
	mov [di],ah
	inc bx
	inc dx
	inc cmccnt
	jmp cmky33
cmky34:	mov ah,' '
	mov di,dx
	mov [di],ah		; Put a blank in the buffer.
	inc dx
	mov cx,cmcptr		; Remember where we were (for printing below).
	mov cmcptr,dx		; Update our pointers.
	mov cmdptr,dx
	mov ah,'$'
	mov di,dx
	mov [di],ah		; Add '$' for printing.
	mov ah,prstr
	mov dx,cx		; Point to beginning of filled in data.
	int dos
	inc bx			; Point to address we'll need.
	mov bx,[bx]
	mov cmaflg,0 		; Turn off action flag.
	jmp rskp

cmky35:	inc bx
	mov ah,[bx]		; Find end of keyword. 
	cmp ah,'$'
	jne cmky35	
	inc bx
	mov bx,[bx]		; Address of next routine to call.
;	mov cmaflg,0		; Zero the action flag.
	jmp rskp

cmky38:	cmp ah,al
        jne cmky6               ; Go to end of keyword and try next.
        jmp cmky3
           
cmky4:  and ah,7FH              ; Turn off minus bit.
        cmp ah,'?'              ; Need help?
        je cmky5
	cmp ah,' '		; Just a space - no error.
	je cmky51
	cmp ah,cr
	je cmky51
	cmp ah,tab
	je cmky51 
	cmp ah,esc		; Ignore escape?
	je cmky43
cmky41: mov ah,prstr
        mov dx,offset cmer03
        int dos
        jmp prserr              ; Parse error - give up.

cmky43:	mov ah,conout		; Ring a bell.
	mov dl,bell
	int dos
	mov bx,cmcptr
	dec bx
	mov cmcptr,bx
	mov cmdptr,bx
	dec cmccnt		; Don't count the escape.
	mov cmaflg,0		; Reset action flag.
	inc ch			; Account for a previous 'dec'.
	jmp cmky1		; Start over.

cmky5:  mov ah,prstr
        mov dx,cmhlp            ; Print the help text.
        int dos
	mov dx,offset crlf
	int dos
	mov dx,offset kerm
	int dos
	mov bx,cmdptr		; Get pointer into buffer.
	mov al,'$'
	mov [bx],al		; Add dollar sign for printing.
	mov dx,offset cmdbuf
	int dos
	dec cmcptr		; Don't keep it in the buffer.
	dec cmccnt		; Don't conut it.
	mov cmaflg,0            ; Turn off the action flag.
        jmp repars

cmky51:	jmp prserr

cmky6:  inc bx                  ; Find end of keyword.
        mov al,[bx]
        cmp al,'$'
        jne cmky6             
        inc bx                  ; Beginning of next command.
        inc bx
        inc bx
	mov dx,cmsptr		; Get old cmdptr.
	mov cmdptr,dx		; Restore.
	mov cmsflg,0FFH
        jmp cmky1               ; Keep trying.

cmky7:  call cmgtch             ; Get char.
	cmp ah,0
	js cmky71		; Ok if a terminator.
        dec bx
        jmp cmky6               ; No match - try next keyword.
cmky71: inc bx                  ; Get necessary data.
        mov bx,[bx]
	cmp ah,9BH		; An escape?
	jne cmky72
	mov ah,prstr
	mov dx,offset prsp      ; Print a space.
	int dos
	mov di,cmcptr
	dec di
	mov ah,20H
	mov [di],ah		; Replace escape char with space.
	mov cmaflg,0
	mov cmsflg,0FFH		; Pretend they typed a space.
cmky72: jmp rskp

; See if keyword is unambiguous or not from what the user has typed in.

cmambg:	cmp ch,0		; Any keywords left to check?
	jne cmamb0
	ret			; If not then not ambiguous.
cmamb0:	inc bx			; Go to end of keyword ...
	mov al,[bx]		; So we can check the next one.
	cmp al,'$'
	jne cmamb0
	add bx,4		; Point to start of next keyword.
	dec cl			; Don't count escape.
	mov dx,cmsptr		; Buffer with input typed by user.
cmamb1:	mov ah,[bx]		; Keyword char.	
	mov di,dx
	mov al,[di]		; Input char.
	cmp al,'a'		; Do capitalizing.
	jl cmam11
	cmp al,'z'+1
	jns cmam11
	and al,137O
cmam11:	cmp ah,al		; Keyword bigger than input (alphabetically)?
	jle cmamb2		; No - keep checking.
	ret			; Yes - not ambiguous.
cmamb2:	inc bx			; Advance one char.
	inc dx
	dec cl
	jnz cmamb1
	jmp rskp		; Fail - it's ambiguous.

cmifil: mov bx,dx               ; Get the fcb address in bx.
        mov cmfcb,bx            ; Save it.
        mov ch,0                ; Initialize char count.
        mov ah,0
        mov [bx],ah                     ; Set the drive to default to current.
	inc bx
        mov cmfcb2,bx
        mov cl,' '
cmifi0: mov [bx],cl                     ; Blank the FCB.
        inc bx
        inc ah
        cmp ah,0BH                      ; Twelve?
        jl cmifi0
cmifi1: call cmgtch             ; Get another char.
        cmp ah,0                        ; Is it an action character.
        jns cmifi2
        and ah,7FH                      ; Turn off the action bit.
        cmp ah,'?'                      ; A question mark?
        jne cmif12
        mov al,0
        mov cmaflg,al           ; Blank the action flag.
        dec cmcptr           ; Decrement the buffer pointer.
	dec cmccnt		; Decrement count.
;        jmp cmifi8              ; Treat like any other character.
	mov ah,prstr
	mov dx,offset filhlp	; Help  message.
	int dos
	mov dx,offset crlf
	int dos
	mov dx,offset kerm
	int dos
	mov bx,cmdptr
	mov al,'$'
	mov [bx],al		; Put in dollar sign for printing.
	mov dx,offset cmdbuf
	int dos
	jmp repars
cmif12: cmp ah,esc                      ; An escape?
        jne cmif13
        mov ah,0
        mov cmaflg,ah           ; Turn off the action flag.
        mov ah,conout
        mov dl,bell
        int dos         ; Ring the bell.
        mov bx,cmcptr           ; Move the pointer to before the escape.
        dec bx
        mov cmcptr,bx
        mov cmdptr,bx
        dec cmccnt              ; Decrement char count.
        jmp repars
cmif13: mov ah,ch                       ; It must be a terminator.
        cmp ah,0                        ; Test the length of the file name.
	jnz cmf3x
        jmp cmifi9               ; If zero complain.
cmf3x:  cmp ah,0DH
        js cmf3y
	jmp cmifi9              ; If too long complain.
cmf3y:  jmp rskp                ; Otherwise we have succeeded.
cmifi2: cmp ah,'.'
        jne cmifi3
        inc ch
        mov ah,ch
        cmp ah,1H                       ; Any chars yet?
      	jnz cmf2x
	jmp cmifi9               ; No, give error.
cmf2x:  cmp ah,0AH                      ; Tenth char?
      	js cmf2y
	jmp cmifi9              ; Past it, give an error.
cmf2y:  mov dl,9H
        mov dh,0
        mov bx,cmfcb
        add bx,dx               ; Point to file type field.
        mov cmfcb2,bx
        mov ch,9H               ; Say we've gotten nine.
        jmp cmifi1              ; Get the next char.
cmifi3: cmp ah,':'
        jne cmifi4
        inc ch
        cmp ch,2H                       ; Is it in right place for a drive?
	je cmif3x
        jmp cmifi9              ; If not, complain.
cmif3x: mov ch,0		; Reset char count.
	mov bx,cmfcb2
	sub bx,1
        mov ah,[bx]                     ; Get the drive name.
        sub ah,'@'              ; Get the drive number.
	mov cmfcb2,bx
 	mov bx,cmfcb
        mov [bx],ah                     ; Put it in the fcb.
        jmp cmifi1
cmifi4: cmp ah,'*'
        jne cmifi7
        mov ah,ch
        cmp ah,8H                       ; Is this in the name or type field?
        jz cmifi9               ; If its where the dot should be give up.
        jns cmifi5              ; Type.
        mov cl,8H               ; Eight chars.
        jmp cmifi6
cmifi5: mov cl,0CH              ; Three chars.
cmifi6: mov wldflg,0FFH		; Remember we had a wildcard.
	mov bx,cmfcb2           ; Get a pointer into the FCB.
        mov ah,'?'
        mov [bx],ah                     ; Put a question mark in.
        inc bx
        mov cmfcb2,bx
        inc ch
        mov ah,ch
        cmp ah,cl
        jl cmifi6               ; Go fill in another.
        jmp cmifi1              ; Get the next char.
cmifi7: cmp ah,03DH		; Equals sign (wildcard)?
	jne cmif7x
	mov ah,'?'
	mov wldflg,0FFH		; Say we have a wildcard.
	jmp cmifi8		; Put into FCB.
cmif7x:	cmp ah,'0'
        jl cmif8x
        cmp ah,'z'+1
        jns cmif8x
        cmp ah,'A'                      ; Don't capitalize non-alphabetics.
        jl cmifi8
        and ah,137O             ; Capitalize.
cmifi8: mov bx,cmfcb2           ; Get the pointer into the FCB.
        mov [bx],ah                     ; Put the char there.
        inc bx
        mov cmfcb2,bx
        inc ch
        jmp cmifi1

cmif8x:	push es
	mov cx,ds
	mov es,cx		; Scan uses ES register.
	mov di,offset spchar    ; Special chars.
	mov cx,20		; Twenty of them.
	mov al,ah		; Char is in al.
	repnz scasb		; Search string for input char.
	cmp cx,0		; Was it there?
	pop es
	jnz cmifi8
 
cmifi9: mov ah,prstr
        mov dx,offset cmer02
        int dos
        ret
 
cmofil: jmp cmifil              ; For now, the same as CMIFI.

; Parse arbitrary text up to a CR.  Put chars into data buffer sent to
; the host (pointed to by BX).   Return updated pointer in BX and 
; input size in AH.

cmtext:	mov cmptab,bx		; Save pointer to data buffer.   [8 start]
	mov cl,0		; Init the char count.
cmtxt1:	call cmgtch		; Get a char.
	cmp ah,0		; Terminator?
	jns cmtxt5		; Nope, put into the buffer.
	and ah,07FH
	cmp ah,esc		; An escape?
	jne cmtxt2
	mov ah,conout
	mov dl,bell		; Ring a bell.
	int dos
	mov cmaflg,0		; Reset action flag.
	dec cmcptr		; Move pointer to before the escape.
	dec cmdptr
	dec cmccnt		; Decrement count.
	jmp cmtxt1		; Try again.
cmtxt2:	cmp ah,'?'		; Asking a question?
	jz cmtxt3
	cmp ah,ff		; Formfeed?
	jne cmtx2x
	call cmblnk
cmtx2x: mov ah,cl		; Return count in AH.
	mov bx,cmptab		; Return updated pointer.
	jmp rskp
cmtxt3:	mov cmaflg,0		; Reset action flag to zero.
cmtxt5: inc cl			; Increment the count.
	mov bx,cmptab		; Pointer into destination array.
	mov [bx],ah		; Put char into the buffer.
	inc bx
	mov cmptab,bx
	jmp cmtxt1					; [8 end]

cminbf: push dx
        push bx
        mov cx,dx               ; Save value here too.
        mov ah,cmaflg           ; Is the action char flag set?
        cmp ah,0
	je cminb1
        jmp cminb9              ; If so get no more chars.
cminb1: inc cmccnt              ; Increment the char count.
        mov ah,conin            ; Get a char.
        int dos
	mov ah,al		; Keep char in 'ah'.
        mov bx,cmcptr           ; Get the pointer into the buffer.
        mov [bx],ah                     ; Put it in the buffer.
        inc bx
        mov cmcptr,bx
        cmp ah,25O                      ; Is it a ^U?
        jne cminb2
cmnb12: mov ah,prstr
	mov dx,offset clrlin
	int dos
IF ibmpc
	mov ax,0920H	   		; Write spaces.
        mov bx,7 	           ; Clear the line.
	mov cx,80
        int bios
ENDIF
        mov ah,prstr
        mov dx,cmprmp           ; Print the prompt.
        int dos
        mov bx,offset cmdbuf
        mov cmcptr,bx           ; Reset the point to the start.
	mov cmccnt,0	           ; Zero the count.
        mov dx,cx               ; Preserve original value of dx.
        jmp repars              ; Go start over.
cminb2: cmp ah,10O                      ; Or backspace?
        jz cminb3
        cmp ah,del                      ; Delete?
        jne cminb4
        mov ah,prstr            ; Print the delete string.
        mov dx,offset delstr
        int dos
cminb3: mov ah,cmccnt           ; Decrement the char count by two.
        dec ah
        dec ah
        cmp ah,0                        ; Have we gone too far?
        jns cmnb32              ; If not proceed.
        mov ah,conout           ; Ring the bell.
        mov dl,bell
        int dos
        jmp cmnb12              ; Go reprint prompt and reparse.
cmnb32: mov cmccnt,ah           ; Save the new char count.
        mov ah,prstr            ; Erase the character.
        mov dx,offset clrspc
        int dos
        mov bx,cmcptr           ; Get the pointer into the buffer.
        dec bx                  ; Back up in the buffer.
        dec bx
        mov cmcptr,bx
        jmp repars              ; Go reparse everything.
cminb4: cmp ah,'?'                      ; Is it a question mark.
        jz cminb6
        cmp ah,esc                      ; Is it an escape?
        jz cminb8
        cmp ah,cr                       ; Is it a carriage return?
        jz cminb5
        cmp ah,lf                       ; Is it a line feed?
        jz cminb5
        cmp ah,ff                       ; Is it a formfeed?
        jne cminb7
        call cmblnk
	call locate
cminb5: mov ah,cmccnt           ; Have we parsed any chars yet?
        cmp ah,1
	jnz cminb6
        jmp prserr               ; If not, just start over.
cminb6: mov ah,0FFH             ; Set the action flag.
        mov cmaflg,ah
        jmp cminb9
cminb7: jmp cminb1		; Get another char.

cminb8: mov ah,prstr		; Don't print the escape char.
	mov dx,offset escspc
	int dos
	jmp cminb6
 
cminb9: pop bx
        pop dx
        ret
 
cmgtch: push cx
	push bx
        push dx
cmgtc1: mov ah,cmaflg
        cmp ah,0                        ; Is it set.
        jne cmgt10
        call cminbf             ; If the action char flag is not set get more.
cmgt10: mov bx,cmdptr           ; Get a pointer into the buffer.
        mov ah,[bx]                     ; Get the next char.
        inc bx
        mov cmdptr,bx
        cmp ah,' '                      ; Is it a space?
        jz cmgtc2
        cmp ah,tab                      ; Or a tab?
        jne cmgtc3
cmgtc2: mov ah,cmsflg           ; Get the space flag.
        cmp ah,0                        ; Was the last char a space?
        jne cmgtc1              ; Yes, get another char.
        mov ah,0FFH             ; Set the space flag.
        mov cmsflg,ah
        mov ah,' '
        pop dx
        pop bx
        jmp cmgtc5
cmgtc3: mov al,0
        mov cmsflg,al           ; Zero the space flag.
        pop dx
        pop bx
        cmp ah,esc
        jz cmgtc5
        cmp ah,'?'                      ; Is the user curious?
        jz cmgtc4
        cmp ah,cr
        jz cmgtc4
        cmp ah,lf
        jz cmgtc4
	cmp ah,ff
	je cmgtc4
	pop cx
	ret			; Not an action char, just return.
cmgtc4: dec cmdptr
cmgtc5: or ah,80H		; Make the char negative to indicate
	pop cx
	ret			; it is a terminator.
CMND	ENDP

; This routine blanks the screen.

CMBLNK	PROC	NEAR		; This is stolen from the IBM example.
IF ibmpc
	mov cx,0
	mov dx,184FH
	mov bh,7
	mov ax,600H
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Get the function code
	mov dx,offset clrscr	; Want to clear the screen
	int dos			; Do it
ENDIF
	ret
CMBLNK  ENDP

; Cursor control.

LOCATE  PROC	NEAR
IF ibmpc
	mov dx,0		; Go to top left corner of screen.
	mov bh,0
	mov ah,2
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Function is print string
	mov dx,offset homcur	; Home cursor
	int dos			; do it
ENDIF
	ret
LOCATE  ENDP

 
MAIN 	ENDS			; End of code section.
	END	START
umpkt
rdat33: mov bx,bufpnt           ; Get the dma pointer.
	mov ax,80H
        sub ax,chrcnt           ; Get the number of