home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
msr313src.tar.gz
/
msr313src.tar
/
msyap3.asm
< prev
next >
Wrap
Assembly Source File
|
1988-08-16
|
80KB
|
1,752 lines
NAME msyap3
; File MSYAP3.ASM;
; NEC APC III system dependent module (taken from msyibm.asm).
; Much EGA and other screen support commented out from ibm code.
; NEC modifications by Robert F. Goeke
; Last Edit: 14 March 1988
; edit history:
; 15 Mar 1988 Incorporate latest IBM mods for NEC
; Following comments from msyibm.asm code:
; 5 Jan 1988 Restore cursor codes broken by Tek code additions. [jrd]
; 1 Jan 1988 version 2.30
; 24 Dec 1987 Restore startup screen attributes at Kermit prompts. [jrd]
; 21 Dec 1987 Fix memory size sign problem for >640K systems. From Edgar Butt
; 4 Dec 1987 cleanup mode switching, add more Video 7 material. [jrd]
; 8 Nov 1987 Add EGA mode switching, from Terry Kennedy.
; 1 Nov 1987 Add support for Tektronix, based on work by Brian Holley. [jrd]
; 13 Oct 1987 Revise memory allocation sequence to avoid small holes. [jrd]
; 2 Oct 1987 Make log file character width match Set Display but 8 bits when
; debugging. [jrd]
; 12 Sept 1987 clarify sequence of translation and 8 bit display. [jrd]
; 27 Aug 1987 Do Translation before logging. [jrd]
; 18 Aug 1987 Change ESC to escape for MASM 4.5+ [jrd]
; 28 July 1987 Fix scron problem in screen save. [jrd]
; 23 June 1987 Add plain_attribute macro; fix bug in circular buffer
; routines which kept attributes from being stored (and replayed)
; 8 June 1987 Add keypad application mode tests to emit single chars. [jrd]
; 6 June 1987 Adapt to most recent msyibm file (keyboard translator et al)
; [jrd]
; 10 May 1987 Move input translation into terminal emulator, leave copy
; here for terminal type None, use mszibm byte anspflg to sense print
; screen is active, print translated characters but don't translate if
; debugging is active. [jrd]
; 28 March 1987 Make low_rgt screen coord word a global parameter.
; Add support for variable length screens and cursor size changes with
; EGA boards. Tests ok with 25, 35, 43, 50 lines with &/without MS Windows.
; EGA Memory locations 40:84H and 40:87H are used in this process.
; Use savadr dw as place to save screen: usually screen page 1 if screen
; dimensions are non-standard (80x25), else memory buffer scrsav. [jrd]
; 21 March 1987 Translate arriving Connect mode chars via table rxtable. [jrd]
; Add 132 Column support for Tseng Labs EVA board via procedure chgdsp,
; add restore scrolled screen before writing to it. From David L. Knoell [dlk]
; Modify msy and msz to use variable screen length and widths. [dlk] and [jrd]
; 17 March 1987 Reduce screen roll back buffer to half the memory to do the
; same number of screens. [jrd]
; 12 Jan 1987 Add keyboard translator, remove older code. [jrd]
; 1 Oct 1986 Version 2.29a
public term, lclyini ; entry points
public prtbout, prtnout, csrtype, scrmod, scrseg, scrsync
public scroff, scron, atsclr, vtscru, vtscrd, scrloc, trnmod, telmsy
public chgdsp, vtroll
; action verb procedures for keyboard translator
public uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
public kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
public kpminus, kpcoma, kpenter, kpdot, chrout, cstatus, cquit
public cquery, dmpscn, vtans52, vtinit, dnwpg, upwpg, endwnd, homwnd
public upone, dnone, trnprs, dumpscr, modlin, modwrt, snull
public klogon, klogof, cdos, chang
public vtemu, crt_mode, scbattr, refresh, low_rgt ; data
public crt_cols, crt_lins, savescr, restscr, getflgs
include mssdef.h
; some definitions
; NEC APC III hardware
screen equ 19h ; bios screen call
kb equ 18h ; keyboard interrupt
vram equ 0A000H ; Video Ram
alt_shift equ 8H ; alt shift key down
ctl_shift equ 4H ; ctl key down
left_shift equ 2H ; left shift key down
; right_shift equ 1H ; right shift key down
func_shift equ 1H ; an NEC mod RFG
biostty equ 0eh ; Bios screen tty write mode [jrd]
modfrm struc ; format of mode (status) line
db 'Esc-chr: ' ; do not write in last column.
m_echr db 2 dup (?)
db ' help: '
m_hlp db 2 dup (?)
db '? port:'
m_prt db 1 dup (?)
db ' speed:'
m_baud db 5 dup (?)
db ' parity:'
m_par db 4 dup (?)
db ' echo:'
m_echo db 3 dup (?)
m_term db 13 dup (' ') ; 13 bytes for term type
m_prn db 3 dup (' ') ; show PRN when printer is on [jrd]
modfrm ends
; This macro flips the rev_video bit of attribute in ah. RFG
; NB this neither changes any other attribute nor any other register
flip_rev_video macro
local flip,flop
test ah,att_rev_video
jnz flip
or ah,att_rev_video
jmp flop
flip: and ah,not att_rev_video
flop: nop
endm
; This macro makes takes the character attributes in ah and makes them plain
; Different than IBM case 'cause we don't really have "intensity". RFG
plain_attribute macro
and ah,not(att_overline+att_blink+att_underline)
endm
att_overline equ 01H ; this is all NEC version stuff RFG
att_blink equ 02H
att_rev_video equ 04H
att_underline equ 08H
att_intensity equ 04H ; same as reverse video
datas segment public 'datas'
extrn flags:byte, mar_top:byte, mar_bot:byte, portval:word
extrn filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
extrn anspflg:byte, tekflg:byte
; stuff for screen routines
yflags db ? ; status flags...
flags1 db 0 ; internal flags (but used in mszibm).
prtscr equ 1 ; print screen pressed
inited equ 08h ; been here before...
vtinited db 0 ; flag for emulator having been inited
cursor dw ?
esc_ch db ?
parmsk db ? ; 8/7 bit parity mask, for reception
argadr dw ? ; address of arg blk
savadr dw 2 dup (?) ; offset then segment of saved screen
savflg dw ? ; low_rgt at time of screen save
vtemu emulst <> ; emulator flags [jrd]
ansflgs db 0 ; ANSI flags
trmtyp db 0 ; most recent terminal type
mtty db ' TTY ' ; no terminal type (mode line)
lincur dw ? ; cursor type save area
scbattr db ? ; Screen background attribute
oldattr db ? ; screen attributes at init time
curattr db ? ; current attribute
temp dw ? ; scratch storage
modtemp db 0 ; temp to hold Kermit modeline status
captrtn dw ? ; routine to call for captured output
dmphand dw ? ; screen dump file handle
dumpbuf db 132 dup (?), cr, lf ; 134 byte dump work buffer
dumpsep db FF,cr,lf ; screen image separators
dmperr db ' Cannot open file to save screen to disk $'
crlf db cr,lf,'$'
; some static data for mode line
modbuf modfrm <> ; mode line buffer
unkbaud db 'unkwn' ; must be 5 chars...
baudn db ' 45.5',' 50 ',' 75 ',' 110 ','134.5',' 150 ',' 300 ',' 600 '
db ' 1200',' 1800',' 2000',' 2400',' 4800',' 9600','19200','38400'
db '57.6K','115 K'
baudnsiz equ 18 ; # of baud rates known (tbl size / 4)
parnams db 'even','mark','none','odd ','spc '
lclmsg db 'loc'
remmsg db 'rem'
portno db ?
; storage for multi-window stuff
swidth equ 80 ; max screen width
slen equ 24 ; and length of text
npages equ 10 ; # of pages of scrolling on each side
crt_norm db ? ; video mode for normal screen
crt_mode db ? ; video mode (typ 3, must be text)
crt_cols db ? ; number of screen columns (typ 80)
crt_lins db 24 ; number of screen rows - 1 (typ 24)
low_rgt dw ? ; lower right corner of text window
; high = row address (typ 23)
; low = column address (typ 79)
inipara dw ? ; initial paragraphs of scroll memory
refresh db 0 ; screen refresh (0=wait for retrace)
vtroll db 0 ; auto roll back allowed (0 = no).
; circular buffer for screen roll back.
cbuf struc
pp dw ? ; place ptr in buffer
bend dw ? ; end of buffer
orig dw ? ; buffer origin
lcnt dw 0 ; # of lines in buffer.
lmax dw ? ; max lines of buffer. [jrd]
cbuf ends
twnd cbuf <> ; top screen spill-buffer struct
bwnd cbuf <> ; bottom screen spill buffer struct
datas ends
code segment public 'code' ; code segment
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
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]
; delete screen dump memory allocation; see savescr RFG
lclyini proc near
call msuinit ; initialize keyboard module msuxxx
mov ax,swidth ; ask for two lines (1 per buffer)
add ax,ax
add ax,ax ; times four (2 lines of char + attrib)
call sbrk ; allocate mem. Exit Kermit on failure
;if we get here them we have the lines
mov bwnd.orig,ax ; memory segment, bottom window area
mov twnd.orig,ax ; top. same place for both buffers!
push es ; save this register.
mov es,ax ; seg pointer to new memory block
mov bx,(swidth*slen*npages+7)/8 ; paragraphs wanted for roll back
add bx,24000D/16 ; plus paragraphs to run Command.com
mov ah,setblk ; DOS Setblock. Ask for that space.
int dos ; bx has # paragraphs available
sub bx,24000D/16 ; deduct space for DOS 3.x Command.Com
cmp bx,(swidth*4+15)/16 ; any room left for buffers?
jae lclyin2 ; some space is available for buffers
mov bx,(swidth*4+15)/16 ; else use our sbrk allocation
lclyin2:mov ah,setblk ; ask for that many (bx) paragraphs
int dos ; Errors here == DOS deceived us.
pop es ; restore reg.
mov ax,bx ; bx = # paragraphs allocated by DOS
mov inipara,bx ; save for later resizing of buffers
mov cl,3 ; 2**3 = 8
shl ax,cl ; paragraphs to words (char + attrib)
xor dx,dx ; clear extended size
mov cx,swidth ; 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 scrseg ; test running in an Environment
call scrmod ; read video state, get crt_mode.
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
call vsinit ; init terminal emulator module MSZ
ret
lclyini endp
scrini proc near ; init screen stuff
call scrmod ; get screen mode, low_rgt
mov ah,3 ; get cursor position and char.
xor bh,bh ; page 0
int screen
mov lincur,cx ; save cursor type (scan line #'s)
mov dx,cursor ; assume old cursor
test flags1,inited ; have we been here before?
jnz scrin4 ; nz = yes, use old cursor
mov ah,oldattr ; get init time attributes
mov curattr,ah ; and set nice screen attribute
mov scbattr,ah
mov ah,3 ; figure out where cursor is
xor bh,bh ; page 0
int screen ; read cursor position, in dx
scrin4: cmp dh,byte ptr low_rgt+1 ; past logical end of screen?
jb scrin2 ; b = no, keep going
mov dh,byte ptr low_rgt+1 ; yes, just use lower right corner
scrin2: cmp dl,byte ptr low_rgt ; maybe past right margin
jb scrin3 ; b = no, use the way it is
mov dl,byte ptr low_rgt
scrin3: mov cursor,dx ; init cursor
mov ah,2 ; set cursor position
xor bh,bh ; page zero
int screen ; set cursor in case it moved
ret
scrini endp
; Routine to initialize terminal emulator. Call once.
vtinit proc near
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 al,yflags ; Pass the flags.
mov bx,argadr ; Get address of argument block
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
test flags.remflg,d8bit ; eight bit display?
jnz vtini1 ; nz = yes
or dh,07H ; Just say 7 data bits.
call ansini ; call startup routine in mszibm.
ret
vtini1: or dh,8 ; say 8 bits
call ansini
vtinix: clc
ret
vtini2: call tekcls ; clear Tek screen
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
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
mov cl,2 ; each is 4 bytes long...
shl al,cl
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 [jrd]
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
; 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 ;[IU2] Get terminal attributes
plain_attribute
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
int screen
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 [jrd]
dec cx ; don't let screen scroll
modl6: cld
lodsb ; get a byte
push si ; RFG
mov ah,14 ; write to terminal
mov bh,0 ; page 0
int screen
pop si ; RFG
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 ; and return
modlin endp
clrmod proc near ; clear mode line
cmp flags.vtflg,tttek ; NEC -- a precaution only
je clrmodx
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
int screen ; clear mode line
clrmodx: ret ; and return
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? [jrd]
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. [jrd]
mov bl,curattr ; And cursor attribute.
mov ah,al ; where modlin needs them [jrd]
plain_attribute
flip_rev_video ; reverse the video
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.
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 acs over call
push bx
mov al,yflags
call anstat ; Get status and attributes
mov ansflgs,bh ; Save.
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
test flags1,inited ; have we run yet?
jz term1 ; z = no, so no saved screen yet
call restscr ; restore screen
term1: or flags1,inited ; remember we've run already.
cmp flags.vtflg,0 ; current terminal type = None?
je term3a ; e = yes, nothing to init.
mov al,yflags ; tell emulator we are back
cmp vtinited,inited ; inited emulator yet?
je term3 ; e = yes
cmp tekflg,0 ; Tek mode still active?
jne term3a ; ne = yes, no re-init here
call vtinit ; init it now
jmp term3a
term3: call ansrei ; reinit the emulator
call ansflg ; and get its flags
term3a: cmp flags.modflg,0 ; is mode line disabled?
je term2a ; e = yes, disabled
cmp flags.vtflg,0 ; emulating a terminal?
jne term1a ; ne = yes, can have mode line
cmp trmtyp,0 ; previous terminal type = none?
jne term2 ; ne = no. need to clear mode line.
jmp term2a ; yes, let 25th line be intact
term1a: test yflags,modoff ; is mode line toggled off?
jnz term2 ; nz = yes, clear the line.
cmp flags.vtflg,tttek ; going to be a Tek terminal?
je term2a ; e = yes, no mode line
call modlin ; turn on mode line
jmp term2a
term2: call clrmod ; ensure its off
term2a: mov al,flags.vtflg ; current terminal type
mov trmtyp,al ; place to remember it til next time
cmp flags.vtflg,tttek ; Tek mode?
je term4 ; e = yes
cmp tekflg,0 ; Tek mode active within DEC stuff?
je lp ; e = no
term4: call tekini ; reinit to get graphics screen
lp: call portchr ; char at port?
jnc chkinp ; nc = no, keep going
nop
call outtty ; print on terminal
chkinp: call keybd ; call keyboard translator in msu
jnc lp ; nc = no char or have processed it
; carry set = quit Connect mode.
quit: call tekend
mov ah,3 ; get cursor position
xor bh,bh ; page 0
int screen
mov cursor,dx ; save position
call savescr ; save screen
cmp flags.vtflg,0 ; emulating?
je quit1 ; e = no
call clrmod ; erase mode line
quit1: mov ah,oldattr ; attributes at init time
mov scbattr,ah ; background = original state [jrd]
; for ega in non-standard # lines
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
int screen ; Do it.
mov al,yflags
mov bx,argadr
mov [bx].flgs,al ; update flags in arg block
ret ; and return to caller
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
push ax
mov ah,lstout ; write to system printer device
mov dl,al
int dos
pop ax
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 tekflg,0 ; Tek mode active?
jne outnp6 ; ne = yes, skip screen rolling
cmp vtroll,0 ; auto roll back allowed?
jz outnp6 ; z = no, leave screen as is.
cmp bwnd.lcnt,0 ; is screen rolled back? [dlk]
je outnp6 ; e = no
call endwnd ; restore screen before writing [dlk]
outnp6: cmp flags.vtflg,0 ; emulating a terminal?
jnz outnop1 ; nz = 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: int screen
ret
outnp4: cmp al,bell ; bell (Control G)? [jrd]
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 ; and return
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
; get shift state into al. We care about only shift, ctl, and alt keys.
; right shift is collapsed into left shift.
; in NEC there is no left/right shift, but the right_shift code is used
; to indicate FUNC RFG
gss proc near
mov ah,2
int kb ; get current shift state
mov bl,al ; copy for a moment
and al,(func_shift + left_shift + alt_shift + ctl_shift)
ret
gss 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
nop ; Ignore skip return.
nop
nop
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 ; Output to port
nop
nop
nop
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
nop
nop
nop ; skip returns...
ret
outprt endp
; returns with carry on if a character is available
portchr proc near
call prtchr ; character at port?
jmp short portc1 ; yes, go handle
nop ; skip return is stupid...
portc0: clc ; no carry -> no character
ret ; and return...
portc1: and al,parmsk ; apply 8/7 bit parity mask [jrd]
stc ; have a character
ret ; and return
portchr 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'
jmp short comarr
lfarr: mov al,'D'
comarr: push ax ; save final char
mov al,escape ; Output an escape.
cmp flags.vtflg,tttek ; Tek terminal
je comar0 ; e = yes, use VT100 codes
call outprt ; Output, echo permitted
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
call outprt ; Output to port (echo permitted)
clc
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 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
call prtbout ; Output to port
clc
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 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: call prtbout ; send it
clc
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
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
klogo: clc
ret
klogof endp
snull proc near ; send a null byte
mov al,0 ; the null
call prtbout ; send without logging and local echo
clc
ret
snull endp
; 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
clc
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
; 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,0 ; is mode line enabled?
je trnm2 ; e = 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 ; and return
trnm1: and yflags,not modoff ; Clear flag first.
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
;;;;; General screen management routines for NEC APC
; computes screen location to ax, given row and col in [dh,dl], resp.
; trashes dx
scrloc proc near
mov al,dh ; get row
xor ah,ah ; clear ah
mul crt_cols ; multiply by number of columns
xor dh,dh ; clear row
add ax,dx ; this is current position
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, 3 = restore cursor,
; 5 = No blink underline, 6 = No blink block.
; modified for NEC RFG
csrtype proc near
push cx ; save the reg
mov ah,1 ; Video fxn for set cursor type
mov cx,0707H ; Set one line.
cmp al,1 ; Underline?
je csrty2 ; Right - then do it
or cx,0400H ; set for no blink
cmp al,5 ; is it this?
je csrty2 ; Right - then do it
mov cx,0007H ; set for block
cmp al,2 ; Block?
je csrty2 ; Right - then do it
or cx,0400H ; set for no blink
cmp al,5 ; no-blink underline?
je csrty2 ; Right - then do it
cmp al,0 ; Disable cursor?
je csrty3 ; Right - then do it
jmp csrty4 ; last choice is enable
csrty2: int screen ; Set it.
pop cx
ret
csrty3: push bx
mov ah,3 ; BIOS call to read current
mov bh,0 ; current cursor status
int screen
or ch,80H ; Set disable bit
mov ah,1 ; And set cursor
pop bx
jmp csrty2
csrty4: push bx
mov ah,3
mov bh,0
int screen
and ch,7FH ; Clear disable bit
mov ah,1
pop bx
jmp csrty2
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]
; modified for the NEC since text/attribute pattern is different.
; put image of Page 0 VRAM into Page 1 VRAM for the save RFG
savescr proc near
push ax
push bx
push cx
push dx
push di
push si
push ds
push es
mov ax,vram ; start of VRAM is A000:0000
mov savadr+2,ax ; save segment in this word
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
mov si,0 ; this is Page 0, to be saved
mov di,1000H ; this is Page 1, the save buffer
mov savadr,di ; save offset in this word
mov cx,80*25
mov ax,vram
mov ds,ax
mov es,ax
cld
rep movsw ; move the text page
mov si,2000H ; this is Page 0, attributes
mov di,3000H ; this is Page 1
mov cx,80*25
rep movsw ; move the attribute page
pop es
pop ds
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret ; and return
savescr endp
; restore screen from scrsav buffer. Restores all 25 lines. [jrd]
; like savescr, modified for NEC RFG
restscr proc near
push ax
push bx
push cx
push dx
push di
push si
push ds
push es
mov ax,vram ; start of VRAM is A000:0000
mov ds,ax
mov es,ax
mov si,1000H ; this is Page 1, to be restored
mov di,0 ; this is Page 0
mov cx,80*25
rep movsw ; move the text page
mov si,3000H ; this is Page 1, attributes
mov di,2000H ; this is Page 0
mov cx,80*25
rep movsw ; move the attributes
pop es
pop ds
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret ; and return
restscr 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.
; Mod to use VRAM (see savescr) RFG
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
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 + trash
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. [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 [jrd]
mov dl,ah ; # of cols again
mov dh,crt_lins ; and # of rows (constant from msster)
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 ; And return.
scrmod endp
; Get screen segment - returns screen segment in ax, and full address in es:di
; modified for NEC; there is only one answer RFG
scrseg proc near
mov ax,vram
mov es,ax
xor di,di ; start at beginning of screen (0,0)
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.
; Stripped out on NEC RFG
scrsync proc near
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.
; not an NEC required function RFG
scroff proc near
ret ; And return.
scroff endp
; Turn screen on for (known) color card modes only
; All registers are preserved.
scron proc near
ret ; And return.
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]
; redone for the NEC in a non-Topview manner RFG
atsclr: push ax
push bx
push cx
push dx
mov cx,ax ; upper left corner
mov dx,bx ; lower right corner
mov bh,scbattr ; attribute
mov al,0 ; blank entire window
mov ah,6 ; scroll the page described above
int screen
pop dx
pop cx
pop bx
pop ax
ret
; Scrolling routines. vtscru scrolls up one row, vtscrd scrolls down one
; row. atsprep is called before scrolling up to save the top line in the
; circular buffer. 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 ax,701H ; scroll down one line
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
int screen ; scroll it down
pop dx
pop cx
pop bx
pop ax
clc
ret
; worker routine for vtscru/d
atsprep:push es ; upgraded from older version [jrd]
call scrseg ; get display address in es:di
mov si,di ; si will be source
mov bx,offset twnd ; this is where it goes
call putcirc ; put screen line in circular buffer
pop es ; and that
ret ; and return
; Screen scroll up one line (text moves up) for terminal emulator use.
vtscru: push ax ; Upgraded by [jrd]
push bx
push cx
push dx
push si
push di
cmp mar_top,0 ; scrolling the top screen line?
ja scru1 ; a = no. don't save anything
call atsprep ; save top line
scru1: mov ax,601H ; scroll up one line
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 ; background attributes
int screen ; scroll up that region
pop di ; Restore the rest of the regs.
pop si
pop dx
pop cx
pop bx
pop ax
clc
ret ; And return
;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 atsprep ; save top line
mscru1: 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
push es
push ax ; save count
call scrseg ; get screen's segment into ax, es:di
pop ax ; recover count
add di,ax ; 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
mscru2: pop di ; Restore the rest of the regs.
pop si
pop dx
pop cx
pop bx
pop ax
ret
; prep for screen scroll down. [jrd]
; copies bottom scroll line from screen to bottom window buffer.
; destroys ax,cx,dx,si,di.
getbot proc near ; Upgraded from old version [jrd]
push es
mov dx,low_rgt ; from screen location, row
mov dl,0 ; starting in col 0
call scrseg ; get adaptor's offset into es:di
call scrloc ; get offset in display buffer in ax
add di,ax ; source addr in display buffer es:di
mov si,di ; screen is source (si)
mov bx,offset bwnd ; buffer to use (bottom window)
call putcirc ; copy bottom screen line to circ buf
pop es
ret
getbot endp
;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 getbot ; fetch bottom line from screen
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
call scrseg ; get segment address of screen
mov bx,offset twnd ; buffer to use (top window)
call getcirc ; copy from circ buf to screen
pop es
mscrd1: pop di ; Restore the rest of the ACs.
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 vram:si which is the current screen address.
; Rewritten by [jrd]
; Modified for the NEC screen attribute structure -- RFG
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
push ax
mov ax,vram ; video memory segment
mov ds,ax ; use screen segment for ds:si
putci1z: ; NEC mod starts here -- RFG
movsb ; transfer a text byte
mov ax,si ; remember 'movsb' incremented di
add ax,1FFFH ; point at the attribute
mov si,ax
movsb ; transfer an attribute byte
dec cx ; count one full character
mov ax,si
sub ax,1FFFH ; point at the next text
mov si,ax
cmp cx,0 ; have we done it all?
jne putci1z ; no, keep truckin'
; ; end of NEC mod -- RFG
pop ax
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
push ax
mov ax,vram ; video memory segment
mov ds,ax ; use screen segment for ds:si
putci8z: ; NEC mod starts here -- RFG
movsb ; transfer a text byte
mov ax,si
add ax,1FFFH ; point at the attribute
mov si,ax
movsb ; transfer an attribute byte
dec cx ; count one full character
mov ax,si
sub ax,1FFFH ; point at the text
mov si,ax
cmp cx,0 ; have we done it all?
jne putci8z ; no, keep truckin'
; ; end of NEC mod -- RFG
pop ax
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 ; and return
getci1: ; top and bottom window common code
mov cl,crt_cols ; # of chars to copy
xor ch,ch
push cx ; save around calls
mov si,[bx].pp ; this is source
cld ; set direction to forward
push ds ; save original ds
mov ds,[bx].orig ; use seg address of buffer for si
getci1z: ; NEC mod starts here -- RFG
movsb ; transfer a text byte
mov ax,di ; remember 'movsb' incremented di
add ax,1FFFH ; point at the attribute
mov di,ax
movsb ; transfer the attribute byte
dec cx ; count one full character
mov ax,di
sub ax,1FFFH ; point at the next text byte
mov di,ax
cmp cx,0 ; have we done it all?
jne getci1z ; no, keep truckin'
; ; NEC mod ends here -- RFG
pop ds ; recover original data segment
pop cx ; length for Topview
push cx ; save again
mov si,[bx].pp ; get ptr again
pop cx
add cx,cx ; words
cmp bx,offset bwnd ; bottom window?
je getci6 ; e = yes
sub si,cx ; top window, move back
jnc getcir2 ; nc = still in buffer, continue
mov si,twnd.bend ; else use end of buffer
sub si,cx ; minus length of a piece
inc si
getcir2:mov twnd.pp,si ; update ptr
dec twnd.lcnt ; decrement # of lines in buffer
clc ; make sure no carry
ret
getci6: ; bottom window
add si,cx ; words, move back (bot buf = reverse)
cmp si,bwnd.bend ; still in buffer?
jb getci7 ; b = yes
mov si,0 ; else use beginning of buffer
getci7: 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]
;
chgdsp proc near
ret ; return to caller
chgdsp endp
; Jumping to this location is like retskp. It assumes the instruction
; after the call is a jmp addr.
RSKP PROC NEAR
pop bp
add bp,3
push bp
ret
RSKP ENDP
; Jumping here is the same as a ret.
R PROC NEAR
ret
R ENDP
code ends
if1
%out [End of pass 1]
else
%out [End of assembly]
endif
end