home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
mskermit
/
msyz10.asm
< prev
next >
Wrap
Assembly Source File
|
2018-01-01
|
75KB
|
2,421 lines
NAME msyz10
; File MSYZ10.ASM
include mssdef.h
; Copyright (C) 1982,1991, Trustees of Columbia University in the
; City of New York. Permission is granted to any individual or
; institution to use, copy, or redistribute this software as long as
; it is not sold for profit and this copyright notice is retained.
; Kermit system dependent module for Heath/Zenith Z100
; Edit history
; 2 March 1991 version 3.10
; Last change: 3 November 1990.
; Minor changes to outtty and outprt. Added setchtab, modified termtb.
; Putcirc and getcirc have been modified from msyibm and added but remains
; untested and inactive. VTS and VTSTAT and most of the corresponding data
; is kept in msx in order to allow assemly of this file , msy, with MASM 4.
; Procedures savescr, restscr, atsclr and setcol added and calls to these
; added to scrini and quit. Procedure revscn (2 variants) added.
; Procedure dumpscr moved from msxz10.asm and restructured to allow general
; use of some code now put in local subroutines rdset, rdlne and endfix.
; Procedure scroll added, to allow 26 lines scrolling entirely in video
; memory, provided 64k video ram chips are installed.
; Handling of ESC E and ESC J in outtty for the S-100 ports, COM3/COM4,
; refined.
; Getpos and setpos corrected (dl = col, dh = row, comments incorrect in
; msyibm.asm).
;
; Bo Gedda
;
public term, lclyini, holdscr, scroll, savescr, restscr, atsclr
public outprt, prtbout, chrout, vclick, vtemu, yflags
public cquit, udkclear, low_rgt, vtclear, getpos, setpos
public csrtype, termtb, comptab, ontab, beltab
public scrtab, curtab, chatab, cntltab, kpamtab, dirtab
public vtbell, dumpscr, fcsrtype
public f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, sf0
public sf1, sf2, sf3, sf4, sf5, sf6, sf7, sf8, sf9, sf10, sf11
public i_chr, d_chr, i_line, d_line
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, cstatus, cquit
public out8bit, trnmod, cdos, cquery, chang, trnprs, dmpscn
public homwnd, endwnd, dnwpg, upwpg, upone, dnone, klogon, klogof
public snull, doscol, setcol, revscn, lincur
public belltype, vtroll, setchtab
public extmacro, vtmacname, vtmaclen
true equ 1
false equ 0
delaycount equ 1fffh ; Range 1h to 0h (ffffh + 1h = 0h!)
; Entry points to ROM monitor
MTR_SEG SEGMENT AT 0FE01H ; Segment addr for Monitor ROM calls
ORG 000H
MTR_RES LABEL FAR ; Reset function
ORG 005H
MTR_MON LABEL FAR ; Monitor call
ORG 00AH
MTR_SWIM LABEL FAR ; Trace/breakpoint handler
ORG 00FH
MTR_DCRT LABEL FAR ; Dumb display output
ORG 014H
MTR_DKBD LABEL FAR ; Dumb keyboard handler
ORG 019H
MTR_SCRT LABEL FAR ; Smart display output
ORG 01EH
MTR_SKBD LABEL FAR ; Smart keyboard input
ORG 023H
MTR_TTY_INTR LABEL FAR ; Vertical retrace interrupt handler
MTR_SEG ENDS
MTR_D_SEG SEGMENT AT 0 ; Monitor data segment(not really at 0)
ORG 000H
; Monitor Parameters
MTR_WIP LABEL FAR ; Far jump to wild interrupt handler
DB 5 DUP(?) ; the far jump
MTR_VER DB ? ; BCD version of ROM monitor
MTR_CVER EQU 01H ; Lowest version BIOS can run on
MTR_DS_SIZE DW ? ; Size of the ROM monitor data segment
; Boot parameters
MTR_BINDX DB ? ; Boot device index
MTR_BPORT DB ? ; Boot device base port number
MTR_BSTRING DB 80 DUP(?) ; Boot string
MTR_BUNIT DB ? ; Boot unit number
; Pointers to All sorts of things
MTR_DCI DD ? ; Addr of Display Character Initialization
MTR_DFC DD ? ; Addr of Display Font Character Routine
MTR_DXMTC DD ? ; Addr of Dumb Keyboard Transmit Character
MTR_EDC DD ? ; Addr of Erase Display Character Routine
MTR_EMEC DD ? ; Addr of Escape Character Handler Routine
MTR_FONT DD ? ; Addr of Character Font table
MTR_FNT_SIZE EQU 9*(256-' ') ; Size of reserved font table
; number of bytes copied from rom font
; area if version = 1)
MTR_MDC DD ? ; Addr of Move Display Characters Routine
MTR_MDL DD ? ; Addr of Move Display Line Routine
MTR_PROMPT DD ? ; Addr of Display ROM Monitor Prompt Routine
MTR_RDC DD ? ; Addr of Read Displayed Character Routine
MTR_SXMTC DD ? ; Addr of Smart Keyboard Transmit Character
MTR_UIES DD ? ; Addr of Unimplemented Escape Sequence
MTR_XCA DD ? ; Addr of Transmit Character Attributes
MTR_FNTSIZ DW ? ; Size of FONT in bytes (If version > 1)
MTR_KYB DB 256 DUP (?) ; Keyboard map table
MTR_CHR DB 256 DUP (?) ; Display map table
MTR_HORP DB ? ; Horizontal position of cursor (column)
MTR_VERP DB ? ; Vertical position of cursor (row)
MTR_MIB DB ? ; Base interrupt number for master
MTR_SIB DB ? ; Base interrupt number for slave
MTR_RESF DB ? ; Reset flag to re-enter monitor
; Color structure
ORG 2A1H
FORE DB ? ; Current foreground color
BACK DB ? ; Current backpround color
MSK DB ? ; Color to mask
CLEAR DB ? ; Color to clear
PAINTED DB ? ; Color to paint
PFONT DB ? ; Color to set to font pattern
COMP_FONT DB ? ; Color to set to complement of font pattern
; These are the new ones
BACK_CB DB ? ; Back control bits
BACK_SEG DW ? ; Back segment
CP_BACK_CB DB ? ; Complement back control bits
CP_BACK_SEG DW ? ; Complement back segment
CLEAR_CB DB ? ; Clear control bits
CLEAR_SEG DW ? ; Clear segment
PAINTED_CB DB ? ; Painted control bits
PAINTED_SEG DW ? ; Painted segment
PFONT_CB DB ? ; Font control bits
PFONT_SEG DW ? ; Font segment
CP_FONT_CB DB ? ; Complement font control bits
CP_FONT_SEG DW ? ; Complement font segment
; CRT-C display structure
ORG 2BDH
DISP_START DW ? ; CRT-C display start address
DISP_UPDATE DB ? ; FF to request update
; H-19 mode structure
ORG 2D1H
BWO DB ? ; Black/white optimization
ORG 2DBH
STATUS DB ? ; FF modeline on, 0 modline off
; H-19 parameter structure
ORG 2E1H
PROVRAM DB ? ; 0 = monochrome, 3 = color
ORG 2E6H
VRAM_SIZE DB ? ; 0 = 32k, 1 = 64k
MTR_D_SEG ENDS
IPAGE_SEG SEGMENT AT 0 ; The interrupt area page
ORG 03FEH
MTR_DS LABEL WORD ; Location that contains monitor DS value
IPAGE_SEG ENDS
;bios definitions
BIOS_SEG SEGMENT AT 40H ; Define segment where BIOS really is
ORG 1*3
BIOS_STATUS LABEL FAR ; Console input status
ORG 2*3
BIOS_CONIN LABEL FAR ; Console input
ORG 3*3
BIOS_CONOUT LABEL FAR ; Console output
ORG 4*3
BIOS_PRINT LABEL FAR ; Printer output
ORG 6*3
BIOS_AUXOUT LABEL FAR ; AUX output routine
ORG 25*3
BIOS_PRNFUNC LABEL FAR ; PRN: FUNCTION
ORG 26*3
BIOS_AUXFUNC LABEL FAR ; AUX: function
ORG 27*3
BIOS_CONFUNC LABEL FAR ; CON: function
BIOS_SEG ENDS
; Define functions of BIOS_CONFUNC, BIOS_PRNFUNC, and BIOS_AUXFUNC
CHR_WRITE EQU 0 ; Write function
CHR_READ EQU CHR_WRITE+1 ; Read function
CHR_STATUS EQU CHR_READ+1 ; Status function
CHR_SFGS EQU 0 ; Get status subfunction
CHRS_WA EQU 00000001B ; <ETX> sent, waiting for <ACK>
CHRS_WD EQU 00000010B ; <DC3> seen, waiting for <DC1>
CHRS_SN EQU 00000100B ; Sending nulls
CHRS_TXR EQU 10000000B ; Transmitter ready to send data
CHRS_RXR EQU 01000000B ; Receiver has data
CHRS_RXOF EQU 00100000B ; Receiver queue overflow
CHRS_RXE EQU 00010000B ; Other type of reciver error
CHRS_TXE EQU 00001000B ; Transmitter error
CHR_SFGC EQU CHR_SFGS+1 ; Get configuration info subfunction
CHR_CONTROL EQU CHR_STATUS+1 ; Control function
CHR_CFSU EQU 0 ; Setup new configuration parms subfunction
CHR_CFCI EQU CHR_CFSU+1 ; Clear input subfunction
CHR_CFCO EQU CHR_CFCI+1 ; Clear output subfunction
CHR_LOOK EQU CHR_CONTROL+1; Nondestructive read function
CHR_FMAX EQU CHR_LOOK ; Maximum function number
; Z-100 Keyboard commands
keyrst equ 00h ; reset
keyrpon equ 01h ; auto repeat on
keyrpof equ 02h ; auto repeat off
keyclon equ 03h ; click on
keyclof equ 04h ; click off
keyclr equ 05h ; clear buffer
keycli equ 06h ; make key click
keybel equ 07h ; make bell sound
keyena equ 08h ; enable keyboard
keydis equ 09h ; disable keyboard
keyeve equ 0ah ; make keyboard event driven (up/down mode)
keyasc equ 0bh ; make keyboard scan ascii
keyiena equ 0ch ; enable interrupt
keyidis equ 0dh ; disable interrupt
; Definitions for cursor type.
; bit 0 set = 1 => Cursor on cleared = 0 => Cursor off
; bit 1 set = 2 => Block cursor cleared = 0 => Underline cursor
; bit 2 set = 4 => Non blinking cursor cleared = 0 => Blinking cursor
cur_on equ 1 ; 00000001b
cur_blo equ 2 ; 00000010b
cur_nob equ 4 ; 00000100b
; Miscellaneous scan codes used for functions
prscan equ 0a2h ; print-screen scan code (F12)...
brkscan equ 0aah ; Break key
COLUMNS EQU 80 ; Characters per screen line
ROWS EQU 24 ; Text lines per screen
VID_CMD EQU 0d8h ; Video-memory control port
VID_NOR EQU 01111000b ; Video access on, individual color write
; only, all colors displayed
PAR_GRN EQU 0e000h ; Green video plane segment address
PAR_RED EQU 0d000h ; Red video plane segment address
PAR_BLU EQU 0c000h ; Blue video plane segment address
; Kinds of terminals available
;ttgenrc equ 0 ; Type 0: no emulation done by Kermit
;ttheath equ 1 ; Type 1: Heath-19
;ttvt52 equ 2 ; Type 2: VT52
;ttvt100 equ 3 ; Type 3: VT102
;TTTYPES equ 4 ; Number of terminal types defined
; DEC emulator status flags (bits in words vtemu.vtflgst and vtemu.vtflgop)
;anslnm equ 1H ; ANSI line feed/new line mode
;decawm equ 2H ; DEC autowrap mode
;decscnm equ 80H ; DEC screen mode
;decckm equ 200H ; DEC cursor keys mode
;deckpam equ 400H ; DEC keypad application mode
;decom equ 800H ; DEC origin mode
;deccol equ 1000H ; DEC column mode (0=80 col)
;decanm equ 2000H ; ANSI mode
;dececho equ 4000H ; ANSI local echo on (1 = on)
;
; Terminal SETUP mode flags (joint with bits above, some name dups)
;vsnewline equ 1H ; ANSI new line (0 = off)
;vswrap equ 2H ; Line wrap around (0 = no wrap)
;vsnrcm equ 4H ; National Rep Char set (0=none)
;vswdir equ 8H ; Writing direction (0=left, 1 right)
;vskeyclick equ 10H ; Keyclick (0 = off)
;vsmarginbell equ 20H ; Margin bell (0 = off)
;vscursor equ 40H ; Cursor (0 = block, 1 = underline)
;vsscreen equ 80H ; Screen (0 = normal, 1 = rev. video)
;vscntl equ 100h ; 8 or 7 bit controls (1 = 8-bit)
; bit for flag byte
havtt equ 10h ; have translate table
modfrm struc ; format of mode line
db 'Esc chr: '
m_echr db 2 dup (?)
db ' Help: '
m_hlp db 2 dup (?)
db '?'
db ' Port: '
m_prt db 1 dup (?)
db ' Speed: '
m_baud db 4 dup (?)
db ' Parity: '
m_par db 4 dup (?)
db ' Echo: '
m_echo db 3 dup (?)
db ' '
m_emul db 10 dup (?)
m_pad db 1 dup (?)
db ' '
m_prn db 3 dup (?)
db '$'
modfrm ends
data segment
extrn flags:byte, caplft:byte, portval:word, trans:byte
extrn klen:word, ktab:word, krpl:word, flowon:byte, flowoff:byte
extrn dosnum:word, kbdflg:byte, kbcodes:byte, npages:word
extrn taklev:byte, takadr:word, mcctab:byte, dupflg:byte
extrn ttyact:byte, dmpname:byte, filtst:byte, rdbuf:byte
extrn prnhand:word
anspflg db 0 ; printer flag bits and definitions
vtmacname dw 0 ; pointer to selected macro name
vtmaclen db 0
udkseg dw 18 dup (0) ; segment of user definable key defs
oldsp dw 0 ; offset to longjmp to for i/o failure
inited equ 08h ; been here before
vtinited db 0 ; flag for emulator having been inited
cursor dw 0
lincur dw ? ; cursor type save area
doscol db ?,? ; foreground col, background col
tercol db 6,0 ; foreground col, background col
dosattr db ? ; screen attributes at init time
tv_segs dw 0 ; Topview virtual screen, segment
tv_sego dw 0 ; and offset
yflags db 0 ; status flags
argadr dw ? ; address of arg blk
savadr dw 2 dup (0) ; offset then segment of saved screen
trmtyp dw 0 ; most recent terminal type
vtclear db 0 ; nonzero to redo emulator screen
insert db 'O' ; flag for overwrite/insert mode, O/@
temp dw 0 ; scratch storage
pntmsg db 'Printer not ready, printing request skipped$'
pntptr dw dumpbuf ; pointer to next free byte in buffer
dumplen equ 132
dumpbuf db dumplen dup (?) ; / 134 byte dump work buffer
crlf db cr,lf,'$' ; \ needs these too
scbattr db ? ; screen background attribute
belltype db 0 ; 0 = aural bell, 1 = visual
fairness dw 0
savattr db 78h ; cur. emul. attrib., 78h = all colors
fairprn dw 0
parmsk db 0 ; 8/7 bit parity mask, for reception
captrtn dw 0 ; routine to call for captured output
portno db 0
memerr db cr,lf,'Not enough memory for terminal emulator$'
vstate db 0 ; Video ram port-status at invocation.
int_cy dw 0 ; Vertical screen index (line number).
line db (COLUMNS+4) dup (0) ; Screen's line buffer.
lines dw 0 ; Number of lines valid on screen.
eos db 0 ; flag: 0= not end of screen, 1= yes.
dmphand dw ? ; screen dump file handle [jrd]
dmperr db cr,' Cannot open save screen file $'
dmperr1 db cr,' Cannot write save screen file $'
holdscr db 0 ; Hold-Screen, non-zero to stop reading
; storage for multi-window stuff
swidth equ COLUMNS ; max screen width, 80
slen equ ROWS ; and length of text, 24
crt_norm db 3 ; video mode for normal screen
crt_mode db 3 ; video mode (typ 3, must be text)
crt_cols db COLUMNS ; number of screen columns (typ 80)
crt_lins db ROWS ; number of screen rows - 1 (typ 24)
low_rgt dw 174fh ; lower right corner of text window
startad dw 0 ; storage for CRTC Start Address
refresh db 0 ; screen refresh (0=wait for retrace)
vtroll db 0 ; auto roll back allowed (0 = no)
inipara dw 0 ; initial paragraphs of scroll memory
even ; screen rollback material
iniseg dw ? ; (BDT) initial seg of scroll memory
ppl dw 0 ; (BDT) paragraphs per line
lcnt dw 0 ; (BDT) number of "filled" buffer lines
linef dw 0 ; (BDT) "first" filled line is here
linec dw 0 ; (BDT) "current" screen line number
linee dw 0 ; (BDT) total # of lines in the buffer
lmax dw 0 ; (BDT) max lines in buff (less 1 scrn)
lxtra dw 0 ; (BDT) "extra" lines rqd for screen
; begin video ram complement storage
vidmsg db cr,' Cannot scroll, need 64k video ram $'
mtrmsg db cr,lf,'Monitor boot rom must be Version 2.5 or above. Refer '
db 'to your Z-100 Manual$',cr,lf
; begin Terminal emulator data set
setchtab db 6 ; Set File Character-Set table
mkeyw 'CP437',437 ; hardware default Code Page
mkeyw 'CP850',850 ; Multilingual CP
mkeyw 'CP860',860 ; Portuguese CP
mkeyw 'CP863',863 ; French Canadian CP
mkeyw 'CP865',865 ; Norwegian CP
mkeyw 'CP866',866 ; Latin5/Cryillic CP
termtb db 2 ; entries for Status, not Set
mkeyw 'Heath-19',ttheath
mkeyw 'none',ttgenrc
comptab db 12 ; Twelve entries.
mkeyw '1',1
mkeyw '2',2
mkeyw '3',3
mkeyw '4',4
mkeyw 'COM1',1
mkeyw 'COM2',2
mkeyw 'COM3',3
mkeyw 'COM4',4
mkeyw 'A',2
mkeyw 'B',1
mkeyw 'J1',2
mkeyw 'J2',1
cntltab db 2 ; 8-bit controls
mkeyw '7-bit',0
mkeyw '8-bit',1
scrtab db 2 ; screen attributes
mkeyw 'normal',0
mkeyw 'reverse',1
ontab db 2 ; two entries
mkeyw 'off',0
mkeyw 'on',1
chatab db 14 ; National Replacement Character sets
mkeyw 'ASCII',0 ; ASCII is default (0, no NRC)
mkeyw 'British',1 ; start NRC set (1-12)
mkeyw 'Dutch',2
mkeyw 'Finnish',3
mkeyw 'French',4
mkeyw 'Fr-Canadian',5
mkeyw 'German',6
mkeyw 'Italian',7
mkeyw 'Norwegian/Danish',8
mkeyw 'Portuguese',9
mkeyw 'Spanish',10
mkeyw 'Swedish',11
mkeyw 'Swiss',12 ; end of NRC proper
mkeyw 'Transparent',14 ; use native display adapter hardware
curtab db 3 ; cursor attributes
mkeyw 'block',0
mkeyw 'underline',1
mkeyw 'none',2
beltab db 3 ; bell type
mkeyw 'audible',0
mkeyw 'visual',1
mkeyw 'none',2
dirtab db 2 ; writing direction
mkeyw 'left-to-right',0
mkeyw 'right-to-left',1
kpamtab db 2 ; keypad, application
mkeyw 'Numeric',0
mkeyw 'Application',1
flags1 db 0 ; internal flags
prtscr equ 80h ; print screen pressed flag
escflg db 0 ; esc character received flag
padflg db 0 ; keypad mode changed flag
ansflgs dw 0 ; ANSI/VT100 mode flags
; (flags are defined in mssdefs.h)
vtemu emulst <> ; emulator flags
eeolstr db ESCAPE,'K$' ; Erase to end of line
enascan db ESCAPE,'y?$' ; Enable scan codes, disable key expansion
disscan db ESCAPE,'x?$' ; Disable scan codes, enable key expansion
enacurs db ESCAPE,'y5$' ; Enable cursor
discurs db ESCAPE,'x5$' ; Disable cursor
enablnk db ESCAPE,'y;$' ; Enable cursor blink
disblnk db ESCAPE,'x;$' ; Disable cursor blink
enabloc db ESCAPE,'x4$' ; Enable block cursor
enaunde db ESCAPE,'y4$' ; Enable underscore cursor
savcur db ESCAPE,'j$' ; Save current cursor position
begrev db ESCAPE,'p$' ; Enter reverse video
padpos db ESCAPE,'Y8k$' ; Row 25 column 75
endrev db ESCAPE,'q$' ; Exit reverse video
precur db ESCAPE,'k$' ; Restore cursor to previous position
modbuf modfrm <> ; mode line buffer
; some static data for mode line
unkbaud db 'Unk ' ; must be 4 chars...
baudn db '45.5'
db ' 50'
db ' 75'
db ' 110'
db ' 135'
db ' 150'
db ' 300'
db ' 600'
db '1200'
db '1800'
db '2000'
db '2400'
db '4800'
db '9600'
db ' 19K'
db ' 38K'
baudnsiz equ 16 ; # of baud rates known (tbl size / 4)
parnams db 'Even'
db 'Mark'
db 'None'
db 'Odd ' ; must be 4 chars
db 'Spc '
lclmsg db 'Lcl'
remmsg db 'Rem'
prmsg db 'PRN'
db ' '
noleds db ' None ' ; For no emulation
ansleds db 'VT102 ....' ; "LEDs". Terminal ident (10 bytes)
v52leds db ' VT52 ' ; This is used in VT52 mode
h19leds db ' Heath-19 ' ; For Heath-19 mode
vtable dw ontab, ontab, chatab, dirtab ,ontab, ontab, curtab, scrtab
dw cntltab, kpamtab, 0
; which are newline wrap char direct key margin cursor screen
; controls key-app
data ends
code1 segment
fcsrtype proc far
ret
fcsrtype endp
code1 ends
code segment
extrn prtchr:near,outchr:near,putmod:near,clrmod:near,sendbr:near
extrn sprtch:near, beep:near, pcwait:near, poscur:near, cmblnk:near
extrn msuinit:near, keybd:near, keycom:near, isfile:near, outch2:near
extrn atoi:near, strlen:near
extrn comnd:near, statc:near, replay:near, pntchr:near, pntflsh:near
assume cs:code, ds:data, es:nothing
; 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
mov ax,ipage_seg ; the interrupt page
mov es,ax
mov es,word ptr es:mtr_ds ; find monitor data segment here
cmp es:MTR_VER,25 ; Must be higher than Version 2.5
jnl lclyini1
mov ah,prstr ; Tell user and abort
mov dx,offset mtrmsg
int dos
mov ah,4ch
int dos
lclyini1:mov ax,word ptr es:FORE ; get current colors
mov word ptr doscol,ax ; save it
in al,VID_CMD ; Get the current video status.
mov dosattr,al ; Save it.
mov al,VID_NOR ; Set up video to normal
out VID_CMD,al ; suit us, normally all colors active
call msuinit ; initialize keyboard module msuxxx
mov al,1 ; underscore
call csrtype ; turn on underline cursor
; call getpos ; get cursor position
; mov ax,1 ; underline cursor
; call setpos ; set cursor position and type
; screen roll back buffers
mov al,crt_lins ; physical length of user area
mul crt_cols ; physical width
add ax,7 ; round up
mov cl,3
shr ax,cl ; bytes/screen to paragraphs/screen
mov si,ax ; save a copy in si
mov bx,npages ; number of roll back screens wanted
inc bx ; include current screen in count
mul bx ; total number of screens wanted
mov cx,ax ; save total wanted paragraphs in cx
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 bx,26000D/16 ; space for Command.com copy #2
jc lclyin2 ; c = not enough for it
cmp bx,si ; minimum roll back space left over?
jle lclyin2 ; le = not even that much
cmp bx,cx ; got vs wanted paras for roll back
jle lclyin3 ; le = enough but not more than needed
mov bx,cx ; limit to our actual needs
jmp short lclyin3 ; ask for all we really want
lclyin2:xor bx,bx ; use no space at all
mov cx,bx ; remember this new request
lclyin3:mov ah,alloc
int dos
mov tv_segs,PAR_GRN ; the green video plane holds it all
mov tv_sego,0 ; and it starts at PAR_GRN:00
mov iniseg,ax ; (BDT) memory segment, window area
mov inipara,bx ; save for later resizing of buffers
cmp cx,bx ; paragraphs wanted vs delivered
jae lclyin4 ; ae = enough
mov ah,prstr
mov dx,offset memerr ; say not enough memory to operate
int dos
mov flags.extflg,1 ; set Kermit exit flag
lclyin4:call bufadj ; set roll back buffer parameters
; call vsinit ; init terminal emulator module MSZ
; mov bx,vtemu.att_ptr ; attributes pointer
; mov ah,dosattr ; startup video attributes
; and ah,not att_intensity ; emulation intensity to normal
; or ah,userbold
; mov [bx],ah ; set initial emulation attributes
ret
lclyini endp
; This is the terminal emulator.
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
or kbcodes,80h ; set need-to-init flg for kbd xtlator
mov bx,portval ; port data structure address
mov bx,[bx].flowc ; get flow control chars (bl=xoff)
mov flowon,bh
mov flowoff,bl ; save for later
mov oldsp,sp ; remember stack for i/o failure,
; used by procedure endcon
mov fairprn,0 ; set printer buffer flush counter
lp: call prtchr ; char at port?
jnc short lpinp ; nc = yes, go handle
cmp flags.comflg,2 ; check if S-100 ports
ja lpkbd ; yes, go do it the simple way
push bx
mov bx,portval ; port structure address
cmp [bx].portrdy,0 ; is port ready for business?
pop bx
jne lpkbd ; ne = ready
jmp endcon ; end the communications now
lpkbd: mov fairness,0 ; say kbd was examined
inc fairprn ; inc printer dump counter
cmp fairprn,1000 ; been here enough times now?
jb lpkbd1 ; b = no
cmp flags.comflg,2 ; check if S-100 ports
ja lpkbd1 ; yes, this will delay us too much
call pntflsh ; flush printer buffer
mov fairprn,0 ; reset for next time
lpkbd1: call keybd ; call keyboard translator in msu
jnc lp ; nc = no char or have processed it
jmp short quit ; carry set = quit connect mode
lpinp: and al,parmsk ; apply 8/7 bit parity mask
call outtty ; print on terminal
inc fairness ; say read port but not kbd, again
cmp fairness,100 ; this many port reads before kbd?
jb lp ; b = no, read port again
jmp short lpkbd ; yes, let user have a chance too
quit: mov ah,scbattr ; current emulator attributes
mov savattr,ah ; save them here
call pntflsh ; flush printer buffer
call getpos ; get cursor position into dx
mov cursor,dx ; save position
mov al,1 ; underscore
call csrtype ; turn on underline cursor
cmp flags.vtflg,0 ; terminal type of none?
je quit1 ; e = yes
cmp flags.modflg,2 ; is modeline owned by remote host?
je quit1 ; e = yes
call clrmod ; clear it before storing screen
quit1:
call savescr ; save screen
mov dh,byte ptr low_rgt+1 ; bottom line
xor dl,dl ; left most column
call setpos ; set cursor position
mov dx,word ptr doscol ; set color back to dos values
xchg dl,dh ; get the sequence right
call setcol
mov al,VID_NOR ; reset video port
out VID_CMD,al
mov al,yflags
and al,not lclecho ; don't copy host's echo flag
mov bx,argadr
mov ah,[bx].flgs ; get user's flag settings
and ah,lclecho ; clear all but local echo bit
or [bx].flgs,al ; update flags in arg block
ret
term endp
argini proc near ; read passed arguments
mov bx,argadr ; base of argument block
mov al,[bx].flgs ; get flags
and al,capt+emheath+trnctl+lclecho+modoff
mov yflags,al ; mask for allowable and save
mov al,[bx].prt
mov portno,al ; update port number
mov crt_lins,ROWS ; init # of rows
mov ax,[bx].captr
mov captrtn,ax ; buffer capture routine
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
scrini proc near ; init screen stuff
mov dx,word ptr tercol ; set terminal color
xchg dl,dh ; get the sequence right
call setcol
call clrmod ; clear mode line
test yflags,modoff ; is mode line disabled?
jnz scrin1 ; yes, skip it
call modlin ; turn on mode line
scrin1:
cmp flags.vtflg,0 ; terminal type of None?
ja scrin3 ; a = no, emulating
;some code?
scrin3:
in al,VID_CMD ; Get the current video status.
mov savattr,al ; Save it.
mov scbattr,al ; Here too
mov dx,cursor ; use old cursor, if any
call restscr ; restore screen, if any saved
call setpos ; set cursor position
or flags1,inited ; remember we've run already
cmp flags.vtflg,0 ; current terminal type = None?
je scrin13 ; e = yes, nothing to init
cmp vtclear,2 ; screen need clearing?
jae scrin10 ; ae = yes, do emulator reinit now
cmp vtinited,inited ; inited emulator yet?
je scrin11 ; e = yes
scrin10:call vtinit ; init it now
jmp short scrin13
scrin11:
; call ansrei ; reinit the emulator
scrin13:mov ax,flags.vtflg ; current terminal type
mov trmtyp,ax ; place to remember it til next time
mov vtclear,0 ; say screen is updated
ret
scrini endp
; Routine to initialize VT102/52/Heath-19 terminal emulator.
vtinit proc near
mov holdscr,0 ; clear holdscreen
mov ah,conout
mov dl,ESCAPE ; Take the
int dos ; Z-100
mov dl,'y' ; terminal
int dos ; out of
mov dl,'3' ; holdscreen
int dos ; mode
or vtinited,inited
cmp flags.vtflg,0 ; doing emulation?
je vtinix ; e = no
mov bx,argadr ; address of argument block
mov dl,[bx].flgs
and dl,lclecho ; local echo flag
and yflags,not lclecho
or yflags,dl
mov dl,[bx].baudb ; baud rate code in dl
mov dh,[bx].parity ; parity code in bits
mov cl,4 ; 0-3 of dh
shl dh,cl
or dh,07H ; just say 7 data bits
test flags.remflg,d8bit ; eight bit display?
jz vtini1 ; z = no
inc dh ; set low four bits to value 8
vtini1:
; call ansini ; call startup routine
vtinix: clc
ret
vtinit endp
trnprs: push ax ; toggle ^ PrtSc screen to printer
test flags1,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,prnhand ; file handle for Connect printing
int dos
pop bx
jc trnpr1 ; c = printer not ready
cmp al,0ffh ; Ready status?
je trnpr2 ; e = Ready
trnpr1: call vtbell ; Not Ready, complain
jmp trnpr3 ; and ignore request
trnpr2: xor flags1,prtscr ; flip the flag
test yflags,modoff ; mode line off?
jnz trnpr3 ; nz = yes
call modlin ; else rewrite mode line
call pntflsh ; print the last of printer buffer
trnpr3: pop ax
clc ; return carry clear (don't quit)
ret
; Put the character in al to the screen.
; Monitor rom calls used in emulator mode for speed reasons.
; The Z-100 screen is very slow in the handling of esc E and esc J;
; if esc E or esc J and S-100 modem, trap these and do it our own way
; while polling port in order to avoid loosing characters at port.
; The esc sequencies esc x ?, esc y ? and esc y @ are trapped and defused
; as these would either lock up the keyboard or interfere with the function
; of the keys.
outtty proc near
cmp escflg,true ; Esc last time?
jl outtt04 ; No, but maybe this time
jz outtt01 ; Yes
jmp outtt31 ; No, but earlier
outtt01:cmp al,'=' ; Is it =?
jnz outtt02 ; No, go on
mov ansflgs,deckpam ; Yes, it is application keypad mode
or vtemu.vtflgop,deckpam ; here too
mov modbuf.m_pad,'A'; A for Application
mov padflg,true ; Keypad mode changed
jmp outtt03
outtt02:cmp al,'>' ; Is it >?
jnz outtt1 ; No, go on
mov ansflgs,false ; Yes, it is numeric keypad mode
and vtemu.vtflgop,not deckpam
mov modbuf.m_pad,'N'; N for Numeric
mov padflg,true ; Keypad mode changed
outtt03:mov escflg,false ; reset
jmp outtt4 ; Go display it
outtt04:cmp al,ESCAPE ; Esc now?
jnz outtt05 ; No
mov escflg,true
outtt05:jmp outtt4 ; Go display it
outtt1: inc escflg ; Count
cmp escflg,true
jnz outtt11
mov escflg,false ; reset
outtt11:cmp al,ESCAPE ; Esc now?
jnz outtt2 ; No, just go on
mov escflg,true ; Yes, set escflg to 1
outtt2: cmp al,'x' ; Yes, set modes?
jz outtt05 ; Yes, just deliver
cmp al,'y' ; Reset modes?
jz outtt05 ; Yes, just deliver
mov escflg,false ; reset
cmp flags.comflg,2 ; check if S-100 ports
jle outtt4 ; no, go do it the simple way
cmp al,'E' ; Is it E?
jz outtt3 ; Yes, go handle
cmp al,'J' ; Is it J?
jnz outtt4 ; No, go write the character
push ax ; Need this later
jmp short outtt3a ; Have ESC J
outtt3: push ax ; Yes, we have ESC E
mov ah,conout ; break it up into smaller parts,
mov dl,'H' ; first, home cursor (ESC was sent before)
int dos
mov dl,ESCAPE ; Send ESC again (first part of ESC j)
int dos
outtt3a: ; This is where we handle ESC J
mov cx,1 ; No delay for sprtch
call sprtch ; Go get possible char at port
mov ah,conout
mov dl,'j' ; Save cursor position (ESC was sent before)
int dos
mov ah,prstr
mov dx,offset eeolstr ; Clear to the end of the current line
int dos
call getpos ; Get cursor position
xor dl,dl ; Column 0
cmp dh,23 ; Line 23 = the 24th line?
jae outtt3d ; Yes, we are at 23 or 24 (24th or 25th), done
push dx ; Save cursor position
outtt3b:pop dx ; Get cursor
inc dh ; Next line
cmp dh,24 ; Will this one be line 24, the 25th line
jae outtt3c ; Yes, done
push dx ; Save it again
mov cx,1 ; No delay
call sprtch ; Go get possible char at port
pop dx ; Get cursor back
push dx ; Save it again
call poscur ; Set cursor to beginning this new line
mov ah,prstr
mov dx,offset eeolstr ; Clear to the end of the current line
int dos
jmp short outtt3b
outtt3c:mov dx,offset precur; Set cursor to 'original' position
int dos
outtt3d:mov escflg,false ; reset
jmp outtt5
outtt31:mov escflg,false ; reset
cmp al,'?' ; key expansion?
jz outtt32 ; yes, inhibit it
cmp al,'@' ; event driven?
jnz outtt4 ; no, just deliver
outtt32:xor al,al ; put something harmless in
outtt4: push ax ; Need it later
test flags.remflg,d8bit ; keep 8 bits for displays?
jnz outtt40 ; nz = yes, 8 bits if possible
and al,7fh ; Strip parity
outtt40:test yflags,emheath ; Are we using emulation?
jnz outtt41 ; Yes, go on, do it fast
; No, use dos to allow term. device driver
mov dl,al ; We need it here
mov ah,conout ; Write char in dl ; This may loose
int dos ; do it ; characters
jmp outtt5
outtt41:mov ah,chr_write ; Write char in al ; This is faster
; call bios_confunc ; Do it fast
call MTR_SCRT ; Do it very fast
outtt5: pop ax ; Restore char
test yflags,capt ; capturing output?
jz outtt7 ; no, forget it
cmp flowoff,0 ; Are we doing flow control
je outtt6 ; No, just continue
cmp caplft,1 ; yes, one more space left in capture buffer?
jnz outtt6 ; no, give it the char
push ax ; yes, send xoff first
mov bx,portval
mov ax,[bx].flowc ; ah gets xon al gets xoff
call outpr1
cmp flags.comflg,2 ; check if S-100 ports
jle outtt51 ; no, go do it the simple way
mov cx,delaycount ; delay to ensure that, in spite of possible
call sprtch ; slow link, xoff is in effect
outtt51:pop ax ; get char back
push ax ; save it again
call captrtn ; give it the captured char
mov bx,portval
mov ax,[bx].flowc ; ah gets xon al gets xoff
mov al,ah
call outpr1
pop ax
jmp outtt7
outtt6: call captrtn
outtt7: test flags1,prtscr ; print screen?
jz outtt8 ; no, keep going
call pntchr ; queue char for printer
jnc outtt8 ; nc = successful print
push ax
call beep ; else make a noise and
call trnprs ; turn off printing
pop ax
outtt8: test padflg,true ; no, has keypad mode been changed?
jz outtt9 ; no, skip it
test yflags,modoff ; is mode line disabled?
jnz outtt9 ; yes, skip it
call dispad ; yes, display keypad mode
mov padflg,false ; reset flag
outtt9: ret
outtty endp
; display the keypad mode information on the mode line
dispad proc near
mov ah,prstr ; print string
mov dx,offset savcur ; save cursor position
int dos
mov dx,offset begrev ; reverse video
int dos
mov dx,offset padpos ; position cursor
int dos
mov dl,modbuf.m_pad ; this is it
mov ah,conout
int dos
mov ah,prstr
mov dx,offset endrev ; normal video
int dos
mov dx,offset precur ; reposition cursor
int dos
ret
dispad endp
; general character out for emulator
chrout: cmp flags.vtflg,0 ; emulating?
je chrou5 ; e = no
; call anskbi ; say we had keyboard input
cmp al,cr ; CR?
jne chrou5 ; ne = no, just output it and return
test vtemu.vtflgop,anslnm ; ANSI new-line mode set?
jz chrou5 ; z = no, just send the cr
cmp dupflg,0 ; full duplex?
je chrou4 ; e = yes
cmp al,trans.seol ; End of Line char?
jne chrou5 ; ne = no
chrou4: mov ah,trans.seol ; save eol char
push ax ; save on stack
mov trans.seol,lf ; make LF the eol char
call outprt ; output a carriage-return
mov al,lf ; followed by a line feed
call outprt ; send the LF
pop ax
mov trans.seol,ah ; restore eol char
ret
chrou5: jmp outprt
; 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
prtbout label near ; label used in msz
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 ; outpr1 entry point used for no echo
; sending of char in al
call outchr ; output to the port
jc outpr3 ; c = failure
ret
OUTPR2: mov ah,al ; outpr2 entry point used for no echo
; no flow control sending of char
call outch2 ; output to the port, no flow control
jc outpr3 ; c = failure
ret
outpr3: jmp endcon ; failure, end connection
outprt endp
; Toggle Mode Line
trnmod proc near
cmp flags.modflg,1 ; mode line enabled and owned by us?
jne trnm1 ; ne = no, don't touch it
test yflags,modoff ; mode line already off?
jnz trnm2 ; nz = yes, go turn on
or yflags,modoff ; say modeline is toggled off
call clrmod ; clear mode line
trnm1: clc ; clear c bit so don't exit Connect
ret
trnm2: cmp flags.vtflg,0 ; emulating a terminal?
jne trnm3 ; ne = yes
push dx ; scroll screen to save bottom line
mov ah,prstr ; for terminal type none
mov dx,offset crlf
int dos
pop dx
trnm3: call modlin ; turn on modeline
and yflags,not modoff ; say modeline is not toggled off
clc
ret
trnmod endp
modlin proc near ; turn on mode line
push es
mov al,trans.escchr
mov modbuf.m_echr,' ' ; first char is initial space
mov modbuf.m_hlp,' ' ; goes here too.
cmp al,32 ; printable?
jnb modl0 ; yes, keep going
add al,40h ; made printable
mov modbuf.m_echr,'^' ; note control char
mov modbuf.m_hlp,'^'
modl0: 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 modl3 ; yes, use default
shl al,1 ; each is 4 bytes long...
shl al,1
mov ah,0
add ax,offset baudn
cmp flags.comflg,2 ; com1/com2?
jna modl2 ; yes, jump
add ax,5*4 ; no, starts 5 rates higher
modl2: mov si,ax
modl3: mov cx,size m_baud ; length of baud space
mov di,offset modbuf.m_baud
push ds
pop es
cld
rep movsb ; copy in baud rate
mov al,[bx].parity ; get parity code
shl al,1 ; each is 4 bytes long...
shl al,1
mov ah,0
add ax,offset parnams ; names of parity settings
mov si,ax
mov cx,4 ; each is 4 long
mov di,offset modbuf.m_par
rep movsb
mov si,offset remmsg ; assume remote echoing
test yflags,lclecho ; echoing?
jz modl4 ; no, keep going
mov si,offset lclmsg
modl4: mov cx,3 ; size of Rem & Lcl
mov di,offset modbuf.m_echo
rep movsb
cmp flags.comflg,1 ; port 1 (port B)?
mov al,'B' ; enter 'B'
je modl5 ; yes, keep going
cmp flags.comflg,3 ; port 3 (S-100 port 1)
mov al,'3' ; enter '3'
je modl5 ; yes, keep going
cmp flags.comflg,4 ; port 4 (S-100 port 2)
mov al,'4' ; enter '4'
je modl5 ; yes, keep going
mov al,'A' ; then must be port 2 (port A)!
modl5: mov modbuf.m_prt,al ; fill in port number
mov cx,3 ; size of PRN
mov di,offset modbuf.m_prn
test flags1,prtscr ; print screen?
mov si,offset prmsg ; printer on msg
jnz modl6 ; yes, prepare to display it
add si,3 ; no, print blank
modl6: rep movsb
mov cx,10 ; size of leds
mov di,offset modbuf.m_emul
test yflags,emheath ; are we using Heath-19 emulation?
mov si,offset noleds ; "None" message
jz modl7 ; no, prepare to display it
mov si,offset h19leds ; Heath-19 emulation
modl7: rep movsb
mov modbuf.m_pad,'N' ; N for Numeric
test ansflgs,deckpam ; are we in keypad application mode?
jz modl8 ; no, leave the blank in
mov modbuf.m_pad,'A' ; A for Application
modl8: mov cx,size modfrm ; this is size of mode line
mov si,offset modbuf ; mode line image
mov dx,offset modbuf
call putmod
pop es
ret ; and return
modlin endp
; Invoked by keyboard translator when an unknown keyboard verb is used as
; a string definition, such as {\ktest}. Enter with vtmacname pointing to
; uppercased verb name, asciiz, and vtmaclen set to its length.
extmacro proc near
jmp short vtmacro
extmacro endp
;
; Reference Macro structure for db number of entries (mac names)
; is file table mcctab |-> db length of macroname, excl '$'
; mssset.asm each entry |-> db 'macroname','$'
; where these |-> dw segment:0 of definition string
; are stored. (offset part is always 0)
; Definition string in db length of <string with null>
; buffer macbuf db 'string with trailing null'
;
vtmacro proc far ; common code for macros vtsmac,vtrmac
push bx ; and Product
push cx
push si
push di
push es
mov ax,ds
mov es,ax
mov di,offset rdbuf+1 ; macro def buffer starts here
mov si,vtmacname ; pointer to macro name
mov cl,vtmaclen ; length of macro name<sp/null>text
xor ch,ch
mov [di-1],cl ; counted string field
cld
rep movsb ; copy to rdbuf
mov byte ptr [di],0 ; null terminator
mov si,offset rdbuf+1 ; look for name-text separator
mov cl,vtmaclen
xor ch,ch
vtmac1: lodsb
cmp al,' ' ; space separator?
je vtmac1a ; e = yes, stop here
or al,al ; null terminator?
jz vtmac1a ; e = yes, stop here
loop vtmac1
inc si ; to do null lenght correctly
vtmac1a:sub si,offset rdbuf+1+1 ; compute length of macro name
mov cx,si
mov vtmaclen,cl ; save a macro name length
; check for existence of macro
mov bx,offset mcctab ; table of macro names
mov cl,[bx] ; number of names in table
xor ch,ch
jcxz vtmacx ; z = empty table, do nothing
inc bx ; point to length of first name
vtmac2: mov al,[bx] ; length of this name
xor ah,ah
cmp al,vtmaclen ; length same as desired keyword?
jne vtmac3 ; ne = no, search again
mov si,bx
inc si ; point at first char of name
push cx ; save name counter
push di ; save reg
mov cl,vtmaclen ; length of name, excluding '$'
xor ch,ch
mov di,vtmacname ; point at desired macro name
push es ; save reg
push ds
pop es ; make es use data segment
cld
repe cmpsb ; match strings
pop es ; need current si below
pop cx
pop di ; recover saved regs
je vtmac4 ; e = matched
vtmac3: add bx,ax ; step to next name, add name length
add bx,4 ; + count, dollar sign, def word ptr
loop vtmac2 ; try next name
vtmacx: pop es
pop di
pop si ; no macro, return to Connect mode
pop cx
pop bx
ret
vtmac4: cmp taklev,maxtak ; room in Take level?
jge vtmacx ; ge = no, exit with no action
inc taklev ; increment take level
add takadr,size takinfo ; make a new Take entry/macro
mov bx,takadr ; point to current macro structure
mov ax,ds ; segment of rdbuf
mov [bx].takbuf,ax ; segment of definition string struc
mov cl,rdbuf ; length of whole string
xor ch,ch
mov [bx].takcnt,cx ; number of chars in definition
mov [bx].takargc,0 ; our argument count
mov [bx].takptr,offset rdbuf+1 ; where to read next command char
mov [bx].taktyp,0ffh ; flag as a macro
pop es
pop di
pop si
pop cx
pop bx
jmp endcon ; exit Connect mode
vtmacro endp
; Error recovery routine used when outchr reports unable to send character
; or when vtmacro requests exiting Connect mode.
; Exit Connect mode cleanly, despite layers of intermediate calls.
endcon proc near
mov kbdflg,'C' ; report 'C' to TERM's caller
mov sp,oldsp ; recover startup stack pointer
; TERM caller's return address is now
; on the top of stack. A longjmp.
jmp quit ; exit Connect mode cleanly
endcon endp
; Clear all User Definable Keys, deallocate memory for their definitions
udkclear proc near
push ax
push bx
push cx
push es
mov cx,17 ; 17 entries
xor bx,bx
udkcle1:mov ax,udkseg[bx] ; segment of definition
or ax,ax ; segment defined?
jz udkcle2 ; z = no, try next key
mov es,ax
mov udkseg[bx],0 ; clear the entry
mov ah,freemem ; release the memory
int dos
udkcle2:add bx,2 ; word index
loop udkcle1 ; do all
pop es
pop cx
pop bx
pop ax
clc
ret
udkclear endp
; Determine screen roll back buffer parameters depending on current screen
; dimensions and available memory. Each rollback screen line has its own
; segment (lines start on segment boundaries for rollback).
bufadj proc near
push bx
push cx
push dx
mov lxtra,0 ; assume no storage for "extra" lines
xor bh,bh ; (BDT) get bytes / line
mov bl,crt_cols ; (BDT) physical line width
add bx,7 ; (BDT) round up to paragraph boundary
mov cl,3 ; (BDT) now convert to
shr bx,cl ; (BDT) paragraphs / line
mov ppl,bx ; (BDT) save this in buffer area
mov ax,inipara ; (BDT) compute the number of lines
xor dx,dx
div bx ; (BDT) in the buffer
mov lmax,ax ; max line capacity of the buffer
mov linee,ax ; (BDT) save as number of total lines
or ax,ax ; is this zero?
je bufadj1 ; e = yes, no space at all
xor bh,bh ; (BDT) get lines / screen
mov bl,byte ptr low_rgt+1 ; (BDT) rows on user/host screen
inc bx ; (BDT) adjust for counting from 0
mov lxtra,bx ; (BDT) save as "extra" lines
sub lmax,bx ; (BDT) deduct "extra" lines req'd
jg bufadj1 ; g = have some rollback space
mov lmax,0 ; say none
mov lxtra,0 ; say none of these too
bufadj1:mov lcnt,0 ; (BDT) # of lines filled in buffer
mov linef,0 ; (BDT) first filled in line
mov linec,0 ; (BDT) last filled in line
pop dx
pop cx
pop bx
ret
bufadj endp
; Routine to set cursor type. Pass bits for cursor type in al:
; bit 0 set = 1 => Cursor on cleared = 0 => Cursor off
; bit 1 set = 2 => Block cursor cleared = 0 => Underline cursor
; bit 2 set = 4 => Non blinking cursor cleared = 0 => Blinking cursor
; Thus, in decimal form
; 0 = No cursor, 1 = Blinking underline cursor , 3 = Blinking block cursor
; 4 = No cursor, 5 = No blink underline cursor , 6 = No blink block cursor
csrtype proc near
mov byte ptr lincur,al ; remember type set
push ax
push dx ; save the reg
mov ah,prstr
test al,cur_on ; any cursor at all?
jz csrty3 ; z=no, go put it out
mov dx,offset enacurs ; enable cursor
int dos
mov dx,offset enablnk ; assume blink
int dos
test al,cur_nob ; non blinking?
jnz csrty1 ; nz=no to no blink, leave as is
mov dx,offset disblnk ; set blink off
int dos
csrty1: mov dx,offset enaunde ; assume underline
int dos
test al,cur_blo ; block?
jz csrty2 ; z=no, leave as is
mov dx,offset enabloc ; set block
int dos
csrty2: jmp short csrty4
csrty3: mov dx,offset discurs ; disable cursor
int dos
csrty4: pop dx
pop ax
ret
csrtype endp
; Save the screen to a buffer and then append buffer to a disk file. [jrd]
; Default filename is Kermit.scn; actual file can be a device too. Filename
; is determined by mssset and is passed as pointer dmpname.
DUMPSCR PROC NEAR ; dumpscr dumps sreen to file
push ax
push bx
push cx
push dx
push di
push si
push es
; Open and prepare screen dump file
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 dmp1 ; c = no such file, create it
test byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
jnz dmp2 ; nz = no, indicate open failure
mov al,1 ; writing
mov ah,open2 ; open existing file
int dos
jc dmp2 ; c = failure, indicate open failure
mov dmphand,ax ; save file handle
mov bx,ax ; need handle here
mov cx,0 ; setup file pointer
mov dx,0 ; to end of file
mov al,2 ; seek the end
mov ah,lseek
int dos
jc dmp2 ; failure, indicate open failure
jmp short dmp3 ; success
dmp1: mov ah,creat2 ; file did not exist
mov cx,20h ; attributes, archive bit
int dos
mov dmphand,ax ; save file handle
jnc dmp3 ; nc = ok
dmp2: call beep
mov ah,prstr ; print string
mov dx,offset dmperr ; cannot open file
int dos
jmp short dmp8 ; Failure, exit
dmp3: call rdset ; Set up for screen reading
dmp4: call rdlne ; Read a screen line
call endfix ; Fix end of line and srceen
; Write out the line
dmp5: mov dx,offset line ; array to be written
mov bx,dmphand ; need file handle
mov ah,write2 ; write the line
int dos
jc dmp6 ; Go if trouble.
cmp cx,ax ; Write as many bytes as requested?
jnz dmp6 ; Go if trouble.
cmp eos,1 ; End of screen?
je dmp7 ; If yes, go.
mov ax,int_cy ; Else get the line index and set the
shl al,1 ; pointer to the next line of screen
shl al,1 ; data.
shl al,1
mov bh,al
jmp short dmp4 ; Now loop back, do another line
dmp6: call beep ; Error writing file
mov ah,prstr ; print string
mov dx,offset dmperr1 ; The message
int dos
dmp7: mov ah,close2 ; close the file now
mov bx,dmphand ; file handle
int dos
mov al,vstate ; Restore the original video port
out VID_CMD,al ; state.
dmp8: pop es
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret ; Done with screen: return.
DUMPSCR ENDP
; Local routine rdset to set up for screen buffer reading. Modifies ax, bx
; and es and enables acces to video memory.
RDSET: cld ; Clear direction indicator.
mov eos,0 ; Initialize end of screen flag to NO
mov lines,ROWS ; Assume 24 lines on the screen.
mov ax,IPAGE_SEG ; The interrupt page
mov es,ax ; Fetch the variable containing the
mov es,es:[MTR_DS] ; status of the 25th line:
cmp byte ptr es:[STATUS],0 ; 00= disabled, FF= enabled.
je rdset1
inc lines ; Set number of lines on screen to 25.
rdset1: in al,VID_CMD ; Get the current video status.
mov vstate,al ; Save it.
mov al,78h ; Enable access to the memory.
out VID_CMD,al
mov ax,PAR_GRN ; Address the green plane, which is
mov es,ax ; where the characters are stored.
mov int_cy,0 ; Start at line 0 on the screen.
xor bh,bh
ret
; Local routine rdlne to read a screen line. Enter with es pionting to
; the monitor interrup page. Modifies ax, bx, si and di.
RDLNE: mov bl,COLUMNS-1 ; Offset of the last character.
mov di,COLUMNS-1 ; Offset to the end of the line.
xor si,si ; Show no non-spaces found yet.
rdlne1: mov al,es:[bx+9*128] ; Get the character's font index.
add al,' ' ; Then make it into the character.
cmp al,' ' ; Is the character a space?
jne rdlne2 ; If not, go.
and si,si ; Any non-space found yet?
jz rdlne3 ; If no, go.
rdlne2: mov line[di],al ; Save the character.
and si,si ; Non-space found yet?
jnz rdlne3 ; If yes, just go.
lea si,[di+1] ; Else keep the offset to the non-space.
rdlne3: dec bl ; Go to next character.
dec di ; Decrement the offset to the line.
jge rdlne1 ; Repeat this sequence for all chars.
ret ; Reached the end of line:
; Local routine to add cr and lf at the end of each line and ff at the
; end of each page. Modifies ax and cx. Returns with number of chars
; in line buffer in cx.
endfix: mov byte ptr line[si],CR ; Put in a CR
mov byte ptr line[si+1],LF ; Put in a LF
lea cx,[si+2] ; Set up the counter.
inc int_cy ; Up index to the next line and then
mov ax,int_cy ; get it.
cmp ax,lines ; Are we at the end of screen?
jne endfix1 ; If not, go.
mov byte ptr line[si+2],FF ; Else store form feed for end of page.
inc cx ; Up length to print.
mov eos,1 ; Turn on the end-of-screen flag.
endfix1:ret
; Save the entire screen in a buffer so we can restore it.
; Saves regular (80x25) screens to memory buffer allocated dynamically from
; DOS. Save address is savadr+2:savadr (seg:offset). A memory buffer is
; allocated as required.
savescr proc near
push ax
push bx
push cx
push dx
push si
push di
push es
mov ax,low_rgt ; text screen lower right (typ 23,79)
add al,3 ; plus 1 col, cr, lf
add ah,2 ; plus 1 row plus status line
mul ah ; times rows = characters on screen
inc ax ; plus the last one, ff
mov dx,ax ; save number of screen bytes in dx
mov ax,savadr+2 ; seg of saved memory, if any
or ax,ax ; none?
jnz savsc4 ; no, there is some
; allocate and use DOS memory for save
savsc1: mov bx,dx ; bytes to do
add bx,16 ; round up
mov cl,4
shr bx,cl ; bytes/screen to paragraphs/screen
mov ah,alloc ; allocate memory
int dos ; bx has # free paragraphs
jc savsc2 ; c = not enough for it, skip
mov savadr+2,ax ; working seg address for restore
jmp short savsc4
savsc2: mov savadr+2,0 ; then say no seg because no save
jmp short savsc7 ; exit without saving screen
; save the screen
savsc4: mov savadr,0 ; no offset for memory buffer
mov cx,dx ; number of screen bytes
call rdset ; Set up for screen reading
savsc5: call rdlne ; Read screen line
call endfix ; Add cr, lf and possibly ff
mov ax,savadr+2 ; Reached the end of line:
push es
mov es,ax ; Segment for buffer
mov si,offset line ; Array to be written
mov di,savadr ; We are here in buffer
cld
rep movsb
pop es
mov savadr,di ; Save it for next line
cmp eos,1 ; End of screen?
je savsc6 ; If yes, go.
mov ax,int_cy ; Else get the line index and set the
shl al,1 ; pointer to the next line of screen
shl al,1 ; data.
shl al,1
mov bh,al
jmp short savsc5 ; Now loop back, do another line
savsc6: mov al,vstate ; Restore the original video port
out VID_CMD,al ; state.
savsc7: pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
savescr endp
; Restore screen from buffer (savadr+2:savadr, with number to write in savadr).
; Restores all screen lines.
restscr proc near
push ax
push bx
xor ax,ax ; upper left corner
mov bx,low_rgt
call atsclr ; blank screen
mov bx,dx ; holds cursor position
mov dx,ax ; upper left corner
call poscur ; set it
cmp savadr+2,0 ; saved anything yet?
mov dx,ax ; restore it
je restsc2 ; e = no
push cx
push bx ; this is in reality dx, cursor
push si
push di
push es
mov cx,savadr ; this many bytes to write
sub cx,3 ; but skip last cr,lf and ff
mov ax,savadr+2 ; get segment for buffer
mov es,ax ; into es
xor si,si ; offset zero for first char
restsc1:mov al,byte ptr es:[si] ; get char
push cx ; MTR_SCRT messes up ax, bx, cx, dx,
push si ; si, di and es, so we assume this
call MTR_DCRT ; one is as bad.
pop si
pop cx
mov ax,savadr+2 ; get segment for buffer
mov es,ax ; into es
inc si ; next char
loop restsc1
pop es
pop di
pop si
pop dx
pop cx
restsc2:pop bx
pop ax
ret
restscr endp
; Read cursor position
; DL = column, DH = row, both counted from 0,0 at upper left corner
getpos proc near
push bx
push es
mov bx,IPAGE_SEG ; the interrupt page
mov es,bx
mov es,word ptr es:MTR_DS ; find monitor data segment here
mov dl,byte ptr es:MTR_HORP ; column 0 to 79
mov dh,byte ptr es:MTR_VERP ; row 0 to 24
pop es
pop bx
ret
getpos endp
; Screen clearing routine atsclr.
;
; 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.
ATSCLR PROC NEAR
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
mov cx,IPAGE_SEG ; Get into es
mov es,cx
mov ds,es:[MTR_DS] ; Now get MTR_DS into ds and the
mov bp,offset es:MTR_EDC ; offset to the dword into bp
mov cx,ax ; Top left corner
mov cl,ch ; Top line to cl
xor ch,ch ; Top line now in cx
push cx ; * First parameter
mov cl,al ; Left column now in cx
push cx ; ** Second parameter
sub bh,ah ; Line count
inc bh ; adjust
sub bl,al ; Char count
inc bl ; adjust
atsclr1:push bx ; *** Third parameter in bl (and bh)
call dword ptr ds:[bp] ; Do a line
sub sp,2 ; -2 ; Point to first parameter, line
pop cx ; 0 ; Get it
inc cx ; Go to the next line
push cx ; -2 ; Put it back into stack
sub sp,4 ; -6 ; The next param, left column, is ok
pop bx ; -4 ; But we will check on the line count
dec bh ; which we sneaked into here
jnz atsclr1 ; If more lines left, do it again
add sp,4 ; 0 ; Don't waste time popping this junk
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
ATSCLR ENDP
; Routine to do close to VT100-style bell, no arguments
vtbell proc near
cmp belltype,1 ; visual bell?
je vtbell1 ; e = yes
call beep
ret
vtbell1:
in al,VID_CMD ; Get the current video status.
mov ah,al ; Save it.
mov al,0f0h ; Make screen all white
out VID_CMD,al ; Do it
push ax
mov ax,40 ; for 40 milliseconds
call pcwait
pop ax
mov al,ah ; Get old status back
out VID_CMD,al ; Do it
ret
vtbell endp
comment @
; This routine is called when we want to reverse everything on the screen
; from normal to reverse video, or vice versa. It is called only when
; the decscnm attribute is changed. Preserves all registers.
; Call: no arguments.
; This will work on graphics as well as text. However, this is a true
; reverser meaning that ALL 'dark bits' will be 'lit upp' all 'lit up'
; ones will be 'darkened'. This means for example that the reverse of
; yellow (green + red) on black (none) will be blue on white (all =
; blue + green + red).
revscn proc near
push ax
push cx
push si
push di
push ds
push es
in al,VID_CMD ; Get video port status
push ax ; Save it
mov al,7fh ; Turn off multiple access
out VID_CMD,al ; and display
mov ax,PAR_GRN ; Green first
revscn0:mov ds,ax ; Set up
mov es,ax ; all
xor si,si ; the
mov di,si ; pointers
mov bx,8000h ; The whole plane
mov cx,40 ; One line
mov dx,9 ; 9 scan lines per char
cld
revscn1:lodsw
xor ax,0ffffh
stosw
loop revscn1 ; A full scan line
dec dx ; done
jnz revscn2 ; A full char line?
add si,7*128 ; Yes, skip the
mov di,si ; 7 next lines
sub bx,7*64 ; and adjust count
mov dx,9 ; Prepare for next char line
revscn2:sub bx,64 ; Plane done?
jz revscn3 ; z = yes, plane done
add si,48 ; no, skip the non displayed
mov di,si ; last 48
mov cx,40 ; Prepare for next scan line
jmp short revscn1 ; and go do it
revscn3:mov ax,ds ; Have we done
cmp ax,PAR_BLU ; the blue?
jz revscn5 ; Yes, all done, almost
sub ah,10h ; Go do next plane
jmp short revscn0
revscn5:pop ax ; Restore video
out VID_CMD,al ; status
pop es
pop ds
pop di
pop si
pop cx
pop ax
ret
revscn endp
end comment @
; This is revscn which reverses the color attributes of characters currently
; displayed on the video screen. It will only work on text and graphic
; characters. Takes no arguments, preserves all registers.
REVSCN PROC NEAR
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
in al,VID_CMD ; Read video state
push ax ; Save it
mov al,01111000b ; Mask current write bits, enable vram
out VID_CMD,al ; Set up
mov ax,IPAGE_SEG ; Interrupt page
mov es,ax ; into es
mov bp,offset es:MTR_DFC
mov ds,es:[MTR_DS] ; Monitor data segment
mov es,es:[MTR_DS] ; Monitor data segment
xor cx,cx ; Char index 0
revscn1:push cx ; Preserve around call to mtr rom
push es ; This too
mov ax,cx ; Index here
mov bl,COLUMNS
div bl ; Line now in al and column in ah
mov bh,al ; Line in bh
mov bl,ah ; Parameter 1, column, in bl
push bx ; * Parameter # 1 set
xchg bh,bl ; Parameter 2, line, from bh to bl
push bx ; ** Parameter # 2 set
xchg bh,bl ; Get right order back
mov ax,PAR_GRN ; Point to green plane
mov es,ax
shl bh,1
shl bh,1
shl bh,1
mov al,es:byte ptr [bx+9*128] ; Char index
mov ah,es:byte ptr [bx+10*128] ; Char attributes
push ax ; *** Third param, al holds char index
mov dh,ah
and dh,111b ; Foreground color
mov dl,ah
shr dl,1
shr dl,1
shr dl,1
and dl,111b ; Background color
cmp cs:tempcol,dx ; New color or fresh start?
jz revscn2 ; No, just skip all of this
mov cs:tempcol,dx ; Remember color
xchg dh,dl ; Reverse it
call setcol ; Set the reversed color
revscn2:mov ax,0
push ax ; **** Fourth, display it as is
call dword ptr ds:[bp] ; Display char
pop es ; Get these
pop cx ; back
inc cx
cmp byte ptr es:[STATUS],0 ; Status line not on?
jz revscn3 ; No, go do 24 lines
cmp cx,COLUMNS * (ROWS + 1) ; < 80 * (24 + 1) = 2000?
jb revscn1 ; Yes, go do next char
revscn3:cmp cx,COLUMNS * ROWS ; < 80 * 24 = 1920?
jb revscn1 ; Yes, go do next char
pop cx ; No, all done, almost
out VID_CMD,al ; Restore video
mov cs:tempcol,0ffffh ; Reset for next time
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
tempcol dw 0ffffh ; Storage for the last set colors
REVSCN ENDP
; Set cursor postion. Destroys dx.
; DL = column, DH = row, both counted from 0,0 at upper left corner
setpos proc near
jmp poscur
setpos endp
; Set coloring attributes.
; Enter with AH holding current video attribute byte,
; BL holding ANSI color code (30-37 or 40-47) where 30's are foreground,
; 40's are background. ANSI colors are 1 = red, 2 = green, 4 = blue.
; Return new attribute byte in AH.
setcolor proc near
setcol0:cmp bl,30 ; ANSI color series?
jb setcol7 ; b = no
cmp bl,37 ; foreground set (30-37)?
ja setcol4 ; a = no, try background set
sub bl,30 ; take away the bias
test bl,1 ; ANSI red?
jz setcol1 ; z = no
or ah,2 ; Z-100 red foreground bit
setcol1:test bl,2 ; ANSI green?
jz setcol2 ; z = no
or ah,4 ; Z-100 green foreground bit
setcol2:test bl,4 ; ANSI blue?
jz setcol3 ; z = no
or ah,1 ; Z-100 blue foreground bit
setcol3:ret
setcol4:cmp bl,40 ; background color set?
jb setcol7 ; b = no
cmp bl,47 ; background set is 40-47
ja setcol7 ; nb = no, not a color command
sub bl,40 ; take away the bias
test bl,1 ; ANSI red?
jz setcol5 ; z = no
or ah,10h ; Z-100 red background bit
setcol5:test bl,2 ; ANSI green?
jz setcol6 ; z = no
or ah,20h ; Z-100 green background bit
setcol6:test bl,4 ; ANSI blue?
jz setcol7 ; z = no
or ah,8h ; Z-100 blue background bit
setcol7:ret
setcolor endp
; Set screen color. Destroys dx.
; DH = foregroung color, DL = backgrond color per Z-100 standards.
; 0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = magenta,
; 6 = yellow, 7 = white
setcol proc near
push ax
push dx
mov ah,conout
mov dl,ESCAPE
int dos
mov dl,'m'
int dos
pop dx
push dx
mov dl,dh
add dl,'0'
int dos
pop dx
add dl,'0'
int dos
pop ax
ret
setcol endp
; Routine to do keyclick if flag is set, no arguments
vclick proc near
test vtemu.vtflgop,vskeyclick ; is keyclick flag on?
jz vclick1 ; z = no, just return
mov dl,keycli
call keycom
vclick1:ret
vclick endp
;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
; These are invoked by a jump instruction. Return carry clear for normal
; processing, return carry set for invoking Quit (kbdflg has transfer char).
uparrw: mov al,'A' ; cursor keys
jmp short comarr
dnarrw: mov al,'B'
jmp short comarr
rtarr: mov al,'C'
test vtemu.vtflgop,vswdir ; writing left to right?
jz comarr ; z = yes
mov al,'D' ; reverse sense of keys
jmp short comarr
lfarr: mov al,'D'
test vtemu.vtflgop,vswdir ; writing left to right?
jz comarr ; z = yes
mov al,'C' ; reverse sense of keys
comarr: push ax ; save final char
mov ttyact,0 ; network, group chars for packet
test vtemu.vtflgop,decanm ; ANSI mode?
jz comar2 ; z = no
mov al,CSI ; CSI character
test vtemu.vtflgop,decckm ; cursor key mode reset?
jz comar1 ; z = yes
mov al,SS3 ; SS3 character
comar1: call out8bit ; send in 7 or 8 bit form
jmp short comar3
comar2: mov al,escape ; do Heath/VT52 mode "ESC char"
call prtbout
comar3: pop ax ; recover final char
mov ttyact,1 ; network, restore tty active flag
call prtbout
ret
f0: mov al,'J' ; Z-100 function keys
jmp short comf
f1: mov al,'S'
jmp short comf
f2: mov al,'T'
jmp short comf
f3: mov al,'U'
jmp short comf
f4: mov al,'V'
jmp short comf
f5: mov al,'W'
jmp short comf
f6: mov al,'P'
jmp short comf
f7: mov al,'Q'
jmp short comf
f8: mov al,'R'
jmp short comf
f9: mov al,'I'
jmp short comf0
f10: mov al,'J'
jmp short comf0
f11: mov al,'K'
jmp short comf0
f12: mov al,'L'
jmp short comf0
sf0: mov al,'E'
comf: mov ah,0 ; only one char
jmp short comf_
sf1: mov al,'A'
jmp short comf1
sf2: mov al,'B'
jmp short comf1
sf3: mov al,'C'
jmp short comf1
sf4: mov al,'D'
jmp short comf1
sf5: mov al,'E'
jmp short comf1
sf6: mov al,'F'
jmp short comf1
sf7: mov al,'G'
jmp short comf1
sf8: mov al,'H'
jmp short comf1
sf9: mov al,'I'
jmp short comf1
sf10: mov al,'J'
jmp short comf1
sf11: mov al,'K'
jmp short comf1
i_chr: cmp insert,'O' ; overwrite mode?
mov insert,'O'
jnz i_chr1 ; no, make it overwrite
mov insert,'@' ; yes, make it insert
i_chr1: mov al,insert
jmp short comf
d_chr: mov al,'N'
jmp short comf
i_line: mov al,'L'
jmp short comf
d_line: mov al,'M'
jmp short comf
comf0: mov ah,'0' ; second char is '0'
jmp short comf_
comf1: mov ah,'1' ; second char is '1'
comf_: push ax ; save final char
mov ttyact,0 ; network, group chars for packet
mov al,escape ; output ESC
call prtbout
pop ax ; get the saved char
cmp ah,0 ; only one char?
jz comf_1
push ax ; save it again
xchg al,ah ; need ah first
call prtbout
pop ax ; get the saved char
comf_1: mov ttyact,1 ; network, restore tty active flag
call prtbout
ret
pf1: mov al,'P' ; keypad function keys PF1-4
jmp short compf
pf2: mov al,'Q'
jmp short compf
pf3: mov al,'R'
jmp short compf
pf4: mov al,'S'
compf: push ax ; save final char
mov ttyact,0 ; network, group chars for packet
test vtemu.vtflgop,decanm ; ansi mode?
jz short compf1 ; z = no
mov al,SS3
call out8bit ; send 7 or 8 bit version
jmp short compf2
compf1: mov al,escape ; output ESC
call prtbout
compf2: pop ax ; get the saved char
mov ttyact,1 ; network, restore tty active flag
call prtbout
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 vtemu.vtflgop,deckpam ; keypad application mode active?
jnz comkp1 ; nz = yes, use escape sequences
sub al,40h ; deduct offset to numeric symbols
push ax ; save final char
jmp comkp3 ; and send that single char
comkp1: push ax
mov ttyact,0 ; network, group chars for packet
test vtemu.vtflgop,decanm ; ANSI mode?
jz comkp2 ; z = no
mov al,SS3 ; SS3 character
call out8bit ; send 7 or 8 bit version
jmp comkp3
comkp2: mov al,escape ; output "ESC ?"
call prtbout
mov al,'?'
call prtbout
comkp3: pop ax ; recover final char
mov ttyact,1 ; network, restore tty active flag
call prtbout ; send it
ret
klogon proc near ; resume logging (if any)
test flags.capflg,logses ; session logging enabled?
jz klogn ; z = no, forget it
or argadr.flgs,capt ; turn on capture flag
or yflags,capt ; set local msy flag as well
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
clc
ret
klogof endp
snull proc near ; send a null byte
xor al,al ; the null
jmp prtbout ; send without logging and local echo
snull endp
; output, no echo, 8-bit control chars as literals or "ESC char" form
out8bit proc near
mov ttyact,0 ; network, group chars for packet
cmp flags.vtflg,ttvt320 ; VT320?
jne out8bi1 ; ne = no
cmp parmsk,7fh ; using parity?
je out8bi1 ; e = yes
test vtemu.vtflgop,vscntl ; doing 8-bit controls?
jnz out8bi2 ; nz = yes, send 8-bit control char
out8bi1:test al,80h ; in range for C1 controls?
jz out8bi2 ; z = no
cmp al,9fh
ja out8bi2 ; a = no
push ax
mov al,escape ; send ESCAPE
call prtbout
pop ax
sub al,40h ; compose second char
out8bi2:mov ttyact,1 ; network, restore single char mode
jmp prtbout ; send final char
out8bit endp
; 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
cmdcom: mov kbdflg,al ; pass char to msster.asm via kbdflg
stc ; signal that Quit is needed
ret
;SCROLL makes it possible to review the last screen (up to 26 lines). F11
;invokes scroll and scrolling is done with BACK SPACE and LINE FEED keys.
;The RETURN key latches the screen in the new position, any other key restores
;to the original status.
scroll proc near
push ax
push cx
push dx
push es
mov ax,ipage_seg ; the interrupt page
mov es,ax
mov es,word ptr es:mtr_ds ; find monitor data segment here
cmp byte ptr es:VRAM_SIZE,1 ; Must be 1 for 64k video chips
jz scroll1 ; Yes, go on
mov ah,prstr ; No, tell user, skip
mov dx,offset vidmsg
int dos
jmp short scroll6
scroll1:mov dx,word ptr es:DISP_START ; get start address
mov startad,dx ; save it
scroll2:mov dx,word ptr es:DISP_START ; get start address
sub dx,80 ; assume 1 line backwards
cmp al,10 ; line feed ^J
jnz scroll3 ; no, backwards
add dx,160 ; yes, forward
scroll3:mov word ptr es:DISP_START,dx ; set new start address
mov dx,0ffh
mov byte ptr es:DISP_UPDATE,dl ; request update
mov ah,coninq
int dos
cmp al,8 ; if back space ^H, go scroll up
jz scroll2
cmp al,10 ; if line feed ^J, go scroll down
jz scroll2
cmp al,cr ; if carrage return, go latch it
jz scroll4
mov dx,startad ; else, just go back
mov word ptr es:DISP_START,dx ; set start address
mov dx,0ffh
mov byte ptr es:DISP_UPDATE,dl ; request update
jmp short scroll6
;
scroll4:
mov ax,word ptr es:DISP_START ; get start address
mov cl,4 ; shift count
shr ax,cl ; al now has latch value
out 0dah,al ; initialize latch
mov dx,1700h ; put cursor at beginning of last line
call poscur
test yflags,modoff ; is mode line disabled?
jnz scroll5 ; yes, skip it
call modlin ; enable and write modline
jmp short scroll6
scroll5:call clrmod ; clear mode line
scroll6:pop es
pop dx
pop cx
pop ax
ret
scroll endp
; (BDT) new screen-scrolling routines. Single, circular buffer
homwnd proc near ; "home" to start of the buffer
push cx ; save registers
mov cx,lxtra ; save this many lines
call putcirc ; save them
mov linec,0 ; reset the current pointer
call getcirc ; now get the new screen
pop cx ; restore registers
clc
ret
homwnd endp
endwnd proc near ; "end" to end of the buffer
push cx ; save registers
mov cx,lxtra ; save this many lines
call putcirc ; save them
mov cx,lcnt ; reset the current pointer
mov linec,cx ; save the results
call getcirc ; now get the new screen
pop cx ; restore registers
clc
ret
endwnd endp
dnwpg proc near ; scroll down 1 page
push cx ; save registers
mov cx,lxtra ; save this many lines
call putcirc ; save them
mov cx,linec ; reset the current pointer
add cx,lxtra ; to the next page
cmp cx,lcnt ; did we go past the end?
jbe dnwpg1 ; be = no, we're OK
mov cx,lcnt ; yup, back up
dnwpg1:
mov linec,cx ; save the results
call getcirc ; now get the new screen
pop cx ; restore registers
clc
ret
dnwpg endp
dnone proc near ; scroll down 1 line
push cx ; save registers
mov cx,lxtra ; save this many lines
call putcirc ; save them
mov cx,linec ; reset the current pointer
inc cx ; to the next line
cmp cx,lcnt ; oops, did we go past the end?
jbe dnone1 ; be = no, we're OK
mov cx,lcnt ; yup, back up
dnone1:
mov linec,cx ; save the results
call getcirc ; now get the new screen
pop cx ; restore registers
clc
ret
dnone endp
upwpg proc near ; scroll up 1 page
push cx ; save registers
mov cx,lxtra ; save this many lines
call putcirc ; save them
mov cx,linec ; reset the current pointer
sub cx,lxtra ; to the previous page
cmp cx,0 ; oops, did we go past the end?
jge upwpg1 ; ge = no, we're OK
xor cx,cx ; yup, back up
upwpg1:
mov linec,cx ; save the results
call getcirc ; now get the new screen
pop cx ; restore registers
clc
ret
upwpg endp
upone proc near ; scroll up 1 line
push cx ; save registers
mov cx,lxtra ; save this many lines
call putcirc ; save them
mov cx,linec ; reset the current pointer
dec cx ; to the previous line
cmp cx,0 ; oops, did we go past the end?
jge upone1 ; ge = no, we're OK
xor cx,cx ; yup, back up
upone1:
mov linec,cx ; save the results
call getcirc ; now get the new screen
pop cx ; restore registers
clc
ret
upone endp
; Put cx lines into the circular buffer. Characters are stored as a word
; containig the Z-100 font index (low) and the Z-100 attributes (high).
; Source segment is tv_segs which is set to point to the green video plane.
; Source offset for each char is calculated below based on the screen char
; index in si. The index starts at 0 and ends at COLUMNS * ROWS - 1 = 1919,
; corresponding to 1920 characters.
putcirc proc near ; put lines in the circular buffer
jcxz putcir9 ; z = no lines to save
push es ; save ES for a tad
xor si,si ; Screen char index
mov ax,linef ; get the first line pointer
add ax,linec ; add the current line counter
dec ax ; get a running start
sub si,COLUMNS ; Here too
putcir1:inc ax ; increment the current line pointer
add si,COLUMNS ; This many char per line
cmp ax,linee ; fallen off the end of the buffer?
jb putcir2 ; b = no, proceed
sub ax,linee ; back up to the buffer start
putcir2:push ax ; save the current line pointer
mul ppl ; compute the paragraph offset
add ax,iniseg ; add the initial segment
mov es,ax ; now we have the segment pointer
xor di,di ; initial buffer offset is 0
push cx ; save the number of lines
push si ; Save index
xor ch,ch ; get the number of characters to move
mov cl,COLUMNS ; One row
push ds ; get the offset of the screen
mov ds,tv_segs ; get the segment of the screen
mov ax,si ; Index here
div cl ; Line now in al and column in ah
mov bh,al ; Line in bh
mov bl,ah ; Column in bl
shl bh,1
shl bh,1
shl bh,1
putcir3:mov al,ds:byte ptr [bx+9*128] ; Char index
mov ah,ds:byte ptr [bx+10*128] ; Char attributes
stosw
inc bl ; Next char
loop putcir3 ; Go back for next char
pop ds ; restore DS
pop si ; Restore index
pop cx ; restore the line count
pop ax ; restore the buffer counter
loop putcir1 ; go back for more
pop es ; restore ES
putcir9:ret ; Note, also used by getcirc below
putcirc endp
; Get CX lines from the circular buffer, non destructivly. Destination
; segment is the green video plane and destination offset for each char
; is calculated below based on the screen char index in di. The index
; starts at 0 and ends at COLUMNS * ROWS - 1 = 1919, corresponding to
; 1920 characters. The call to MTR_DFC writes to the destination.
getcirc proc near ; get lines from the circular buffer
mov cx,lxtra ; restore this many lines
jcxz putcir9 ; z = nothing to do
push es ; save ES for a tad
mov ax,IPAGE_SEG ; Interrupt page
mov es,ax ; into es
mov bp,offset es:MTR_DFC ; Need this pointer for our call
mov es,es:[MTR_DS] ; Monitor data segment
xor di,di ; Screen char index
mov ax,linef ; get the first line pointer
add ax,linec ; add the current line counter
dec ax ; get a running start
sub di,COLUMNS ; Here too
getcir1:inc ax ; increment the current line pointer
add di,COLUMNS ; This many char per line
cmp ax,linee ; fallen off the end of the buffer?
jb getcir2 ; b = no, proceed
sub ax,linee ; back up to the buffer start
getcir2:push ax ; save the current line pointer
mul ppl ; compute the paragraph offset
add ax,iniseg ; add the initial segment
xor si,si ; initial offset is 0
push cx ; save the number of lines
push di ; Save index
xor ch,ch ; get the number of characters to move
mov cl,COLUMNS ; One row
push ds ; save DS for a tad
push es ; Save MTR_DS
mov ds,ax ; now we have the segment pointer
mov ax,di ; Index here
div cl ; Line now in al and column in ah
mov bh,al ; Line in bh
mov bl,ah ; Parameter 1, column, in bl
push bx ; * Parameter # 1 set
xchg bh,bl ; Parameter 2, line, from bh to bl
push bx ; ** Parameter # 2 set
xchg bh,bl ; Get right order back
getcir3:mov bh,0 ; Column now in bx
shl bx,1 ; 2 bytes per cell in buffer
mov ax,word ptr ds:[di.bx] ; Get the char from buffer
push ax ; *** Parameter # 3 set
mov dh,ah
and dh,111b ; Foreground color
mov dl,ah
shr dl,1
shr dl,1
shr dl,1
and dl,111b ; Background color
cmp cs:tempcol,dx ; New color or fresh start?
jz getcir4 ; No, just skip all of this
mov cs:tempcol,dx ; Remember color
call setcol ; Set the color
getcir4:and ah,80h ; Reverse video?
mov ax,0 ; Assume no
jz getcir5 ; No, skip this
mov ax,0ffffh ; Set up parameter # 4
getcir5:push ax ; **** Parameter # 4 set
call dword ptr es:[bp] ; Display char
pop es ; We need this for our call
push es ; Save again
sub sp,2 ; Point to first parameter
pop bx ; Get it back
inc bl ; Next char
push bx ; * Parameter # 1 set
sub sp,2 ; ** Parameter # 2 set, old value
loop getcir3
add sp,6
pop ds ; restore DS
pop di ; restore index
pop cx ; restore the line count
loop getcir1 ; go back for more
mov cs:tempcol,0ffffh ; Restore for next time
pop es ; restore ES
getcir6:ret
getcirc endp
; Screen dump entry from keyboad xlat
dmpscn proc near ; dump screen to file
call dumpscr ; do buffer to file
clc ; do not exit Connect mode
ret
dmpscn endp
code ends
end