home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
ccdos
/
ccyibm.asm
< prev
next >
Wrap
Assembly Source File
|
2020-01-01
|
121KB
|
2,631 lines
NAME ccyibm
; File CCYIBM.ASM
; Edit History:
; Mar.21,1991:
; * Add MASM Option /DCGA in serval places. The goal is to make ZUnet-PBX
; can be run in different CCDOS versions(Such as: CCDOS213,LIANXIAN,
; STCDOS,CGA17,etc.) on different video adapers( such as CGA,EGA,VGA
; and MDA).
; In this program Macro Conditions "IFDEF CGA ... ENDIF" and "IFNDEF CGA
; ... ENDIF" are used.
; Option CGA is used only when you want to build a program used in PC/XT
; (CGA or MDA adapter).Maybe it can be used in VGA adapter. [zqf]
; 1990:
; * Program is modified in many places to suit for different CCDOS versions.
; You can check them by indexing 'zqf' or 'CCDOS'. [zqf]
;CHINESE
ifdef MSDOS
include msyibm.dat
else
include ccyibm.dat
endif
code segment public 'code'
extrn beep:near, prtchr:near, outchr:near, sbrk:near, pcwait:near
extrn isfile:near, strlen:near, strcpy:near ; in mssfil
extrn anstty:near,ansini:near,ansrei:near ; in mszibm
extrn anstat:near,anskbi:near,ansdsl:near ; in mszibm
extrn ans52t:near, vsinit:near ; in mszibm
extrn msuinit:near, keybd:near ; in msuibm
extrn tekini:near,tekcls:near,tekemu:near,tekend:near ;in msgibm
extrn tekrint:near
ifdef DEBG
; extrn debgp:near
endif
assume cs:code, ds:datas, es:datas
; do initialization local to this module
; Dynamically allocates 4000 bytes for screen save/restore buffer plus
; 320 to 38400 bytes for screen scroll back buffers. Tries to leave space
; for Command.com before enlarging buffers. [jrd]
lclyini proc near
call msuinit ; initialize keyboard module msuxxx
mov ax,swidth*(slen+1)*2 ; (80 char + 80 attr) * 25 lines
call sbrk ; memory allocation routine (mssker)
;if we get here them we have the lines
mov scrsav,ax ; memory segment for save screens
; screen roll back buffers
mov bx,0ffffh ; ask for all of memory, to get size
mov ah,alloc ; allocate all of memory (must fail)
int dos ; bx has # free paragraphs
mov ax,bx ; ax has copy of number free paragraphs
sub ax,24000D/16 ; space for Command.com copy #2
jbe lclyin1 ; be = not enough for it. [ebb]
cmp ax,(swidth*slen+15)/16 ; minimum roll back space left over?
jbe lclyin1 ; be = not even that much
cmp ax,(swidth*slen*npages+7)/8 ; paragraphs wanted for roll back
jbe lclyin2 ; be = enough but not more than needed
mov ax,(swidth*slen*npages+7)/8 ; limit to our actual needs
jmp short lclyin2 ; ask for all we really want
lclyin1:mov ax,(4*swidth+15)/16 ; use minimum needed paragraphs
lclyin2:mov inipara,ax ; save for later resizing of buffers
mov cl,4 ; convert paragraphs to bytes
shl ax,cl ; for sbrk
call sbrk ; ask for that many bytes
;if we get here them we have the space
mov bwnd.orig,ax ; memory segment, bottom window area
mov twnd.orig,ax ; top. same place for both buffers!
call scrseg ; test running in an Environment
call scrmod ; read video state, get crt_mode
mov ax,low_rgt ; lower right corner of screen
mov al,crt_mode
mov crt_norm,al ; save as normal mode
mov savflg,ax
mov ah,conout ; output a space to set background
mov dl,' ' ; and foreground screen colors
int dos
mov ah,3 ; get current cursor position into dx
mov bh,0
int screen
dec dl ; backup to the space
mov ah,2 ; set cursor
int screen
mov ah,8 ; read current attributes
xor bh,bh ; page 0
int screen
mov scbattr,ah ; save video attributes
mov oldattr,ah ; and here too
mov ax,inipara ; # paragraphs allocated by DOS
mov cl,3 ; 2**3 = 8
shl ax,cl ; paragraphs to words (char + attrib)
xor dx,dx ; clear extended size
mov ch,0
mov cl,byte ptr low_rgt
inc cl ; number of chars per line in buffer
div cx ; ax = number of lines in buffer
mov bwnd.lmax,ax ; max lines per buffer (quotient)
mov twnd.lmax,ax ; max lines per buffer
add cx,cx ; count char and attribute per item
xor dx,dx ; clear extended numerator
mul cx ; ax = effective # bytes per buffer
dec ax ; adjust for counting from zero
mov bwnd.bend,ax ; offset of last byte in buffer
mov twnd.bend,ax ; offset of last byte in buffer
mov bwnd.pp,0 ; offset of first byte in buffer
mov twnd.pp,0 ; offset of first byte in buffer
mov bwnd.lcnt,0 ; number of lines occupied in buffer
mov twnd.lcnt,0 ; number of lines occupied in buffer
call vsinit ; init terminal emulator module MSZ
mov ega_mode,0 ; assume no EGA
mov ax,1200H ; EGA: Bios alternate select
mov bl,10H ; Ask for EGA info
mov bh,0ffH ; Bad info, for testing
mov cl,0fH ; Reserved switch settings
int screen ; EGA, are you there?
cmp cl,0cH ; Test reserved switch settings
jge lclyin3 ; ge = no EGA in use
push es
mov ax,40h ; check Bios 40:87h for ega being
mov es,ax ; the active display adapter
test byte ptr es:[87h],8 ; is ega active?
pop es
jnz lclyin3 ; nz = no
mov ega_mode,1 ; yes, set flag to say so
mov crt_norm,3 ; assume color monitor is attached
cmp bh,0 ; is color mode in effect?
je lclyin3 ; e = yes
mov crt_norm,7 ; else use mode 7 for mono
lclyin3:ret
lclyini endp
scrini proc near ; init screen stuff
call scrseg ; update screen segment tv_seg(s/o)
call scrmod ; get screen mode, low_rgt
mov ah,3 ; get cursor position and type
xor bh,bh ; page 0
int screen
mov lincur,cx ; save cursor type (scan line #'s)
mov ax,low_rgt ; present screen text size
cmp ax,savflg ; vs size of saved screen
jne scrin1 ; ne = different, initialize
jmp scrin3 ; same, skip initialization
; Re-initialize screen buffers
scrin1: mov ax,inipara ; paragraphs allotted to roll back
mov cl,3 ; 2**3 = 8
shl ax,cl ; paragraphs to words (char + attrib)
xor dx,dx ; clear extended size
mov cl,byte ptr low_rgt ; number of chars per line in buffer
inc cl ; chars per line
xor ch,ch ; clear high byte
div cx ; ax = number of lines in buffer
mov bwnd.lmax,ax ; max lines per buffer (quotient)
mov twnd.lmax,ax ; max lines per buffer
add cx,cx ; count char and attribute per item
xor dx,dx ; clear extended numerator
mul cx ; ax = effective # bytes per buffer
dec ax ; adjust for counting from zero
mov bwnd.bend,ax ; offset of last byte in buffer
mov twnd.bend,ax ; offset of last byte in buffer
mov bwnd.pp,0 ; offset of first byte in buffer
mov twnd.pp,0 ; offset of first byte in buffer
mov bwnd.lcnt,0 ; number of lines occupied in buffer
mov twnd.lcnt,0 ; number of lines occupied in buffer
mov ega_mode,0 ; assume no EGA
mov ax,1200H ; EGA: Bios alternate select
mov bl,10H ; Ask for EGA info
mov bh,0ffH ; Bad info, for testing
mov cl,0fH ; Reserved switch settings
int screen ; EGA, are you there?
cmp cl,0cH ; Test reserved switch settings
jge scrin2 ; ge = no EGA in use
push es
mov ax,40h ; check Bios 40:87h for ega being
mov es,ax ; the active display adapter
test byte ptr es:[87h],8 ; is ega active?
pop es
jnz scrin2 ; nz = no
mov ega_mode,1 ; yes, set flag to say so
mov crt_norm,3 ; assume color monitor is attached
cmp bh,0 ; is color mode in effect?
je scrin2 ; e = yes
mov crt_norm,7 ; else use mode 7 for mono
scrin2: mov ah,oldattr ; get init time attributes
mov curattr,ah ; and set nice screen attribute
mov scbattr,ah
mov cursor,0 ; cursor to upper left corner
cmp flags.vtflg,0 ; terminal type of None?
ja scrin3 ; a = no, emulating
mov dh,byte ptr low_rgt+1
inc dh ; bottom
mov dl,0 ; left corner
jmp short scrin5
; Common finish code
scrin3: mov dx,cursor ; use old cursor, if any
cmp flags.vtflg,0 ; emulating?
je scrin4 ; e = no
cmp dh,byte ptr low_rgt+1 ; past logical end of screen?
jbe scrin4 ; be = no, keep going
mov dh,byte ptr low_rgt+1 ; yes, just use lower right corner
scrin4: cmp dl,byte ptr low_rgt ; maybe past right margin
jbe scrin5 ; be = no, use the way it is
mov dl,byte ptr low_rgt
scrin5: mov cursor,dx ; init cursor
mov ah,2 ; set cursor position
xor bh,bh ; page zero
; ---------don't set cursor in CCDOS. Dec.12,1990 [zqf]
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
cmp isccdos,1 ; is in CCDOS ?
je scrin6 ; e = yes, skip
ENDIF
int screen ; set cursor in case it moved
scrin6:
; -----------
test flags1,inited ; have we run yet?
jz scrin7 ; z = no, so no saved screen yet
call restscr ; restore screen[zqf]Dec.13,1990
scrin7: or flags1,inited ; remember we've run already
cmp flags.modflg,1 ; is mode line on and locally owned?
ja scrin10 ; a = host owned, leave intact
cmp flags.vtflg,0 ; emulating a terminal?
jne scrin8 ; ne = yes, can have mode line
or yflags,modoff ; for no emulation say toggled off
cmp trmtyp,0 ; previous terminal type = none?
jne scrin9 ; ne = no. need to clear mode line
jmp scrin10 ; yes, let 25th line be intact
scrin8: cmp flags.modflg,0 ; is mode line disabled?
je scrin9 ; e = yes, clear it
test yflags,modoff ; is mode line toggled off?
jnz scrin9 ; nz = yes, clear the line
call modlin ; turn on mode line
jmp short scrin10
scrin9: call clrmod ; ensure its off
scrin10:cmp flags.vtflg,0 ; current terminal type = None?
je scrin12 ; e = yes, nothing to init
mov al,yflags ; tell emulator we are back
cmp vtclear,0 ; screen need clearing?
jne scrin10a ; yes, do emulator reinit now
cmp vtinited,inited ; inited emulator yet?
je scrin11 ; e = yes
cmp tekflg,0 ; Tek mode still active?
jne scrin12 ; ne = yes, no re-init here
scrin10a:call vtinit ; init it now
mov vtclear,0 ; say screen is clear
jmp short scrin12
scrin11:call ansrei ; reinit the emulator
call ansflg ; and get its flags
scrin12:mov al,flags.vtflg ; current terminal type
mov trmtyp,al ; place to remember it til next time
cmp flags.vtflg,tttek ; Tek mode?
je scrin13 ; e = yes
cmp tekflg,0 ; Tek mode active within DEC stuff?
je scrin14 ; e = no
scrin13:call tekini ; reinit to get graphics screen
scrin14:ret
scrini endp
; Routine to initialize VT102/52/Heath-19 terminal emulator.
vtinit proc near
mov holdscr,0 ; clear holdscreen
cmp flags.vtflg,0 ; doing emulation?
je vtinix ; e = no
cmp tekflg,0 ; Tek mode active?
jne vtini2 ; ne = yes, do it's reinit
or vtinited,inited
call ansflg ; update ansi flags
mov bx,argadr ; Get address of argument block
mov dl,[bx].flgs
and dl,lclecho
and yflags,not lclecho
or yflags,dl
mov al,yflags ; Pass the flags
mov dl,[bx].baudb ; Baud rate code in dl
mov dh,[bx].parity ; Parity code in bits
mov cl,4 ; 0-3 of dh
shl dh,cl
or dh,07H ; Just say 7 data bits
test flags.remflg,d8bit ; eight bit display?
jz vtini1 ; z = no
inc dh ; set low four bits to value 8
vtini1: call ansini ; call startup routine in mszibm
vtinix: clc
ret
vtini2: call tekrint ; reinitialize Tek emulator
clc
ret
vtinit endp
argini proc near ; read passed arguments
mov bx,argadr ; base of argument block
mov al,[bx].flgs ; get flags
and al,capt+emheath+havtt+trnctl+lclecho+modoff+lnwrap
mov yflags,al ; mask for allowable and save
mov al,[bx].prt
mov portno,al ; update port number
mov al,[bx].rows
mov crt_lins,al ; init # of rows and cols
mov ax,[bx].captr
mov captrtn,ax ; buffer capture routine
mov al,[bx].escc
mov esc_ch,al
mov parmsk,0ffh ; parity mask, assume parity = None
cmp [bx].parity,parnon ; is parity None?
je argini1 ; e = yes, keep all 8 bits
mov parmsk,07fh ; else keep lower 7 bits
argini1:ret ; that's it
argini endp
modlin proc near ; turn on mode line
; ************************** Change Connect Mode Line, Oct.8,1990 [zqf].
cmp isccdos, 0 ; if in MS-DOS or CC-DOS ?
je modl0 ; e = in MS-DOS
jmp cmodl0 ; in CC-DOS
; ***
; ******** in MS-DOS below
modl0: mov al,esc_ch
mov modbuf.m_echr,' ' ; first char is initial space
mov modbuf.m_hlp,' ' ; goes here too
cmp al,32 ; printable?
jnb modl1 ; yes, keep going
add al,40h ; made printable
mov modbuf.m_echr,5eh ; caret, note control char
mov modbuf.m_hlp,5eh
modl1: mov modbuf.m_echr+1,al ; fill in character
mov modbuf.m_hlp+1,al
mov bx,argadr ; get argument block
mov al,[bx].baudb ; get baud bits
mov si,offset unkbaud ; assume unknown baud
cmp al,baudnsiz ; too big?
jnb modl2 ; nb = yes, use default
mov cl,size m_baud ; each is 5 bytes long
mul cl
mov ah,0
add ax,offset baudn
mov si,ax
modl2: mov cx,size m_baud ; length of baud space
mov di,offset modbuf.m_baud
push es ; save es
push ds
pop es ; set es to datas segment
cld
rep movsb ; copy in baud rate
mov al,[bx].parity ; get parity code
shl al,1 ; each is 4 bytes long
shl al,1
mov ah,0
add ax,offset parnams ; names of parity settings
mov si,ax
mov cx,4 ; each is 4 long
mov di,offset modbuf.m_par
rep movsb
mov si,offset remmsg ; Assume remote echoing
test yflags,lclecho ; Is remote side echoing?
jz modl4 ; Yes, keep going
mov si,offset lclmsg ; Else it's local echoing.
modl4: mov cx,3 ; size of on/off
mov di,offset modbuf.m_echo
rep movsb
mov al,portno ; communications port
cmp al,' ' ; binary (non-printable)?
jae modl5 ; ae = no, ascii
add al,'0' ; convert to ascii
modl5: mov modbuf.m_prt,al ; fill in port number
mov cx,8 ; blank out terminal id field
mov si,offset mtty ; assume no terminal emulation
mov di,offset modbuf.m_term ; destination
rep movsb ; copy it in
mov modbuf.m_prn,' ' ; assume not printing the screen
mov modbuf.m_prn+1,' '
mov modbuf.m_prn+2,' '
test anspflg,prtscr ; doing a print the screen?
jz modl5a ; z = no
mov modbuf.m_prn,'P' ; yes. display PRN at end of line
mov modbuf.m_prn+1,'R'
mov modbuf.m_prn+2,'N'
modl5a: mov cx,size modfrm ; this is size of mode line
mov si,offset modbuf ; mode line image
pop es
; ****
jmp modwrt
; ******** in CC-DOS below
cmodl0: mov al,esc_ch
mov cmodbuf.cm_echr,' ' ; first char is initial space
mov cmodbuf.cm_hlp,' ' ; goes here too
cmp al,32 ; printable?
jnb cmodl1 ; yes, keep going
add al,40h ; made printable
mov cmodbuf.cm_echr,5eh ; caret, note control char
mov cmodbuf.cm_hlp,5eh
cmodl1: mov cmodbuf.cm_echr+1,al ; fill in character
mov cmodbuf.cm_hlp+1,al
mov bx,argadr ; get argument block
mov al,[bx].baudb ; get baud bits
mov si,offset cunkbaud ; assume unknown baud
cmp al,baudnsiz ; too big?
jnb cmodl2 ; nb = yes, use default
mov cl,size cm_baud ; each is 5 bytes long
mul cl
mov ah,0
add ax,offset baudn
mov si,ax
cmodl2: mov cx,size cm_baud ; length of baud space
mov di,offset cmodbuf.cm_baud
push es ; save es
push ds
pop es ; set es to datas segment
cld
rep movsb ; copy in baud rate
mov al,[bx].parity ; get parity code
shl al,1 ; each is 4 bytes long
shl al,1
mov ah,0
add ax,offset cparnams ; names of parity settings
mov si,ax
mov cx,4 ; each is 4 long
mov di,offset cmodbuf.cm_par
rep movsb
mov si,offset cremmsg ; Assume remote echoing
test yflags,lclecho ; Is remote side echoing?
jz cmodl4 ; Yes, keep going
mov si,offset clclmsg ; Else it's local echoing.
cmodl4: mov cx,4 ; size of on/off
mov di,offset cmodbuf.cm_echo
rep movsb
mov al,portno ; communications port
cmp al,' ' ; binary (non-printable)?
jae cmodl5 ; ae = no, ascii
add al,'0' ; convert to ascii
cmodl5: mov cmodbuf.cm_prt,al ; fill in port number
mov cx,8 ; blank out terminal id field
mov si,offset mtty ; assume no terminal emulation
mov di,offset cmodbuf.cm_term ; destination
rep movsb ; copy it in
mov cmodbuf.cm_prn,' ' ; assume not printing the screen
mov cmodbuf.cm_prn+1,' '
mov cmodbuf.cm_prn+2,' '
test anspflg,prtscr ; doing a print the screen?
jz cmodl5a ; z = no
mov cmodbuf.cm_prn,'P' ; yes. display PRN at end of line
mov cmodbuf.cm_prn+1,'R'
mov cmodbuf.cm_prn+2,'N'
cmodl5a: mov cx,size cmodfrm ; this is size of mode line
mov si,offset cmodbuf ; mode line image
pop es
; ************************** Oct.8,1990 [zqf].
; alternate entry to write an alternate mode line
modwrt: push cx
push si ; save mode line and size
mov ah,3 ; read cursor position
xor bx,bx ; screen page 0
int screen
mov cursor,dx ; save cursor position
call trmatt ; Get terminal attributes
and ah,77h ; omit blinking/bold attributes
mov bh,ah ; get video attribute
mov dx,low_rgt ; right most column
inc dh ; refer to status line
mov ch,dh ; bottom line [dlk]
mov cl,0 ; left col = 0 (first) [dlk]
mov ax,600h ; scroll to clear the line
;**** Modify to suit CCDOS. Sept 5,1990 [zqf]
cmp isccdos,1 ; if in CCDOS ?
jne modl5b ; ne = No, in MS-DOS
mov ax,cx ; in CCDOS
mov bx,dx
call atsclr ; clear mode line in CC-DOS
jmp modl5c
modl5b: int screen ; clear mode line in MS-DOS
modl5c:
;****
mov dh,byte ptr low_rgt+1 ; refer to status line
inc dh
xor dl,dl ; left most column
mov bh,0
mov ah,2 ; set cursor position
int screen
pop si
pop cx ; restore these
cmp cl,crt_cols ; mode line longer than screen?
jbe modl6 ; le = no
mov cl,crt_cols ; else do just one line's worth
dec cx ; don't let screen scroll
modl6: cld
lodsb ; get a byte
mov ah,14 ; write to terminal
mov bh,0 ; page 0
int screen
loop modl6 ; write out entire mode line
cmp flags.vtflg,0 ; emulating?
je modl7 ; e = no
and yflags,not modoff ; update local flags (mode line on)
mov al,yflags ; Yes - update flags also
call ansdsl ; get extras from emulator
modl7: mov dx,cursor
mov ah,2
mov bh,0
int screen ; put cursor back where it belongs
ret
modlin endp
clrmod proc near ; clear mode line
call trmatt ; Get terminal screen attributes
mov bh,al ; Use screen background attribute
mov ax,600h ; blank window
mov dx,low_rgt ; right most column
inc dh ; refer to status line
mov cx,dx ; bottom line [dlk]
xor cl,cl ; left most column
;**** Modify to suit CCDOS. June 25,1990 [zqf]
mov ax,cx
mov bx,dx
call atsclr
; int screen ; clear mode line
;****
or yflags,modoff ; turn on flag
ret
clrmod endp
; Fetch screen attributes from emulator (if emulating). It exists mainly
; so that the reverse video will work. Returns the current mode
; line background attribute in ah, the current screen background in al,
; and the current "cursor" (foreground) attribute in bl. (Note: anstat
; returns status yflags in bh).
trmatt proc near ; Get attributes
cmp flags.vtflg,0 ; emulating?
je trmat1 ; No, just do simple stuff
mov al,yflags ; anstat expects flags byte in al
call anstat ; Fetch emulator status/attributes
ret
trmat1: mov al,scbattr ; Background attributes
mov bl,curattr ; And cursor attribute
mov ah,al ; where modlin needs them
and ah,77h ; get colors part, no blink/bold
rol ah,1 ; reverse them
rol ah,1
rol ah,1
rol ah,1
ret
trmatt endp
; Get byte yflags of terminal emulator passed in AL. Used in mode line
; handling when 25th line is used by the emulator. [jrd]
telmsy proc near
mov yflags,al ; get the updated flags
call ansflg ; and any other emulator info
ret
telmsy endp
;[IU2] This routine updates the ANSI status flags from the emulator,
; and passes the "yflags" byte to the VT100 emulator also.
ansflg proc near
push ax ; save regs
push bx
mov al,yflags
call anstat ; Get status and attributes
mov ansflgs,bh ; Save
test ansflgs,dececho ; does host want us to do local echo?
jz ansflg1 ; z = no, use working default
or yflags,lclecho ; turn on local echoing
ansflg1:pop bx
pop ax
ret
ansflg endp
getflgs proc near ; supply yflags for terminal emulators
mov al,yflags
ret
getflgs endp
term proc near ; terminal mode entry point
mov argadr,ax ; save argument ptr
call argini ; init options from arg address
call scrini ; init screen stuff
mov bx,portval ; port data structure address
mov bx,[bx].flowc ; get flow control chars (bl=xoff)
mov flowon,bh
mov flowoff,bl ; save for later
mov oldsp,sp ; remember stack for i/o failure,
; used by procedure endcon
lp: call prtchr ; char at port?
jmp short lpinp ; yes, go handle
nop ; else look at kbd
lpkbd: mov fairness,0 ; say kbd was examined
call keybd ; call keyboard translator in msu
jnc lp ; nc = no char or have processed it
jmp short quit ; carry set = quit connect mode
lpinp: and al,parmsk ; apply 8/7 bit parity mask
call outtty ; print on terminal
inc fairness ; say read port but not kbd, again
cmp fairness,100 ; this many port reads before kbd?
jb lp ; b = no, read port again
jmp short lpkbd ; yes, let user have a chance too
quit:
call pntflsh ; flush printer buffer
call tekend ; cleanup Tektronix mode [bjh]
mov ah,3 ; get cursor position into dx
xor bh,bh ; page 0
int screen
mov cursor,dx ; save position
cmp flags.vtflg,0 ; terminal type of none?
ja quit1 ; a = yes
test yflags,modoff ; is modeline still toggled off?
jnz quit1 ; nz = yes
call clrmod ; clear it before storing screen
quit1: nop
;******************
call savescr ; save screen in MS-DOS
;*******************
mov ax,0600h ; clear mode line with old attributes
mov bh,oldattr ; attributes
mov dx,low_rgt ; right most column
inc dh ; refer to status line
mov cx,dx ; bottom line [dlk]
xor cl,cl ; left most column
;**** Modify to suit CCDOS. June 25,1990 [zqf]
mov ax,cx
mov bx,dx
call atsclr
; int screen ; clear mode line
;****
mov ah,oldattr ; attributes at init time
mov scbattr,ah ; background = original state
; for ega in non-standard # lines
cmp ega_mode,0 ; ega board active?
je quit2 ; e = no
cmp byte ptr low_rgt+1,23 ; is screen standard length?
je quit2 ; e = yes, so regular cursor set is ok
push es ; turn off ega cursor emulation
mov ax,40h ; byte 40:87H is ega Info byte
mov es,ax
push es:[87h] ; save info byte around call
or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
mov cx,lincur ; cursor shape to set
mov ah,1 ; set the shape
int screen ; back to starting value
pop es:[87h] ; recover original Info byte
pop es ; and our work reg
jmp short quit3 ; skip regular mode cursor setting
quit2: ; for regular sized screen
mov cx,lincur ; cursor type at startup
mov ah,1
int screen ; restore cursor type
quit3: mov ah,2 ; Position cursor
mov bh,0 ; Page 0
mov dx,low_rgt ; bottom line
inc dh ; status line position
xor dl,dl ; left most column
; ---------don't set cursor in CCDOS. Dec.12,1990 [zqf]
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
cmp isccdos,1 ; is in CCDOS ?
je quit4 ; e = yes, skip
ENDIF
int screen ; Do it
quit4:
; -----------
mov al,yflags
and al,not lclecho ; don't copy host's echo flag
mov bx,argadr
mov ah,[bx].flgs ; get user's flag settings
and ah,lclecho ; clear all but local echo bit
or [bx].flgs,al ; update flags in arg block
ret
term endp
; put the character in al to the screen
outtty proc near
cmp flags.vtflg,0 ; emulating a terminal?
jne outnoc ; ne = yes, emulator handles printing
test flags.remflg,d8bit ; keep 8 bits for displays?
jnz outnp9 ; nz = yes, 8 bits if possible
and al,7fh ; remove high bit
outnp9: cmp rxtable+256,0 ; translation turned off?
je outnp7 ; e = yes, no translation
push bx
mov bx,offset rxtable ; address of translate table
xlatb ; new char is in al
pop bx
outnp7: test anspflg,prtscr ; should we be printing?
jz outnop ; no, keep going
call pntchr ; queue char for printer
jnc outnop ; nc = successful print
push ax
call beep ; else make a noise and
call trnprs ; turn off printing
pop ax
outnop: test yflags,capt ; capturing output?
jz outnoc ; no, forget this part
push ax ; save char
call captrtn ; give it captured character
pop ax ; restore character and keep going
outnoc: cmp vtroll,0 ; auto roll back allowed?
jz outnp6 ; z = no, leave screen as is
cmp tekflg,0 ; Tek mode active?
jne outnp6 ; ne = yes, skip screen rolling
cmp bwnd.lcnt,0 ; is screen rolled back? [dlk]
je outnp6 ; e = no
; ---------don't set cursor in CCDOS. Dec.12,1990 [zqf]
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
cmp isccdos,1 ; is in CCDOS ?
je outnpa ; e = yes, skip
ENDIF
call endwnd ; restore screen before writing [dlk]
outnpa:
; -----------
outnp6: cmp flags.vtflg,0 ; emulating a terminal?
jne outnop1 ; ne = yup, go do something smart
test yflags,trnctl ; debug? if so use Bios tty mode
jz outnp4 ; z = no
mov ah,biostty ; Bios tty screen write
cmp al,7fh ; Ascii Del char or greater?
jb outnp1 ; b = no
je outnp0 ; e = Del char
push ax ; save the char
mov al,7eh ; output a tilde for 8th bit
int screen
pop ax ; restore char
and al,7fh ; strip high bit
outnp0: cmp al,7fh ; is char now a DEL?
jne outnp1 ; ne = no
and al,3fH ; strip next highest bit (Del --> '?')
jmp outnp2 ; send, preceded by caret
outnp1: cmp al,' ' ; control char?
jae outnp3 ; ae = no
add al,'A'-1 ; make visible
outnp2: push ax ; save char
mov al,5eh ; caret
int screen ; display it
pop ax ; recover the non-printable char
outnp3: push ax
int screen
pop ax
ret
outnp4: cmp al,bell ; bell (Control G)?
jne outnp5 ; ne = no
jmp beep ; use short beep, avoid char loss
outnp5: mov dl,al ; write without intervention
mov ah,conout
int dos ; else let dos display char
ret
outnop1:cmp flags.vtflg,tttek ; doing Tektronix emulation?
je outnop2 ; e = yes, use Tek emulator
cmp tekflg,0 ; Tek submode active?
jne outnop2 ; ne = yes, use Tek emulator
jmp anstty ; call terminal emulator routine & ret
outnop2:jmp tekemu ; use Tek emulator and return
outtty endp
;[IU2] Here to output character to port with no echo (like escape sequences
; sent by PF keys, responses to requests from the host, etc. It is
; wrong thinking to echo these).
prtbout proc near ; Global routine now
mov ah,al ; This is where outchr expects it
call outchr
jmp endcon ; failure, end connection
nop
clc ; carry clear for success
ret
prtbout endp
;[IU2] Here to output an unsigned 8-bit number (in al) to the port without
; echoing. Used by terminal emulator escape sequence output.
prtnout proc near
mov bl,10 ; Output in base 10
jmp prtno2 ; Ensure at least a zero
prtno1: cmp al,0
jne prtno2 ; Yes - do more digits
ret ; No - return from recursive call
prtno2: mov ah,0 ; Clear previous remainder
div bl ; Divide off a digit
push ax ; Push remainder (in ah) on stack
call prtno1 ; Recur
pop ax ; Pop off a digit
add ah,'0' ; Make it ASCII
call outchr ; send to port
jmp endcon ; failure, end connection
nop
clc ; carry clear for success
ret
prtnout endp
; send the character in al out to the serial port; handle echoing.
; Can send an 8 bit char while displaying only 7 bits locally.
outprt proc near
test yflags,lclecho ; echoing?
jz outpr1 ; z = no, forget it
push ax ; save char
call outtty ; print it
pop ax ; restore
outpr1: mov ah,al ; this is where outchr expects it
call outchr ; output to the port
jmp endcon ; failure, end connection
nop
clc ; carry clear for success
ret
outprt endp
; Jump here to exit Connect mode and execute macros 'TERMINALR' (vtrmac) or
; 'TERMINALS' (vtsmac). Does nothing if macro does not exist.
; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
vtrmac proc near ; RESET macro
mov ax,offset vtrname ; select macro name
mov vtmacname,ax
mov vtmaclen,vtrlen ; and its length
jmp short vtmacro ; finish in common code
vtrmac endp
vtsmac proc near ; SET macro
mov ax,offset vtsname
mov vtmacname,ax
mov vtmaclen,vtslen
jmp short vtmacro
vtsmac endp
;
; Reference Macro structure for db number of entries (mac names)
; is file table mcctab |-> db length of macroname, excl '$'
; mssset.asm each entry |-> db 'macroname','$'
; where these |-> dw offset of definition string
; are stored.
; Definition string in db length of <string with null>
; buffer macbuf db 'string with trailing null'
;
vtmacro proc near ; common code for macros vtsmac,vtrmac
push bx
push cx
push si
mov bx,offset mcctab ; table of macro names
mov cl,[bx] ; number of names in table
xor ch,ch
jcxz vtmacx ; z = empty table, do nothing
inc bx ; point to length of first name
vtmac2: mov al,[bx] ; length of this name
xor ah,ah
cmp al,vtmaclen ; length same as desired keyword?
jne vtmac3 ; ne = no, search again
mov si,bx
inc si ; point at first char of name
push cx ; save name counter
push di ; save reg
mov cl,vtmaclen ; length of name, excluding '$'
xor ch,ch
mov di,vtmacname ; point at desired macro name
push es ; save reg
push ds
pop es ; make es use datas segment
cld
repe cmpsb ; match strings
pop es ; need current si below
pop cx
pop di ; recover saved regs
je vtmac4 ; e = matched
vtmac3: add bx,ax ; step to next name, add name length
add bx,4 ; + count, dollar sign, def word ptr
loop vtmac2 ; try next name
vtmacx: pop si ; no macro, return to Connect mode
pop cx
pop bx
ret
vtmac4: cmp taklev,maxtak ; room in Take level?
jge vtmacx ; ge = no, exit with no action
inc taklev ; increment take level
add takadr,size takinfo ; make a new Take entry/macro
mov bx,takadr ; point to current macro structure
inc si ; skip dollar sign after name
mov si,[si] ; get definition address
mov [bx].takbuf,si ; address of definition string struc
mov cl,[si] ; length byte of definition
xor ch,ch
mov [bx].takcnt,cx ; number of chars in definition
inc si ; address of definition text proper
mov [bx].takptr,si ; where to read next command char
mov [bx].taktyp,0ffh ; flag as a macro
pop si
pop cx
pop bx
jmp endcon ; exit Connect mode
vtmacro endp
; Error recovery routine used when outchr reports unable to send character
; or when vtmacro requests exiting Connect mode.
; Exit Connect mode cleanly, despite layers of intermediate calls.
endcon proc near
mov kbdflg,'C' ; report 'C' to TERM's caller
mov sp,oldsp ; recover startup stack pointer
; TERM caller's return address is now
; on the top of stack. A longjmp.
jmp quit ; exit Connect mode cleanly
endcon endp
;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
; These are invoked by a jump instruction. Return carry clear for normal
; processing, return carry set for invoking Quit (kbdflg has transfer char).
uparrw: mov al,'A' ; cursor keys
jmp short comarr
dnarrw: mov al,'B'
jmp short comarr
rtarr: mov al,'C'
test vtemu.vtflgop,vswdir ; writing left to right?
jz comarr ; z = yes
mov al,'D' ; reverse sense of keys
jmp short comarr
lfarr: mov al,'D'
test vtemu.vtflgop,vswdir ; writing left to right?
jz comarr ; z = yes
mov al,'C' ; reverse sense of keys
comarr: push ax ; save final char
mov ttyact,0 ; network, group chars for packet
mov al,escape ; Output an escape
call outprt ; Output, echo permitted
cmp flags.vtflg,tttek ; Tek terminal?
je comar0 ; e = yes, use VT100 codes
cmp flags.vtflg,ttvt100 ; VT100 terminal emulation?
jne comar2 ; No, do VT52/HEATH-19 sequence
comar0: call ansflg ; Update flags all around
mov al,'[' ; Maybe this next?
test ansflgs,decckm ; Cursor key mode reset?
je comar1 ; Yes, output the "["
mov al,'O' ; No, set, use the "O"
comar1: call outprt ; Output it (echo permitted)
comar2: pop ax ; recover final char
mov ttyact,1 ; network, restore tty active flag
call outprt ; Output to port (echo permitted)
ret
pf1: mov al,'P' ; keypad function keys 1-4
jmp short compf
pf2: mov al,'Q'
jmp short compf
pf3: mov al,'R'
jmp short compf
pf4: mov al,'S'
compf: push ax ; save final char
mov ttyact,0 ; network, group chars for packet
mov al,escape ; Output an escape
call prtbout
call ansflg ; get emulator flags
test ansflgs,decanm ; ansi mode?
jz short compf1 ; z = no
mov al,'O' ; send an "O"
call prtbout ; Output it
compf1: pop ax ; Get the saved char back
mov ttyact,1 ; network, restore tty active flag
call prtbout ; Output to port
ret
kp0: mov al,'p' ; keypad numeric keys
jmp short comkp
kp1: mov al,'q'
jmp short comkp
kp2: mov al,'r'
jmp short comkp
kp3: mov al,'s'
jmp short comkp
kp4: mov al,'t'
jmp short comkp
kp5: mov al,'u'
jmp short comkp
kp6: mov al,'v'
jmp short comkp
kp7: mov al,'w'
jmp short comkp
kp8: mov al,'x'
jmp short comkp
kp9: mov al,'y'
jmp short comkp
kpminus:mov al,'m'
jmp short comkp
kpcoma: mov al,'l'
jmp short comkp
kpenter:mov al,'M'
jmp short comkp
kpdot: mov al,'n'
comkp: test ansflgs,deckpam ; keypad application mode active?
jnz comkp3 ; nz = yes, use escape sequences
sub al,40h ; deduct offset to numeric symbols
jmp comkp0 ; and send that single char
comkp3: push ax ; save final char
mov ttyact,0 ; network, group chars for packet
mov al,escape ; Output an escape
call prtbout
mov al,'O' ; Output the "O"
cmp flags.vtflg,ttvt100 ; VT100 mode?
je comkp1 ; e = yes, use "O" code
cmp flags.vtflg,tttek ; Tek terminal
je comkp1 ; e = yes, use VT100 codes
test ansflgs,decanm ; ANSI (alt application keypad) mode?
jnz comkp1 ; nz = yes, use "O"
comkp2: mov al,'?' ; else use "?" instead of "O"
comkp1: call prtbout
pop ax ; recover final char
comkp0: mov ttyact,1 ; network, restore tty active flag
call prtbout ; send it
ret
klogon proc near ; resume logging (if any)
test flags.capflg,logses ; session logging enabled?
jz klogn ; z = no, forget it
or argadr.flgs,capt ; turn on capture flag
or yflags,capt ; set local msy flag as well
call ansflg ; tell emulator
klogn: clc
ret
klogon endp
klogof proc near ; suspend logging (if any)
and argadr.flgs,not capt ; stop capturing
and yflags,not capt ; reset local msy flag as well
call ansflg ; tell emulator
klogo: clc
ret
klogof endp
snull proc near ; send a null byte
mov al,0 ; the null
jmp prtbout ; send without logging and local echo
snull endp
khold: xor holdscr,1 ; toggle Hold screen byte for msx
clc
ret
; general character out for emulator
chrout: cmp flags.vtflg,0 ; emulating?
je chrou5 ; e = no
call anskbi ; Yes, say we had keyboard input
cmp al,cr ; A CR?
jne chrou5 ; No - just output it and return
call ansflg ; Yes - update VT100 flags
test ansflgs,anslnm ; ANSI new-line mode set?
jz chrou5 ; No - just send the cr
call outprt ; Yes - output a carriage-return
mov al,lf ; Followed by a line feed
chrou5: call outprt
ret
; these commands invoke Quit
cdos: mov al,'P' ; Push to DOS
jmp short cmdcom
cstatus:mov al,'S' ; Status
jmp short cmdcom
cquit: mov al,'C' ; Exit Connect mode
jmp short cmdcom
cquery: mov al,'?' ; Help
jmp short cmdcom
chang: mov al,'H' ; Hangup, drop DTR & RTS
jmp short cmdcom
cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
stc ; signal that Quit is needed
ret
dmpscn proc near ; dump screen to file
call savescr ; save screen to buffer
call dumpscr ; do buffer to file
clc ; do not exit Connect mode
ret
dmpscn endp
;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
vtans52 proc near
cmp flags.vtflg,0 ; emulating?
je vtans5 ; e = no
call ans52t ; Call MSZ toggle-it routine
call ansflg ; Update flags
clc ; clear c bit so don't exit Connect
vtans5: ret
vtans52 endp
; Toggle Mode Line
trnmod: cmp flags.modflg,1 ; mode line enabled and owned by us?
jne trnm2 ; ne = no, don't touch it
cmp flags.vtflg,tttek ; Tek mode?
je trnm2 ; yes
cmp tekflg,0 ; Tek submode?
jne trnm2 ; ne = yes, no mode line changes
test yflags,modoff ; mode line already off?
jnz trnm1 ; yes, go turn on
call clrmod ; no, clear mode line here
or yflags,modoff ; turn on flag
call ansflg ; Update flags all around
clc ; clear c bit so don't exit Connect
ret
trnm1: and yflags,not modoff ; Clear flag first
cmp flags.vtflg,0 ; terminal type of none?
ja trnm3
push dx ; scroll screen to save bottom line
mov ah,prstr ; for terminal type none
mov dx,offset crlf
int dos
pop dx
trnm3: call modlin ; Then turn on mode line
call ansflg ; Update flags all around
trnm2: clc
ret
trnprs: push ax ; toggle ^ PrtSc screen to printer
test anspflg,prtscr ; are we currently printing?
jnz trnpr2 ; nz = yes, its on and going off
mov ah,ioctl
mov al,7 ; get output status of printer
push bx
mov bx,4 ; file handle for system printer
int dos
pop bx
jc trnpr1 ; c = printer not ready
cmp al,0ffh ; Ready status?
je trnpr2 ; e = Ready
trnpr1: call beep ; Not Ready, complain
jmp trnpr3 ; and ignore request
trnpr2: xor anspflg,prtscr ; flip the flag
test yflags,modoff ; mode line off?
jnz trnpr3 ; nz = yes
call modlin ; else rewrite mode line
trnpr3: pop ax
clc ; return carry clear (don't quit)
ret
; Print on PRN the char in register al. On success return with C bit clear.
; On failure do procedure pntchk and return its C bit (typically C set).
; Uses buffer dumpbuf (screen dump).
pntchr proc near
push bx ; buffer the character
mov bx,pntptr ; offset of next free byte in buffer
mov [bx],al ; store the character
inc bx ; update pointer
mov pntptr,bx ; save pointer
cmp bx,offset dumpbuf+dumplen ; buffer full yet?
pop bx
jb pntchrx ; b = no, just return
jmp pntflsh ; go flush the buffer
pntchrx:clc ; clear carry bit
ret
pntchr endp
; Flush printer buffer. Return carry clear if success.
; On failure do procedure pntchk and return its C bit (typically C set).
; Uses buffer dumpbuf (screen dump).
pntflsh proc near
cmp pntptr,offset dumpbuf ; any text in buffer?
jne pntfls1 ; ne = yes
ret ; else nothing to do
pntfls1:push ax
push bx
push cx
push dx
mov bx,portval
mov bx,[bx].flowc ; get flow control chars (bl=xoff)
mov flowon,bh
mov flowoff,bl ; save for later
mov al,bl ; get flow control char
cmp al,0 ; flow control active?
je pntfls2 ; e = no, not using xoff
call prtbout ; output xoff (al), no echo
pntfls2:mov ah,write2
mov bx,4 ; file handle for DOS printer PRN
mov cx,pntptr ; next free byte in buffer
mov dx,offset dumpbuf ; start of buffer
mov pntptr,dx ; reset buffer pointer
sub cx,dx ; cx = current byte count
jcxz pntfls3 ; z = empty, do nothing
int dos ; write buffer to printer
pntfls3:pushf ; save carry status bit
mov al,flowon
cmp al,0 ; flow control active?
je pntfls4 ; e = no, not using xon
call prtbout ; output xon (al), no echo
pntfls4:popf
pop dx
pop cx
pop bx
pop ax
jnc pntflsx ; nc = success
call pntchk ; c = error (printer not ready)
pntflsx:ret
pntflsh endp
; Check for PRN (DOS's printer) being ready. If ready, return with C clear
; Otherwise, write Not Ready msg on mode line and return with C bit set.
; N.B. DOS Critical Error will occur here if PRN is not ready. [jrd]
pntchk proc near
push dx
push cx
push ax
mov cx,10 ; ten retries before declaring error
pntchk0:mov ah,ioctl ; get printer status, via DOS
mov al,7 ; status for output
push bx
mov bx,4 ; std handle for DOS system printer
int dos
pop bx
jc pntchk1 ; c = call failed
cmp al,0ffh ; code for Ready?
je pntchk3 ; e = yes, assume printer is ready
pntchk1:push cx ; save counter, just in case
mov ax,100 ; wait 100 millisec
call pcwait
pop cx
loop pntchk0 ; and try a few more times
; get here when printer is not ready
test yflags,modoff ; is mode line off?
jnz pntchk2 ; nz = off, skip msg
push bx
push si
; mov si,offset pntmsg ; say printer not ready
mcmsgsi pntmsg, cpntmsg
mov cx,pntmsgl ; length
cmp isccdos,0
je pntchk11
mov cx,cpntmsgl
pntchk11:
call modwrt ; write alternate mode line
pop si
pop bx
pntchk2:pop ax
pop cx
pop dx
stc ; say printer not ready
ret
pntchk3:pop ax
pop cx
pop dx
clc ; say printer is ready
ret
pntchk endp
;;;;; General screen management routines for IBM PC
; computes screen location to ax, given row and col in [dh,dl], resp.
scrloc proc near
mov al,dh ; get row
mul crt_cols ; multiply by number of columns
add al,dl ; plus current column number
adc ah,0 ; ripple carry
shl ax,1 ; double for attributes
ret
scrloc endp
; Routine to set cursor type. Pass cursor type in al: 0 = No cursor,
; 1 = Underline cursor, 2 = Block cursor. All cursors blink due to hardware.
; Routine frags any ac that video ints frag.
; For EGA boards running in non-25 line mode the cursor emulation is turned
; off during cursor shape changing and restored afterward. It's another
; ega Feature. [jrd]
; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
csrtype proc near
push cx ; save the reg
mov ah,1 ; Video fxn for set cursor type
mov cx,0F00H ; Assume no cursor
cmp al,0 ; No cursor?
je csrty2 ; Right - set it and be done with it
cmp crt_mode,7 ; B&W card?
je csrty3 ; Yes - different sizes
cmp crt_mode,18h ; Tseng UltraPAK mono board?
je csrty3 ; e = yes, use mono cursor
mov cx,0607H ; No, use CGA underline cursor
cmp al,2 ; Block?
jne csrty2 ; No - set it now
csrty1: xor ch,ch ; Yes - make it a block
csrty2: cmp ega_mode,0 ; ega board active?
je csrty4 ; e = no
cmp byte ptr low_rgt+1,23 ; standard screen length?
je csrty4 ; e = yes, use regular cursor setting
push es ; EGA. turn off cursor emulation
mov ax,40h ; 40:87h is ega Info byte
mov es,ax
push es:[87h] ; save Info byte around call
or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
mov ah,1 ; Video fxn for set cursor type
int screen
pop es:[87h] ; restore Info byte
pop es ; and our work register
pop cx
ret
csrty4: int screen ; regular cursor shape setting
pop cx
ret
csrty3: mov cx,0B0CH ; Assume B&W underline cursor
cmp al,2 ; Block?
jne csrty2 ; No - set it now
jmp csrty1 ; Yes - make it a block
csrtype endp
; Save the entire screen in a buffer so we can restore and/or dump it.
; Saves regular (80x25) screens to memory buffer scrsav and other sized
; screens to video memory page 1. Resultant save place put into savadr
; (offset then segment) and current low_rgt size info in savflg. Note,
; some Environments (TopView/Windows etc) may not permit use of page 1. [jrd]
savescr proc near
push es
push ds
push ax
push cx
push si
push di
; ****************** if in CC-DOS mode? Nov.1990 [zqf]
cmp isccdos,1 ; if CC-DOS ?
jne savsc0 ; ne = No.
IFNDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
call savccscr ; yes, call CCDOS screen save proc
ENDIF
jmp savsc4 ; return
savsc0:
; **********************
call scrseg ; get screen segment in ax and es:di
push ax ; save screen segment
mov si,0
mov di,scrsav ; place to put screen (memory buff)
mov savadr+2,di ; working seg address for restore
mov savadr,0 ; and no offset for memory buffer
call scrmod ; ascertain video mode and screen
mov ax,low_rgt ; text screen lower right (typ 23,79)
mov savflg,ax ; save it for screen restore
inc al ; number of columns
add ah,2 ; plus status line = number of rows
cmp al,swidth ; same as preset screen space (80)?
ja savsc1 ; a = no, use screen video page 1
cmp ah,slen+1 ; same as preset screen length (24)?
je savsc3 ; e = yes, use our memory buffer
savsc1: mul ah ; times rows = characters on screen
shl ax,1 ; times two for attributes = page 1
mov cx,ax ; cx = working copy of screen size
and cx,000fh ; get lower four bits for offset part
mov savadr,cx ; save offset in this word
mov cl,4
shr ax,cl ; compute number of paragraphs
pop di ; source screen address
push di ; restore again
add di,ax ; add paragraphs, point di to page 1
mov savadr+2,di ; and save segment in this word
savsc3:
mov es,savadr+2 ; segment of storage area
mov di,savadr ; offset of same
mov ax,low_rgt ; lower right of text screen
inc al ; number of columns on screen
add ah,2 ; number of rows on screen
mul ah ; number of characters on the screen
mov cx,ax ; save this in counter cx
call scroff ; turn off screen [dt]
pop ds ; address screen
cld
rep movsw ; save the screen
savsc4:
pop di
pop si
pop cx
pop ax
pop ds ; restore this
call scron ; turn on screen [dt]
pop es
ret
savescr endp
; restore screen from buffer (offset and seg in savadr, text coord in savflg).
; Restores all screen lines. [jrd]
restscr proc near
; ****************** if in CC-DOS mode? Nov.1990 [zqf]
cmp isccdos,1 ; if CC-DOS ?
jne rstscr0 ; ne = No.
IFNDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
call rstccscr ; yes, call CCDOS screen restore proc
ENDIF
ret ; return
rstscr0:
; **********************
push es
mov ax,savflg ; saved low_rgt text screen coord
add ah,2 ; number of screen lines
inc al ; number of screen columns
mul ah ; columns time lines = # characters
mov cx,ax ; save this in counter cx
push cx ; save count
call scrseg ; get address of screen in es:di
call scroff ; turn off screen [dt]
push ds ; save original data segment
mov si,savadr ; offset of storage area
push savadr+2 ; segment of same
pop ds ; put storage segment into ds
cld
rep movsw ; restore data to screen
pop ds ; recover original data segment
call scron ; turn on screen [dt]
pop cx ; recover count
call scrsync ; synch Topview with new screen
pop es
ret
restscr endp
;**************************** used in CC-DOS Nov.28,1990 [zqf]
; SAVCCSCR ---- called by <savescr> of module "ccyibm.asm".
; which save screen char & attr in buffer pointed
; by scrsav in CC-DOS. Nov 28,1990 [zqf]
; All registers are reserved.
;********************************
SAVCCSCR proc near
push ax
push bx
push cx
push dx
push di
push es
mov ax,scrsav ; buffer segment address, offset is zero
mov es,ax
mov di,0
mov savadr+2,es
mov savadr,di
; read current cursor
mov bh,0
mov ah,3
int 10h ; read current cursor pos. & type.
mov curpos,dx ; saved in <curattr>
mov curtyp,cx ;
; save screen
mov bh,0
mov dx,0
savccscr1: mov ah,2
int 10h ; set cursor position <DH,DL>---<row,col>
mov ah,8
int 10h ; read char & attr in current cursor pos.
mov es:[di],ax ; save in scrbuf
inc dl
cmp dl,crt_cols ; crt_cols:number of screen cols (typ 80)
jl savccscr2
mov dl,0
inc dh
cmp dh,crt_lins ; crt_lins:number of rows-1 (typ 24)
jg savccscr3
savccscr2:
inc di
inc di
jmp savccscr1
savccscr3:
pop es
pop di
pop dx
pop cx
pop bx
pop ax
ret
SAVCCSCR endp
;*******************************
;**************************** used in CC-DOS Nov.28,1990 [zqf]
; RSTCCSCR ---- called by <restscr> of module "ccyibm.asm".
; which restore screen char & attr in buffer pointed
; by savadr in CC-DOS. Nov 28,1990 [zqf]
; All registers are reserved.
;********************************
RSTCCSCR proc
push ax
push bx
push cx
push dx
push di
push es
mov ax,savadr+2 ; segment address of buffer
mov es,ax
mov di,savadr ; offset address of buffer
; restore screen
mov bh,0
mov dx,0
rstccscr1:mov ah,2
int 10h ; set cursor position <DH,DL>---<row,col>
mov ax,es:[di] ; restore from scrbuf
mov bl,ah
mov cx,1
mov ah,9
int 10h ; write char & attr in current cursor pos.
inc dl
cmp dl,crt_cols ; crt_cols:number of screen cols (typ 80)
jl rstccscr2
mov dl,0
inc dh
cmp dh,crt_lins ; crt_lins:number of rows-1 (typ 24)
jg rstccscr3
rstccscr2:
inc di
inc di ; adjust pointer
jmp rstccscr1
rstccscr3:
; set original cursor pos &type
mov bh,0
mov cx,curtyp
mov ah,1
int 10h ; build cursor type
mov bh,0
mov dx,curpos
mov ah,2
int 10h ; set original cursor pos.
pop es
pop di
pop dx
pop cx
pop bx
pop ax
ret
RSTCCSCR 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 reads the screen image saved by savescr so call savescr call first.
dumpscr proc near
push ax
push bx
push cx
push dx
mov dmphand,-1 ; preset illegal handle
mov dx,offset dmpname ; name of disk file, from mssset
mov ax,dx ; where isfile wants name ptr
call isfile ; what kind of file is this?
jc dmp5 ; c = no such file, create it
test byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
jnz dmp0 ; nz = no.
mov al,1 ; writing
mov ah,open2 ; open existing file
int dos
jc dmp0 ; c = failure
mov dmphand,ax ; save file handle
mov bx,ax ; need handle here
mov cx,0ffffh ; setup file pointer
mov dx,-1 ; and offset
mov al,2 ; move to eof minus one byte
mov ah,lseek ; seek the end
int dos
jmp dmp1
dmp5: test filtst.fstat,80h ; access problem?
jnz dmp0 ; nz = yes
mov ah,creat2 ; file did not exist
mov cx,20h ; attributes, archive bit
int dos
mov dmphand,ax ; save file handle
jnc dmp1 ; nc = ok
dmp0: mov ah,3 ; get cursor position
xor bx,bx ; page 0
int screen
push dx ; save it
mov dh,byte ptr low_rgt+1 ; go to status line
inc dh
xor dl,dl ; left most column
mov ah,2 ; position cursor
int screen
; mov dx,offset dmperr ; say no can do
mcmsg dmperr, cdmperr
mov ah,prstr
int dos
pop dx ; get original cursor position
mov ah,2 ; position cursor
xor bx,bx ; page 0
int screen
pop dx
pop cx
pop bx
pop ax
clc
ret
dmp1: mov ah,ioctl ; is destination ready for output?
mov al,7 ; test output status
mov bx,dmphand ; handle
int dos
jc dmp0 ; c = error
cmp al,0ffh ; ready?
jne dmp0 ; ne = not ready
push di ; read screen buffer, write lines
push si
push es
mov cl,byte ptr low_rgt+1 ; number of lines - 2
add cl,2 ; number of line on screen
xor ch,ch
mov si,savadr ; offset in storage area
dmp2: push cx ; save outer loop counter
mov es,savadr+2 ; get storage segment
mov di,offset dumpbuf ; data segment memory
mov cl,byte ptr savflg ; number of columns on screen - 1
inc cl ; number of columns on screen
xor ch,ch
dmp3: mov ax,word ptr es:[si] ; read char + attribute
mov byte ptr [di],al ; store just char, don't use es:
inc si ; update pointers
inc si
inc di
loop dmp3 ; do for each column
std ; set scan backward
mov cl,byte ptr savflg ; number of columns on screen - 1
inc cl ; number of columns on screen
xor ch,ch
push es
mov ax,ds
mov es,ax ; set es to data segment for es:di
mov di,offset dumpbuf ; start of line
add di,cx ; plus length of line
dec di ; minus 1 equals end of line
mov al,' ' ; thing to scan over
repe scasb ; scan until non-space
cld ; set direction forward
pop es
jz dmp3a ; z = all spaces
inc cx
inc di
dmp3a: mov word ptr [di+1],0A0Dh ; append cr/lf
add cx,2 ; line count + cr/lf
mov dx,offset dumpbuf ; array to be written
mov bx,dmphand ; need file handle
mov ah,write2 ; write the line
int dos
pop cx ; get line counter again
jc dmp3b ; c = error
loop dmp2 ; do next line
mov dx,offset dumpsep ; put in formfeed/cr/lf
mov cx,3 ; three bytes overall
mov ah,write2 ; write them
dmp3b: mov bx,dmphand ; file handle
int dos
mov ah,close2 ; close the file now
int dos
dmp6: pop es
pop si
pop di
pop dx
pop cx
pop bx
pop ax
clc
ret
dumpscr endp
; Get CRT mode - returns mode in variable crt_mode,
; updates crt_cols and low_rgt.
; For EGA active it looks in Bios work memory 40:84H for number of rows. [jrd]
scrmod proc near
push ax
push dx
mov ah,15 ; Get current video state
int screen
mov crt_mode,al ; Store CRT mode value
mov crt_cols,ah ; store # of cols
mov dl,ah ; # of cols again
mov dh,crt_lins ; and # of rows (constant from msster)
cmp ega_mode,0 ; ega active?
je scrmod4 ; e = no
push es ; yes, permit different lengths
mov ax,40h ; refer to 40:84h for # ega rows
mov es,ax
mov ah,es:[84h] ; get number of rows - 1 (typ 24)
cmp ah,20 ; less than 20 rows?
jb scrmod3 ; b = yes, ignore this length
cmp ah,80 ; more than 80 rows?
ja scrmod3 ; a = yes, ignore this length
mov dh,ah ; use this length
mov crt_lins,dh ; update our working constant
scrmod3:pop es
scrmod4:dec dl ; max text column, count from zero
dec dh ; max text row, count from zero
mov low_rgt,dx ; save away window address
pop dx
pop ax
ret
scrmod endp
; Get screen segment - returns screen segment in ax, and full address in es:di
scrseg proc near
xor di,di ; start at beginning of screen (0,0)
mov ax,0B000H ; Assume B&W card
cmp crt_mode,7 ; Is it?
je scrse1 ; e = yes
cmp crt_mode,18h ; Tseng UltraPAK mono in 132 col?
je scrse1 ; e = yes, use seg B000H
mov ax,0B800H ; No - video memory is here on color
cmp crt_mode,12 ; graphics set?
jb scrse1 ; b = no
cmp crt_mode,18 ; end of ordinary 640x480 graphics
ja scrse1 ; a = no, assume CGA segment
mov ax,0A000H ; graphics
scrse1: mov es,ax ; tell Topview our hardware address needs
mov tv_segs,es ; save our hardware screen address
mov tv_sego,di ; segment and offset form
mov tv_mode,1 ; assume we're running under Topview
mov ah,tvhere ; query Topview for its presence
int screen
mov ax,es ; get its new segment for screen work
cmp ax,tv_segs ; same as hardware?
jne scrse2 ; ne = no, we are being mapped
cmp di,tv_sego ; check this too
jne scrse2 ; ne = no too. Use TV's work buf as screen
mov tv_mode,0 ; else no Topview or no mapping
scrse2: mov tv_segs,es ; save segment
mov tv_sego,di ; and offset
ret
scrseg endp
; Synchronize a Topview provided virtual screen buffer with the image
; seen by the user. Requires cx = number of words written to screen
; (char & attribute bytes) and es:di = ENDING address of screen write.
; Changes ax and di.
scrsync proc near
cmp tv_mode,0 ; Topview mode active?
je scrsyn1 ; e = no, skip DOS call below
sub di,cx ; backup to start byte (cx = words)
sub di,cx ; after storing words to screen
mov ah,tvsynch ; tell Topview we have changed screen
int screen ; so user sees updated screen
scrsyn1:ret
scrsync endp
; The following two routines are used to turn off the display while we
; are reading or writing the screen in one of the color card modes.
; Turn screen off for (known) color card modes only. All regs preserved.
; Includes code for old procedure scrwait. 16 June 1987 [jrd]
scroff proc near
cmp refresh,0 ; slow refresh?
jne scrofx ; ne = no wait
cmp ega_mode,0 ; Extended Graphics Adapter in use?
jne scrofx ; ne = yes, no waiting
cmp tv_mode,0 ; Topview mode?
jne scrofx ; ne = yes, no waiting
cmp crt_mode,7 ; B&W card?
jnb scrofx ; Yes - just return
push ax ; Save ax and dx
push dx
mov dx,crt_status ; CGA: Wait for vertical retrace
scrof1: in al,dx
test al,disp_enb ; display enabled?
jnz scrof1 ; yes, keep waiting
scrof2: in al,dx
test al,disp_enb ; now wait for it to go off
jz scrof2 ; so can have whole cycle
mov dx,crtmset ; Output to CRT mode set port
mov al,25H ; This shuts down the display
out dx,al ; Dumb, but card is too
pop dx ; restore regs
pop ax
scrofx: ret
scroff endp
; Turn screen on for (known) color card modes only
; All registers are preserved.
scron proc near
cmp refresh,0 ; slow refresh?
jne scronx ; ne = no wait
cmp ega_mode,0 ; Extended Graphics Adapter in use?
jne scronx ; ne = yes, no waiting
cmp tv_mode,0 ; Topview mode?
jne scronx ; ne = yes, no waiting
cmp crt_mode,7 ; B&W card?
jnb scronx ; Yes - just return
push ax ; Save ax, dx, and si
push dx
push si
mov al,crt_mode ; Convert crt_mode to a word
xor ah,ah
mov si,ax ; Get it in a usable register
mov al,msets[si] ; Fetch the modeset byte
mov dx,crtmset ; This port
out dx,al ; Flash it back on
pop si ; restore regs
pop dx
pop ax
scronx: ret
scron endp
; Screen clearing routine. [IU]
;
; Call: ax/ coordinates of first screen location to be cleared.
; bx/ coordinates of last location to be cleared.
; Coord: ah = row [0-24], al = column [0-79]. Preserves all registers. [jrd]
atsclr: push ax ; save regs
push cx
push dx
CALL PATSCLR ; CALL PROC TO CLEAR LINE
mov dx,bx ; Compute last screen offset in ax
push ax
call scrmod ; update column length
pop ax ; scrmod zaps ax
push ax
call scrloc ; get screen start address in ax
mov cx,ax ; Save it in cx for a minute
pop dx ; Compute first screen offset in ax
call scrloc
sub cx,ax ; Compute number of locs to clear
add cx,2
sar cx,1 ; Make byte count a word count
jle atscl2 ; If nothing to clear, then vamos
push di ; save regs
push es ; save es
push ax ; save around call
call scrseg ; Get address of screen in ax, es:di
pop ax ; recover displacement
add di,ax ; displacement memory address
mov ah,scbattr ; Use current screen background attr
mov al,' ' ; Use space for fill
mov dl,byte ptr low_rgt ; line length - 1
inc dl ; line length
xor dh,dh
;;;;; cmp cx,dx ; Blanking a line or less??
;;;;; jg atscl1 ; No - make scroff disable display
atscl1:
; call scroff ; Turn screen off if color card
push cx ; save word count for Topview
cld
; rep stosw ; Blit... (excuse PDP-10ese please)
pop cx ; recover word count
; call scrsync ; synch Topview
; call scron ; Turn screen back on if color card
pop es ; Restore segment register
pop di ; And destination index
atscl2: pop dx ; restore regs
pop cx
pop ax
ret
; Screen clearing routine.Ver 2.00 Dec. 15,1989 [ZU]
; (Screen clearing by scroll whole bolck between <ah,al> and <bh,bl>
; Call ax/ corrdinates of upon left location to be cleared.
; <ah,al>--<row,col>
; bx/ corrdinates of down right location to be cleared.
; <bh,bl>--<row,col>
; Cord: ah=row [0-24], al = col [0-79]. Preserves all registers. [zqf]
patsclr proc near
push ax
push bx
push cx
push dx
push si
push di
; check if clear block or a line ?
cmp bh,ah
jg patsclr_b ; le= clear a block more than one line
; clear a block in one line
; read screen mode
patsclr_l:
push ax
push bx
mov ah,15 ;state
int video
mov activepage,bh
; mov cols,ah
pop bx
pop ax
; save current cursor
push ax
push bx
mov bh,activepage
mov ah,readcur
int video
mov currow,dh
mov curcol,dl
mov curtype,cx
pop bx
pop ax
; compute number of chars to clear in cx
push ax
xor cx,cx
mov dx,0
patscl1: cmp bh,ah
jle patscl2
mov dl,80 ;cols
sub dl,al
add cx,dx
xor al,al
inc ah
jmp patscl1
patscl2: cmp bl,al
jl patscl3
sub bl,al
mov bh,0
add cx,bx
inc cx
patscl3: pop ax
cmp cx,0
jle patscl10
; set cursor at start location of clearing area
mov dx,ax
mov bh,activepage
mov ah,setcur
int video
; clear screen < CX__number of chars >
mov al,' ' ;space
mov bh,activepage
mov bl,scbattr
; mov ah,writech ; ????? different with 'writeach'
mov ah,writeach
int video
; restore current cursor
mov dh,currow
mov dl,curcol
mov bh,activepage
mov ah,setcur
int video
patscl10:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
; scroll window at location <ah,al> to <bh,bl>
patsclr_b:
mov cx,ax
mov dx,bx
mov bh,scbattr
mov al,0
mov ah,06h
int video
jmp patscl10
patsclr endp
; Scrolling routines. vtscru scrolls up, vtscrd scrolls down 'scroll'
; rows. The top line is saved in the circular buffer before scrolling up.
; When running under an Environment control number of line positions moved
; to be less than scrolling region. [jrd]
; All registers are preserved.
; Screen-roll down. Move text down one line, for terminal emulator only.
vtscrd: push ax ; Upgraded by [jrd]
push bx
push cx
push dx
mov ah,7 ; scroll down
mov ch,mar_top ; top margin line
mov cl,0 ; left most column
mov dh,mar_bot ; bottom margin line
mov dl,byte ptr low_rgt ; right most column
mov bh,scbattr ; attributes
mov bl,dh
sub bl,ch ; region size - 1 line
mov al,scroll ; number of lines to scroll, from msz
vscrd1: cmp al,bl ; want to scroll more that than?
jbe vscrd2 ; be = no
push ax
mov al,bl ; limit to region-1 for Windows
int screen ; and do in parts
pop ax
sub al,bl ; get remainder
jmp short vscrd1 ; do next part
vscrd2: int screen ; scroll it down
pop dx
pop cx
pop bx
pop ax
ret
; Screen scroll up one line (text moves up) for terminal emulator use.
; When running under an Environment control number of line positions moved
; to be less than scrolling region. [jrd]
vtscru: push ax ; Upgraded by [jrd]
push bx
push cx
push dx
mov cl,scroll ; number of lines to scroll
mov ch,0
cmp cx,0
jnz vscru0
jmp vscru3 ; z = nothing to do
vscru0:
cmp mar_top,0 ; scrolling the top screen line?
ja vscru2 ; a = no. don't save anything
push si
push di
;******** test for CCDOS. Dec.12,1990 [zqf]
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
cmp isccdos,1 ; if CCDOS ?
je vscru1a ; e = yes, in CCDOS, skip
ENDIF
call scroff ; turn off color screen
mov si,tv_sego ; screen offset for es:si
mov bx,offset twnd ; put lines in top window buffer
vscru1: push cx ; save count
call putcirc ; put screen line in circular buffer
pop cx
loop vscru1 ; save 'scroll' number of lines
call scron ; turn on screen again
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
vscru1a:
ENDIF
;********
pop di
pop si ; now scroll the visible screen
vscru2: mov ah,6 ; scroll up
mov dh,mar_bot ; bottom row
mov dl,byte ptr low_rgt ; right most column
mov ch,mar_top ; top row of scrolling region
mov cl,0 ; left most column
mov bh,scbattr ; attributes
mov bl,dh
sub bl,ch ; region size - 1 line
mov al,scroll ; number of lines to scroll, from msz
vscru2a:cmp al,bl ; want to scroll more that than?
jbe vscru2b ; be = no
push ax
mov al,bl ; limit to region - 1 for Windows
;******** test for CCDOS. Dec.12,1990 [zqf]
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
cmp isccdos,1 ; if CCDOS ?
je vscru2c ; e = yes, in CCDOS, skip
ENDIF
int screen ; and do in parts
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
jmp vscru2d ; in MSDOS
vscru2c:
push dx
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
pop dx
vscru2d:
ENDIF
;********
pop ax
sub al,bl
jmp short vscru2a ; do next part
vscru2b:
;******** test for CCDOS. Dec.12,1990 [zqf]
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
cmp isccdos,1 ; if CCDOS ?
je vscru2e ; e = yes, in CCDOS, skip
ENDIF
int screen ; and do in parts
IFDEF CGA ; Add Option CGA to servered screen.Mar.21,1991 [zqf]
jmp vscru2f ; in MSDOS
vscru2e:
push dx
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
pop dx
vscru2f:
ENDIF
;********
vscru3: pop dx ; Restore the rest of the regs
pop cx
pop bx
pop ax
ret
;screen text roll up, version for manual scrolling only
mscru: push ax ; Upgraded by [jrd]
push bx
push cx
push dx
push si
push di
cmp bwnd.lcnt,0 ; any lines in bottom window?
je mscru2 ; e = no, so ignore request
call scroff ; turn off color screen
mov bx,offset twnd ; this is where it goes
mov si,tv_sego ; screen offset for es:si
call putcirc ; put screen line in circular buffer
mov ax,601H ; scroll up one line
mov dx,low_rgt ; lower right corner
xor cx,cx ; top row of scrolling region
mov bh,scbattr ; background attributes
int screen ; scroll up that region
mov dx,low_rgt
mov dl,0 ; location is lower left corner
call scrloc ; get count from display start
mov di,ax
push es
mov bx,tv_segs ; get screen's segment into, es:di
mov es,bx ; segment
add di,tv_sego ; destination memory address (es:di)
mov bx,offset bwnd ; source of lines
call getcirc ; get line from circ buf to screen
pop es ; restore es
call scron ; turn on the screen
mscru2: pop di ; Restore the rest of the regs
pop si
pop dx
pop cx
pop bx
pop ax
ret
;screen text scroll down, for manual mode only
mscrd: push ax ; Upgraded by [jrd]
push bx
push cx
push dx
push si
push di
cmp twnd.lcnt,0 ; any lines left in top window?
je mscrd1 ; e = no, ingore request
call scroff ; turn off screen
mov dx,low_rgt ; from screen location, row
mov dl,0 ; starting in col 0
call scrloc ; get offset in display buffer in ax
mov si,tv_sego ; screen offset for es:di
add si,ax ; source addr in display buffer es:si
mov bx,offset bwnd ; buffer to use (bottom window)
call putcirc ; copy bottom screen line to circ buf
mov ax,701H ; scroll down one line
xor cx,cx ; top left corner
mov dx,low_rgt ; bottom right corner
mov bh,scbattr ; attributes
int screen ; scroll it down
push es
mov di,tv_segs ; screen segment
mov es,di
mov di,tv_sego ; screen offset, for es:di
mov bx,offset twnd ; buffer to use (top window)
call getcirc ; copy from circ buf to screen
pop es
call scron ; turn on display again
mscrd1: pop di ; Restore the rest of the regs
pop si
pop dx
pop cx
pop bx
pop ax
ret
; move viewing window down as much as possible (text moves up)
endwnd proc near ; go to end of scrolling text
push cx
mov cx,bwnd.lcnt ; all bottom window lines [dlk]
jmp dnwp0 ; and enter dwnpg
endwnd endp
dnone proc near ; move text up one line [jrd]
push cx
mov cx,1
jmp dnwp0
dnone endp
; scroll viewing window down (text moves up) one page (24 lines)
dnwpg proc near
push cx
mov cl,byte ptr low_rgt+1 ; number of rows, excl status
inc cl ; count from 1, not 0
mov ch,0
dnwp0: ; additional entry point
cmp bwnd.lcnt,cx ; enough lines in bottom line buffer?
jge dnwp1 ; ge = we have that many lines stored
mov cx,bwnd.lcnt ; do as many as we have
dnwp1: jcxz dnwp2 ; z = nothing to do
cmp tekflg,0 ; Tek mode active?
jne dnwp2 ; ne = yes, no scrolling
call mscru ; scroll up text one line
loop dnwp1
dnwp2: pop cx
clc
ret
dnwpg endp
; home viewing window
homwnd proc near
push cx
mov cx,twnd.lcnt ; all top window lines [dlk]
jmp upwp0 ; join upwpg
homwnd endp
upone proc near ; move text down one line [jrd]
push cx
mov cx,1
jmp upwp0
upone endp
; scroll viewing window up (text moves down) a page (24 lines)
upwpg proc near
push cx
mov cl,byte ptr low_rgt+1 ; number of rows, excl status line
inc cl ; count from 1, not 0
mov ch,0
upwp0: ; additional entry point
cmp twnd.lcnt,cx ; enough lines in top line buffer?
jae upwp1 ; ae = at least as many as requested
mov cx,twnd.lcnt ; do only as many as are stored
upwp1: jcxz upwp2 ; z = no lines to scroll
cmp tekflg,0 ; Tek mode active?
jne upwp2 ; ne = yes, no scrolling
call mscrd ; roll down text one line
loop upwp1
upwp2: pop cx
clc
ret
upwpg endp
; Put a line into the circular buffer. Pass the buffer structure in bx.
; Source is tv_segs:si which is the current screen address.
; Rewritten by [jrd]
putcirc proc near
push es
mov cl,crt_cols ; number of columns
xor ch,ch
mov es,[bx].orig ; get segment of memory area
cmp bx,offset bwnd ; bottom buffer?
je putci6 ; e = yes
mov di,twnd.pp ; pick up buffer ptr (offset from es)
add di,cx ; increment to next available slot
add di,cx ; char and attribute
cmp di,twnd.bend ; would line extend beyond buffer?
jb putci1 ; b = not beyond end
mov di,0 ; else start at the beginning
putci1: mov twnd.pp,di ; update ptr
cld ; set direction to forward
push ds ; save regular datas seg reg
mov ds,tv_segs ; use screen segment for ds:si
rep movsw ; copy into buffer
pop ds ; restore regular datas segment
mov cx,twnd.lmax ; line capacity of buffer
dec cx ; minus one work space line
cmp twnd.lcnt,cx ; can we increment line count?
jae putci1b ; ae = no, keep going
inc twnd.lcnt ; else count this line
putci1b:cmp bwnd.lcnt,0 ; any lines in bottom buffer?
je putci2 ; e = no
mov cx,bwnd.pp ; see if we overlap bot buf
cmp cx,twnd.pp ; is this line in bot buf area?
jne putci2 ; ne = no
add cl,crt_cols ; move bottom pointer one slot earlier
adc ch,0
add cl,crt_cols ; words
adc ch,0
cmp cx,bwnd.bend ; beyond end of buffer?
jb putci1a ; b = no
mov cx,0 ; yes, start at beginning of buffer
putci1a:mov bwnd.pp,cx ; new bottom pointer
dec bwnd.lcnt ; one less line in bottom buffer
putci2: pop es
ret
putci6: ; bottom buffer
add cx,cx ; words worth
cmp bwnd.lcnt,0 ; any lines in the buffer yet?
jne putci7 ; ne = yes
mov di,twnd.pp ; get latest used slot of top buff
add di,cx ; where first free (?) slot starts
cmp di,bwnd.bend ; are we now beyond the buffer?
jb putci6a ; b = no
mov di,0 ; yes, start at beginning of buffer
putci6a:add di,cx ; start of second free (?) slot
cmp di,bwnd.bend ; are we now beyond the buffer?
jb putci6b ; b = no
mov di,0 ; yes, start at beginning of buffer
putci6b:mov cx,twnd.lmax ; buffer line capacity
sub cx,twnd.lcnt ; minus number used by top buffer
sub cx,2 ; minus one work slot and one we need
cmp cx,0 ; overused some slots?
jge putci8 ; ge = enough to share
add twnd.lcnt,cx ; steal these from top window beginning
jmp short putci8
putci7: mov es,bwnd.orig ; get segment of memory area
mov di,bwnd.pp ; pick up buffer ptr (offset from es)
cmp di,0 ; would line start before buffer?
jne putci7a ; ne = after start of buffer
mov di,bwnd.bend ; else start at the end minus one slot
inc di
putci7a:sub di,cx
putci8: mov bwnd.pp,di ; update ptr (this is latest used slot)
mov cl,crt_cols
xor ch,ch
cld ; set direction to forward
push ds ; save regular datas seg reg
mov ds,tv_segs ; use screen segment for ds:si
rep movsw ; copy into buffer
pop ds ; restore regular datas segment
mov cx,bwnd.lmax ; line capacity of buffer
cmp bwnd.lcnt,cx ; can we increment line count?
jae putci8b ; ae = no, keep going
inc bwnd.lcnt ; else count this line
putci8b:cmp twnd.lcnt,0 ; any lines in top line buf?
je putci9 ; e = no
mov cx,twnd.pp ; yes, see if we used last top line
cmp cx,bwnd.pp ; where we just wrote
jne putci9 ; not same place, so all is well
dec twnd.lcnt ; one less line in top window
cmp cx,0 ; currently at start of buffer?
jne putci8a ; ne = no
mov cx,twnd.bend ; yes
inc cx
putci8a:sub cl,crt_cols ; back up top window
sbb ch,0
sub cl,crt_cols ; by one line
sbb ch,0
mov twnd.pp,cx ; next place to read
putci9: pop es
ret
putcirc endp
; Get a line from the circular buffer, removing it from the buffer.
; returns with carry on if the buffer is empty.
; Pass the buffer structure in bx.
; Destination preset in es:di which is the current screen address.
; Rewritten by [jrd]
getcirc proc near
cmp [bx].lcnt,0 ; any lines in buffer?
jne getci1 ; ne = yes, ok to take one out
stc ; else set carry
ret
getci1: ; top and bottom window common code
mov cl,crt_cols ; # of chars to copy
xor ch,ch
mov si,[bx].pp ; this is source
push si ; save around calls
push cx ; save around calls
cld ; set direction to forward
push ds ; save original ds
mov ax,[bx].orig ; use seg address of buffer for si
mov ds,ax
rep movsw ; destination = screen at es:di
pop ds ; recover original data segment
pop cx ; recover word count
call scrsync ; synch Topview
pop si ; get ptr again
add cx,cx ; words
cmp bx,offset bwnd ; bottom window?
je getci7 ; e = yes
sub si,cx ; top window, move back
jnc getci6 ; nc = still in buffer, continue
mov si,twnd.bend ; else use end of buffer
sub si,cx ; minus length of a piece
inc si
getci6: mov twnd.pp,si ; update ptr
dec twnd.lcnt ; decrement # of lines in buffer
clc ; make sure no carry
ret
getci7: ; bottom window
add si,cx ; words, move back (bot buf = reverse)
cmp si,bwnd.bend ; still in buffer?
jb getci8 ; b = yes
mov si,0 ; else use beginning of buffer
getci8: mov bwnd.pp,si ; update ptr
dec bwnd.lcnt ; decrement # of lines in buffer
clc ; make sure no carry
ret
getcirc endp
;
; CHKDSP - procedure to check for hardware support of 132 cols [dlk]
;
; Supported hardware: EVA board from Tseng Labs w/132-col kit installed
; Tseng Labs UltraPAK mono/Herc board w/132 column modes.
; Video 7 Vega Deluxe w/ 132X25.COM driver installed [tmk]
; and VGA board, ATI EGA Wonder, Everex ev-659 and fvga-673.
; The routine checks for the presence of a 132-column-capable adapter. If
; one is found, its handler returns the proper video mode in [CX]. The main-
; line code then moves this to [AX] and issues the video interrupt.
;
chgdsp proc near
push es ; save all we use
push ax
push bx
push cx
push dx
push si
push di
mov temp,ax ; save set/reset flag from msz
mov ah,flowoff ; get xoff
cmp ah,0 ; flow control?
je chgds0 ; e = none
call outchr ; send it
nop ; avoid serial port interrupts while
nop ; doing many rep scasb's below
nop
call savescr ; save current screen
mov ax,40 ; wait 40 millisec before video tests
call pcwait ; so don't mix screen and port intrpts
chgds0: call ckteva ; try Tseng Labs EVA
jnc chgds1 ; nc = found
call ckv7vd ; try Video 7 EGA Deluxe and VGA
jnc chgds1 ; nc = found
call ckatiw ; try ATI EGA Wonder
jnc chgds1 ; nc = found
call ckevrx ; try Everex Micro Enhancer Deluxe
jnc chgds1 ; nc = found
call ckevga ; try Everex EVGA-673
jnc chgds1 ; nc = found
jmp chgdsx ; if not, exit
; Perform mode change
chgds1: mov ax,cx ; get returned value in proper reg
int screen ; call the bios
cmp flags.modflg,1 ; is mode line enabled?
jbe chgds2 ; be = yes, and off or locally owned
mov flags.modflg,1 ; remove foreign ownership
chgds2: call scrini ; reset parameters
chgdsx: mov ah,flowon ; get flowon byte
cmp ah,0 ; using flow control?
je chgdsx1 ; e = no
call outchr ; send it
nop
nop
nop
chgdsx1:pop di ; restore what we saved
pop si
pop dx
pop cx
pop bx
pop ax
pop es
ret ; return to caller
chgdsp endp
; Individual tests for various 132-column boards
;
; Tseng LABS EVA and UltraPAK
ckteva: mov ax,0c000h ; seg addr for EVA
mov es,ax ; set into es register
mov di,76h ; offset of board's string
lea si,tsngid ; validation string
mov cx,tsnglen ; length of validiation string
cld
repe cmpsb ; compare strings
je ckteva2 ; e = strings match
mov ax,4d00h ; check for UltraPAK mono driver
int screen
cmp ax,5aa5h ; driver signature?
jne chnoad ; ne = no
mov cx,7 ; default to mono (7) for this board
cmp byte ptr temp,0 ; setting 132 columns?
je ckteva1 ; e = resetting to normal
mov cx,18h ; set to 132 cols (Set Mode 18H)
ckteva1:clc ; carry clear means found
ret
ckteva2: ; an EVA board - check for 132 col kit
cmp byte ptr es:099h,0 ; check 132 col kit installed
je chnoad ; e=0=not installed
jmp catfnd ; do the mode change
chnoad: stc ; indicate adapter not present
ret ; and exit
;
; ATI EGA Wonder
ckatiw: mov ax,0c000h ; seg addr for EGA Wonder
mov es,ax ; set into es register
mov di,012fh ; offset of message in ROM
lea si,atiwid ; offset of message here
mov cx,atilen ; length of validation string
cld
repe cmpsb ; compare strings
jne chnoad ; ne = strings differ
;
catfnd: mov cx,0003h ; prepare to reset video mode
cmp byte ptr temp,0 ; are we setting or resetting?
je ckexit ; e is reset, exit
mov cx,0023h ; set to 132 cols (Set Mode 23H)
ckexit: clc ; carry clear means found
ret
;
; Video 7 Vega Deluxe
ckv7vd: mov ax,0c000h ; seg addr for Vega rom bios
mov es,ax ; set into es register
mov di,002ah ; offset of message in ROM
lea si,vid7id ; offset of message here
mov cx,vid7len
cld
repe cmpsb ; compare strings
je cnv7fn0 ; e = same
mov di,002ah ; offset of ident string
mov si,offset vid7id2 ; Video 7 VGA board
mov cx,vid7len2
repe cmpsb
je cnv7fn2 ; e = found
cnv7fx: jmp chnoad ; ne = strings are different
;
cnv7fn0:test byte ptr es:[03ffeh],1 ; is this a 'Deluxe' Vega?
jz chnoad ; z = nope, can't do it
mov ah,35h ; DOS Get Vector
mov al,10h ; Bios video interrupt
int dos ; get it into es:bx
mov di,bx ; es:bx is returned int 10h entry pnt
sub di,5ah ; back offset to msg in 132X25.COM
lea si,vid7id ; offset of validation message
mov cx,vid7len ; length of validation string
cld
cnv7fn1:repe cmpsb ; Look for repeat of msg by 132X25.COM
jne cnv7fn2 ; if different
mov cl,crt_mode ; prepare to reset video mode
mov ch,0
cmp byte ptr temp,0 ; are we setting or resetting?
je ckexit ; e is reset, exit
mov cx,0000h ; set to 132 cols (old 40x25)
jmp short ckexit ; and exit
cnv7fn2:mov ax,6f00h ; check for VegaBios driver
int screen
cmp bx,'V7' ; Video 7 Bios presence response
jne cnv7fx ; ne = not there
mov ax,6f01h ; al gets monitor type (mono,color,ega)
int screen
mov bx,51h ; presume mono 132x25, page 0
cmp crt_lins,42 ; 43 lines active?
jb cnv7fn2a ; b = no
inc bx ; use bx = 52h for 132x43
cnv7fn2a:
cmp al,10h ; analogue fixed freq (IBM 85xx)?
je cnv7fx ; e = yes, no 132 columns
cmp al,2 ; 1 = mono, 2 = color, above = ega
jb cnv7fn3 ; b = mono or unknown
mov bx,4fh ; presume med res color 132x25
je cnv7fn3 ; e = med res color, al = 2
mov bx,41h ; ega high res 132x25, enhanced mons
cmp crt_lins,42 ; 43 lines active?
jb cnv7fn3 ; b = no
inc bx ; use bx = 42h for 132x43
cnv7fn3:mov ax,6f05h ; set special mode found in bl
cmp byte ptr temp,0 ; resetting to 80 column mode?
jne cnv7fn4 ; ne = no, setting 132x25
mov al,crt_norm ; get normal mode
mov ah,0 ; set mode
cmp crt_lins,42 ; 43 lines active?
jb cnv7fn4 ; b = no
mov bl,40h ; use Video 7 mode 40h 80x43 for color
mov ax,6f05h ; and do special mode set
cnv7fn4:int screen ; special mode is in bl
mov cx,0f00h ; a nop screen bios command
clc
ret
ckevrx: mov ax,0c000h ; seg addr for Everex EV-659
mov es,ax ; set into es register
mov di,0047h ; offset of message in ROM
lea si,evrxid ; offset of message here
mov cx,evrxlen ; length of validation string
cld
repe cmpsb ; compare strings
jne ckfnr2 ; ne = strings differ
mov ah,crt_lins ; we recognize either 44 or 25 rows
cmp ah,43 ; equal to 44-1 rows?
jne ckfnr1 ; ne = no
mov cx,0070h ; Everex extended mode ident
mov bl,09h ; prepare to reset video mode to 80x44
cmp byte ptr temp,0 ; are we setting or resetting?
je ckfnr4 ; e is reset, exit
mov bl,0bh ; 132x44
jmp ckexit
ckfnr1: cmp ah,24 ; equal to 25-1 rows?
je ckfnr3 ; e = yes
ckfnr2: jmp chnoad ; ne = no
ckfnr3: mov cx,0003h ; prepare to reset video mode
cmp byte ptr temp,0 ; are we setting or resetting?
je ckfnr4 ; e is reset, exit
mov cx,0070h ; Everex extended mode ident
mov bl,0ah ; 132x25
ckfnr4: jmp ckexit
ckevga: mov ax,0c000h ; Everex FVGA-673, rom segment
mov es,ax
mov di,76h ; offset in rom for board's id string
lea si,evgid ; id string
mov cx,evglen ; length of id string
cld
repe cmpsb ; do they match?
jne ckevg2 ; ne = no
mov cx,3 ; prepare to reset video mode
cmp byte ptr temp,0 ; setting or resetting mode?
je ckevg1 ; e = resetting, exit
mov cx,0070h ; mode for 132x25
mov bl,0ah ; Everex mode 0ah
ckevg1: clc
ret
ckevg2: stc ; say board not found
ret
; 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
if1
%out [End of pass 1]
else
%out [End of assembly]
endif
end