home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
mskermit
/
msy55x.asm
< prev
next >
Wrap
Assembly Source File
|
2018-01-01
|
89KB
|
2,173 lines
NAME msy55x
; File MSY55X.ASM
; Sanyo version by Robert W. Babcock and Joe H. White
; For version which replaces the BIOS keycode translation table,
; use -dMODIFIED flag for MASM
; Last edit 11 May 1988
; edit history:
; 15 Sept 1987 version which runs with or without optional video board [rwb]
; 1 Jan 1988 version 2.30
; Add mods to msyibm to produce Sanyo version 16 Aug, 1987 [rwb]
; 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]
; 16 June 1987 Remove global byte jwait (wait for vertical retrace), embedd
; code for proc scrwait in proc scroff. Replace calls for scrwait with
; calls to scron/scroff. Thanks to Dave Tweten (dt). [jrd]
; 11 June 1987 Add control of automatic screen roll back when new characters
; are to be displayed; default is off (no roll back). [jrd]
; 8 June 1987 Add keypad application mode tests to emit single chars. [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, crt_lins, crt_cols, getflgs, tv_mode
; 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
ifdef MODIFIED ; [jhw]
public ktest,dkeytab,skeyptr ; for diagnostics [jhw]
endif ; [jhw]
public vtemu, crt_mode, scbattr, refresh, low_rgt ; data
public savescr, restscr
public usevb ; [rwb]
ifdef MODIFIED
public rbtabl, sbtabl ; bios key set/reset [jhw]
endif
include mssdef.h
; some definitions
; hardware
crt_status equ 3dah ; CGA crt status port
disp_enb equ 8 ; CGA display enable bit
crtmset equ 3D8H ; CGA CRT mode set port.
screen equ 10h ; bios screen interrupt
biostty equ 0eh ; Bios screen tty write mode
cmd8251 equ 2ah ; i/o address of 8251 command port [jhw]
rxrdy equ 02h ; 8251 receiver ready bit [jhw]
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
modfrm ends
datas segment para 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
; [begin jhw]
ifdef MODIFIED
;
; stuff for replacement key definition table for the Sanyo BIOS
;
dkeytab dw 00000h,04F00h,05100h,04603h,04900h,00F00h,00000h,05200h
dw 00E08h,00F09h,01C0Ah,04700h,00000h,01C0Dh,00000h,00000h
dw 03B00h,03C00h,03D00h,03E00h,03F00h,04000h,04100h,04200h
dw 04300h,04400h,00000h,0011Bh,04B00h,04D00h,04800h,05000h
dw 03920h,00221h,02822h,00423h,00524h,00625h,00826h,02827h
dw 00A28h,00B29h,0372Ah,00D2Bh,0332Ch,00C2Dh,0342Eh,0352Fh
dw 00B30h,00231h,00332h,00433h,00534h,00635h,00736h,00837h
dw 00938h,00A39h,0273Ah,0273Bh,0333Ch,00D3Dh,0343Eh,0353Fh
dw 00340h,01E41h,03042h,02E43h,02044h,01245h,02146h,02247h
dw 02348h,01749h,0244Ah,0254Bh,0264Ch,0324Dh,0314Eh,0184Fh
dw 01950h,01051h,01352h,01F53h,01454h,01655h,02F56h,01157h
dw 02D58h,01559h,02C5Ah,01A5Bh,02B5Ch,01B5Dh,0075Eh,00C5Fh
dw 02960h,01E61h,03062h,02E63h,02064h,01265h,02166h,02267h
dw 02368h,01769h,0246Ah,0256Bh,0266Ch,0326Dh,0316Eh,0186Fh
dw 01970h,01071h,01372h,01F73h,01474h,01675h,02F76h,01177h
dw 02D78h,01579h,02C7Ah,01A7Bh,02B7Ch,01B7Dh,0297Eh,05300h
dw 00080h,00081h,00082h,00083h,00084h,00085h,00086h,00087h
dw 00088h,00089h,0008Ah,0008Bh,0008Ch,0008Dh,0008Eh,0008Fh
dw 00090h,00091h,00092h,00093h,00094h,00095h,00096h,00097h
dw 00098h,00099h,0009Ah,0009Bh,0009Ch,0009Dh,0009Eh,0009Fh
dw 000A0h,000A1h,000A2h,000A3h,000A4h,000A5h,000A6h,000A7h
dw 000A8h,000A9h,000AAh,000ABh,000ACh,000ADh,000AEh,000AFh
dw 000B0h,000B1h,000B2h,000B3h,000B4h,000B5h,000B6h,000B7h
dw 000B8h,000B9h,000BAh,000BBh,000BCh,000BDh,000BEh,000BFh
dw 000C0h,000C1h,000C2h,000C3h,000C4h,000C5h,000C6h,000C7h
dw 000C8h,000C9h,000CAh,000CBh,000CCh,000CDh,000CEh,000CFh
dw 000D0h,000D1h,000D2h,000D3h,000D4h,000D5h,000D6h,000D7h
dw 000D8h,000D9h,000DAh,000DBh,000DCh,000DDh,000DEh,000DFh
dw 000E0h,000E1h,000E2h,000E3h,000E4h,000E5h,000E6h,000E7h
dw 000E8h,000E9h,000EAh,000EBh,000ECh,000EDh,000EEh,000EFh
dw 000F0h,000F1h,000F2h,000F3h,000F4h,000F5h,000F6h,000F7h
dw 000F8h,000F9h,000FAh,000FBh,000FCh,000FDh,000FEh,000FFh
dw 00000h,08400h,07600h,08500h,08600h,08700h,00000h,08800h
dw 00E7Fh,00009h,07500h,07700h,00000h,08900h,00000h,00000h
dw 06800h,06900h,06A00h,06B00h,06C00h,06D00h,06E00h,06F00h
dw 07000h,07100h,00000h,08A1Bh,07300h,07400h,08B00h,08C00h
dw 08D20h,07800h,06200h,07A00h,07B00h,07C00h,07E00h,06400h
dw 08000h,08100h,07F00h,08300h,06500h,09300h,06600h,06700h
dw 05D00h,05400h,05500h,05600h,05700h,05800h,05900h,05A00h
dw 05B00h,05C00h,06100h,06300h,08E00h,05E00h,08F00h,09000h
dw 07900h,01E00h,03000h,02E00h,02000h,01200h,02100h,02200h
dw 02300h,01700h,02400h,02500h,02600h,03200h,03100h,01800h
dw 01900h,01000h,01300h,01F00h,01400h,01600h,02F00h,01100h
dw 02D00h,01500h,02C00h,01A1Bh,02B1Ch,01B1Dh,07D00h,08200h
dw 00300h,01E01h,03002h,02E03h,02004h,01205h,02106h,02207h
dw 02308h,01709h,0240Ah,0250Bh,0260Ch,0320Dh,0310Eh,0180Fh
dw 01910h,01011h,01312h,01F13h,01414h,01615h,02F16h,01117h
dw 02D18h,01519h,02C1Ah,05F00h,0911Ch,06000h,0071Eh,09200h
dw 00080h,00081h,00082h,00083h,00084h,00085h,00086h,00087h
dw 00088h,00089h,0008Ah,0008Bh,0008Ch,0008Dh,0008Eh,0008Fh
dw 00090h,00091h,00092h,00093h,00094h,00095h,00096h,00097h
dw 00098h,00099h,0009Ah,0009Bh,0009Ch,0009Dh,0009Eh,0009Fh
dw 000A0h,000A1h,000A2h,000A3h,000A4h,000A5h,000A6h,000A7h
dw 000A8h,000A9h,000AAh,000ABh,000ACh,000ADh,000AEh,000AFh
dw 000B0h,000B1h,000B2h,000B3h,000B4h,000B5h,000B6h,000B7h
dw 000B8h,000B9h,000BAh,000BBh,000BCh,000BDh,000BEh,000BFh
dw 000C0h,000C1h,000C2h,000C3h,000C4h,000C5h,000C6h,000C7h
dw 000C8h,000C9h,000CAh,000CBh,000CCh,000CDh,000CEh,000CFh
dw 000D0h,000D1h,000D2h,000D3h,000D4h,000D5h,000D6h,000D7h
dw 000D8h,000D9h,000DAh,000DBh,000DCh,000DDh,000DEh,000DFh
dw 000E0h,000E1h,000E2h,000E3h,000E4h,000E5h,000E6h,000E7h
dw 000E8h,000E9h,000EAh,000EBh,000ECh,000EDh,000EEh,000EFh
dw 000F0h,000F1h,000F2h,000F3h,000F4h,000F5h,000F6h,000F7h
dw 000F8h,000F9h,000FAh,000FBh,000FCh,000FDh,000FEh,000FFh
skeyptr dw 0,0 ; for address of pointer in bios to key
; scan code/char translation table
ckeyptr dw 0,0 ; same for control keys (seg:offset)
kinitf db 0 ; flag to indicate pointers were found
keyng db "Unable to Find BIOS Key Translation Table Pointers"
db cr,lf,'$'
; [end jhw]
endif
; 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
ega_mode db 0 ; non-zero if IBM EGA is in use.
tvhere equ 0feh ; Topview active query
tvsynch equ 0ffh ; Topview resynch request
tv_segs dw ? ; Topview virtual screen, segment
tv_sego dw ? ; and offset
tv_mode db 0 ; flag, 0 = no Topview.
savadr dw 2 dup (?) ; offset then segment of saved screen
savflg dw ? ; low_rgt at time of screen save
;
swid2m db swidth * 2 ; used as divisor in getcirc [jhw]
curpost dw 0 ; temp storage for cursor position[jhw]
usevb db ? ; 1 if video board, 0 if Sanyo mode [rwb]
vbmsg db CR,'Video board in use',CR,LF,'$'
novbmsg db CR,'Sanyo mode screen',CR,LF,'$'
; The following are used to turn the display back on (after scrolling etc.)
msets db 2CH,28H,2DH,29H,2AH,2EH,1EH,29H
vtemu emulst <> ; emulator flags
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
scrsav dw ? ; segment address of save area
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.
cbuf ends
twnd cbuf <> ; top screen spill-buffer struct
bwnd cbuf <> ; bottom screen spill buffer struct
datas ends
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
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
; Figure out whether a Video board is in use by writing 2 different [rwb]
; characters to the same screen location with a DOS call and reading
; back from the correspnding video board memory location. Cursor is known
; to be in the first column before doing this, but may not be in the last row
; if the screen was recently cleared.
mov ax,0b800h ; VB segment
mov es,ax
mov ah,3
mov bh,0
int screen ; read cursor position
mov ax,0a0h ; length of row (2 bytes/char)
mul dh ; offset of current row, col 0
push ax ; save offset
mov ax,0a00h+'i'
mov cx,1
int SCREEN ; display 'i'
pop si ; recover offset
cmp byte ptr es:[si],'i' ; read character back (maybe)
jne lclynovb ; ne = no video board
push si ; save offset again
mov ax,0a00h+'V'
int SCREEN ; display 'V'
pop si ; recover offset
cmp byte ptr es:[si],'V' ; read it back
jne lclynovb ; ne = no video board
mov usevb,1 ; say video board
mov dx,offset vbmsg
jmp short lclyvb
lclynovb:
mov usevb,0 ; say no video board
mov dx,offset novbmsg
lclyvb: mov ah,9
int dos ; display msg with video board status
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!
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 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 al,crt_mode
mov crt_norm,al ; save as normal 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
test usevb,1 ; video board in use? [rwb]
jnz lcliniv ; nz = yes [rwb]
; [begin jhw]
; store ank segment:offset in topview
; pointers left over from IBM vers.
; (the ank buffer, sometimes called
; shadow buffer is an array of 4000
; bytes containing the char/attrib
; of all characters currently on
; the screen.
call scrseg ; get ank ram seg:offset in es:di
mov tv_segs,es ; store segment
mov tv_sego,di ; store offset
lcliniv:
ifdef MODIFIED
; find ptr to keyboard translation table (pointer is in BIOS keyboard
; interrupt service routine
ktest: xor ax,ax ; set segment register to
mov es,ax ; point to interrupt vector table
mov si,es:[3ech] ; get offset of int 0fb ser.rtn
mov es,es:[3eeh] ; and segment
mov cx,30h ; set safety counter
lcini3: cmp word ptr es:[si],1ec5h ; look for "lds bx"
je lcini4 ; found? yes, jump out of loop
inc si ; increment and try again
loop lcini3
jmp lclng ; not found, go tattle
lcini4: inc si
inc si ; point to arg of lds bx
mov di,es:[si] ; es:di pts at pointer to std key table
mov word ptr skeyptr,di ; store address of pointer
mov word ptr skeyptr+2,es ;
mov cx,30h ; set another safety counter
lcini5: cmp word ptr es:[si],1ec5h ; look for lds bx again
je lcini6 ; jmp out of loop if found
inc si ; point to next location
loop lcini5 ; and try again
lcini6: inc si ; point to arg of lds bx
inc si
mov di,es:[si] ; get pointer to control key table ptr
mov word ptr ckeyptr,di ; store address of pointer
mov word ptr ckeyptr+2,es
les si,dword ptr skeyptr
cmp word ptr es:[si],0 ; check present value in pointer
jne lclng ; should be fc00:0000 (0000 first)
cmp word ptr es:[si+2],0fc00h
jne lclng
les si,dword ptr ckeyptr ; check pointer for control key table
cmp word ptr es:[si],200h ; should be fc00:0200 (200 first)
jne lclng
cmp word ptr es:[si+2],0fc00h
jne lclng
mov kinitf,1 ; success, remember that
jmp lcini7 ; and go on
lclng: mov kinitf,0 ; failure, remember that too
mov ax,0900h ; and notify someone
mov dx,offset keyng
int 21h
mov word ptr skeyptr,0 ; zero pointers to pointers
mov word ptr skeyptr+2,0
mov word ptr ckeyptr,0
mov word ptr ckeyptr+2,0
endif
lcini7:
; [end jhw]
call vsinit ; init terminal emulator module MSZ
ret
lclyini endp
; ; [begin jhw]
ifdef MODIFIED
sbtabl proc near ; set ptr (in bios) to new key table
cmp kinitf,1 ; did we find the pointer?
jne sbtab9 ; no, skip this stuff
push di
push es
push ax
mov ax,offset dkeytab
shr ax,1
shr ax,1
shr ax,1
shr ax,1
add ax,seg dkeytab ; get segment of new table
les di,dword ptr skeyptr ; get address of standard key tab. ptr
mov word ptr es:[di+2],ax ; put seg. in -- offset doesn't change
les di,dword ptr ckeyptr ; get address of control key tab. ptr
mov word ptr es:[di+2],ax ; put segment in like before
pop ax ; that was it!
pop es
pop di
sbtab9: ret
sbtabl endp
;
rbtabl proc near ; set ptr (in bios) to new key table
cmp kinitf,1 ; did we find the pointer?
jne rbtab9 ; no, skip this stuff
push di
push es
push ax
mov ax,0fc00h ; get segment of original table
les di,dword ptr skeyptr ; get address of standard key tab. ptr
mov word ptr es:[di+2],ax ; put seg. in -- offset doesn't change
les di,dword ptr ckeyptr ; get address of control key tab. ptr
mov word ptr es:[di+2],ax ; put segment in like before
pop ax ; that was it!
pop es
pop di
rbtab9: ret
rbtabl endp
endif
; [end jhw]
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
scrin6: 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 VT102/52/Heath-19 terminal emulator.
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,'1' ; only port one possible on Sanyo [rwb]
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
; 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
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
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 ; and return
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
int screen ; clear mode line
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?
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 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
ifdef MODIFIED
call sbtabl ; reset kbd table [jhw]
endif
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?
jc lp1 ; yes, go display it [begin jhw]
; check for receipt of character which
; came in without generating interrupt
in al,cmd8251 ; get port status
test al,rxrdy ; is character in 8251?
jz chkinp ; no, go on
cli ; yes, hold interrupts and
int 0fah ; call the interrupt service routine
sti ; re-enable interrupts
call portchr ; get the character
jnc chkinp ; if there was no character, go on
lp1: call outtty ; else display it [end jhw]
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 ; [bjh]
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
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
int screen ; clear the mode line
quit1: mov ah,oldattr ; attributes at init time
mov scbattr,ah ; background = original state
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
ifdef MODIFIED
call rbtabl ; reset key trans table ptr [jhw]
endif
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)?
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
;[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 ; send 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...
clc ; no carry -> no character
ret ; and return...
portc1: and al,parmsk ; apply 8/7 bit parity mask
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.
call outprt ; Output, echo permitted
cmp flags.vtflg,tttek ; Tek terminal?
jne comar0 ; ne = 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
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 ; 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
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
;[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,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 IBM PC
; 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. 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]
csrtype proc near
push cx ; save the reg
test usevb,1 ; video board present?
jz sancsr ; z = no
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.
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:
csrty4: int screen ; regular cursor shape setting
pop cx
ret
; [begin jhw]
; Sanyo does not support small/large cursor changes without patching the
; BIOS. Since there are so many BIOS versions around, I considered it to be
; too risky to try to implement that here. So the following routine modifies
; the flash rate instead of the cursor size -- 0 for no cursor, 1 for slow
; (normal) flash, and 2 for rapid flash.
sancsr: push ax ; save cursor type
mov ax,0100h ; Sanyo bios is sequence sensitive on
xor cx,cx ; cursor type calls. Can't set fast
int SCREEN ; cursor from no cursor -- so set to
pop ax ; normal, then set to desired type
cmp al,0
jne csr1
mov cx,2600h ; set for no cursor
jmp csr3
csr1: cmp al,1
jne csr2
xor cx,cx ; set for slow cursor (normal)
jmp csr3
csr2: mov cx,107h ; set for quick flash
csr3: mov ah,1 ; ah=1 for cursor set bios call
int SCREEN
pop cx
ret ; [end jhw]
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
call scrseg ; get screen segment in ax and es:di
push ax ; save screen segment
mov si,0
test usevb,1 ; video board in use?
jnz savscv1 ; nz = yes
mov si,di
savscv1:
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
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
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]
test usevb,1 ; video board in use?
jz rstscv1 ; z = no
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
jmp short rstscv2
rstscv1:mov si,savadr
push savadr+2
pop es
dec cx
add si,cx ; move to end, reload backwards
add si,cx
xor ax,ax
mov bx,low_rgt
inc bh ; also do mode line
call atsclr ; clear screen before restoring
mov al,' '
mov ah,scbattr
mov temp,ax ; blank with background attribute
mov dx,low_rgt ; lower right corner
inc dh ; including mode line
rstsc1: mov ax,es:[si]
cmp ax,temp
je rstsc2 ; skip over blanks
mov ah,2 ; set cursor function
int SCREEN ; position cursor
mov ax,es:[si] ; get char and attribute
mov bl,ah
mov cx,1 ; number of chars to display
mov ah,9 ; write attribute and char function
int SCREEN ; display char
rstsc2: dec si
dec si
dec dl ; back one column
jge rstsc1 ; jump unless row done
mov dl,byte ptr low_rgt ; end of row
dec dh ; on to previous column
jge rstsc1 ; jump unless all done
;
rstscv2:
mov ah,2 ; set cursor position
mov bh,0 ; page 0
mov dx,cursor ; saved cursor position
int SCREEN ; position cursor
call scron ; turn on screen [dt]
pop cx ; recover count
call scrsync ; synch Topview with new screen
pop es
ret
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.
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 + 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)
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 ; And return.
scrmod endp
; Get screen segment - returns screen segment in ax, and full address in es:di
scrseg proc near
test usevb,1 ; video board in use?
jz scrsegv ; z = no
xor di,di ; start at beginning of screen (0,0)
mov ax,0B800H ; No - video memory is here on color
jmp short scrse1
scrsegv:push bx
push cx
mov ah,71h ; find shadow screen
int SCREEN
push ds
mov ds,ax
mov ax,[bx] ; ax:bx points to variable with segment
mov bx,cx ; can't do mov from [cx]
mov di,[bx] ; ax:cx points to variable with offset
mov es,ax
pop ds
pop cx
pop bx
cmp crt_mode,12 ; graphics set?
jb scrse1 ; b = no
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
scrse2: 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
test usevb,1 ; video board in use?
jz scrofx ; z = no
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 acs.
pop ax
scrofx: ret ; And return.
scroff endp
; Turn screen on for (known) color card modes only
; All registers are preserved.
scron proc near
test usevb,1 ; video board in use?
jz scronx ; z = no
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 acs.
pop dx
pop ax
scronx: 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]
atsclr: push ax ; Save some acs
push cx
push dx
test usevb,1 ; video board in use?
jz atsclv ; z = no
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 some more acs
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
jmp short atscl2
atsclv: push bx
push di
push si
mov cx,ax
mov dx,bx
mov ax,600h
mov bh,scbattr
int SCREEN
pop si
pop di
pop bx
atscl2: pop dx ; restore regs
pop cx
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 scroff ; turn off color screen
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
call scron ; turn on screen again
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
call scroff
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
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
; prep for screen scroll down.
; 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
call scroff ; turn off screen
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
call scron ; turn on display again
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
call scroff ; turn off display
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
call scron ; turn on display again
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 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 ; and return
getci1: ; top and bottom window common code
test usevb,1 ; video board in use?
jz getci1v ; z = no
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
rep movsw
pop ds ; recover original data segment
pop cx ; length for Topview
push cx ; save again
jmp getci2v
getci1v:mov si,[bx].pp ; this is source [begin jhw]
push es ; calculate screen location
push di
call scrseg ; get start of ank seg in es:di
pop ax ; restore current curs posit. in ank seg
sub ax,di ; compute cursor offset from above
pop es
div swid2m ; row in al,col in ah
xchg ah,al ; ax now contains row/col
push ax
mov al,' ' ; [rwb]
mov ah,scbattr ; [rwb]
mov temp,ax ; blank with background attribute [rwb]
mov ax,0300h ; save present cursor position
int SCREEN
mov curpost,dx
pop dx ; retrieve row/col (was in ax)
; write line to screen
push bx ; save bx before reusing in bios call
push es ; save es
mov es,[bx].orig ; get segment for circular buffer
mov cx,swidth ; # of characters to copy per line
getci1a:
mov bx,es:[si] ; get character and attribute [rwb]
cmp bx,temp ; is it a blank with proper attr [rwb]
je getci1x ; yes, no need to display [rwb]
push si ; potentially zapped by int 10h [rwb]
push cx ; save character count for loop counter
mov ax,0200h
int SCREEN ; position the cursor
mov ax,bx ; get attr/char in ah,al [rwb]
mov bl,ah
mov cx,1
mov ah,09
int SCREEN ; display character with attribute
pop cx ; restore character count
pop si ; [rwb]
getci1x:
inc si
inc si
cmp dl,79 ; are we at end of line?
jae getci1b
inc dl
getci1b:
loop getci1a ; loop until line is written
pop es ; restore es
;
mov dx,curpost ; restore the cursor to where it was
mov ax,0200h
int SCREEN ; above code assumes dx is preserved
; through bios calls [end jhw]
pop bx ; restore bx [jhw]
mov cx,swidth ; length for Topview
push cx ; save again
getci2v:
call scrsync ; synch Topview
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
;
; CHGDSP dummy routine which sets 132 col display boards on ibm
; not useful on 550
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