home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
mskermit.tar.gz
/
mskermit.tar
/
msyibm.asm
< prev
next >
Wrap
Assembly Source File
|
1998-05-28
|
262KB
|
8,840 lines
NAME msyibm
; File MSYIBM.ASM
include mssdef.h
; Copyright (C) 1982, 1997, Trustees of Columbia University in the
; City of New York. The MS-DOS Kermit software may not be, in whole
; or in part, licensed or sold for profit as a software product itself,
; nor may it be included in or distributed with commercial products
; or otherwise distributed by commercial concerns to their clients
; or customers without written permission of the Office of Kermit
; Development and Distribution, Columbia University. This copyright
; notice must not be removed, altered, or obscured.
; Edit history
; 12 Jan 1995 version 3.14
; Last edit
; 12 Jan 1995
public lclyini, csrtype, fcsrtype, scrseg
public atsclr, trnmod, vtbell, vtroll, crt_lins, crt_cols
public vtemu, crt_mode, scbattr, refresh, low_rgt ; data
public setchtab, extattr, vtcpage, tv_mode, dos_bottom
public setpos, setatch, yflags, vtinited, useexp
public vts, vtstat, termtb, modbuf, qsetatch ; terminal emulation
public tv_segs, tv_sego
ifndef no_terminal
public term, enqbuf
public chgdsp, vtclear, ftogmod, getatch, nextses, setprot, clrprot
public prtbout, prtnout, vtscru, vtscrd, vclick, reset_color
public getbold, setbold, clrbold, getblink, setblink, clrblink
public getunder, setunder, clrunder, revideo, revscn, setcolor
public setrev, clrrev, frepaint, touchup, reversed_screen
; 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, snull, ignore_key
public klogon, klogof, cdos, chang, khold, product, termesc_flag
public vtksmac, vtkrmac, apcmacro, apcenable, vtenqenable
public decf6,decf7,decf8,decf9,decf10,decf11,decf12,decf13,decf14
public dechelp,decdo,decf17,decf18,decf19,decf20, udkclear
public decfind, decinsert, decremove, decselect, decprev
public decnext, setudk, extmacro, vtmacname, vtmaclen
public rtone, lfone, rtpage, lfpage, kbdcompose, kdebug
public dgkc1,dgkc2,dgkc3,dgkc4,dgkf1,dgkf2,dgkf3,dgkf4,dgkf5
public dgkf6,dgkf7,dgkf8,dgkf9,dgkf10,dgkf11,dgkf12,dgkf13
public dgkf14,dgkf15, dgpoint, dgnckey
public dgkSf1,dgkSf2,dgkSf3,dgkSf4,dgkSf5,dgkSf6,dgkSf7,dgkSf8
public dgkSf9,dgkSf10,dgkSf11,dgkSf12,dgkSf13,dgkSf14,dgkSf15
public udkf6, udkf7, udkf8, udkf9, udkf10, udkf11, udkf12, udkf13
public udkf14, udkf15, udkf16, udkf17, udkf18, udkf19, udkf20
public wykf1,wykf2,wykf3,wykf4,wykf5,wykf6,wykf7,wykf8
public wykf9,wykf10,wykf11,wykf12,wykf13,wykf14,wykf15,wykf16
public wykSf1,wykSf2,wykSf3,wykSf4,wykSf5,wykSf6,wykSf7,wykSf8
public wykSf9,wykSf10,wykSf11,wykSf12,wykSf13,wykSf14,wykSf15,wykSf16
public dgsettek, vtclrflg, tn_AYT, tn_IP, jpnxltkey, rcvmacro
public srvmacro, crdisp_mode
ifndef no_tcp
public termswapout, termswapin, termswapdel, commbyte
public ses1, ses2, ses3, ses4, ses5, ses6
endif ; no_tcp
endif ; no_terminal
; some definitions
SIchar equ 0fh
SOchar equ 0eh
DGescape equ 1eh
CSI equ 9bh
SS2 equ 8eh
SS3 equ 8fh
bapito_3270 equ 0b3h ; KERMIT BAPI extension, byte to 3270
; 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
att_protect equ 01h ; protected in vsatt
att_uline equ 02h ; underscored in vsatt
att_rev equ 04h ; reversed video in vsatt
att_bold equ 08h ; bold in main video word
att_blink equ 80h ; blinking in main video word
att_low_mask equ 06H ; Various attribute-related equates
;;;att_normal equ 07h
att_underline equ 01H ; for mono monitors, in video word
ifndef nls_portuguese
modfrm struc ; format of mode (status) line
db 'Esc:Alt-x help:Alt-h port:'
m_prt db 20 dup (' ')
m_baud db 6 dup (' ')
m_par db 3 dup (' ')
db ' echo:'
m_echo db 3 dup (' ')
m_term db 12 dup (' ') ; 12 bytes for term type
m_prn db 3 dup (' ') ; show PRN when printer is on
m_comp db ' ' ; Compose indicator
db '$' ; terminator
modfrm ends
else
modfrm struc ; format of mode (status) line
db 'Esc:Alt-X help:Alt-H porta:'
; db 'Carac-Esc: ajuda: ? porta:'
; db 'Carac-Esc:' ; do not write in last column
m_prt db 19 dup (' ')
m_baud db 6 dup (' ')
m_par db 3 dup (' ')
db ' eco:'
m_echo db 3 dup (' ')
m_term db 12 dup (' ') ; 12 bytes for term type
m_prn db 3 dup (' ') ; show PRN when printer is on
m_comp db ' ' ; Compose indicator
db '$' ; terminator
modfrm ends
endif ; nls_portuguese
; structure for status information table sttab.
stent struc
sttyp dw ? ; type (actually routine to call)
msg dw ? ; message to print
val2 dw ? ; needed value: another message, or tbl addr
tstcel dw ? ; address of cell to test, in data segment
basval dw 0 ; base value, if non-zero
stent ends
data segment
extrn flags:byte, decbuf:byte, rdbuf:byte, xms:dword
extrn filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
extrn trans:byte, comand:byte, kstatus:word, prnhand:word
extrn comptab:byte, dosnum:word, fossil_port:word, termserver:byte
ifndef no_terminal
extrn anspflg:byte, scroll:byte, ttyact:byte
extrn mar_top:byte, mar_bot:byte, npages:word
extrn holdscr:byte, portval:word
extrn taklev:byte, takadr:word, mcctab:byte, dupflg:byte
extrn apctrap:byte, denyflg:word
extrn kbcodes:byte, repflg:byte
extrn param:word, nparam:word
extrn upss:byte, GRptr:word, G1set:byte, G2set:byte
extrn G3set:byte, cursor:word, linescroll:byte
extrn savezlen:word, savezoff:word
extrn savexoff:word, savexlen:word, savepoff:word
extrn saveplen:word, rollwidth:word, dgkbl:byte, apcstring:word
extrn blinkdis:byte, protectena:byte, dghscrdis:byte
extrn dgwindcomp:byte, att_normal:byte
extrn emsrbhandle:word, curattr:byte, saveuoff:word, saveulen:word
extrn dgd470mode:byte, tekflg:byte, xmsrhandle:word
extrn xmsghandle:word, xmsep:dword
extrn parmsk:byte, flowon:byte, flowoff:byte, flowcnt:byte
extrn isps55:byte ; [HF]940130 in MSXIBM.ASM
extrn ps55mod:byte ; [HF]940206 in MSXIBM.ASM
extrn domath_ptr:word, domath_cnt:word, domath_msg:word
ifndef no_graphics
extrn chcontrol:byte, softlist:word
extrn tekgraf:byte, tekcursor:byte, dgcross:byte, cursorst:byte
extrn savegoff:word, saveglen:word
endif ; no_graphics
ifndef no_network
ifndef no_tcp
extrn tcpnewline:byte
extrn seslist:byte, sescur:word, tcphost:byte, tcpmode:byte
extrn sestime:byte
endif ; no_tcp
endif ; no_network
endif ; no_terminal
inited equ 08h ; been here before
prtscr equ 1 ; print screen pressed
; stuff for screen routines
;;;;;;;;;;;;;; start session save area
even
saveyoff label word
yflags db 0 ; status flags
vtemu emulst <> ; emulator flags
vtsave db 7 dup (0) ; inuse/color/charset save around ANSI
belltype db 0 ; 0 = aural bell, 1 = visual
scbattr db ? ; screen background attribute
savattr db ? ; current emulator attributes
extattr db 0 ; extended scbattr
colunder db 0ffh ; underline color (0ffh = uninited)
vtclrflg db 0 ; erase with scbattr(0) or curattr(1)
vtclkflg db 1 ; status line clock (0=off)
reversed_screen db 0 ; if whole screen has been reversed
crt_mode db 3 ; video mode (typ 3, must be text)
; keep crt_cols & crt_lins in order
crt_cols db 80 ; number of screen columns (typ 80)
crt_lins db 24 ; number of screen rows - 1 (typ 24)
dos_bottom db 24 ; num of rows-1 at DOS level (typ 24)
low_rgt dw 174fh ; lower right corner of text window
; high = row address (typ 23)
; low = column address (typ 79)
handhsc db 0 ; hand horizontal scroll
dosetcursor dw -1 ; place to set tekcursor, -1 = don't
vtinited db 0 ; flag for emulator having been inited
vtclear db 0 ; nonzero to redo emulator screen
reset_color db 0 ; reset color on CSI m
writemode db 0 ; screen writing mode
vchgmode db 2 ; video-change mode (0=enabled)
vtcpage dw 437 ; terminal code page
apcenable db 0 ; enable APC macro (default is off)
vtenqenable db 0 ; enable Answerback
saveflag flginfo <> ; copy of flags array
ytermtype dw 0
ymodetype db 0
keypend dw 0 ;[HF]940207 buffer for double byte code
keyj7st dw 0 ;[HF]940211 keyoutput status for JIS7
enqbuf db 40 dup (0),0 ; local enquiry string, asciiz
crdisp_mode db 0 ; CR display mode
saveylen dw ($ - saveyoff)
;;;;;;;;;;;;;;;;; end of session save area
modbuf modfrm <> ; mode line buffer
argadr dw 0 ; address of arg blk
skip dw 0
inemulator db 0 ; non-zero if term emlator active
inwindows db 0 ; non-zero if Windows is active
crlf db cr,lf,'$'
even
ifndef no_terminal
vid7id db 'VEGA BIOS Code, ' ; Video 7 Vega version string subset
vid7len equ $-vid7id ; length of string
vid7id2 db 'Video Seven BIOS Code, ' ; Video 7 VGA board
vid7len2 equ $-vid7id2
atiwid db 'ATI EGA Wonder Bios,' ; ATI EGA wonder version string subset
atilen equ $-atiwid ; length of string, inc terminator
atiwid2 db '761295520' ; ATI signature #2
atilen2 equ $-atiwid2
tsngid db 'Tseng' ; Tseng Labs EVA (& Orchid Designer)
tsnglen equ $-tsngid
stbvid db 'TVGA' ; STB VGA/EM (also Tseng TVGA)
stbvlen equ $-stbvid
stavid db '4000' ; STB VGA/EM Plus (Tesng 4000)
stavlen equ $-stavid
evrxid db 'Everex' ; Everex Micro Enhancer Deluxe EGA
evrxlen equ $-evrxid
evgid db 'VGA EV673' ; Everex EVGA EV-673
evglen equ $-evgid
evvid db 'EV-678' ; Everex Viewpoint EV-678
evvlen equ $-evvid
attvdc6 db '003116' ; AT&T video board, at c000:35h
attvdlen equ $-attvdc6
attvdc7 db 'C02000' ; AT&T video board, at e000:10h
pmega1 db '28190-A1001' ; Paradise AutoSwitch EGA Mono String1
pmegal1 equ $-pmega1
p30id db 'VGA' ; VGA Plus, Plus 16, Professional
p30ln equ $-p30id ; and VGA1024 by Paradise
emsrollname db 'KERMIT ',0 ; 8 byte EMS region name, + safety
pageready dw -1 ; ems page currently active
cols80 db 'COLS80.BAT',0 ; to 80 column mode batch file
cols132 db 'COLS132.BAT',0 ; to 132 column mode batch file
xga_reg_base dw -1 ; PS/2 MCA I/O register base
emsname db 'EMMXXXX0',0 ; expanded memory manager dev name
jis7des db 'B','B' ; [HF] 941016 JIS7 designators (Kanji/ASCII)
cpwarn db cr,lf
db '?Warning: Code Page CP866 is required but it is not active.$'
endif ; no_terminal
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 0 ; Topview virtual screen, segment
tv_sego dw 0 ; and offset
tv_mode db 0 ; flag, 0 = no Topview or DESQview
vtcpumode db 0 ; timeslice-release (0 = enabled)
vs_ptr dd 0 ; offset, segment of vscreen (dynamic)
vsat_ptr dd 0 ; offset, segment of vs's attributes
; Note: (vswidth+1)/2 bytes of attributes/line, at two attributes/byte
vswidth equ 207 ; columns across DG virtual screen
; The following are used to turn the display back on (after scrolling etc.)
msets db 2CH,28H,2DH,29H,2AH,2EH,1EH,29H
wysecurtab db 0bh,0ah,0ch,08h ; VT to Wyse-50 cursor converter
dgcurtab db 23,26,24,25 ; ANSI to DG cursor converter
dgcrostab db 72,80,77,75 ; DG cursor to PC scan for croshair
mtty db ' TTY ' ; no terminal type (mode line)
fairness dw 0
fairprn dw 0
lincur dw ? ; cursor type save area
dosattr db ? ; screen attributes at init time
userbold db 0 ; screen bold attribute at start up
dos_cols db 0 ; screen width (crt_cols) at DOS
ifndef no_terminal
oldsp dw 0 ; offset to longjmp to for i/o failure
ten db 10 ; byte constant for key defines
temp dw 0 ; scratch storage
temp2 dw 0 ; scratch storage
endif ; no_terminal
ifndef no_terminal
dmphand dw -1 ; screen dump file handle
dumpsep db 0ch,cr,lf ; screen image separators
dmperr db ' Cannot open file to save screen to disk $'
memerr db cr,lf,'Not enough memory for terminal emulator$'
pntmsg db 'Printer not ready, printing request skipped$'
; some static data for mode line
modmaster modfrm <> ; master template
unkbaud db 'unkwn ' ; must be 6 chars
baudn db ' 45.5 ',' 50 ',' 75 ',' 110 ','134.5 ',' 150 ',' 300 '
db ' 600 ',' 1200 ',' 1800 ',' 2000 ',' 2400 ',' 4800 ',' 9600 '
db '14400 ', '19200 ','28800 ', '38400 ','57.6K ','115 K '
db '75/12 '
baudnsiz equ 21 ; # of baud rates known (tbl size / 6)
repmsg db 'REPLAY' ; REPLAY message for speed field
repmsgl equ $-repmsg
parnams db '7e1','7m1','8n1','7o1','7s1'
lclmsg db 'loc'
remmsg db 'rem'
portno db 0
termesc_flag db 0 ; SET TERM ESCAPE flag
endif ; no_terminal
; storage for multi-window stuff
slen equ 24 ; and length of text
crt_norm db 3 ; video mode for normal screen
inipara dw 0 ; initial paragraphs of scroll memory
; also is number ems pages for same
refresh db 0 ; screen refresh (0=wait for retrace)
vtroll db 0 ; auto roll back allowed (0 = no)
useexp db 0 ; non-zero to use exp mem for rollback
vsbuff_inited db 0 ; non-zero if inited screen buffers
setnoshow db 0 ; quiet setatch flag
lastsec db -1 ; seconds of last gettim call
ifndef no_terminal
vtkrname db 'KEYBOARDR' ; a macro name, must be Upper Case
vtkrlen equ $-vtkrname
vtksname db 'KEYBOARDS' ; a macro name, must be Upper Case
vtkslen equ $-vtksname
prodname db 'PRODUCT'
vtplen equ $-prodname
vtsesname db 'SESSION'
vtsesnum db '1'
vtseslen equ $-vtsesname
vtmacname dw vtkrname ; pointer to selected macro name
vtmaclen dw vtkrlen
udkseg dw 18 dup (0) ; segment of user definable key defs
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)
lineems dw 0 ; lines per EMS 16KB page frame
xgatmp1 dw 0 ; XGA display adapter work word pair
xgatmp2 dw 0
tsave dw 6 dup (0) ; list of term swap paragraphs
; DG SPCL three stroke Compose key
grab dw 0 ; zero if not grabbing output
grabbox db 0,0 ; store incoming pair of bytes
endif ; no_terminal
setchtab db 10 ; Set File Character-Set table
mkeyw 'CP437',437 ; hardware default Code Page
mkeyw 'CP850',850 ; Multilingual CP
mkeyw 'CP852',852 ; Latin2 CP
mkeyw 'CP860',860 ; Portuguese CP
mkeyw 'CP861',861 ; Icelandic CP
mkeyw 'CP862',862 ; Hebrew CP
mkeyw 'CP863',863 ; French Canadian CP
mkeyw 'CP865',865 ; Norwegian CP
mkeyw 'CP866',866 ; Latin5/Cryillic CP
mkeyw 'Shift-JIS',932 ; Japanese Shift-JIS
ifdef no_terminal
; begin Terminal emulator data set
termtb db 1 ; entries for Status, not Set
mkeyw 'none',ttgenrc
vttbl db 0 ; number of entries
endif ; no_terminal
ifndef no_terminal
; begin Terminal emulator data set
ifndef no_graphics
termtb db tttypes ; entries for Status, not Set
else
termtb db tttypes - 1
endif
mkeyw 'VT320',ttvt320
mkeyw 'VT220',ttvt220
mkeyw 'VT102',ttvt102
mkeyw 'VT100',ttvt100
mkeyw 'VT52',ttvt52
mkeyw 'Honeywell VIP7809',tthoney
mkeyw 'Heath-19',ttheath
ifndef no_graphics
mkeyw 'Tek4010',tttek
endif
mkeyw 'PT200',ttpt200
mkeyw 'D217',ttd217
mkeyw 'D463',ttd463
mkeyw 'D470',ttd470
mkeyw 'Wyse50',ttwyse
mkeyw 'Ansi-BBS',ttansi
mkeyw 'none',ttgenrc
ifndef no_graphics
vttbl db 55 ; number of entries
else
vttbl db 55 - 2
endif ; no_graphics
mkeyw 'Answerback',vtenqctl
mkeyw 'APC-macro',apcctl
mkeyw 'Arrow-keys',flg11
mkeyw 'Autodownload',vtdownld
mkeyw 'Character-set',vtchar
mkeyw 'Clock',vtclock
mkeyw 'Code-Page',vtcodepage
mkeyw 'Compressed-text',flg14
mkeyw 'Controls',flg9
mkeyw 'CR-display',vtcrdisp
mkeyw 'Cursor-style',flg7
mkeyw 'Direction',flg4
mkeyw 'Escape-character',termesc
mkeyw 'Expanded-memory',expmemory
mkeyw 'Horizontal-scroll',flg13
mkeyw 'Keyclick',flg5
mkeyw 'Keypad',flg10
mkeyw 'Margin-bell',flg6
mkeyw 'Newline',flg1
mkeyw 'Reset',termreset
mkeyw 'Screen-background',flg8
mkeyw 'Video-writing',scrwrite
mkeyw 'Video-change',scrchange
mkeyw 'Tabstops',tabmod
mkeyw 'Timeslice-release',vtcpu
mkeyw 'Width',flg12
mkeyw 'Wrap-lines',flg2
mkeyw 'Bell',vtbeep
mkeyw 'Bytesize',vtbyte
mkeyw 'Clear-screen',vtcls
mkeyw 'Color',vtcolor
mkeyw 'Display',vtbyte ; syn for set display 7/8
mkeyw 'Erase',vterase
ifndef no_graphics
mkeyw 'Graphics',vtgraph
mkeyw 'Tek4010',vttyp40
endif ; no_graphics
mkeyw 'Replay',replay
mkeyw 'Rollback',vtrollbk
mkeyw 'output-shift',vtshift
mkeyw 'Underscore',vtucolor
mkeyw 'UPSS',vtupss
mkeyw 'Type',vttype ; SET TERM TYPE
mkeyw 'None',vttyp0
mkeyw 'Heath-19',vttyp1
mkeyw 'VT52',vttyp2
mkeyw 'VT100',vttyp4
mkeyw 'VT102',vttyp8
mkeyw 'VT220',vttyp10
mkeyw 'VT320',vttyp20
mkeyw 'Honeywell',vttyp80
mkeyw 'PT200',vttyp100
mkeyw 'D217',vttyp1000
mkeyw 'D463',vttyp200
mkeyw 'D470',vttyp400
mkeyw 'Wyse50',vttyp800
mkeyw 'ANSI',vttyp2000
ontab db 2 ; two entries
mkeyw 'off',0
mkeyw 'on',1
beltab db 3 ; bell type
mkeyw 'audible',0
mkeyw 'visual',1
mkeyw 'none',2
clktab db 3
mkeyw 'Off',0
mkeyw 'On',1
mkeyw 'Elapsed-time',2
distab db 2 ; display
mkeyw '7-bit',0
mkeyw '8-bit',d8bit
erasetb db 2 ; erase
mkeyw 'normal-background',0
mkeyw 'current-color',1
scrtab db 2 ; screen attributes
mkeyw 'normal',0
mkeyw 'reverse',1
dirtab db 2 ; writing direction
mkeyw 'left-to-right',0
mkeyw 'right-to-left',1
writetab db 2 ; writing
mkeyw 'direct',0
mkeyw 'Bios',1
curtab db 2 ; cursor attributes
mkeyw 'block',0
mkeyw 'underline',1
apctab db 3 ; three entries
mkeyw 'off',0
mkeyw 'on',1
mkeyw 'unchecked',2
chatab db 32 ; National Replacement Character sets
mkeyw 'ASCII',C_ASCII ; ASCII is default (0, no NRC)
mkeyw 'British',C_UKNRC ; start NRC set (1-12)
mkeyw 'Dutch',C_DUNRC
mkeyw 'Finnish',C_FINRC
mkeyw 'French',C_FRNRC
mkeyw 'Fr-Canadian',C_FCNRC
mkeyw 'German',C_DENRC
mkeyw 'Hebrew-7',C_DHEBNRC
mkeyw 'Italian',C_ITNRC
mkeyw 'Norwegian/Danish',C_NONRC
mkeyw 'Portuguese',C_PONRC
mkeyw 'Spanish',C_SPNRC
mkeyw 'Swedish',C_SENRC
mkeyw 'Swiss',C_CHNRC ; end of NRC proper
mkeyw 'Alternate-ROM',C_ALTROM ; Alternate-ROM character set
mkeyw 'Transparent',C_XPARENT ; use native display adapter hardware
mkeyw 'Latin1',C_LATIN1 ; Latin-1 in GR
mkeyw 'Latin2',C_LATIN2 ; Latin-2 (will presume CP852)
mkeyw 'Hebrew-ISO',C_HEBREWISO ; Hebrew-ISO (presumes CP862)
mkeyw 'HP-Roman8',C_HPROMAN8 ; HP-Roman8
mkeyw 'DEC-MCS',C_DMULTINAT ; DEC Supplemental Graphics in GR
mkeyw 'DEC-Technical',C_DECTECH
mkeyw 'DEC-Special',C_DECSPEC
mkeyw 'DG-International',C_DGINT
mkeyw 'DG-Line-Drawing',C_DGLINE
mkeyw 'DG-Word-Processing',C_DGWP
mkeyw 'JIS-Kanji',C_JISKANJI ; [HF] JIS X 208, ISO(ECMA)#87
mkeyw 'JIS-Katakana',C_JISKAT ; [HF] JIS X 201, ISO(ECMA)#13
mkeyw 'JIS-Roman',C_JISROM ; [HF] JIS X 201, ISO(ECMA)#14
mkeyw 'Cyrillic-ISO',C_CYRILLIC_ISO
mkeyw 'KOI8',C_KOI8
mkeyw 'Short-KOI',C_SHORT_KOI
upsstab db 4
mkeyw 'DEC-MCS','5%' ; DEC Supplemental Graphics
mkeyw 'Latin1','A' ; Latin-1
mkeyw 'Hebrew-7','4"' ; DEC Hebrew-7
mkeyw 'Hebrew-ISO','H' ; Hebrew-ISO
sidetab db 4 ; SET TERM CHAR <char set> Gn
mkeyw 'G0','0'
mkeyw 'G1','1'
mkeyw 'G2','2'
mkeyw 'G3','3'
shifttab db 8 ; SET TERM OUTPUT-SHIFT
mkeyw 'none',0
mkeyw 'automatic',8
mkeyw 'SI/SO',1
mkeyw 'SS2',2
mkeyw 'SS3',4
mkeyw 'JIS7-Kanji',(128+1) ; [HF]940211
mkeyw 'EUC-Kanji',(128+2) ; [HF]940211
mkeyw 'DEC-Kanji',(128+3) ; [HF]941012
jis7tab db 6 ;[HF]941014
mkeyw 'JIS83-US','BB' ;[HF]941014
mkeyw 'JIS83-Roman','JB' ;[HF]941014
mkeyw 'JIS83-75Roman','HB' ;[HF]941014
mkeyw 'JIS78-US','B@' ;[HF]941014
mkeyw 'JIS78-Roman','J@' ;[HF]941014
mkeyw 'JIS78-75Roman','H@' ;[HF]941014
enqtab db 5 ; set term enquire table
mkeyw 'off',0
mkeyw 'on',1
mkeyw 'message',2
mkeyw 'UNSAFE-MESSAGE',3
mkeyw 'UNSAFE-MESSAGE ',4 ; invisible to force spelled out
graftab db 13
mkeyw 'auto-sensing',0 ; autosensing
mkeyw 'CGA',1
mkeyw 'EGA',2
mkeyw 'VGA',3
mkeyw 'VESA(800x600)',9
mkeyw 'Hercules',4
mkeyw 'ATT',5
mkeyw 'WyseA(1280x800)',6 ; Wyse-700 1280 x 800 mode
mkeyw 'WyseH(1280x780)',7 ; Wyse-700 1280 x 780 mode
mkeyw 'WyseT(1024x780)',8 ; Wyse-700 1024 x 780 mode
mkeyw 'character-writing',101h
mkeyw 'color',103h
mkeyw 'cursor',102h
gchrtab db 2 ; set term graphics char-writing
mkeyw 'opaque',1
mkeyw 'transparent',0
disatab db 2 ; Tek disable/enable table
mkeyw 'disabled',1 ; video-change table
mkeyw 'enabled',0
tabtab db 2 ; label says it all!
mkeyw 'at',0FFH ; For setting tab stops
mkeyw 'Clear',0 ; For clearing tab stops
alltab db 2 ; more tab command decoding
mkeyw 'all',0
mkeyw 'at',1
cntltab db 2 ; 8-bit controls
mkeyw '7-bit',0
mkeyw '8-bit',1
kpamtab db 2 ; keypad, application
mkeyw 'numeric',0
mkeyw 'application',1
arrtab db 2 ; cursor keys, application
mkeyw 'cursor',0
mkeyw 'application',1
widtab db 2
mkeyw '80-columns',0
mkeyw '132-columns',1
vchgtab db 3 ; video-change
mkeyw 'enabled',0
mkeyw 'disabled',1
mkeyw 'DOS-only',2
hstab db 2 ; horizontal scrolling
mkeyw 'auto',0
mkeyw 'manual',1
cmptab db 2
mkeyw 'graphics',0
mkeyw 'text-132',1
emmtab db 4
mkeyw 'off',0
mkeyw 'expanded',1
mkeyw 'extended',2
mkeyw 'on',3
termesctab db 2 ; SET TERM ESCAPE
mkeyw 'Enabled',0
mkeyw 'Disabled',1
crdisptab db 2
mkeyw 'normal',0
mkeyw 'CRLF',1
colortb db 0,4,2,6,1,5,3,7 ; color reversed-bit setting bytes
clrset db 0 ; Temp for SET Term Tabstops xxx
erms41 db cr,lf,'?More parameters are needed$'
tbserr db cr,lf,'?Column number is not in range 1 to screen width-1$'
colerr db cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
vtwrap db 'Term wrap-lines: $'
vtbellm db 'Term margin-bell: $'
vtnewln db 'Term newline: $'
vtcur db 'Term cursor-style: $'
vtcset db 'Term character-set: $'
vtclik db 'Term key-click: $'
vtscrn db 'Term screen-background: $'
txtcolst1 db 'Term color (normal) f:3$'
colst2 db ' b:4$'
colst3 db ' rst:$'
undcolst1 db 'Term underscore color f:3$'
grcolst1 db 'Term graphics color f:3$'
vtgraf db 'Term graphics: $'
vtrolst db 'Term rollback: $'
vtdir db 'Term direction: $'
vtcntst db 'Term controls: $'
vtkpst db 'Term keypad: $'
vtarst db 'Term arrow-keys: $'
vtbset db 'Term bell: $'
vtgchst db 'Term graph char: $'
vtwdst db 'Term width: $'
vtupsst db 'Term UPSS: $'
vtshftst db 'Term output-shift: $'
vthscst db 'Term horizontal-scroll: $'
vtapcst db 'Term APC-macro: $'
vtenqst db 'Term Answerback: $'
vtenqst2 db 'ab msg: '
vtenqst2_len equ $-vtenqst2
vtwrtst db 'Term video-writing: $'
vtexpmst db 'Term expanded-memory: $'
vtcpagest db 'Term Code-Page: $'
vtcmptst db 'Term compressed-text: $'
vtchgst db 'Term video-change: $'
vtcpust db 'Term timeslice-release: $'
vtclrst db 'Term erase: $'
vtdnldst db 'Term autodownload: $'
vtcrdispst db 'Term CR-display: $'
; terminal emulator
vtstbl stent <srchkw,vtenqst,ontab,vtenqenable> ; Answerback
stent <ansbkstat>
stent <srchkw,vtcset,chatab,vtemu.vtchset> ; char set
stent <srchkw,vtapcst,apctab,apcenable> ; APC-macro
stent <txtcolstat> ; colors
stent <srchkb,vtclik,ontab,vskeyclick,vtemu.vtflgop> ; keyclick
stent <undcolstat> ; colors
stent <srchkb,vtwrap,ontab,vswrap,vtemu.vtflgop> ; line wrap
ifndef no_graphics
stent <grcolstat> ; colors
endif ; no_graphics
stent <srchkb,vtcntst,cntltab,vscntl,vtemu.vtflgop> ; controls
stent <srchkw,vtclrst,erasetb,vtclrflg> ; erase
stent <srchkb,vtbellm,ontab,vsmarginbell,vtemu.vtflgop>;margin bell
stent <srchkb,vtcur,curtab,vscursor,vtemu.vtflgop> ; cursor type
stent <srchkw,vtbset,beltab,belltype> ; bell
stent <srchkb,vtdir,dirtab,vswdir,vtemu.vtflgop> ; write direct
stent <srchkb,vtnewln,ontab,vsnewline,vtemu.vtflgop> ; newline
ifndef no_graphics
stent <srchkw,vtgraf,graftab,tekgraf> ; graphics
endif ; no_graphics
stent <srchkw,vtrolst,ontab,vtroll> ; rollback
ifndef no_graphics
stent <srchkw,vtgchst,gchrtab,chcontrol> ; chr cntrl
endif ; no_graphics
stent <srchkb,vtarst,arrtab,decckm,vtemu.vtflgop> ; arrow-keys
stent <srchkb,vtscrn,scrtab,vsscreen,vtemu.vtflgop> ; screen
stent <srchkb,vtkpst,kpamtab,deckpam,vtemu.vtflgop> ; keypad
stent <srchkb,vtwdst,widtab,deccol,vtemu.vtflgop> ; width
stent <srchkww,vtupsst,upsstab,upss+1> ; UPSS
stent <srchkw,vtshftst,shifttab,flags.oshift> ; output-shift
stent <srchkb,vthscst,hstab,vshscroll,vtemu.vtflgop> ; Horz scroll
stent <srchkw,vtchgst,vchgtab,vchgmode> ; V change
stent <srchkw,vtexpmst,emmtab,useexp> ; exp mem
stent <srchkw,vtwrtst,writetab,writemode> ; Writing
stent <srchkww,vtcpagest,setchtab,vtcpage> ; Code-Page
stent <srchkb,vtcmptst,cmptab,vscompress,vtemu.vtflgop> ; compress
stent <srchkw,vtcpust,disatab,vtcpumode> ; timeslice
stent <srchkw,vtcrdispst,crdisptab,crdisp_mode> ; CR-display
stent <srchkw,vtdnldst,ontab,vtemu.vtdnld> ; autodownload
stent <tabstat> ; VT320 tab status - needs one whole line
dw 0 ; end of table
vtmacroptr dd vtmacro ; FAR pointer
ftogmod dd togmod ; FAR pointer
termlatch db 0 ; reentry block for session macros
rcvstring db 9,0,'RECEIVE',CR,'C'
rcvstring_len equ $-rcvstring-2
srvstring db 5,0,'SER',CR,'C'
srvstring_len equ $-srvstring-2
endif ; no_terminal
data ends
ifndef no_terminal
data1 segment
vthlp db ' one of the following:',cr,lf
db ' TYPE of: None, ANSI, Heath-19, Honeywell VIP7809, Wyse50,'
db ' VT52, VT100, VT102'
db cr,lf
db ' VT220, VT320 (default), Tek4010,'
db ' PT200 (Prime), D217, D463, D470 (Data Gen)'
db cr,lf
db ' Newline-mode Cursor-style Character-set'
db cr,lf
db ' Keyclick Margin-bell Screen-background'
db ' (normal, reverse)',cr,lf
db ' Tabstops Wrap (long lines) Color (fore & background)'
db cr,lf,' Answerback response (on or off, default is off)'
db cr,lf,' APC-macro (APC cmd from host invokes local cmds)'
db cr,lf,' Autodownload (on, off=default) kermit file xfers'
db cr,lf,' Arrow-keys cursor (normal) or application mode'
db cr,lf,' Bell audible or visual or none'
db cr,lf,' Clear-screen (clears old startup screen)'
db cr,lf,' Clock (status line HH:MM) on or off, default is off'
db cr,lf,' Code-Page (overrides default)'
db cr,lf,' Compressed-text Graphics or Text-132 (for D463/D470)'
db cr,lf,' Controls 7-bit or 8-bit (permits VT320 to send'
db ' 8-bit control sequences (C1))'
db cr,lf,' CR-display normal or CR-LF'
db cr,lf,' Direction Left-to-right or Right-to-left'
db ' (screen writing direction)'
db cr,lf,' Display or Bytesize 7-bit or 8-bit'
db cr,lf,' Erase in normal bkground or in current char color'
db cr,lf,' Expanded/extended-memory (rollback), default on'
db cr,lf,' Graphics (type of display adapter when in Tek4010'
db ' mode, and char writing)'
db cr,lf,' Horizontal scrolling, auto (default) or manual'
db cr,lf,' Keypad numeric (normal) or application mode'
db cr,lf,' Output-shift (prefix 8-bit data for 7-bit channel)'
db cr,lf,' Reset, resets terminal emulation to startup defaults'
db cr,lf,' Rollback (undo screen roll back before writing new'
db ' chars, default=off)'
db cr,lf,' TEK ENABLE or DISABLE (activation by host command)'
db cr,lf,' Timeslice-release (OS/2, DV, Windows, def: enabled)'
db cr,lf,' Underscore Color (same syntax as SET TERM COLOR)'
db cr,lf,' Width 80 or 132 columns, if the adapter can do it'
db cr,lf,' Video-change, enable or disable 132 column switching'
db ' or restrict to DOS-only'
db cr,lf,' Video-writing, Direct or via Bios$'
clrhlp db ' one of the following:'
db cr,lf,' AT #s (to set tabs at column #s) or'
db ' AT start-column:spacing'
db cr,lf,' Clear AT #s (clears individual tabs) or'
db ' AT start-column:spacing'
db cr,lf,' Clear ALL (to clear all tabstops)'
clrhlp2 db cr,lf,' Ex: Set term tab at 10, 20, 34 sets tabs'
db cr,lf,' Ex: Set term tab at 1:8 sets tabs at 1, 9,'
db cr,lf,' Ex: Set term tab clear at 9, 17, 65 clears tabs'
db cr,lf,' Ex: Set term tab clear at 1:8 clears tabs at 1, 9,'
db ' 17,...$'
colhlp db cr,lf,' Set Term Color value, value, value, ...'
db cr,lf,' 0 no-snow mode on an IBM CGA and white on black'
db cr,lf,' 1 for high intensity foreground'
db cr,lf,' 10 for fast CGA screen updating (may cause snow)'
db cr,lf,' 20 to restore normal colors after ESC [ 0 m'
db cr,lf,' Foreground color (30-37) = 30 + sum of colors'
db cr,lf,' Background color (40-47) = 40 + sum of colors'
db cr,lf,' where colors are 1 = red, 2 = green, 4 = blue'
db cr,lf,' Ex: 0, 1, 37, 44 IBM CGA(0), bright(1) white(37)'
db ' chars on a blue(44) field'
db cr,lf,' Attributes are applied in order of appearance.$'
upsshlp db ' User Preferred Supplemental Set:'
db cr,lf, 'DEC-MCS, Latin-1, Hebrew-7, Hebrew-ISO$'
apchlp db cr,lf,'ON to allow APC cmd from host to invoke commands'
db cr,lf,'OFF to prevent all use of APC from the host'
db ' (default)'
db cr,lf,'UNCHECKED to allow any command to be executed$'
dnldhlp db cr,lf,'ON to act upon incoming Kermit file transfer packets'
db cr,lf,'OFF to prevent that action. Default is off$'
enqhlp db cr,lf,' ON to permit Answerback to Control-E Enquire request'
db ' (default is OFF),'
db cr,lf,' MESSAGE text to append local message to safe'
db ' response prefix'
db cr,lf,' UNSAFE-MESSAGE text to send message as-is, without'
db ' prefix$'
enqhlp2 db ' string to send$'
expmhlp db cr,lf,' Use expanded or extended memory for screen rollback'
db ' buffer,'
db cr,lf,' OFF, EXPANDED, EXTENDED, or ON (try expanded first)$'
; structures below: byte cnt of combos, dw input combo list, db output list
; using DG International or Latin1 codes for output.
grl1dgi db 48 ; case and order insensitive
dw '++','AA','((','//','/<','^ ','(-','/^',')-','<<'
dw '0^','* ','+-','>>','SS','/U','2^','3^','C/','C|'
dw 'L-','L=','Y-','Y=','SO','S!','S0','XO','X0','A-'
dw 'CO','C0','PP','P!','.^','O-','12','!!','??','T-'
dw 'TM','FF','<=','>=',',-','""',2727h,'RO'
grc1dgi db '#', '@', '[', '\', '\', '^', '{', '|', '}', 0b1h
db 0bch,0bch,0b6h,0b0h,0fch,0a3h,0a4h,0a5h,0a7h,0a7h
db 0a8h,0a8h,0b5h,0b5h,0bbh,0bbh,0bbh,0a6h,0a6h,0a9h
db 0adh,0adh,0b2h,0b2h,0b9h,0aah,0a2h,0abh,0ach,0afh
db 0b3h,0b4h,0b7h,0b8h,0a1h,0bdh,0beh, 0aeh
grl1lat db 44 ; case and order insensitive
dw '<<','0^','* ','+-','>>','SS','/U','2^','3^','C/'
dw 'C|','L-','L=','Y-','Y=','SO','S!','S0','XO','X0'
dw 'A-','CO','C0','PP','P!','.^','O-','12','!!','??'
dw 'TM',',-','""',2727h,'RO','||','--','-^',',,','34'
dw 'XX','-:','1^','14'
grc1lat db 0abh,0b0h,0b0h,0b1h,0bbh,0dfh,0b5h,0b2h,0b3h,0a2h
db 0a2h,0a3h,0a3h,0a5h,0a5h,0a7h,0a7h,0a7h,0a4h,0a4h
db 0aah,0a9h,0a9h,0b6h,0b6h,0b7h,0bah,0bdh,0a1h,0bfh
db 0aeh,0ach,0a8h,0b4h, 0aeh,0a6h,0adh,0afh,0b8h,0beh
db 0d7h,0f7h,0b9h,0bch
grl2dgi db 25 ; case sensitive, order insensitive
dw '''A','`A','^A','"A','~A','*A','''E','`E','^E','"E'
dw '''I','`I','^I','"I','~N','''O','`O','^O','"O','~O'
dw '''U','`U','^U','"U','"Y'
grc2dgi db 0c0h, 0c1h,0c2h,0c3h,0c4h,0c5h,0c8h, 0c9h,0cah,0cbh
db 0cch, 0cdh,0ceh,0cfh,0d0h, 0d1h,0d2h,0d4h,0d6h,0d5h
db 0dah, 0d9h,0dbh,0dch,0ddh
grl2lat db 25 ; case sensitive, order insensitive
dw '''A','`A','^A','"A','~A','*A','''E','`E','^E','"E'
dw '''I','`I','^I','"I','~N','''O','`O','^O','"O','~O'
dw '''U','`U','^U','"U','''Y'
grc2lat db 0c1h, 0c0h,0c2h,0c4h,0c3h,0c5h,0c9h, 0c8h,0cah,0cbh
db 0cdh, 0cch,0ceh,0cfh,0d1h, 0d3h,0d2h,0d4h,0d6h,0d5h
db 0dah, 0d9h,0dbh,0dch,0ddh
grl3dgi db 7 ; case and order sensitive
dw 'EO','AE',',C','/O','ae',',c','/o'
grc3dgi db 0d7h,0c6h,0c7h,0d6h,0e6h,0e7h,0f6h
grl3lat db 10+2 ; case and order sensitive
; The last two, OE/oe dipthong, are for DEC MCS but added here for user help
dw 'AE',',C','/O','HT','-D','ae',',c','/o','ht','-d'
dw 'OE','oe'
grc3lat db 0c6h,0c7h,0d8h,0deh,0d0h,0e6h,0e7h,0f8h,0feh,0f0h
db 0d7h,0f7h
; CP852 Latin 2 codes in gr<l/c><1/2/3>lat2
grl1lat2 db 24 ; case and order insensitive
db '%%','::','--','==',"''",'&&',',,','##','xx','..'
db '++','AA','aa','((','//','/<','))','(-','/^',')-'
db '^^','``','~~','""'
grc1lat2 db 0a2h,0a8h,0adh,0b2h,0b4h,0b7h,0b8h,0bdh,0d7h,0ffh
db '#','@','@','[','\','\',']','{','|','}'
db '^','`','~','"'
grl2lat2 db 83 ; case sensitive, order insensitive
db 'A=','L/','L&',"S'",'S&','S,','T&',"Z'",'Z&','Z.'
db 'a=','l/','l&',"s'",'s&','s,','t&',"z'",'z&','z.'
db "R'","A'",'A^','A%','A"',"L'","C'",'C,','C&',"E'"
db 'E=','E"','E&',"I'",'I^','D&','D-',"N'",'N&',"O'"
db 'O^','O#','O"','R&','U*',"U'",'U#','U"',"Y'",'T,'
db 'ss',"r'","a'",'a^','a%','a"',"I'","c'",'c,','c&'
db "e'",'e=','e"','e&',"i'",'i^','d&','d-',"n'",'n&'
db "o'",'o^','o#','o"','r&','u*',"u'",'u#','u"',"y'"
db 't,',".'",',.'
grc2lat2 db 0a1h,0a3h,0a5h,0a6h,0a9h,0aah,0abh,0ach,0aeh,0afh
db 0b1h,0b3h,0b5h,0b6h,0b9h,0bah,0bbh,0bbh,0beh,0bfh
db 0c0h,0c1h,0c2h,0c3h,0c4h,0c5h,0c6h,0c7h,0c8h,0c9h
db 0cah,0cah,0cch,0d8h,0d9h,0dah,0dbh,0dch,0ddh,0deh
db 0d4h,0d5h,0d6h,0fch,0deh,0e9h,0ebh,09ah,0edh,0ddh
db 0dfh,0e0h,0e1h,0e2h,0e3h,0e4h,0e5h,0e6h,0e7h,0e8h
db 0e9h,09ah,0ebh,0ech,0edh,0eeh,0efh,0f0h,0f1h,0f2h
db 0f3h,0f4h,0f5h,0f6h,0f8h,0f9h,0fah,0fbh,0fch,0fdh
db 0feh,"'", ','
grl3lat2 db 12 ; case and order sensitive
db 'XO','X0','xo','x0','SO','S!','S0','so','s!','s0'
db '0^','-:'
grc3lat2 db 0a4h,0a4h,0a4h,0a4h,0a7h,0a7h,0a7h,0a7h,0a7h,0a7h
db 0b0h,0f7h
;[HF] 941012 Double-byte katakana code table
kanatbl dw 2121h, 2123h, 2156h, 2157h, 2122h, 2126h, 2572h, 2521h ;[HF]
dw 2523h, 2525h, 2527h, 2529h, 2563h, 2565h, 2567h, 2543h ;[HF]
dw 213ch, 2522h, 2524h, 2526h, 2528h, 252ah, 252bh, 252dh ;[HF]
dw 252fh, 2531h, 2533h, 2535h, 2537h, 2539h, 253bh, 253dh ;[HF]
dw 253fh, 2541h, 2544h, 2546h, 2548h, 254ah, 254bh, 254ch ;[HF]
dw 254dh, 254eh, 254fh, 2552h, 2555h, 2558h, 255bh, 255eh ;[HF]
dw 255fh, 2560h, 2561h, 2562h, 2564h, 2566h, 2568h, 2569h ;[HF]
dw 256ah, 256bh, 256ch, 256dh, 256fh, 2573h, 212bh, 212ch ;[HF]
data1 ends
; end of Terminal data set
code1 segment
extrn ans52t:far, vsinit:near ; in mszibm
extrn anstty:near, ansini:near, ansrei:near ; in mszibm
extrn anskbi:near, ansdsl:near, chrdef:near ; in mszibm
extrn tabset:near, tabclr:near, dgnctoggle:far
extrn toupr:far, domath:far, cboff:far, cbrestore:far
assume cs:code1
fanskbi proc far
call anskbi ; in mszibm
ret
fanskbi endp
ftabset proc far
call tabset ; in mszibm
ret
ftabset endp
ftabclr proc far
call tabclr ; in mszibm
ret
ftabclr endp
fchrdef proc far
call chrdef
ret
fchrdef endp
code1 ends
endif ; no_terminal
ifndef no_graphics
code2 segment
extrn tekini:far, tekemu:far, tekend:far, tekrint:far ;in msgibm
extrn ttxtchr:far, teksetcursor:far, tekremcursor:far
extrn croshair:far, dgcrossrpt:far
code2 ends
endif ; no_graphics
ifndef no_tcp
_TEXT segment
extrn ktcpcom:far
_TEXT ends
_DATA segment
commbyte db 0 ; byte from msyibm to 3270 emulator
_DATA ends
endif ; no_tcp
code1 segment
extrn strlen:far, strcpy:far, strcat:far, isfile:far
extrn dec2di:far
assume cs:code1
code1 ends
code segment
extrn prtchr:near, outchr:near, pcwait:far
extrn clrmod:near, putmod:near, cmblnk:near, cptchr:near
extrn telnet:near, srchkww:near, jpnftox:near
extrn srchkb:near, srchkw:near, pasz:near
extrn prompt:near, comnd:near, statc:near, replay:near
extrn crun:near, serini:near, spath:near
extrn prttab:near, ctlu:near
extrn pntchr:near, pntflsh:near, serrst:near
ifndef no_graphics
extrn tekgcptr:near, tekdmp:near
endif ; no_graphics
ifndef no_network
extrn ubclose:near
endif ; no_network
ifndef no_tcp
extrn tcpstart:near, winupdate:far
endif ; no_tcp
ifndef no_terminal
extrn takopen_macro:far
extrn msuinit:near, keybd:near, kbhold:near ; in msuibm
endif ; no_terminal
assume cs:code, ds:data, es:nothing
ifdef no_terminal
; 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.
lclyini proc near
call far ptr flclyini ; far call specifics
ret
lclyini endp
; begin Terminal set & status code
; SET Term parameters, especially for use with VT100 emulator.
; VTS is called only by mssset to set terminal type and characteristics.
; Exit carry set for failure.
VTS proc near ; SET TERM whatever
mov ah,cmeol ; Clear-screen
call comnd
ret
VTS endp ; end of Set Term things
; Terminal Status display, called within STAT0: in MSSSET
VTSTAT proc near ; enter with di within sttbuf, save bx
jmp statc ; status common code, in mssset
vtstat endp
trnmod proc near
ret
trnmod endp
; Screen dump entry from keyboad xlat
dmpscn proc near ; dump screen to file
stc
ret
dmpscn endp
endif ; no_terminal
ifndef no_terminal
; 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.
lclyini proc near
call msuinit ; initialize keyboard module msuxxx
call far ptr flclyini ; far call specifics
ret
lclyini endp
; begin Terminal set & status code
; SET Term parameters, especially for use with VT100 emulator.
; VTS is called only by mssset to set terminal type and characteristics.
; Exit carry set for failure.
VTS proc near ; SET TERM whatever
mov kstatus,kssuc ; success
mov ah,cmkey ; Parse another keyword
mov bx,offset vthlp ; Use this help
mov dx,offset vttbl ; Use this table
call comnd
jnc vset1 ; nc = success
ret ; failure
vset1: call bx ; dispatch to processing routine
ret
vtcls: mov ah,cmeol ; Clear-screen
call comnd
jc vtclsx ; c = failure
mov vtclear,2 ; set trigger for emulator clear scn
clc ; success
vtclsx: ret
vtclock:mov ah,cmkey ; SET TERM CLOCK {ON | OFF | ELAPSED}
xor bx,bx
mov dx,offset clktab
call comnd
jnc vtclo1
ret
vtclo1: mov vtclkflg,bl ; status line clock flag
ret
vterase:mov ah,cmkey ; SET TERM ERASE
xor bx,bx ; table is help
mov dx,offset erasetb ; use this table
call comnd
jc vterasex ; c = failure
mov vtclrflg,bl
vterasex:ret
; SET TERM kind
vttyp0: mov bx,ttgenrc ; NONE
jmp vsett1
vttyp1: mov bx,ttheath ; Heath-19
jmp vsett1
vttyp2: mov bx,ttvt52 ; VT52
jmp vsett1
vttyp4: mov bx,ttvt100 ; VT100
jmp vsett1
vttyp8: mov bx,ttvt102 ; VT102
jmp vsett1
vttyp10:mov bx,ttvt220 ; VT220
jmp vsett1
vttyp20:mov bx,ttvt320 ; VT320
jmp vsett1
vttyp40:mov bx,tttek ; Tek
jmp vsett1
vttyp80:mov bx,tthoney ; Honeywell VIP7809
jmp vsett1
vttyp100:mov bx,ttpt200 ; Prime PT200
jmp short vsett1
vttyp200:mov bx,ttd463 ; Data General D463
jmp short vsett1
vttyp400:mov bx,ttd470 ; Data General D470
jmp short vsett1
vttyp800:mov bx,ttwyse ; Wyse-50
jmp short vsett1
vttyp1000:mov bx,ttd217 ; Data General D217
jmp short vsett1
vttyp2000:mov bx,ttansi ; Ansi-BBS
call ansi_save ; save settings
jmp short vsett1
vttype: mov ah,cmkey ; SET TERM TYPE
xor bx,bx ; table is help
mov dx,offset termtb ; use this table
call comnd
jnc vsett1 ; nc = success
ret ; failure
vsett1: mov temp,bx ; save terminal type
mov vtemu.vtchop,-1 ; say reinit char tables
mov temp2,-1 ; assume no enable/disable Tek
cmp bx,ttansi ; going to be ANSI?
je vsett1a ; e = yes
cmp vtsave,0 ; VT save area in use?
je vsett1a ; e = no
mov ax,word ptr vtsave+1 ; get saved video and char set
mov vtemu.vtchset,al ; restore current char set
mov si,vtemu.att_ptr ; pointer to attributes
mov [si],ah ; restore current screen coloring
mov ax,word ptr vtsave+3
mov reset_color,al ; this too
mov savattr,ah
mov ax,word ptr vtsave+5
mov vtcpage,ax ; restore terminal Code Page
mov vtclear,1 ; signal color change
mov vtsave,0 ; save area is free
vsett1a:cmp bx,tttek ; set term tek?
jne vsett2 ; ne = no
mov dx,offset disatab ; disable/enable keyword table
xor bx,bx ; help is the table
mov comand.cmcr,1 ; allow bare CR's
mov ah,cmkey ; get enable/disable keyword
call comnd
mov comand.cmcr,0 ; no more bare CR's
jc vsett2 ; c = no such keyword
ifndef no_graphics
mov temp2,bx ; save enable/disable keyword value
mov bx,flags.vtflg ; get current terminal type
mov temp,bx ; and force it here
endif ; no_graphics
vsett2: mov ah,cmeol
call comnd ; get a confirm
jc vsettx ; c = failure
vsett3: mov bx,temp
mov flags.vtflg,bx ; Set the terminal emulation type
call ansi_save ; save if going to ANSI
mov tekflg,0 ; clear graphics mode
or vtemu.vtflgst,vscompress+vshscroll ; set compress to text-132
or vtemu.vtflgop,vscompress+vshscroll
; and horz scroll to manual
cmp bx,tttek ; adjusting Tek?
je vsett4 ; e = yes
test bx,ttd463+ttd470+ttd217 ; DG D463/470/217?
jz vsett6 ; z = no
and vtemu.vtflgst,not (vshscroll) ; comp = graphics,
and vtemu.vtflgop,not (vshscroll) ; horz scroll = auto
vsett6: cmp temp2,-1 ; just enable/disable tek?
je vsett5 ; e = no
vsett4:
ifndef no_graphics
and denyflg,not tekxflg ; enable Tek
cmp temp2,1 ; ought we disable?
jne vsett5 ; ne = no
endif ; no_graphics
or denyflg,tekxflg ; disable Tek
vsett5: call fchrdef ; make tables in mszibm.asm
clc ; success
vsettx: ret
; save coloring and character set around ANSI terminal type, worker
ansi_save proc near
cmp flags.vtflg,ttansi ; are we ANSI now?
jne ansi_savex ; ne = no
cmp vtsave,0 ; save area in use?
jne ansi_savex ; ne = yes
mov vtsave,1 ; state that save area is in use
mov al,vtemu.vtchset ; get current char set
mov si,vtemu.att_ptr ; pointer to attributes
mov ah,[si] ; get current screen coloring
mov word ptr vtsave+1,ax ; save them
mov al,reset_color ; this too
mov ah,savattr
mov word ptr vtsave+3,ax
mov ax,437 ; forced codepage is 437
xchg ax,vtcpage ; get old CP
mov word ptr vtsave+5,ax ; save old CP
mov reset_color,1 ; reset colors with CSI m
mov byte ptr [si],07h ; dim white on black
mov savattr,07h
mov vtclear,1 ; signal color change
mov vtemu.vtchset,15 ; Transparent char set
or flags.remflg,d8bit ; set 8-bit display
ansi_savex:
ret
ansi_save endp
vtchar: mov ah,cmkey ; Set Term character set
xor bx,bx ; character set table for help
mov temp,bx ; counter of trailing items
mov dx,offset chatab ; character set table
call comnd
jc vtcharx ; c = failure
call chkcp866 ; check on CP866 requirements
mov decbuf,bl ; save here
mov ax,word ptr vtemu.vttable ; table of 4 overrides now
mov word ptr decbuf+1,ax ; copy them to temporary table
mov ax,word ptr vtemu.vttable+2
mov word ptr decbuf+3,ax
vtchar1:mov comand.cmcr,1 ; allow bare CR's
mov ah,cmkey
xor bx,bx
mov dx,offset sidetab ; read Gnumber item, if any
call comnd
mov comand.cmcr,0 ; no bare CR's
jc vtchar2 ; c = no match, get confirm
inc temp ; say have a trailing table number
and bx,3 ; remove ASCII value encoding
add bx,offset decbuf+1 ; address of slot to store info
mov al,decbuf ; set ident
mov [bx],al ; store table ident in G0..G3 slot
jmp short vtchar1 ; repeat
; vtemu.vtchset: changed to new set if no table trailers, else intact
; vtemu.vttable db 4 dup(0ffh) char set numbers for G0..G3 as overrides,
; use 0ffh to mean no override for table Gn
vtchar2:mov ah,cmeol ; get EOL confirmation
call comnd
jc vtcharx ; c = failure, quit
mov vtemu.vtchop,-1 ; say reinit char tables
cmp temp,0 ; trailers (skip regular setup)?
jne vtchar3 ; ne = yes
mov al,decbuf ; get character set
mov vtemu.vtchset,al ; set default character set
clc
ret
; just overrides
vtchar3:mov ax,word ptr decbuf+1 ; first pair of char set idents
mov word ptr vtemu.vttable,ax
mov ax,word ptr decbuf+3 ; second pair
mov word ptr vtemu.vttable+2,ax
clc
vtcharx:ret
vtshift:mov ah,cmkey ; Set Term Output-shift auto, none
xor bx,bx
mov dx,offset shifttab
call comnd
jc vtshifx ;[HF] c = failed
cmp bl,(128+1) ;[HF] JIS7-Kanji ?
jne vtshif3 ;[HF] ne = no
mov temp2,bx ; save shift from above
mov temp,'BB' ;[HF] set default
mov comand.cmcr,1 ;[HF] allow bare CR
mov ah,cmkey ;[HF] get Roman/ASCII set
xor bx,bx ;[HF]
mov dx,offset jis7tab ;[HF]
call comnd ;[HF]
jc vtshif2 ;[HF] get confirm
mov temp,bx ;[HF] set value
vtshif2:mov ah,cmeol ;[HF] get confirm
call comnd ;[HF]
jc vtshifx ;[HF]
mov bx,temp ;[HF] restore value
mov word ptr jis7des,bx ;[HF] set it
mov bx,temp2 ; initial shift
mov flags.oshift,bl ; shift
clc ;[HF]
ret
vtshif3:push bx
mov ah,cmeol
call comnd
pop bx
jc vtshifx
mov flags.oshift,bl ; shift
clc
vtshifx:ret
vtrollbk:mov ah,cmkey ; Set Term Roll On/Off, auto roll back
xor bx,bx ; Use on/off table as help
mov dx,offset ontab ; Use on/off table
call comnd
jc vtrollx ; c = failure
push bx
mov ah,cmeol ; get a confirm
call comnd
pop bx
jc vtrollx ; c = failure
mov vtroll,bl ; set roll state (0=no auto rollback)
clc
vtrollx:ret
; Set Term Color foreground, background
vtcolor:mov bx,vtemu.att_ptr ; get address of attributes byte
mov bl,[bx] ; get attributes
mov decbuf,bl ; save in work temp
mov al,vtclear ; screen clear state
mov ah,refresh ; refresh state
mov word ptr decbuf+1,ax ; save here
mov al,reset_color ; reset color state
mov decbuf+3,al
call vsetcol ; get and analyze colors
jc vtcolo1 ; c = failure
mov al,decbuf ; get current attributes
mov bx,vtemu.att_ptr ; get address of attributes byte
mov [bx],al ; store attributes
mov savattr,al ; saved emulator attributes
and al,att_bold ; pick up userbold preference
mov userbold,al
mov ax,word ptr decbuf+1
mov vtclear,al ; update these items
mov refresh,ah
mov al,decbuf+3
mov reset_color,al ; reset color state
clc
vtcolo1:ret
; setup color information
vsetcol:mov ah,cmword ; get number(s) after set term color
mov dx,offset colhlp ; use this help
mov bx,offset rdbuf ; temp buffer
mov comand.cmcr,1 ; allow bare c/r's
mov comand.cmcomma,1 ; commas are equivalent to spaces
call comnd
jc vsetco2 ; c = failure
or ax,ax ; text given?
jz vsetco1 ; z = no
mov si,offset rdbuf ; si = string
call vsetco3 ; analyze
jmp short vsetcol ; get more data
vsetco1:mov ah,cmeol ; get end of line confirm
call comnd
vsetco2:ret ; c set if failure
vsetco3:mov dx,si
call strlen ; get string count
mov domath_ptr,si
mov domath_cnt,cx
call domath
mov si,domath_ptr ; where to read next string byte
cmp domath_cnt,0
jne vsetco1 ; ne = did not convert whole string
or ax,ax ; reset all? regular IBM CGA refresh
jnz vsetco4 ; nz = no
mov word ptr decbuf+2,0 ; slow screen refresh, no reset color
mov decbuf,07h ; clear all, set white on black
mov decbuf+1,2 ; set trigger for emulator clear scrn
jmp short vsetcol
vsetco4:cmp ax,1 ; high intensity?
jne vsetco5 ; e = no
or decbuf,08h ; set high intensity
mov decbuf+1,1 ; set trigger for emulator keep screen
jmp short vsetcol
vsetco5:cmp ax,10 ; fast refresh?
jne vsetco5a ; ne = no
mov decbuf+2,1 ; Fast screen refresh
jmp short vsetcol
vsetco5a:cmp ax,20 ; reset color upon CSI m?
jne vsetco6 ; ne = no
mov decbuf+3,1 ; reset color state is yes
jmp vsetcol
vsetco6:cmp ax,30 ; check range
jb vsetco8 ; b = too small, complain
cmp ax,37
ja vsetco7 ; 30-37 is foreground color
sub al,30 ; remove foreground bias
and decbuf,not 07H ; clear foreground bits
mov bx,ax
mov al,colortb[bx] ; get reversed bit pattern
or decbuf,al ; load new bits
mov decbuf+1,2 ; set trigger for emulator clear scn
jmp vsetcol
vsetco7:cmp ax,40
jb vsetco8 ; b = bad value
cmp ax,47 ; compare as unsigned
ja vsetco8 ; 40-47 is background
sub al,40 ; remove background bias
and decbuf,not 70H ; clear background bits
mov bx,ax
mov al,colortb[bx] ; get reversed bit pattern
mov cl,4 ; rotate 4 positions
rol al,cl
or decbuf,al ; load new bits
mov decbuf+1,2 ; set trigger for emulator clear scn
jmp vsetcol
vsetco8:mov ah,prstr ; not in range - complain and exit
mov dx,offset colerr
int dos
mov kstatus,ksgen ; general failure
stc ; error
ret
vtucolor:mov al,vtclear ; screen clear state
mov ah,refresh ; refresh state
mov word ptr decbuf+1,ax ; save here
mov al,scbattr
mov decbuf,al
call vsetcol ; get and analyze colors
jc vtucol1 ; c = failure
mov al,decbuf ; get current attributes
mov colunder,al ; saved underlined color
mov ax,word ptr decbuf+1
mov vtclear,al ; update these items
mov refresh,ah
clc
vtucol1:ret
ifndef no_graphics
vtgraph:mov ah,cmkey ; Set Term graphics
xor bx,bx ; Use graphics table as help
mov dx,offset graftab ; Use graphics table
call comnd
jc vtgrapx ; c = failure
cmp bx,100h ; in the special options area?
ja vtgrap1 ; a = yes
push bx
mov ah,cmeol ; get a confirm
call comnd
pop bx
jc vtgrapx ; c = failure
mov tekgraf,bl ; set Tek graphics board type
clc
vtgrapx:ret
vtgrap1:cmp bx,101h ; character writing?
jne vtgrap2 ; ne = no
mov ah,cmkey ; Set Term graphics char-writing
xor bx,bx ; no help
mov dx,offset gchrtab ; opaque/transparent table
call comnd
jc vtgrapx ; c = failure
push bx
mov ah,cmeol ; get a confirm
call comnd
pop bx
jc vtgrapx
mov chcontrol,bl ; set/reset opaque char control
clc
ret
vtgrap2:cmp bx,102h ; cursor on/off?
jne vtgrap4 ; ne = no
mov ah,cmkey ; Set Term graphics cursor on/off
xor bx,bx ; no help
mov dx,offset ontab ; on/off table
call comnd
jc vtgrapx ; c = failure
push bx
mov ah,cmeol ; get a confirm
call comnd
pop bx
jc vtgrapx
mov tekcursor,bl ; set Tek text cursor on/off
clc
ret
vtgrap4:cmp bx,103h ; Color?
jne vtgrap6 ; ne = no
call tekgcptr ; get pointer to active Tek color pal
mov al,[bx] ; get background attributes
and al,7 ; discard intensity bit
mov cl,4
shl al,cl
mov ah,[bx+7] ; get foreground attributes
or al,ah
mov decbuf,al ; setup work temp for vsetcol
push bx ; save index
call vsetcol ; get and analyze colors
pop bx
jnc vtgrap5 ; nc = ok
ret
vtgrap5:mov al,decbuf ; get current attributes
mov ah,al ; get background bits
mov cl,4
shr ah,cl ; just background here
and al,0fh ; just foreground here
mov [bx],ah ; store colpal[0] as background
mov [bx+7],al ; store colpal[7] as foreground
clc ; success
vtgrap6:ret
endif ; no_graphics
vtbeep: mov ah,cmkey ; SET TERM BELL
xor bx,bx ; use table as help
mov dx,offset beltab ; use Bell table
call comnd
jc vtbeepx ; c = failure
push bx
mov ah,cmeol ; get a confirm
call comnd
pop bx
jc vtbeepx ; c = failure
mov belltype,bl ; set bell type
vtbeepx:ret ; return carry clear or set
; SET TERM BYTESIZE {7-bit | 8-bit}
vtbyte: mov ah,cmkey ; SET TERM DISPLAY {7-bit | 8-bit}
mov dx,offset distab ; table
xor bx,bx ; help is table
call comnd
jc vtbytex ; c = failure
push bx
mov ah,cmeol ; get a confirm
call comnd
pop bx
jc vtbytex ; c = failure
and flags.remflg,not d8bit ; clear display 8-bit bit
or flags.remflg,bl ; set or clear the bit
vtbytex:ret
vtupss: mov ah,cmkey ; SET TERM UPSS
mov bx,offset upsshlp ; help
mov dx,offset upsstab ; UPSS table
call comnd ; get UPSS char set
jc vtupssx ; failure
push bx
mov ah,cmeol
call comnd
pop bx
jc vtupssx ; c = fail
mov al,96 ; assume 96 byte set
or bh,bh ; one byte set identifier?
jz vtupss1 ; z = yes
mov al,94 ; a 94 byte set
vtupss1:mov upss,al ; set length
mov word ptr upss+1,bx ; store set ident
mov vtemu.vtchop,-1 ; clear operational char set to reinit
clc
vtupssx:ret
; SET TERM RESET
termreset:mov vtinited,0 ; say uninitialized
clc
ret
apcctl: cmp apctrap,0 ; doing within an APC-macro?
jne apcctl1 ; ne = yes, don't do it
mov ah,cmkey ; SET TERM APC-macro enable, disable
mov bx,offset apchlp ; help
mov dx,offset apctab ; APC table
call comnd
jc apcctl1 ; failure
push bx
mov ah,cmeol
call comnd
pop bx
jc apcctl1 ; c = fail
mov apcenable,bl ; enable flag
clc
apcctl1:ret
vtdownld:mov ah,cmkey ; AUTODOWNLOAD {ON, OFF}
mov bx,offset dnldhlp
mov dx,offset ontab
call comnd
jc vtdownldx
mov vtemu.vtdnld,bl ; status
clc
vtdownldx:ret
vtenqctl:mov ah,cmkey ; SET TERM Answerback {ON, OFF}
mov bx,offset enqhlp ; help
mov dx,offset enqtab ; on/off/message table
call comnd
jc vtenqctl1 ; failure
cmp bl,2 ; message?
je vtenqctl1 ; e = yes
cmp bl,3 ; unsafe-message?
je vtenqctl1 ; e = yes
push bx ; else 0=off, 1=on
mov ah,cmeol
call comnd
pop bx
jc vtenqctlx ; c = fail
mov vtenqenable,bl ; enable (1) flag
clc
ret
vtenqctl1:
mov enqbuf,0 ; presume save message
cmp bl,3 ; unsafe?
jne vtenqctl2 ; ne = no
mov enqbuf,1 ; say unsafe
vtenqctl2:
mov dx,offset enqhlp2 ; help
mov comand.cmdonum,1 ; \number conversion allowed
mov comand.cmblen,length enqbuf-1 ; length of analysis buffer
mov bx,offset rdbuf ; temp response buffer
mov ah,cmline
call comnd
jc vtenqctlx ; c = failure
mov si,offset rdbuf ; temp response buffer
mov di,offset enqbuf+1 ; enquire response buffer
call strcpy ; copy string, asciiz
clc
vtenqctlx:ret
scrwrite:mov ah,cmkey ; SET TERM SCREEN-WRITING
xor bx,bx ; help
mov dx,offset writetab ; screen table
call comnd
jc scrwritx ; failure
push bx
mov ah,cmeol
call comnd
pop bx
jc vtupssx ; c = fail
mov writemode,bl ; store writing mode
clc
scrwritx:ret
scrchange:mov ah,cmkey ; SET TERM VIDEO-CHANGE
xor bx,bx ; help
mov dx,offset vchgtab ; enable/disable/dos-only
call comnd
jc scrchangex ; failure
push bx
mov ah,cmeol
call comnd
pop bx
jc scrchangex ; c = fail
mov vchgmode,bl ; store video-change mode
clc
scrchangex:ret
expmemory:mov ah,cmkey ; EXPANDED-MEMORY {OFF, EXTENDED, EXP}
mov bx,offset expmhlp ; help
mov dx,offset emmtab ; emm choice table
call comnd
jc expmem2 ; failure
push bx
mov ah,cmeol
call comnd
pop bx
jc expmem2 ; c = fail
cmp useexp,bl ; changing kinds?
je expmem1 ; e = no
mov vsbuff_inited,0 ; say reinitialize buffer memory
mov useexp,bl ; enable (1) flag
expmem1:clc
expmem2:ret
vtcodepage:mov ah,cmkey ; SET TERM CODE-PAGE
xor bx,bx ; help
mov dx,offset setchtab ; Code Page table
call comnd
jc vtcode1 ; failure
push bx
mov ah,cmeol
call comnd
pop bx
jc vtcode1 ; c = fail
mov vtcpage,bx ; new terminal Code Page
mov vtemu.vtchop,-1 ; force change of working set
clc
vtcode1:ret
vtcpu: mov ah,cmkey ; SET TERM Timeslice-release
xor bx,bx ; help
mov dx,offset disatab ; enable/disable
call comnd
jc vtcpux ; failure
push bx
mov ah,cmeol
call comnd
pop bx
jc vtcpux ; c = fail
mov vtcpumode,bl ; store timeslice release mode
clc
vtcpux: ret
vtcrdisp:mov ah,cmkey
xor bx,bx
mov dx,offset crdisptab ; table
call comnd
jc vtcrdispx
push bx
mov ah,cmeol
call comnd
pop bx
jc vtcrdispx
mov crdisp_mode,bl
clc
vtcrdispx:ret
termesc:mov ah,cmkey ; SET TERM ESCAPE
xor bx,bx
mov dx,offset termesctab ; table
call comnd
jc termescx
push bx
mov ah,cmeol
pop bx
jc termescx
mov termesc_flag,bl
clc
termescx:ret
; SET Term flags. These are the (near) equivalent of VT100 Setup mode values.
flg1: mov ax,vsnewline ; NEWLINE
mov dx,offset ontab
jmp short flgset
flg2: mov ax,vswrap ; WRAP
mov dx,offset ontab
jmp short flgset
flg4: mov ax,vswdir ; DIRECTION
mov dx,offset dirtab
jmp short flgset
flg5: mov ax,vskeyclick ; KEYCLICK
mov dx,offset ontab
jmp short flgset
flg6: mov ax,vsmarginbell ; MARGIN BELL
mov dx,offset ontab
jmp short flgset
flg7: mov ax,vscursor ; CURSOR
mov dx,offset curtab
jmp short flgset
flg8: mov ax,vsscreen ; SCREEN
mov dx,offset scrtab
jmp short flgset
flg9: mov ax,vscntl ; CONTROLS
mov dx,offset cntltab
jmp short flgset
flg10: mov ax,deckpam ; KEYPAD
mov dx,offset kpamtab
jmp short flgset
flg11: mov ax,decckm ; ARROW
mov dx,offset arrtab
jmp short flgset
flg12: mov ax,deccol ; WIDTH
mov dx,offset widtab
jmp short flgset
flg13: mov ax,vshscroll ; Horizontal scrolling
mov dx,offset hstab
jmp short flgset
flg14: mov ax,vscompress ; compressed text display
mov dx,offset cmptab
;; jmp short flgset
flgset: push ax ; save flag
mov ah,cmkey ; another keyword
xor bx,bx ; use default help, dx has table ptr
call comnd
pop ax ; recover index
jc flgse0 ; c = failure
push ax
push bx ; save result of keyword
mov ah,cmeol ; get confirm
call comnd
pop bx
pop ax ; recover flag
jc flgse0 ; c = failure
or bx,bx ; set or clear?
jz flgse1 ; z = clear it
or vtemu.vtflgst,ax ; set the flag
or vtemu.vtflgop,ax ; in runtime flags too
flgse3: test ax,deccol ; modifying screen width?
jz flgse2 ; z = no
mov al,crt_cols ; current width
mov dos_cols,al ; width to remember, for changes
flgse2: clc ; success
flgse0: ret
flgse1: not ax ; Complement
and vtemu.vtflgst,ax ; clear the indicated setup flag
and vtemu.vtflgop,ax ; clear the indicated runtime flag
not ax
jmp short flgse3 ; test for screen change
; SET Term Tabstops Clear ALL
; SET Term Tabstops Clear AT n1, n2, ..., nx
; SET Term Tabstops At n1, n2, ..., nx
tabmod: mov ah,cmkey ; parse keyword
mov bx,offset clrhlp ; help text
mov dx,offset tabtab ; table
call comnd
jc tabmo2 ; c = failure
mov clrset,2 ; 2 = code for set a tab
or bl,bl ; clear?
jnz tabmo4 ; nz = no, SET. parse column number(s)
mov clrset,1 ; code for clear at/all tab(s)
mov ah,cmkey ; CLEAR, parse ALL or AT
mov bx,offset clrhlp ; help text
mov dx,offset alltab ; parse ALL or AT
call comnd
jc tabmo2 ; c = failure
or bx,bx ; ALL?
jnz tabmo4 ; nz = AT, clear at specific places
mov ah,cmeol ; confirm the ALL
call comnd
jc tabmo2 ; c = failure
mov cx,vswidth ; ALL, means clear all tab stops
tabmo1: mov dx,cx
dec dl ; column number, starting with 0
mov si,vtemu.vttbs ; the cold-start buffer
call ftabclr ; clear the tab
loop tabmo1 ; do all columns
mov si,vtemu.vttbs
mov di,vtemu.vttbst ; and active buffer
call tabcpy ; update active tabs
clc ; success
tabmo2: ret ; a success/fail return point
tabmo4: mov si,vtemu.vttbs ; from the cold-start buffer
mov di,offset decbuf ; temp work buffer
call tabcpy ; make a working copy of the tabs
mov skip,0 ; clear spacing-active flag
mov temp,0 ; place where last tab was written
tabmo6: mov dx,offset clrhlp2 ; tell them we want a column number
mov ah,cmword ; get line of text
mov bx,offset rdbuf ; temp buffer
mov comand.cmcomma,1 ; commas are equivalent to spaces
call comnd
jc tabmo2 ; c = failure
or ax,ax ; anything given?
jnz tabmo7 ; nz = yes
mov ah,cmeol ; confirm end of line
call comnd
jc tabmo2 ; failure
mov si,offset decbuf ; copy tabs from temp work buffer
mov di,vtemu.vttbs ; to the cold-start buffer
call tabcpy ; copy work to cold start
mov di,vtemu.vttbst ; and terminal emulator's active buf
call tabcpy
clc
ret
tbsbad: mov ah,prstr ; not in range - complain
mov dx,offset tbserr
int dos
stc
ret
tabmo7: mov si,offset rdbuf ; si = string
tabmo8: mov dx,si
call strlen ; get length of this word
jcxz tabmo6 ; empty, get more user input
mov domath_ptr,si ; try for expression
mov domath_cnt,cx
mov domath_msg,1 ; do not complain
call domath
mov si,domath_ptr ; where to read next string byte
jnc tabmo9 ; got a value
cmp byte ptr [si],',' ; comma syntax?
jne tabmo8a ; ne = no
inc si ; skip the comma and try next field
jmp short tabmo8
tabmo8a:cmp byte ptr [si],':' ; spacing separator?
jne tbsbad ; ne = no, no number available
inc si ; skip colon, do start:space analysis
inc skip ; set spacing-active flag
jmp short tabmo8 ; get another token
tabmo9: cmp skip,0 ; want spacing value now?
jne tabmo11 ; ne = yes, go do it
mov dx,ax ; column (1-vswidth style)
dec dx ; put column in range 0-131
or dx,dx ; check range (1-vswidth-->0-...)
js tbsbad ; s = too small. complain
cmp dl,vswidth-1 ; more than the right most column?
ja tbsbad ; a = yes, quit
mov temp,dx ; remember last written position
jmp tabmo15 ; and write this member
tabmo11:mov dx,temp ; continue spacing analysis
mov skip,0 ; clear spacing-active flag
mov cx,ax ; "space" value
or cx,cx ; zero spacing?
jnz tabmo12 ; nz = no
inc cx ; don't get caught with zero spacing
tabmo12:cmp dx,vswidth-1 ; largest tab stop
ja tabmo8 ; a = done largest tab stop
mov temp,dx ; remember last written tabstop
push si
mov si,offset decbuf ; the work buffer
cmp clrset,2 ; set?
jne tabmo13 ; ne = no, clear
call ftabset ; set tabstop in column DL
jmp short tabmo14
tabmo13:call ftabclr ; clear tabstop in column DL
tabmo14:add dx,cx ; new column value
pop si
jmp short tabmo12 ; finish spacing loop
tabmo15:push si ; individual tabstop
mov si,offset decbuf ; the work buffer
cmp clrset,2 ; set?
jne tabmo16 ; ne = no, clear
call ftabset ; set tabstop in column DL
jmp short tabmo17 ; get next command value
tabmo16:call ftabclr ; clear tabstop in column DL
tabmo17:pop si
jmp tabmo8 ; get next command value
VTS endp ; end of Set Term things
; Terminal Status display, called within STAT0: in MSSSET
VTSTAT proc near ; enter with di within sttbuf, save bx
mov bx,offset vtstbl ; table of things to show
jmp statc ; status common code, in mssset
vtstat endp
txtcolstat proc near ; text color status report
push si
mov si,offset txtcolst1
mov bx,vtemu.att_ptr ; pointer to attributes byte
call colstd ; report worker
mov si,offset colst3
txtcols1:lodsb
cmp al,'$'
je txtcols2
stosb
jmp short txtcols1
txtcols2:mov al,reset_color
or al,al ; resetting color after CSI [ m?
jz txtcols3 ; z = no
mov al,'2' ; show as "20"
stosb
txtcols3:mov al,'0'
stosb
pop si
ret
txtcolstat endp
undcolstat proc near ; underline color status report
push si
mov si,offset undcolst1
mov bx,offset colunder ; pointer to attributes byte
call colstd ; report worker
pop si
ret
undcolstat endp
ifndef no_graphics
grcolstat proc near ; graphics color status report
push si
mov si,offset grcolst1
call tekgcptr ; get pointer to active Tek color pal
call colstd ; report worker
pop si
ret
grcolstat endp
endif ; no_graphics
; enter with offset of initial msg in si and ptr to color codes in bx
colstd proc near ; worker for color status reports
cld
colstd1:lodsb
cmp al,'$' ; end of string?
je colstd2 ; e = yes
stosb
jmp short colstd1
colstd2:mov bl,byte ptr[bx] ; attributes
xor bh,bh
push bx
and bx,7 ; get foreground set
mov al,colortb[bx] ; get reversed bit pattern
add al,'0' ; add ascii bias
stosb
pop bx
mov si,offset colst2
colstd3:lodsb
cmp al,'$'
je colstd4
stosb
jmp short colstd3
colstd4:mov cl,4 ; rotate 4 positions
shr bl,cl
and bx,7 ; get background set
mov al,colortb[bx] ; get reversed bit pattern
add al,'0' ; add ascii bias
stosb
ret
colstd endp
tabstat proc near ; worker,display tabs ruler for Status
push dx
cld
mov al,cr
stosb
cmp cl,10 ; are we on a new line?
jb tabsta0 ; b = no, do a lf now
mov al,lf
stosb
tabsta0:xor cl,cl ; column index
xor ax,ax ; ah = tens, al = units counter
tabsta1:mov dl,'.' ; default position symbol
inc al
cmp al,10 ; time to roll over?
jb tabsta2 ; b = not yet
xor al,al ; modulo 10
inc ah
mov dl,ah ; display a tens-digit
add dl,'0'
cmp dl,'9' ; larger than 90?
jbe tabsta2 ; be = no
sub dl,10 ; roll over to 0, 1, etc
tabsta2:push dx
push si
mov dl,cl ; column number, counted from 0
mov si,vtemu.vttbst ; the active buffer
call istabs ; is tab set here?
pop si
pop dx
jnc tabsta3 ; nc = no
mov dl,'T' ; yes, display a 'T'
tabsta3:push ax
mov al,dl
stosb
pop ax
inc cl
cmp cl,byte ptr low_rgt ; done yet?
jb tabsta1 ; b = not yet
pop dx
ret
tabstat endp
; Returns carry set if column in DL is a tab stop, else carry clear.
; Enter with column number in DL (starts at column 0, max of vswidth-1)
; and tabstop buffer offset in SI.
istabs proc near
push bx
push cx
mov cl,dl ; column number (0 to swidth-1)
and cl,00000111b ; keep bit in byte (0-7)
inc cl ; map to 1-8
mov bl,dl ; column
shr bl,1 ; bl / 8 to get byte
shr bl,1
shr bl,1
xor bh,bh ; clear high byte
mov bl,[si+bx] ; get a byte of tab bits
ror bl,cl ; rotate to put tab-set bit into carry
pop cx
pop bx
ret
istabs endp
ansbkstat proc near
mov ax,di ; starting place
push ax
mov si,offset vtenqst2
mov cx,vtenqst2_len
cld
rep movsb
mov si,offset enqbuf+1 ; skip safe/unsafe byte
mov dx,si
call strlen ; append local string
rep movsb
pop ax
mov cx,di
sub cx,ax ; return space used
ret
ansbkstat endp
filler proc near ; use space
mov cx,20
mov al,' '
cld
rep stosb
ret
filler endp
; Jump here to exit Connect mode and execute macros 'KEYBOARDR' (vtkrmac) or
; 'KEYBOARDS' (vtksmac). Does nothing if macro does not exist.
; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
vtkrmac proc near ; RESET macro
mov vtmacname,offset vtkrname ; select macro name
mov vtmaclen,vtkrlen ; and its length
call dword ptr vtmacroptr ; FAR pointer, finish in common code
jc vtkrmac1 ; c = failure
jmp far ptr endcon ; end connect mode, do macro
vtkrmac1:ret
vtkrmac endp
vtksmac proc near ; SET macro
mov vtmacname,offset vtksname
mov vtmaclen,vtkslen
call dword ptr vtmacroptr ; FAR pointer
jc vtksmac1 ; c = failure
jmp far ptr endcon ; end connect mode, do macro
vtksmac1:ret
vtksmac 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
call dword ptr vtmacroptr ; FAR pointer
jc extmac1 ; c = failure
jmp far ptr endcon ; end connect mode, do macro
extmac1:mov kbdflg,' ' ; report ' ' to TERM's caller
ret ; to resume Connect mode
extmacro endp
; Invokes macro PRODUCT with variables \%1..\%9
; defined as the ascii renditions of the control sequence numeric paramters
; param[0]..param[8], and sets script ARGC item to one greater than this.
product proc near
call far ptr prodwork ; FAR pointer
jc prodmac1 ; c = failure
jmp far ptr endcon ; end connect mode, do macro
prodmac1:ret
product endp
term proc near
call far ptr fterm
ret
term endp
fclrmod proc far
call clrmod
ret
fclrmod endp
fputmod proc far
call putmod
ret
fputmod endp
fcmblnk proc far
call cmblnk
ret
fcmblnk endp
fkbhold proc far
call kbhold
ret
fkbhold endp
fprtchr proc far
call prtchr
ret
fprtchr endp
fkeybd proc far
call keybd
ret
fkeybd endp
fpntflsh proc far
call pntflsh
ret
fpntflsh endp
fpntchr proc far
call pntchr
ret
fpntchr endp
foutchr proc far
call outchr
ret
foutchr endp
fspath proc far
call spath
ret
fspath endp
fcrun proc far
call crun
ret
fcrun endp
fserini proc far
call serini
ret
fserini endp
fctlu proc far ; [HF]940211
call ctlu ; [HF]940211
ret ; [HF]940211
fctlu endp ; [HF]940211
vtinit proc near
call fvtinit
ret
vtinit endp
rtone proc near
call frtone
ret
rtone endp
rtpage proc near
call frtpage
ret
rtpage endp
lfone proc near
call flfone
ret
lfone endp
lfpage proc near
call flfpage
ret
lfpage endp
homwnd proc near
call fhomwnd
ret
homwnd endp
endwnd proc near
call fendwnd
ret
endwnd endp
dnwpg proc near
call fdnwpg
ret
dnwpg endp
dnone proc near
call fdnone
ret
dnone endp
upwpg proc near
call fupwpg
ret
upwpg endp
upone proc near
call fupone
ret
upone endp
fcptchr proc far
call cptchr
ret
fcptchr endp
fserrst proc far
call serrst
ret
fserrst endp
ifndef no_network
fubclose proc far
call ubclose
ret
fubclose endp
endif ; no_network
endif ; no_terminal
code ends
code1 segment
assume cs:code1
; Kermit startup time initialization
flclyini proc far
mov ah,conout ; write a space to determine
mov dl,' ' ; DOS's default cursor coloring
int dos
call getpcur ; get current cursor position into dx
mov lincur,cx ; save cursor type (scan line #'s)
dec dl ; backup to last char
or dl,dl
jns lclyin5 ; ns = no problem
xor dl,dl ; else set cursor back to left margin
lclyin5:call setpcur ; set the cursor
call getpcha ; read current attributes into AH
mov scbattr,ah ; save video attributes
mov savattr,ah ; and saved attributes
mov dosattr,ah ; and here too
and ah,att_bold ; select intensity bit
mov userbold,ah ; save bit for user Bold control
mov ega_mode,0 ; assume no EGA
mov ax,1200H ; EGA: Bios alternate select
mov bl,10H ; Ask for EGA info
mov bh,0ffH ; Bad info, for testing
mov cl,0fH ; Reserved switch settings
int screen ; EGA, are you there?
cmp cl,0cH ; Test reserved switch settings
jge lclyin1 ; ge = no EGA in use
push es
mov ax,40h ; check Bios 40:87h for ega being
mov es,ax ; the active display adapter
test byte ptr es:[87h],8 ; is ega active?
pop es
jnz lclyin1 ; nz = no
mov ega_mode,1 ; yes, set flag to say ega is active
mov crt_norm,3 ; assume color monitor is attached
or bh,bh ; is color mode in effect?
jz lclyin1 ; z = yes
mov crt_norm,7 ; else use mode 7 for mono
lclyin1:call scrseg ; test running in an Environment
call dvtest ; test for running under DESQview
call scrmod ; read video state, get crt_mode
mov dosetcursor,-1 ; cursor position reminder, none
mov ax,low_rgt ; lower right corner of screen
mov al,crt_mode
mov crt_norm,al ; save as normal mode
mov ah,crt_cols
mov dos_cols,ah ; remember for exiting Connect mode
ifndef no_terminal
mov keypend,0 ; [HF]940207 clear double byte flag
mov keyj7st,0 ; [HF]940211 clear keyoutput status
mov cursor,0 ; initial cursor
call vsalloc ; allocate memory for virtual screen
jnc lclyin4 ; nc = success
mov ah,prstr
mov dx,offset memerr ; say not enough memory to operate
int dos
mov flags.extflg,1 ; set Kermit exit flag
ret
lclyin4:call vsinit ; init terminal emulator module MSZ
mov bx,vtemu.att_ptr ; attributes pointer
mov ah,dosattr ; startup video attributes
and ah,not att_bold ; emulation intensity to normal
or ah,userbold
mov [bx],ah ; set initial emulation attributes
and vtemu.vtflgst,not deccol ; assume 80 column screen
and vtemu.vtflgop,not deccol
cmp crt_cols,80 ; screen cols now, wide screen?
jbe lclyin6 ; be = no
or vtemu.vtflgst,deccol ; say using 132 columns screen
or vtemu.vtflgop,deccol
endif ; no_terminal
lclyin6:ret
flclyini endp
ifndef no_terminal
; Allocate memory for virtual screen buffers vscreen and vsat.
; Return carry clear if success, else carry set. Removes older allocations.
vsalloc proc near
call vsalloc4 ; free alloc'd memory, if any
mov al,crt_lins ; one minus number of screen rows
inc al
mov cl,vswidth ; virtual screen vscreen
mul cl ; lines time width, words for vscreen
add ax,ax ; need words
add ax,15 ; round up
mov cl,4 ; convert to paragraphs
shr ax,cl ; need words rather than bytes
mov cx,ax ; save total wanted paragraphs in cx
mov bx,ax ; ask for the memory
mov ah,alloc ; allocate memory
int dos ; bx has # free paragraphs
mov word ptr vs_ptr+2,ax ; seg of vsscreen (offset is zero)
cmp cx,bx ; got what we wanted
jb vsalloc5 ; b = no
push es
mov es,ax
xor di,di
shl cx,1
shl cx,1
shl cx,1 ; paragraphs to words
mov ah,scbattr
mov al,' '
cld
rep stosw ; clear the memory with def colors
pop es
mov al,crt_lins
inc al ; attributes (nibbles)
mov cl,vswidth ; lines time width, bytes for vsattr
mul cl
add ax,15 ; round up
mov cl,4 ; convert to paragraphs
shr ax,cl
mov cx,ax ; save total wanted paragraphs in cx
mov bx,ax ; ask for the memory
mov ah,alloc ; allocate the memory
int dos ; bx has # free paragraphs
mov word ptr vsat_ptr+2,ax ; seg of vsattr (offset is zero)
cmp cx,bx ; got what we wanted
jb vsalloc4 ; b = no
push es
mov es,ax
xor di,di
shl cx,1
shl cx,1
shl cx,1
shl cx,1 ; paragraphs to bytes
xor al,al
rep stosb ; clear the memory with def extattr
pop es
clc ; report success
ret
vsalloc4:mov ax,word ptr vsat_ptr+2 ; seg of vsattr (offset is zero)
or ax,ax ; unused?
jz vsalloc5 ; z = yes
push es
mov es,ax ; allocated segment
mov ah,freemem ; free it
int dos
mov word ptr vsat_ptr+2,0 ; clear pointer too
pop es
vsalloc5:mov ax,word ptr vs_ptr+2 ; seg of vsscreen
or ax,ax ; unused?
jz vsalloc6 ; z = yes
push es
mov es,ax ; allocated segment
mov ah,freemem ; free it
int dos
mov word ptr vs_ptr+2,0 ; clear pointer too
pop es
vsalloc6:stc ; return failure
ret
vsalloc endp
; Allocate memory for screen rollback buffers.
; Return carry clear if success, else carry set to exit.
vsbuff proc near ; screen roll back buffers
cmp vsbuff_inited,0 ; inited yet?
je vsbuff0 ; e = no
clc ; say success
ret
vsbuff0:mov vsbuff_inited,1 ; say we are initializing
cmp emsrbhandle,-1 ; valid EMS rollback handle?
je vsbuff20 ; e = no
mov ah,emsrelease ; release pages
mov dx,emsrbhandle ; handle
int emsint
mov emsrbhandle,-1 ; invalidate EMS rollback handle
mov iniseg,0 ; and no segment for page frame
jmp short vsbuff21
vsbuff20:cmp xmsrhandle,0 ; using XMS?
je vsbuff20a ; e = no
mov dx,xmsrhandle ; handle for memory block
mov ah,xmsrelease ; release the memory block
call dword ptr xmsep ; xms handler entry point
mov xmsrhandle,0
mov dx,xmsghandle ; and the graphics area too
mov ah,xmsrelease ; release the memory block
call dword ptr xmsep ; xms handler entry point
mov xmsghandle,0
vsbuff20a:
mov ax,iniseg ; memory segment, window area
or ax,ax ; anything allocated?
jz vsbuff21 ; z = no
mov es,ax
mov ah,freemem ; free regular memory segment
int dos
mov iniseg,0
vsbuff21:
mov bx,rollwidth ; columns to roll back
or bx,bx ; user override given?
jnz vsbuff1 ; nz = yes, else physical screen
mov bl,crt_cols ; physical screen
xor bh,bh
mov rollwidth,bx ; set final roll width
vsbuff1:add bx,7 ; round up (cancel common times twos)
mov cl,3
shr bx,cl ; bytes/line to paragraphs/line
mov ppl,bx ; paragraphs/line
vsbuff11: ; expanded memory
test useexp,1 ; use expanded memory?
jz vsbuff10 ; z = no, try XMS
mov ah,open2 ; file open
xor al,al ; 0 = open readonly
mov dx,offset emsname ; device name EMMXXXX0
int dos
jc vsbuff10 ; can't open, no expanded memory
push ax ; save handle
mov bx,ax ; handle ax
xor al,al ; get device info
mov ah,ioctl
int dos
pop ax
push dx ; save status report in dx
mov dx,ax ; handle
mov ah,close2 ; close device
int dos
pop dx ; recover status report
rcl dl,1 ; put ISDEV bit into the carry bit
jnc vsbuff10 ; nc = not a device
mov ax,sp ; do push sp test for XT vs AT/386
push sp ; XT pushes sp-2, AT's push old sp
pop cx ; recover pushed value, clean stack
xor ax,cx ; same?
jne vsbuff5 ; ne = no, XT. Don't do Int 2fh
mov ax,xmspresent ; XMS presence test
int 2fh
cmp al,80h ; present?
jne vsbuff10 ; ne = no
mov ah,getintv ; get interrupt vector
mov al,emsint ; EMS interrupt 67h
int dos ; to es:bx
mov ax,es
or ax,bx ; check for null
jz vsbuff10 ; z = interrupt not activated
mov ah,emsmgrstat ; LIM 3.2 manager status
int emsint
or ah,ah ; ok?
jnz vsbuff10 ; nz = not ok
mov ax,1024 ; 1024 paragraphs per ems 16KB page
xor dx,dx
div ppl ; divide by paragraphs per line
mov lineems,ax ; lines per ems page, remember
mov al,crt_lins ; lines-1 per physical screen
xor ah,ah
mov cx,npages ; number of roll back screens wanted
inc cx ; include current screen
mul cx ; times number screens
div lineems ; lines total / (lines/emspage)
or dx,dx ; remainder?
jz vsbuff2 ; z = no
inc ax ; add page for fraction
vsbuff2:push ax ; ax is number of emspages
mov ah,emsgetnpgs ; get number pages free
int emsint ; to bx
pop ax
or bx,bx ; any pages free?
jz vsbuff10 ; z = no, try XMS
cmp bx,ax ; enough?
jb vsbuff3 ; b = less, use what we can get
mov bx,ax ; number of pages wanted
vsbuff3:mov ah,emsalloc ; allocate bx pages
int emsint
or ah,ah ; successful?
jnz vsbuff10 ; nz = no, failure
mov emsrbhandle,dx ; returned handle
mov ax,bx ; pages allocated
mov inipara,ax ; save for later resizing of buffers
mov ah,emsgetseg ; get segment of page frame
int emsint ; to bx
or ah,ah ; status, success?
jnz vsbuff10 ; nz = no, no expanded memory today
mov iniseg,bx ; save here
mov ah,emsgetver ; get EMS version number
int emsint ; to al (high=major, low=minor)
cmp al,40h ; at least LIM 4.0?
jb vsbuff4 ; b = no, so no name for our area
mov si,offset emsrollname ; point to name for rollback area
mov di,offset emsrollname+6 ; add digits
mov dx,emsrbhandle
mov ax,dx
call dec2di ; write to handle name
mov ax,emssetname ; set name for handle from ds:si
int emsint
mov useexp,1 ; say using expanded
vsbuff4:jmp vsbuff9
vsbuff10: ; XMS, try this first
test useexp,2 ; use extended memory?
jz vsbuff5 ; z = no, try conventional
cmp xmsrhandle,0 ; have already allocated xms?
je vsbuff10a ; e = no
mov ah,xmsrelease ; release memory block
mov dx,xmsrhandle
call dword ptr xmsep ; release the memory
jmp short vsbuff10b
vsbuff10a:xor bx,bx ; clear entry point response
mov es,bx
mov ax,xmsmanager ; get XMS manager entry point
int 2fh ; to es:bx
mov word ptr xmsep,bx ; save entry point in xmsep
mov ax,es
or bx,ax ; is there an entry point returned?
jz vsbuff5 ; z = no, use regular memory
mov word ptr xmsep+2,ax
vsbuff10b:mov ax,ppl ; paragraphs / line
mul crt_lins ; times lines-1 on physical screen
mov cx,npages ; number of roll back screens wanted
inc cx ; include current screen
mul cx ; total number of paragraphs wanted
mov cx,6
vsbuff10c:shr dl,1
rcr ah,1
rcr al,1 ; get kilobytes to ax
loop vsbuff10c ; divide by 2^6
mov dx,ax ; KB wanted to dx
push dx
mov ah,xmsquery
call dword ptr xmsep ; get largest block KB into ax
pop dx
cmp dx,ax ; wanted KB vs available KB
jbe vsbuff10d ; be = have space
mov dx,ax ; else use space available
vsbuff10d:push dx ; save KB request amount
mov ah,xmsalloc ; allocate block of dx KB
call dword ptr xmsep
mov xmsrhandle,dx ; returned XMS handle of block
pop dx ; recover KB request amount
mov cx,6 ; convert dx KB to paragraphs in AX
mov ax,dx ; KB allocated to AX
xor dx,dx
vsbuff10e:shl al,1 ; convert KB to paragraphs
rcl ah,1
loop vsbuff10e ; times 2^6, yield paragarphs in ax
mov inipara,ax ; initial number of paragraphs
mov useexp,2 ; say using extended
jmp vsbuff9 ; end XMS
; no ems, so use regular memory
vsbuff5:mov useexp,0 ; say no ems
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 vsbuff7 ; c = not enough for it
mov ax,ppl ; paragraphs / line
mul crt_lins ; times lines-1 on physical screen
cmp bx,ax ; minimum roll back space left over?
jbe vsbuff7 ; be = not even that much
mov cx,npages ; number of roll back screens wanted
inc cx ; include current screen
mul cx ; total number of paragraphs wanted
mov cx,ax ; save in cx
or dx,dx ; want more than 1 MB of real memory?
jz vsbuff6 ; e = no
mov cx,0ffffh ; set all of real memory
vsbuff6:cmp bx,cx ; got vs wanted paras for roll back
jbe vsbuff8 ; be = enough but not more than needed
mov bx,cx ; limit to our actual needs
jmp short vsbuff8 ; ask for all we really want
vsbuff7:xor bx,bx ; use no space at all
mov cx,bx ; remember this new request
vsbuff8:mov ah,alloc
int dos
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 vsbuff9 ; ae = enough
mov ah,prstr
mov dx,offset memerr ; say not enough memory to operate
int dos
stc ; carry set = fail
ret
vsbuff9:call bufadj ; set roll back buffer parameters
clc ; carry clear for success
ret
vsbuff endp
scrini proc far ; init screen stuff
call chkwindows ; check for Windows being active
mov al,crt_lins ; screen lines - 1
mov ah,crt_mode ; preserve this too
push ax ; save
call scrmod ; get screen mode now
mov ax,100h ; assume 80 column mode, no-renter
test vtemu.vtflgop,deccol ; supposed to be in 80 col?
jz scrin5 ; z = yes
inc al ; say want 132 cols
scrin5: call chgdsp ; set to 80/132 columns
call scrmod ; get crt_lins again
pop ax
mov crt_mode,ah ; restore in case in graphics now
cmp al,crt_lins ; changed?
je scrin2 ; e = no
mov vtinited,0 ; say must reinit emulator
mov cursor,0
call vsalloc ; reallocate virtual screen
jnc scrin2 ; nc = success
mov ah,prstr
mov dx,offset memerr ; say not enough memory to operate
int dos
mov sp,oldsp
ret ; must be Far return
scrin2:
scrin1: mov ah,savattr ; saved emulator attributes
mov scbattr,ah ; restore active value
call scrseg ; update screen segment tv_seg(s/o)
call getpcur ; get cursor position DX and type CX
cmp flags.vtflg,0 ; emulating anything?
jne scrin4 ; ne = yes
mov cursor,dx ; use physical cursor
scrin4: mov dx,cursor ; use old cursor, if any
call setpos ; set cursor position
cmp vtinited,inited ; inited emulator yet?
je scrin11 ; e = yes, do reinit
call fvtinit ; init it now
call repaint ; repaint screen
ret
scrin11:
ifndef no_graphics
cmp flags.vtflg,tttek ; Tek mode?
je scrin12 ; e = yes
test tekflg,tek_tek+tek_dec ; Tek submode?
jz scrin14 ; z = no
scrin12:call tekini ; init graphics mode
ret
endif ; no_graphics
scrin14:call ansrei ; reinit the emulator
call repaint ; restore screen from vscreen
scrin15:ret
scrini endp
chkwindows proc near
mov inwindows,0 ; presume not in Windows
mov ax,sp ; do push sp test for XT vs AT/386
push sp ; XT pushes sp-2, AT's push old sp
pop cx ; recover pushed value, clean stack
xor ax,cx ; same?
jne chkwin2 ; ne = no, XT. Don't do Int 2fh
mov ax,1683h ; Windows 3, get current virt machine
int 2fh
cmp ax,1683h ; virtual machine, if any
je chkwin2 ; e = none
mov inwindows,1 ; say in Windows
chkwin2:ret
chkwindows endp
; Initialize terminal emulators
fvtinit proc far
mov ax,apcstring ; seg of apcmacro memory area
or ax,ax ; empty?
jz vtini4 ; z = yes
mov es,ax
mov ah,freemem
int dos ; free that memory
mov apcstring,0
vtini4: mov holdscr,0 ; clear holdscreen
mov vtclear,0 ; clear clear-screen indicator
mov keypend,0 ; [HF]940207 clear double byte flag
mov keyj7st,0 ; [HF]940211 clear keyoutput status
call fkbhold ; tell DEC LK250 the state, in msuibm
or vtinited,inited
mov dosetcursor,0 ; cursor position reminder, none
mov bx,portval
mov dl,[bx].ecoflg ; local echo flag
and yflags,not lclecho
or yflags,dl
mov bx,argadr ; 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
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: cmp flags.vtflg,0 ; doing emulation?
je vtini3 ; e = no
cmp tekflg,tek_active+tek_tek ; Tek graphics mode?
je vtini2 ; e = yes, do it's reinit
cmp tekflg,tek_active+tek_dec ; Tek graphics submode?
je vtini2 ; e = yes, do it's reinit
xor ax,ax ; assume 80 col mode (al=0)
test vtemu.vtflgst,deccol ; want wide display?
jz vtini1a ; z = no
inc al ; set AL to 1 for set 132 col mode
vtini1a:call chgdsp ; set screen width
call ansini ; call startup routine in mszibm
cmp flags.vtflg,tttek ; full Tek mode?
jne vtinix ; ne = no
or tekflg,tek_tek ; say tek mode
jmp short vtini2 ; e = yes
vtinix: clc
ret
vtini2:
ifndef no_graphics
call tekrint ; reinitialize Tek emulator
endif ; no_graphics
clc
ret
vtini3: call fcmblnk ; clear the screen
clc
ret
fvtinit 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
ret
argini endp
fterm proc FAR ; terminal mode entry point
mov argadr,ax ; save argument ptr
mov oldsp,sp ; remember stack for i/o failure,
mov apctrap,0 ; un-trap certain commands
ifndef no_tcp
cmp flags.comflg,'t' ; doing internal Telnet?
jne fterm2 ; ne = not Telnet
cmp termlatch,0 ; have we been here for macro?
jne fterm2 ; ne = yes, reset it and skip macro
mov termlatch,1 ; arm reentry bypass
mov bx,sescur ; get session to bl
call vtsesmac ; this returns us to the Kermit prompt
jc fterm2 ; c = no such macro
else
jmp short fterm2
endif ; no_tcp
fterm1: call fserrst ; shut down serial port now
mov kbdflg,'C' ; say exit Connect mode
ret ; return, to process macro
fterm2: mov termlatch,0 ; disable bypass, enable macro again
mov handhsc,0 ; cancel hand scrolling
call vsbuff ; allocate screen buffer memory
jc fterm1 ; c = failure, quit now
mov grab,0 ; clear Compose/Spcl output grabber
call argini ; init options from arg address
mov inemulator,1 ; say in terminal emulator (local)
call scrini ; call screen setup
or kbcodes,80h ; set need-to-init flg for kbd xtlator
mov fairprn,0 ; set printer buffer flush counter
lp: call fprtchr ; char at port?
jnc short lpinp ; nc = yes, go handle
ifndef no_graphics
cmp tekflg,tek_active+tek_sg ; special graphics active?
jne lpcross ; ne = no, stay in idle loop
mov dx,dosetcursor ; preserved cursor position
cmp dx,-1 ; should we set the cursor?
je lpcursor ; e = no
call teksetcursor ; set the cursor at dx
mov dosetcursor,-1 ; turn off reminder
lpcursor:test flags.vtflg,ttd463+ttd470+ttd217 ; doing DG emulation?
jz lpcross ; z = not DG
cmp dgcross,0 ; is DG crosshair active?
je lpcross ; e = no
xor al,al ; feed it a null command, to do mouse
call croshair ; call Tek crosshair to read mouse
endif ; no_graphics
lpcross:cmp repflg,0 ; REPLAY?
jne lpkbd ; ne = yes
push bx
mov bx,portval ; port structure address
cmp [bx].portrdy,0 ; is port ready for business?
pop bx
jne lpkbd ; ne = ready
jmp quit ; end the communications now
lpkbd: mov fairness,0 ; say kbd was examined
call dvpause ; tell DESQview we are not busy
inc fairprn ; inc printer dump counter
cmp fairprn,100 ; been here enough times now?
jb lpkbd1 ; b = no
call fpntflsh ; flush printer buffer
jnc lpkbd0 ; nc = success
call pntdead ; call bad printer notifier
lpkbd0: mov fairprn,0 ; reset for next time
lpkbd1: call fkeybd ; call keyboard translator in msu
jc quit ; carry set = quit connect mode
call clkdsp ; display clock
jmp short lp ; and repeat idle loop
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 sp,oldsp ; recover startup stack pointer
; TERM caller's return address is now
; on the top of stack. A longjmp.
mov ah,scbattr ; current emulator attributes
mov savattr,ah ; save them here
call fpntflsh ; flush printer buffer
ifndef no_graphics
call tekend ; cleanup Tektronix mode
endif ; no_graphics
mov inemulator,0 ; say not in terminal emulator (local)
mov al,1
call csrtype ; turn on underline cursor
mov ah,dosattr ; attributes at init time
mov scbattr,ah ; background = original state
call fclrmod ; clear mode line with DOS attributes
mov ax,100h ; assume using 80 col screen
cmp dos_cols,80 ; startup screen width
jbe quit1 ; be = assume 80 columns
inc al ; say do 132 columns
quit1:
push vtemu.vtflgop
or vtemu.vtflgop,vscompress ; turn off compressed mode
call chgdsp ; reset display width to startup
pop vtemu.vtflgop
call scrmod ; update size info
; for ega in non-standard # lines
test tv_mode,10h ; DV active?
jnz quit2 ; nz = yes, it messes with the cursor
cmp ega_mode,0 ; ega board active?
je quit2 ; e = no
cmp byte ptr low_rgt+1,23 ; is screen standard length?
je quit2 ; e = yes, so regular cursor set is ok
cmp byte ptr low_rgt+1,24 ; ANSI, is screen standard length?
je quit2 ; e = yes, so regular cursor set is ok
push es ; turn off ega cursor emulation
mov ax,40h ; byte 40:87H is ega Info byte
mov es,ax
push es:[87h] ; save info byte around call
or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
mov cx,lincur ; cursor shape to set
mov ah,1 ; set the shape
int screen ; back to starting value
pop es:[87h] ; recover original Info byte
pop es ; and our work reg
jmp short quit3 ; skip regular mode cursor setting
quit2: ; for regular sized screen
mov cx,lincur ; cursor type at startup
mov ah,1
int screen ; restore cursor type
quit3: mov dh,byte ptr low_rgt+1 ; bottom line -1
xor dl,dl ; left most column
call setpcur ; set cursor physical position
mov al,yflags
mov bx,argadr
mov [bx].flgs,al ; update flags in arg block
call dvpause ; tell DESQview we are not busy
cmp isps55,0 ; [HF]940214 Japanese PS/55?
je quit4 ; [HF]940214 e = no
cmp ps55mod,0 ; [HF]940214 system modeline ?
jne quit4 ; [HF]940214 ne = no
push ax ; [HF]940211
push dx ; [HF]940211
mov ah,prstr ; [HF]940211 we need newline for DOS
mov dx,offset crlf ; [HF]940211
int dos ; [HF]940211
call fctlu ; [HF]940211 clear new line
pop dx ; [HF]940211
pop ax ; [HF]940211
quit4: ret
fterm endp
; put the character in al to the screen
outtty proc near
test flags.remflg,d8bit ; keep 8 bits for displays?
jnz outtt1 ; nz = yes, 8 bits if possible
and al,7fh ; remove high bit
outtt1: cmp flags.vtflg,0 ; emulating a terminal?
je outnp10 ; e = no
cmp vtroll,0 ; auto roll back allowed?
je outem1 ; e = no, leave screen as is
test tekflg,tek_active ; Tek mode active?
jnz outem1 ; nz = yes, skip screen rolling
push ax ; (BDT) save this for a tad
mov ax,linec ; (BDT) are we at the buffer end?
cmp ax,lcnt
pop ax ; (BDT) restore the register
je outem1 ; (BDT) e = yes
push ax ; (BDT) save AX again
call fendwnd ; do END to roll screen to end of buf
pop ax ; (BDT) restore the register
outem1: test tekflg,tek_active ; graphics mode active?
jz outem2 ; z = no
test tekflg,tek_tek+tek_dec ; Tek submode active for input?
jnz outem3 ; nz = yes, use Tek emulator
outem2: call anstty ; call terminal emulator, char in AL
ret
outem3:
ifndef no_graphics
call tekemu ; use Tek emulator and return
endif ; no_graphics
ret
; use DOS for screen output
outnp10: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 outnp8 ; no, keep going
call fpntchr ; queue char for printer
jnc outnp8 ; nc = successful print
push ax
call vtbell ; else make a noise and
call ftrnprs ; turn off printing
pop ax
outnp8: test yflags,capt ; capturing output?
jz outnp6 ; no, forget this part
call fcptchr ; give it captured character
outnp6: test yflags,trnctl ; debug? if so use Bios tty mode
jz outnp4 ; z = no
mov ah,conout ; DOS 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 dl,7eh ; output a tilde for 8th bit
int dos
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 dl,5eh ; caret
int dos ; display it
pop ax ; recover the non-printable char
outnp3: push ax
mov dl,al
int dos
pop ax
ret
outnp4: cmp al,bell ; bell (Control G)?
jne outnp5 ; ne = no
jmp vtbell ; use short beep, avoid char loss
outnp5: mov dl,al ; write without intervention
mov ah,conout
int dos ; else let dos display char
ret
outtty endp
;[IU2] Here to output an unsigned 8-bit number (in al) to the port
; Used by terminal emulator escape sequence output.
prtnout proc near
jmp short prtno2 ; ensure at least a zero
prtno1: or al,al
jnz prtno2 ; nz = yes, do more digits
ret ; no, return from recursive call
prtno2: xor ah,ah ; clear previous remainder
mov bl,10 ; output in base 10
div bl ; divide off a digit
push ax ; push remainder (in ah) on stack
call prtno1 ; recurse
pop ax ; pop off a digit
add ah,'0' ; make it ASCII
mov al,ah ; send to port, in ah
call outprt
jc prtno3 ; failure, end connection
ret
prtno3: jmp far ptr endcon
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
mov ah,1 ; say local echo is permitted
jmp short outprt0
prtbout:xor ah,ah ; no local echo
outprt0:cmp grab,0 ; grabbing output?
je outprt0a ; e = no
call fgrabber ; yes, give it to the guy
ret
outprt0a:test al,80h ; high bit set?
jz outpr2 ; z = no
test flags.vtflg,ttd463+ttd470+ttd217 ; Data General?
jz outprt4 ; z = no
test flags.remflg,d8bit ; chop DG high bit?
jnz outpr2 ; nz = no, send as-is
and al,7fh ; chop high bit
jmp short outpr1 ; send with possible DG SI/SO brackets
outprt4:cmp al,0a0h ; C1 area?
jae outpr1 ; ae = no
cmp vtemu.vtchset,C_XPARENT ; TRANSPARENT?
je outpr2 ; e = yes, pass as-is
test vtemu.vtflgop,vscntl ; sending 8-bit controls?
jz outprt5 ; z = no, force use of 7-bit controls
cmp parmsk,7fh ; using parity?
jne outpr2 ; ne = no, no need to force on that
outprt5:push ax ; save char
mov al,Escape ; C1 as ESCAPE <char-40h>
call outpr2 ; send ESCAPE
pop ax ; recover char
sub al,40h ; relocate the code
jmp short outpr2 ; send the char
; GRight printable characters
outpr1: cmp flags.vtflg,ttgenrc ; doing term type of NONE?
je outpr2 ; e = yes, no tables (maybe SO/SI?)
cmp parmsk,7fh ; using parity?
jne outpr2 ; ne = no, no shifts needed
cmp flags.oshift,0 ; allowing shifts on output?
je outpr2 ; e = no
and al,not 80h ; strip high bit
test flags.oshift,8 ; Auto?
jnz outpr1a ; nz = yes
test flags.oshift,1 ; force SI/SO?
jnz outpr8 ; nz = yes
jmp short outpr1b ; else SS2/SS3
outpr1a:cmp GRptr,offset G1set ; GR points to G1 char set?
je outpr8 ; e = yes, use SO/char/SI
outpr1b:push ax ; save char
mov al,Escape ; send SS2 as ESC N
call outpr2 ; ESC N is Single Shift 2
mov al,'N'
cmp flags.oshift,4 ; force SS3?
jb outpr7 ; b = force SS2
je outpr1c ; e = force SS3
cmp GRptr,offset G2set ; GR points to G2 char set?
je outpr7 ; e = yes, else use SS3 (ESC P)
outpr1c:inc al ; use ESC P for Single Shift 3
outpr7: call outpr2
pop ax ; recover char
jmp short outpr2
outpr8: push ax ; save char
mov al,SOchar ; SO locking shift 1 for G1 to GL
cmp flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz outpr8a ; z = no
mov al,DGescape ; send SO as DG's RS N
call outpr2
mov al,'N'
outpr8a:call outpr2 ; send it
pop ax
push ax ; preserve ah around call
call outpr2 ; send real character (7 bit'd)
pop ax
mov al,SIchar ; shift back to normal
test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz outpr2 ; z = no
mov al,DGescape ; send SI as DG's RS O
call outpr2
mov al,'O'
outpr2: or ah,ah ; local echo permitted?
jz outpr3 ; z = no
test yflags,lclecho ; echoing ourselves?
jz outpr3 ; z = no, forget it
push ax ; save char
call outtty ; display it
pop ax ; restore
ifndef no_network
cmp al,CR ; sending CR?
jne outpr3 ; ne = no
cmp flags.comflg,'t' ; doing Telnet?
jne outpr3 ; ne = no
ifndef no_tcp
cmp tcpnewline,1 ; newline mode is on?
ja outpr3 ; a = RAW, no extra LF
je outpr2a ; e = yes, send CR/LF (else NVT/Bin)
cmp tcpmode,0 ; NVT-ASCII?
jne outpr3 ; ne = no, Binary so no extra LF
endif ; no_tcp
outpr2a:push ax
mov al,LF ; locally show LF which we will send
call outtty
pop ax
endif ; no_network
outpr3: mov ah,al ; this is where outchr expects it
call foutchr ; output to the port
jc outpr4 ; c = failure
ret
outpr4: jmp far ptr endcon ; failure, end connection
outprt endp
fansdsl proc far
call ansdsl
ret
fansdsl endp
foutprt proc far
call outprt
ret
foutprt endp
; keyboard handler verbs come here to sidestep transparent mode ALT-nnn
outprt_key proc far
test al,80h ; high bit set?
jz outprt_key1 ; z = no, send as-is
cmp al,0a0h ; C1 area?
jae outprt_key1 ; ae = no, send as-is
cmp vtemu.vtchset,C_XPARENT ; TRANSPARENT?
jne outprt_key1 ; ne = no
push ax ;
mov al,Escape ; C1 as ESCAPE <char-40h>
call outprt ; send escape
pop ax
sub al,40h ; relocate the code
outprt_key1:
call outprt
ret
outprt_key endp
fprtbout proc far
call prtbout
ret
fprtbout endp
fprtnout proc far
call prtnout
ret
fprtnout endp
; Product macro worker
prodwork proc far
push si
push di
push es
mov ax,ds
mov es,ax
mov di,offset decbuf+2 ; macro def buffer starts here
mov si,offset prodname ; pointer to macro name
mov cx,vtplen ; length of macro name
cld
rep movsb ; copy to rdbuf+2
mov byte ptr [di],0 ; null terminator
mov cx,nparam ; number of parameters
cmp cx,9 ; more than 9?
jle produc1 ; le = no
mov cx,9 ; limit to 9
produc1:jcxz produc3 ; z = none
xor bx,bx ; parameter subscript
produc2:push bx
push cx
mov al,' ' ; and a space separator
stosb
shl bx,1 ; address words
mov ax,param[bx] ; get parameter to use as definition
call dec2di ; convert numerics to ascii string
pop cx
pop bx
inc bx
loop produc2
produc3:xor al,al ; safety terminator
mov [di],al ; don't count in length
mov ax,di
sub ax,offset decbuf + 2 ; compute length
mov vtmaclen,ax ; pass along to vtmacro
mov vtmacname,offset decbuf+2 ; say this is our macro text ptr
pop si
pop di
pop es
jmp short vtmacro
prodwork endp
;
; Reference Macro structure for db number of entries (mac names)
; is file table mcctab |-> dw length of macroname
; 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 decbuf+2 ; macro def buffer starts here
mov si,vtmacname ; pointer to macro name
mov cx,vtmaclen ; length of macro name<sp/null>text
mov [di-2],cx ; counted string field
cld
rep movsb ; copy to rdbuf
mov byte ptr [di],0 ; null terminator
mov si,offset decbuf+2 ; look for name-text separator
mov cx,vtmaclen
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 length correctly
vtmac1a:sub si,offset decbuf+2+1 ; compute length of macro name
mov cx,si
mov vtmaclen,cx ; 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 ax,[bx] ; length of this name
cmp ax,vtmaclen ; length same as desired keyword?
jne vtmac3 ; ne = no, search again
mov si,bx
add si,2 ; point at first char of name
push cx ; save name counter
push di ; save reg
mov cx,vtmaclen ; length of name
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 di ; recover saved regs
pop cx
je vtmac4 ; e = matched
vtmac3: add bx,ax ; step to next name, add name length
add bx,4 ; + count and 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
stc ; say failure
ret
vtmac4: call takopen_macro ; open a 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 cx,word ptr decbuf ; length of count + string
mov [bx].takcnt,cx ; number of chars in definition
mov [bx].takargc,0 ; our argument count
mov [bx].takptr,offset decbuf+2 ; where to read next command char
pop es
pop di
pop si
pop cx
pop bx
clc ; say success, can exit connect mode
ret
vtmacro endp
; APC macro. Macro string (word count, string text) preset by mszibm.asm
; into seg apcstring offset 0.
apcmacro proc near
cmp taklev,maxtak ; room in take level?
jb apcmac1 ; b = yes
stc ; fail
ret
apcmac1:call takopen_macro ; open macro
mov bx,takadr ; point to current macro structure
mov ax,apcstring ; segment of buffer
mov [bx].takbuf,ax ; segment of definition string struc
mov [bx].takcnt,cx ; number of chars in definition
or [bx].takattr,take_malloc; say have buffer to be removed
cmp apcenable,2 ; enable all commands?
je apcmac2 ; e = yes
mov apctrap,1 ; trap certain commands
apcmac2:mov apcstring,0 ; takclos will delete the buffer
jmp far ptr endcon ; exit Connect mode cleanly
apcmacro endp
rcvmacro proc near
call takopen_macro ; open macro
mov bx,takadr ; point to current macro structure
mov ax,seg rcvstring ; segment of buffer
mov [bx].takbuf,ax ; segment of definition string struc
mov [bx].takptr,offset rcvstring+2
mov [bx].takcnt,rcvstring_len ; number of chars in definition
mov termserver,1 ; say Connect mode started receive
jmp far ptr endcon ; exit Connect mode cleanly
rcvmacro endp
srvmacro proc near
call takopen_macro ; open macro
mov bx,takadr ; point to current macro structure
mov ax,seg srvstring ; segment of buffer
mov [bx].takbuf,ax ; segment of definition string struc
mov [bx].takptr,offset srvstring+2
mov [bx].takcnt,srvstring_len ; number of chars in definition
mov termserver,1 ; say Connect mode started server
jmp far ptr endcon ; exit Connect mode cleanly
srvmacro 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 FAR
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
tabcpy proc far
push es ; worker copy routine
push si
push di
mov cx,ds
mov es,cx
mov cx,(vswidth+7)/8 ; update all active tab stops
cld
rep movsb
pop di
pop si
pop es
clc ; success
ret
tabcpy endp
ifndef no_terminal
; Issue warning that CP866 is needed but not loaded for Cyrillic char sets
chkcp866 proc far
cmp bl,C_CYRILLIC_ISO ; these Cyrillic character sets?
je chkcp1 ; e = yes
cmp bl,C_KOI8
je chkcp1
cmp bl,C_SHORT_KOI
je chkcp1
ret
chkcp1: cmp vtcpage,866 ; Code Page is CP866?
je chkcp2 ; e = yes, no warning
push ax
push dx
mov ah,prstr
mov dx,offset cpwarn ; issue warning
int dos
pop dx
pop ax
chkcp2: ret
chkcp866 endp
endif ; no_terminal
; Display HHMM on status line over the led dots
clkdsp proc far
cmp inemulator,0 ; in terminal emulator?
je clkdsp1 ; e = no, no mode line
cmp vtclkflg,0 ; do not use clock
je clkdsp1 ; e = correct, no clock
cmp inwindows,0 ; in Windows?
;;; jne clkdsp1 ; ne = yes, no clock
cmp flags.modflg,1 ; mode line enabled and owned by us?
jne clkdsp1 ; ne = no, don't touch it
test flags.vtflg,tttek ; Tek mode?
jnz clkdsp1 ; nz = yes
test tekflg,tek_dec ; in Tek submode?
jnz clkdsp1 ; nz = yes, no mode line changes
test yflags,modoff ; mode line off?
jnz clkdsp1 ; nz = yes
cmp flags.vtflg,0 ; emulating none?
jne clkdsp2 ; ne = no
clkdsp1:ret
clkdsp2:push ax
push bx
push cx
push dx
push es
call cboff ; turn off Control-Break sensing
mov ah,gettim ; read DOS tod clock
int dos ; ch=hours, cl=minutes, dh=seconds
cmp dh,lastsec ; compare with previous call
mov lastsec,dh ; remember last sec
je clkdsp9 ; e = same, do nothing
cmp vtclkflg,1 ; do regular time of day?
je clkdsp6 ; e = yes
mov al,60
mul ch ; hours to minutes in ax
add al,cl ; plus minutes
adc ah,0
mov bl,dh ; save seconds in bx
xor bh,bh
mov cx,60
mul cx ; hh+mm to seconds in dx:ax
add ax,bx ; plus seconds
adc dx,0 ; total seconds in dx:ax
mov bx,portval
ifndef no_tcp
cmp flags.comflg,'t' ; doing TCP/IP Telnet?
je clkdsp4 ; e = yes
endif ; no_tcp
sub ax,word ptr starttime[bx]
sbb dx,word ptr starttime[bx+2]
jns clkdsp5 ; ns = not wrapped
add ax,20864 ; add one day
adc dx,1 ; of 86400 seconds
jmp short clkdsp5
clkdsp4:
ifndef no_tcp
mov bx,sescur ; current session ident
shl bx,1
shl bx,1 ; quad bytes
sub ax,word ptr sestime[bx]
sbb dx,word ptr sestime[bx+2]
jns clkdsp5 ; ns = not wrapped
add ax,20864 ; add one day
adc dx,1 ; of 86400 seconds
endif ; no_tcp
clkdsp5:mov cx,60*60 ; convert seconds back to ch,cl,dh
div cx ; ax = quo = hours, dx = rem = secs
mov ch,al ; ch has hours
mov ax,dx ; remaining seconds to ax
mov cl,60
div cl ; al = quo = minutes, ah = secs
mov cl,al ; minutes
xchg dh,ah ; seconds to dh
clkdsp6:mov ax,tv_segs ; screen segment
mov es,ax
mov al,crt_cols ; typically 80
mul crt_lins ; typically 24
mov bx,65+6 ; led_col from mszibm.asm, dots
sub bl,handhsc ; minus hand scrolling left
sbb bh,0
jc clkdsp4 ; c = off screen
add ax,bx
shl ax,1 ; char cells
mov bx,ax
mov al,ch ; hours
xor ah,ah
div ten ; al = quo, ah=rem
add ax,'00'
mov es:[bx],al
mov es:[bx+2],ah
mov es:[bx+4],al
mov al,' '
test dh,1 ; odd seconds?
jnz clkdsp8 ; nz = yes, show blank
mov al,':' ; show colon
clkdsp8:mov es:[bx+4],al
mov al,cl
xor ah,ah
div ten ; quo = al, rem = ah
add ax,'00'
mov es:[bx+6],al
mov es:[bx+8],ah
push di
mov di,bx ; es:di is start address
add di,9 ; is now ending address
mov cx,5 ; bytes changed
call scrsync ; sync virtual screen
pop di
clkdsp9:call cbrestore ; restore Control-Break sensing
pop es
pop dx
pop cx
pop bx
pop ax
ret
clkdsp endp
code1 ends
code segment
assume cs:code
;;; 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: test flags.vtflg,ttwyse ; Wyse-50?
jnz comar7 ; nz = yes
test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz comar4 ; z = no
cmp dgd470mode,0 ; in D470 ANSI mode?
je comar6 ; e = no
push ax ; these send ESC [ <letter>
mov al,escape
call foutprt
mov al,'['
call foutprt ; pop ax is done by comar3
jmp short comar3 ; send the letter
comar6: sub al,'A' ; translate to DG 463/470/217 form
ifndef no_graphics
cmp tekflg,tek_active+tek_sg ; in special graphics mode?
jne comar5 ; ne = no
test dgcross,1 ; DG crosshair active?
jz comar5 ; z = no
test dgcross,2 ; DG crosshair active for keypad?
jz comar5 ; z = no
mov bx,offset dgcrostab ; use scan code table instead
xlatb
call croshair ; send AL to graphics to move cursor
ret
endif ; no_graphics
comar5: mov bx,offset dgcurtab ; VT to DG cursor code table
xlatb
push ax ; setup for comar3
jmp short comar3
comar7: mov bx,offset wysecurtab ; VT to Wyse-50 code table
sub al,'A' ; remove bias
xlatb
push ax
jmp short comar3
comar4: push ax ; save final char
mov ttyact,0 ; network, group chars for packet
mov al,Escape ; send the ESC
test vtemu.vtflgop,decanm ; ANSI mode?
jz comar1 ; z = no
mov al,CSI ; CSI character
test vtemu.vtflgop,decckm ; cursor keys in application mode?
jz comar1 ; z = no, in cursor mode
mov al,SS3 ; SS3 character
comar1: call outprt_key ; send in 7 or 8 bit form, with echo
comar3: pop ax ; recover final char
mov ttyact,1 ; network, restore tty active flag
call foutprt
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
mov al,Escape ; send the ESC
test vtemu.vtflgop,decanm ; ansi mode?
jz short compf2 ; z = no
mov al,SS3 ; SS3, ESC O
compf2: call outprt_key ; send 7 or 8 bit version
compf1: pop ax ; get the saved char
mov ttyact,1 ; network, restore tty active flag
call foutprt
ret
ignore_key: ; key is to be ignored
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 short 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 outprt_key ; send 7 or 8 bit version
jmp short comkp3
comkp2: mov al,escape ; output "ESC ?"
call foutprt
mov al,'?'
call foutprt
comkp3: pop ax ; recover final char
mov ttyact,1 ; network, restore tty active flag
call foutprt ; send it
ret
klogon proc near ; resume logging (if any)
test flags.capflg,logses ; session logging enabled?
jz klogn ; z = no, forget it
push bx
mov bx,argadr
or [bx].flgs,capt ; turn on capture flag
pop bx
or yflags,capt ; set local msy flag as well
klogn: clc
ret
klogon endp
klogof proc near ; suspend logging (if any)
push bx
mov bx,argadr
and [bx].flgs,not capt ; stop capturing
pop bx
and yflags,not capt ; reset local msy flag as well
clc
ret
klogof endp
kdebug proc near
INT 3
NOP
NOP
xor flags.debug,logses ; toggle debugging
xor yflags,trnctl ; Debug mode local edition
ret
kdebug endp
snull proc near ; send a null byte
xor al,al ; the null
call fprtbout ; send without logging and local echo
ret
snull endp
khold: xor holdscr,1 ; toggle Hold screen byte for msx
call kbhold ; tell DEC LK250 the hold kbd state
clc ; kbhold is in file msuibm.asm
ret
tn_AYT: mov ah,255 ; 'I' Telnet Are You There
call outchr ; send IAC (255) AYT (246)
mov ah,246
call outchr
clc
ret
tn_IP: mov ah,255 ; 'I' Telnet Interrrupt Process
call outchr ; send IAC (255) IP (244)
mov ah,244
call outchr
clc
ret
; Data General "Fn" function keys
dgkf1: mov al,113 ; F1 sends RS q
jmp dgkeyccom
dgkf2: mov al,114 ; F2 sends RS r
jmp dgkeyccom
dgkf3: mov al,115 ; F3 sends RS s
jmp dgkeyccom
dgkf4: mov al,116 ; F4 sends RS t
jmp short dgkeyccom
dgkf5: mov al,117 ; F5 sends RS u
jmp short dgkeyccom
dgkf6: mov al,118 ; F6 sends RS v
jmp short dgkeyccom
dgkf7: mov al,119 ; F7 sends RS w
jmp short dgkeyccom
dgkf8: mov al,120 ; F8 sends RS x
jmp short dgkeyccom
dgkf9: mov al,121 ; F9 sends RS y
jmp short dgkeyccom
dgkf10: mov al,122 ; F10 sends RS z
jmp short dgkeyccom
dgkf11: mov al,123 ; F11 sends RS {
jmp short dgkeyccom
dgkf12: mov al,124 ; F12 sends RS |
jmp short dgkeyccom
dgkf13: mov al,125 ; F13 sends RS }
jmp short dgkeyccom
dgkf14: mov al,126 ; F14 sends RS ~
jmp short dgkeyccom
dgkf15: mov al,112 ; F15 sends RS p
jmp short dgkeyccom
dgkSf1: mov al,'a' ; SF1 sends RS a
jmp short dgkeyccom
dgkSf2: mov al,'b' ; SF2 sends RS b
jmp short dgkeyccom
dgkSf3: mov al,'c' ; SF3 sends RS c
jmp short dgkeyccom
dgkSf4: mov al,'d' ; SF4 sends RS d
jmp short dgkeyccom
dgkSf5: mov al,'e' ; SF5 sends RS e
jmp short dgkeyccom
dgkSf6: mov al,'f' ; SF6 sends RS f
jmp short dgkeyccom
dgkSf7: mov al,'g' ; SF7 sends RS g
jmp short dgkeyccom
dgkSf8: mov al,'h' ; SF8 sends RS h
jmp short dgkeyccom
dgkSf9: mov al,'i' ; SF9 sends RS i
jmp short dgkeyccom
dgkSf10:mov al,'j' ; SF10 sends RS j
jmp short dgkeyccom
dgkSf11:mov al,'k' ; SF11 sends RS k
jmp short dgkeyccom
dgkSf12:mov al,'l' ; SF12 sends RS l
jmp short dgkeyccom
dgkSf13:mov al,'m' ; SF13 sends RS m
jmp short dgkeyccom
dgkSf14:mov al,'n' ; SF14 sends RS n
jmp short dgkeyccom
dgkSf15:mov al,'`' ; SF15 sends RS `
jmp short dgkeyccom
; Data General "C" keys C1..C4
dgkc1: mov al,92 ; C1 sends RS \
jmp short dgkc5
dgkc2: mov al,93 ; C2 sends RS ]
jmp short dgkc5
dgkc3: mov al,95 ; C3 sends RS ^
jmp short dgkc5
dgkc4: mov al,96 ; C4 sends RS _
dgkc5: cmp dgd470mode,0 ; D470 ANSI mode active?
je dgkeyccom ; e = no
add al,40 ; yes, bias, C1=132 et seq
dgkeyccom: ; common code
mov ttyact,0 ; network, group chars for packet
push ax
cmp dgd470mode,0 ; D470 ANSI mode active?
je dgkeyccom1 ; e = no
mov al,ESCAPE ; send ESC [ 0<high><low> z
call fprtbout
mov al,'['
call fprtbout
mov al,'0' ; first byte, always "0"
call fprtbout
pop ax
sub al,112 ; remove bias (to 0..23)
mov cl,10 ; split into two bytes
xor ah,ah
div cl ; al = quotient, ah = remainder
push ax ; save remainder
add al,'0' ; send high part (0..2)
call fprtbout
pop ax
xchg ah,al
add al,'0' ; send low part (0..9)
call fprtbout
mov al,'z' ; terminator
mov ttyact,1 ; network, restore tty active flag
ret
dgkeyccom1:mov al,DGescape ; send DG escape (RS)
call fprtbout ; with no echo
pop ax
mov ttyact,1 ; network, restore tty active flag
call fprtbout ; send the second byte
ret
; Keyboard "Compose" key to compose characters by the three stroke method
kbdcompose proc near
mov grab,1 ; say grabbing normal output
call togmod
call togmod ; update mode line
ret
kbdcompose endp
; DG POINT (aka CMD CURSOR-TYPE)
dgpoint proc near
ifndef no_graphics
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne dgpoint1 ; ne = no, ignore cmd
call dgcrossrpt ; send crosshair report
endif ; no_graphics
dgpoint1:ret
dgpoint endp
; DG N/C (normal, compressed font) key
dgnckey proc near
test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz dgnckey1 ; z = no, ignore
call dgnctoggle ; toggle normal/compressed mode
dgnckey1:clc
ret
dgnckey endp
; Compose char lookup and reemitter.
fgrabber proc far
push bx
mov bx,grab ; count chars grabbed (want two)
dec bx ; first char becomes bx=0
mov grabbox[bx],al ; stuff char in short buffer
cmp bx,1 ; got both chars?
pop bx
jae fgrab2 ; ae = yes, go produce output
inc grab ; keep grabbing
ret ; return for the second
; process the byte pair
fgrab2: mov grab,0 ; say done grabbing output
push dx ; compose new single char result
push di
push es
mov di,seg data1
mov es,di
mov di,offset grl1lat ; use Latin1 ptr
cmp vtcpage,852 ; CP852?
jne fgrab2a ; ne = no
mov di,offset grl1lat2 ; use Latin 2
fgrab2a:test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz fgrab3 ; z = no
cmp dgkbl,16 ; Latin1?
je fgrab3 ; e = yes
mov di,offset grl1dgi ; get DG Internat ptr to structure
cmp dgkbl,20 ; DG keyboard language, DG Internat?
jne fgrab15 ; ne = no
fgrab3: mov ax,word ptr grabbox ; get pair of chars
call toupr ; convert AX to upper case
call match
jnc fgrab11 ; nc = found
xchg ah,al
call match
jnc fgrab11 ; nc = match
fgrab5: mov di,offset grl2lat ; use Latin1 ptr
cmp vtcpage,852 ; CP852?
jne fgrab5a ; ne = no
mov di,offset grl2lat2 ; use Latin 2
fgrab5a:test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz fgrab6 ; z = no
cmp dgkbl,16 ; Latin1?
je fgrab6 ; e = yes
mov di,offset grl2dgi ; get DG Internat ptr to structure
cmp dgkbl,20 ; DG keyboard language, DG Internat?
jne fgrab15 ; ne = no
fgrab6: mov ax,word ptr grabbox
mov dx,ax
cmp vtcpage,852 ; CP852?
je fgrab6a ; e = yes, use as-is
call toupr ; convert AX to upper case
fgrab6a:call match
jnc fgrab7 ; nc = found
xchg ah,al ; try reversed order
xchg dh,dl
call match
jc fgrab8 ; c = not found
fgrab7: cmp vtcpage,852 ; CP852?
je fgrab11 ; e = yes, output as-is
cmp dl,'a' ; lower case char?
jb fgrab11 ; b = no, upper case
or al,20h ; move to lower case output codes
jmp short fgrab11
fgrab8: mov di,offset grl3lat ; use Latin1 ptr
cmp vtcpage,852 ; CP852?
jne fgrab8a ; ne = no
mov di,offset grl3lat2 ; use Latin 2
fgrab8a:test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz fgrab9 ; z = no
cmp dgkbl,16 ; Latin1?
je fgrab9 ; e = yes
mov di,offset grl3dgi ; get DG Internat ptr to structure
cmp dgkbl,20 ; DG keyboard language, DG Internat?
jne fgrab15 ; ne = no
fgrab9: mov ax,word ptr grabbox
xchg ah,al
call match ; look for matching combination
jc fgrab16 ; c = failed
fgrab11:call foutprt ; send it to the host
fgrab15:call togmod
call togmod ; update mode line
pop es
pop di
pop dx
ret
fgrab16:call fvtbell ; mismatch, beep, cancel
jmp short fgrab15 ; finish up
fgrabber endp
; worker for above
match proc near
push bx
push si
push di
mov cl,es:[di] ; get count of pairs
xor ch,ch
inc di
mov si,di ; start of char lists
jcxz match2 ; nothing to look at
mov si,di ; remember where pairs start
mov bx,di
add bx,cx
add bx,cx ; output singles start here
cld
push cx ; save counter
repne scasw ; look for a match
pop cx
jne match2 ; ne = no match
sub di,2 ; backup to match
sub di,si ; get item count
shr di,1 ; count bytes
mov al,es:[bx+di] ; get new output char
pop di
pop si
pop bx
clc ; say success
ret
match2: pop di
pop si
pop bx
stc ; say no match
ret
match endp
; DEC LK201 keyboard keys and "User Definable Keys" in VT3xx mode
decfind:mov al,1 ; Find
jmp dfkout
decinsert:mov al,2 ; Insert
jmp dfkout
decremove:mov al,3 ; Remove
jmp dfkout
decselect:mov al,4 ; Select
jmp dfkout
decprev:mov al,5 ; Previous screen
jmp dfkout
decnext:mov al,6 ; Next screen
jmp dfkout
decf6: mov al,17 ; key ident for DEC F6
jmp dfkout ; process it
decf7: mov al,18 ; key ident for DEC F7
jmp dfkout ; process it
decf8: mov al,19 ; key ident for DEC F8
jmp dfkout ; process it
decf9: mov al,20 ; key ident for DEC F9
jmp dfkout ; process it
decf10: mov al,21 ; key ident for DEC F10
jmp dfkout ; process it
decf11: mov al,23 ; key ident for DEC F11
jmp dfkout ; process it
decf12: mov al,24 ; key ident for DEC F12
jmp dfkout ; process it
decf13: mov al,25 ; key ident for DEC F13
jmp dfkout ; process it
decf14: mov al,26 ; key ident for DEC F14
jmp dfkout ; process it
dechelp:mov al,28 ; key ident for DEC HELP
jmp dfkout ; process it
decdo: mov al,29 ; key ident for DEC DO
jmp dfkout ; process it
decf17: mov al,31 ; key ident for DEC F17
jmp dfkout ; process it
decf18: mov al,32 ; key ident for DEC F18
jmp dfkout ; process it
decf19: mov al,33 ; key ident for DEC F19
jmp dfkout ; process it
decf20: mov al,34 ; key ident for DEC F20
jmp dfkout ; process it
; common worker to output contents of User Definable Key definition strings
; Enter with al = key ident (17 - 34)
dfkout proc near
push ax
push bx
push cx
push es
mov ttyact,0 ; network, group chars for packet
test flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
jnz dfkout4 ; nz = yes, else use VT100/VT52 default
test flags.vtflg,tttek ; Tek?
jnz dfkout4 ; nz = yes, try this
mov ttyact,1 ; network, restore tty active flag
cmp al,23 ; F11 sends ESC
jne dfkou1 ; ne = not F11
mov al,escape
call foutprt
jmp dfkoutx
dfkou1: cmp al,24 ; F12 sends BS
jne dfkou2 ; ne = not F12
mov al,BS
call foutprt
jmp dfkoutx
dfkou2: cmp al,25 ; F13 sends LF
jne dfkoutx ; ne = not F13, ignore
mov al,LF
call foutprt
dfkou3: jmp dfkoutx
dfkout4:push ax ; VT320, use default definitions
mov al,Escape ; char to send, CSI
call foutprt
mov al,'['
call foutprt ; send lead-in char in 7/8-bit form
pop ax
call fprtnout ; key ident (17-34) as ascii digits
mov al,7eh ; tilde terminator
mov ttyact,1 ; network, restore tty active flag
call foutprt
dfkoutx:pop es
pop cx
pop bx
pop ax
clc
ret
dfkout endp
; User Definable Keys
udkf6: mov al,17 ; key ident for DEC F6
jmp udkout ; process it
udkf7: mov al,18 ; key ident for DEC F7
jmp udkout ; process it
udkf8: mov al,19 ; key ident for DEC F8
jmp udkout ; process it
udkf9: mov al,20 ; key ident for DEC F9
jmp udkout ; process it
udkf10: mov al,21 ; key ident for DEC F10
jmp udkout ; process it
udkf11: mov al,23 ; key ident for DEC F11
jmp udkout ; process it
udkf12: mov al,24 ; key ident for DEC F12
jmp udkout ; process it
udkf13: mov al,25 ; key ident for DEC F13
jmp udkout ; process it
udkf14: mov al,26 ; key ident for DEC F14
jmp udkout ; process it
udkf15: mov al,28 ; key ident for DEC HELP
jmp udkout ; process it
udkf16: mov al,29 ; key ident for DEC DO
jmp udkout ; process it
udkf17: mov al,31 ; key ident for DEC F17
jmp udkout ; process it
udkf18: mov al,32 ; key ident for DEC F18
jmp udkout ; process it
udkf19: mov al,33 ; key ident for DEC F19
jmp udkout ; process it
udkf20: mov al,34 ; key ident for DEC F20
; jmp udkout ; process it
udkout proc near
push es
mov ttyact,0 ; network, group chars for packet
mov bl,al ; VT3XX key ident, UDK style (17-34)
sub bl,17 ; minus starting offset of 17
xor bh,bh
cmp bl,17 ; out of range?
ja udkoutx ; a = yes, ignore
shl bx,1 ; index words
mov bx,udkseg[bx] ; segment of definition
or bx,bx ; anything there?
jz udkoutx ; z = no
mov es,bx ; definition segment
xor bx,bx ; and offset
mov cl,es:[bx] ; get string length byte
xor ch,ch ; use cx as a counter
jcxz udkoutx ; z = empty
udkou1: inc bx ; es:bx is now the string text
mov al,es:[bx] ; get a char
push bx
push cx
push es
cmp cx,1 ; last byte
jne udkou2 ; ne = not last byte
mov ttyact,1 ; network, restore tty active flag
udkou2: call foutprt ; output
pop es
pop cx
pop bx
loop udkou1
udkoutx:pop es
clc
ret
udkout endp
; Wyse-50 function keys F1..F16
wykf1: mov al,'@' ; Wyse F1
jmp short wykfcom
wykf2: mov al,'A' ; Wyse F2
jmp short wykfcom
wykf3: mov al,'B'
jmp short wykfcom
wykf4: mov al,'C'
jmp short wykfcom
wykf5: mov al,'D'
jmp short wykfcom
wykf6: mov al,'E'
jmp short wykfcom
wykf7: mov al,'F'
jmp short wykfcom
wykf8: mov al,'G'
jmp short wykfcom
wykf9: mov al,'H'
jmp short wykfcom
wykf10: mov al,'I'
jmp short wykfcom
wykf11: mov al,'J'
jmp short wykfcom
wykf12: mov al,'K'
jmp short wykfcom
wykf13: mov al,'L'
jmp short wykfcom
wykf14: mov al,'M'
jmp short wykfcom
wykf15: mov al,'N'
jmp short wykfcom
wykf16: mov al,'O' ; Wyse F16
jmp short wykfcom
; Wyse-50 Shift function keys F1..F16
wykSf1: mov al,'`' ; Wyse Shift F1
jmp short wykfcom
wykSf2: mov al,'a' ; Wyse Shift F2
jmp short wykfcom
wykSf3: mov al,'b'
jmp short wykfcom
wykSf4: mov al,'c'
jmp short wykfcom
wykSf5: mov al,'d'
jmp short wykfcom
wykSf6: mov al,'e'
jmp short wykfcom
wykSf7: mov al,'f'
jmp short wykfcom
wykSf8: mov al,'g'
jmp short wykfcom
wykSf9: mov al,'h'
jmp short wykfcom
wykSf10:mov al,'i'
jmp short wykfcom
wykSf11:mov al,'j'
jmp short wykfcom
wykSf12:mov al,'k'
jmp short wykfcom
wykSf13:mov al,'l'
jmp short wykfcom
wykSf14:mov al,'m'
jmp short wykfcom
wykSf15:mov al,'n'
jmp short wykfcom
wykSf16:mov al,'o' ; Wyse Shift F16
wykfcom:mov ttyact,0 ; network, group chars for packet
push ax ; save key code
mov al,1 ; send SOH keycode CR
call foutprt
pop ax
call foutprt
mov al,CR
mov ttyact,1 ; network, restore tty active flag
call foutprt
ret
; Change Telnet sessions
ifndef no_tcp
ses1 proc near
mov bx,0
mov cx,1
jmp short nextses4
ses1 endp
ses2 proc near
mov bx,1
mov cx,1
jmp short nextses4
ses2 endp
ses3 proc near
mov bx,2
mov cx,1
jmp short nextses4
ses3 endp
ses4 proc near
mov bx,3
mov cx,1
jmp short nextses4
ses4 endp
ses5 proc near
mov bx,4
mov cx,1
jmp short nextses4
ses5 endp
ses6 proc near
mov bx,5
mov cx,1
jmp short nextses4
ses6 endp
endif ; no tcp
nextses proc near
ifndef no_tcp
cmp flags.comflg,'t' ; doing Telnet?
je nextses1 ; e = yes
clc ; do not exit Connect mode
ret
nextses1:mov bx,sescur ; current session ident
mov cx,6 ; sessions to consider
nextses3:inc bx
cmp bx,6 ; over the top yet
jb nextses4 ; b = no
xor bx,bx ; wrap
nextses4:cmp seslist[bx],0 ; is this session active?
jge nextses5 ; ge = yes
loop nextses3
clc
ret ; do nothing
nextses5:push bx
mov bx,sescur ; old session
call termswapout ; save current terminal items
pop bx
mov sescur,bx ; next session, from above
call tcpstart ; start session, ident in bl
mov bx,sescur ; new session
call termswapin ; get data structures
mov kbdflg,' ' ; return Connect mode
stc ; but exit Connect mode now
else
clc
endif ; no_tcp
ret
nextses endp
vtsesmac proc far ; SESSION macro
mov vtmacname,offset vtsesname
mov al,bl ; session number
add al,'1' ; to ascii, from 1
mov vtsesnum,al ; to name
mov vtmaclen,vtseslen
call dword ptr vtmacroptr ; FAR pointer
ret
vtsesmac endp
; Call from mszibm DG components to put system into DG special graphics mode,
; and thus to cause incoming material to be still sent to the text emulator.
; This also unshifts the screen (as seen on the status line) before starting
; graphics so the column 81 stuff comes out right.
dgsettek proc far
ifndef no_graphics
cmp tekflg,tek_active+tek_sg ; inited already?
je dgsettek3 ; e = yes
push bx
push cx
mov cl,byte ptr low_rgt+1 ; examine whole screen
inc cl ; lines in emulation part
xor ch,ch
mov bx,cx ; for status line
xor al,al
xchg al,linescroll[bx] ; status line scroll value
or al,al
jz dgsettek2 ; z = no shift in effect
xor bx,bx ; start of screen
dgsettek1:sub linescroll[bx],al ; unscroll by status line amount
inc bx ; next line
loop dgsettek1 ; do all emulation lines
dgsettek2:pop cx
pop bx
or tekflg,tek_sg ; set special graphics mode
call TEKINI ; go to Tektronix Emulator
endif ; no_graphics
dgsettek3:ret
dgsettek endp
;[HF]940206 jpnxltkey
;[HF]940207
;[HF]940206 Check if leading byte of Japanese double byte code
;[HF]940207 Range of Japanese second byte
;[HF]940207 ((AL >= 0x40) && (AL <= 0x7e))||((AL >= 0x80) && (AL <= 0xfc))
;[HF]940207
;[HF]940206 If not Japanese, clear carry and return.
;[HF]940207
jpnxltkey proc near ;[HF]940206
cmp keypend,0 ;[HF]940207 Kanji second byte?
jne jpnxltk3 ;[HF]940207 ne = yes, second byte
call iskanji1 ;[HF]941010 Kanji leading byte ?
jc jpnxltk2 ;[HF]941010 c = yes
call iskana ;[HF]941010 Katakana ?
jnc jpnxltk1 ;[HF]941010 nc = no
cmp flags.oshift,(128+3) ;[HF]941012 DEC-Kanji ?
je jpnxltk1c ;[HF]941012 e = yes, use X208 Katakana
cmp flags.oshift,(128+2) ;[HF]941012 EUC-Kanji ?
jne jpnxltk1b ;[HF]941012 ne = no
call outkana ;[HF]941011 katakana output
mov keypend,0 ;[HF]941011 no pending char
stc ;[HF]941011 say, we have done
ret ;[HF]941011
jpnxltk1b: ;[HF]941011
cmp flags.oshift,(128+1) ;[HF]941012 JIS7-Kanji ?
jne jpnxltk1a ;[HF]941012 ne = no
jpnxltk1c: ;[HF]941012
call dblkana ;[HF]941012 get double byte code
or ax,8080h ;[HF]941012 make it GR
mov keypend,ax ;[HF]941012
jmp jpnxltk5c ;[HF]941012
jpnxltk1: ;[HF]940207
cmp flags.oshift,(128+1) ;[HF]940211 JIS7?
jne jpnxltk1a ;[HF]940211 ne = no
cmp keyj7st,0 ;[HF]940211 ASCII state?
je jpnxltk1a ;[HF]940211 e = yes
push ax ;[HF]940211
mov al,ESCAPE ;[HF]940211
call chrout ;[HF]940211
mov al,'(' ;[HF]940211
call chrout ;[HF]940211
mov al,byte ptr jis7des+1 ;[HF]940211
call chrout ;[HF]940211
mov keyj7st,0 ;[HF]940211
pop ax ;[HF]940211
jpnxltk1a: ;[HF]940211
mov keypend,0 ;[HF]940207 Clear second byte flag
clc ;[HF]940206 tell that not Japanese
ret ;[HF]940206
jpnxltk2: ;[HF]940206
push ax ;[HF]940207
mov ah,al ;[HF]940207
xor al,al ;[HF]940207
mov keypend,ax ;[HF]940207 save it for later use
pop ax ;[HF]940207
stc ;[HF]940206 tell that Japanese
ret ;[HF]940206
jpnxltk3: ;[HF]940207
cmp al,40h ;[HF]940207
jb jpnxltk4 ;[HF]940207 not the second byte
cmp al,7eh ;[HF]940207
jbe jpnxltk5 ;[HF]940207 Yes second byte
cmp al,80h ;[HF]940207
jb jpnxltk4 ;[HF]940207 not the second byte
cmp al,0fch ;[HF]940207
jbe jpnxltk5 ;[HF]940207 Yes second byte
jpnxltk4: ;[HF]940207
jmp jpnxltk1 ;[HF]940211 treat as single byte char.
jpnxltk5: ;[HF]940207
mov byte ptr keypend,al ;[HF]940207 make double byte code
mov ax,keypend ;[HF]940207 Shift-JIS code
call jpnftox ;[HF]940207 translate to EUC(JIS-GR)
jpnxltk5c: ;[HF]941012
cmp flags.oshift,(128+1) ;[HF]940211 JIS7?
je jpnxltk5a ;[HF]940211 e = yes
cmp flags.oshift,(128+2) ;[HF]940214 EUC?
je jpnxltk5b ;[HF]940214 e = yes
cmp flags.oshift,(128+3) ;[HF]941012 DEC?
je jpnxltk5b ;[HF]941012 e = yes
mov ax,keypend ;[HF]940214 No. use Shift-JIS code
jmp short jpnxltk5b ;[HF]940211
jpnxltk5a: ;[HF]940211
and ax,7f7fh ;[HF]940211
cmp keyj7st,2 ;[HF]940211 Kanji state?
je jpnxltk5b ;[HF]940211 e=yes, no shift
push ax ;[HF]940211
mov al,ESCAPE ;[HF]940211
call chrout ;[HF]940211
mov al,'$' ;[HF]940211
call chrout ;[HF]940211
mov al,byte ptr jis7des ;[HF]940211
call chrout ;[HF]940211
mov keyj7st,2 ;[HF]940211
pop ax ;[HF]940211
jpnxltk5b: ;[HF]940211
push ax ;[HF]940214 save dble byte code
mov al,ah ;[HF]940207
call chrout ;[HF]940207 send leading byte
pop ax ;[HF]940214 remember dble byte code
mov ah,al ;[HF]940207
call chrout ;[HF]940207 send second byte
mov keypend,0 ;[HF]940207 clear double byte flag
stc ;[HF]940207 say no more char
ret ;[HF]940207
jpnxltkey endp ;[HF]940206
;[HF]941011 outkana
;[HF]941011
;[HF]941011 Output Shift-JIS katakana code in AL to com port.
outkana proc near ;[HF]941011
push ax ;[HF]941011 save AX
push bx ;[HF]941011 save BX
cmp flags.oshift,(128+1) ;[HF]941012 JIS7 ?
je outkan1 ;[HF]941012 e = yes
mov bl,flags.oshift ;[HF]941011 save output-shift
mov flags.oshift,0 ;[HF]941011 Do our own shift
mov bh,al ;[HF]941011 save AL
mov al,SS2 ;[HF]941011 SS2
call chrout ;[HF]941011
mov al,bh ;[HF]941011 restore AL
or al,80h ;[HF]941011 8th bit On
call chrout ;[HF]941011
jmp outkanx ;[HF]941012
outkan1:cmp keyj7st,1 ;[HF]941012 already in katakana mode?
je outkan3 ;[HF]941012 e = yes
cmp keyj7st,2 ;[HF]941012 in kanji mode?
jne outkan2 ;[HF]941012 ne = no
mov bh,al ;[HF]941012 save AL
mov al,ESCAPE ;[HF]941012
call chrout ;[HF]941012
mov al,'(' ;[HF]941012
call chrout ;[HF]941012
mov al,byte ptr jis7des+1 ;[HF]941012
call chrout ;[HF]941012
outkan2:mov al,SOchar ;[HF]941012 SO
call chrout ;[HF]941012
mov keyj7st,1 ;[HF]941012
mov al,bh ;[HF]941012
outkan3:and al,7fh ;[HF]941012 mask 8th bit
call chrout ;[HF]941012
outkanx:mov flags.oshift,bl ;[HF]941011 restore output-shift
pop bx ;[HF]941011 restore BX
pop ax ;[HF]941011 restore AX
ret ;[HF]941011
outkana endp ;[HF]941011
;[HF]941012 dblkana
;[HF]941012
;[HF]941012 convert single byte katakana code to double byte code
;[HF]941012 Input: AL Katakana code in JIS
;[HF]941012 Outpt: AX Double byte JIS katakana code (AH first)
dblkana proc near ;[HF]941012
push es
push bx ;[HF]941012
sub ax,32 ;[HF]941012
and ax,3fh ;[HF]941012
mov bx,seg kanatbl
mov es,bx
mov bx,offset kanatbl ;[HF]941012
add bx,ax ;[HF]941012
add bx,ax ;[HF]941012 word address
mov ax,es:[bx] ;[HF]941012
pop bx ;[HF]941012
pop es
ret ;[HF]941012
dblkana endp ;[HF]941012
;[HF]941010 iskana
;[HF]941010
;[HF]941010 Check if AL is Shift-JIS Katakana code or not.
;[HF]941010 If Katakana, program returns with carry set,
;[HF]941010 if not, carry clear.
;[HF]941010
;[HF]941010 Note: Shift-JIS Katakana is in the range
;[HF]941010 ((AL >= 0xa0) && (AL <= 0xdf))
;[HF]941010 where AL = 0xa0 is space
;[HF]941010
iskana proc near ;[HF]941010
cmp al,0a0h ;[HF]941010
jb iskanan ;[HF]941010 b = no
cmp al,0dfh ;[HF]941010
ja iskanan ;[HF]941010 a = no
stc ;[HF]941010 yes, katakana
jmp short iskanax ;[HF]941010
iskanan:clc ;[HF]941010 no, not katakana
iskanax:ret ;[HF]941010
iskana endp ;[HF]941010
;[HF]940207 Range of Shift-JIS Kanji leading byte
;[HF]940207 ((AL >= 0x81) && (AL <= 0x9f))||((AL >= 0xe0) && (AL <= 0xfc))
iskanji1 proc near ;[HF]941010
cmp al,81h ;[HF]940207
jb iskan1n ;[HF]940207 b = No, not Kanji leading
cmp al,9fh ;[HF]940207
jbe iskan1y ;[HF]940207 Yes, Japanese leading byte
cmp al,0e0h ;[HF]940207
jb iskan1n ;[HF]940207 No, not Japanese
cmp al,0fch ;[HF]940207
jbe iskan1y ;[HF]940207 Yes, Japanese leading byte
iskan1n:clc ;[HF]941010
jmp short iskan1x ;[HF]941010
iskan1y:stc ;[HF]941010
iskan1x:ret ;[HF]941010
iskanji1 endp ;[HF]941010
code ends
code1 segment
assume cs:code1
; Set (define) the DEC "User Definable Keys". Inserts text definitions for
; keyboard verbs \KdecF6 ...\KdecF14, \KdecHELP, \KdecDO, \KdecF17...\KdecF20.
; Enter with the DCS definition string as key-number/hex-chars. UDK key number
; is 17 for \KdecF6, et seq, the definition are pairs of hex digits converted
; here to a single byte per pair. The DCS definition string is pointed at by
; DS:SI, and the byte count is in CX.
; Example: 17/54657374204636 means key \KdecF6 sends string "Test F6"
setudk proc near
push ax
push bx
push cx
push si
push di
push es
cld
lodsb ; get key ident first byte
sub al,'0' ; ascii to binary
mul ten ; times 10
xchg ah,al ; to ah
lodsb ; get key ident second byte
sub al,'0' ; ascii to binary
add al,ah ; plus high order part
xor ah,ah
mov bx,ax ; key ident, 17 - 34
lodsb ; skip slash separator
sub cx,3 ; three less bytes in the string
jge setudk0 ; ge = had three or more bytes
jmp setudkx ; else error
setudk0:sub bx,17 ; remove key ident bias of 17
cmp bx,17 ; out of range?
ja setudkx ; a = yes, ignore
shl bx,1 ; index words
cmp udkseg[bx],0 ; has a segment been allocated for it?
je setudk1 ; e = no
mov ax,udkseg[bx] ; get segment to es
mov es,ax
mov ah,freemem ; deallocate old memory block, es:0
int dos
mov udkseg[bx],0 ; clear table entry too
setudk1:and cl,not 1 ; force an even number of inputs
jcxz setudkx ; z = no definition, clear entry
push bx ; save index BX
mov bx,cx ; get string length
shr bx,1 ; two hex digits per final byte
add bx,15+1 ; round up plus length byte
shr bx,1 ; convert to paragraphs
shr bx,1
shr bx,1
shr bx,1
mov di,bx ; remember request
mov ah,alloc ; allocate BX paragraphs
int dos
jc setudkx ; c = failure
cmp di,bx ; requested vs allocated
pop bx ; recover bx
je setudk2 ; e = enough
mov ah,freemem ; return the memory, es is ptr
int dos
jmp short setudkx ; exit failure
setudk2:mov es,ax ; segment of allocated memory
mov udkseg[bx],ax ; segment:0 of definition string
xor di,di
cld
mov al,cl ; length of string
shr al,1 ; two hex bytes per stored byte
xor ch,ch
stosb ; store length byte
jcxz setudkx ; z = empty string
setukd3:lodsb ; get first hex digit
dec cx ; adjust count remaining
or al,20h ; to lower case
cmp al,'9' ; digit?
jbe setudk4 ; be = yes
sub al,'a'-'9'-1 ; hex letter to column three
setudk4:sub al,'0' ; ascii to binary
shl al,1 ; times 16
shl al,1
shl al,1
shl al,1
mov ah,al ; save in ah
lodsb ; get second hex digit
or al,20h ; to lower case
cmp al,'9' ; digit?
jbe setudk5 ; be = yes
sub al,'a'-'9'-1 ; hex letter to column three
setudk5:sub al,'0' ; ascii to binary
add al,ah ; join both parts
stosb ; store final byte
loop setukd3
setudkx:pop es
pop di
pop si
pop cx
pop bx
pop ax
clc
ret
setudk 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
fsetpos proc far
call setpos
ret
fsetpos endp
frepaint proc far
call repaint
ret
frepaint endp
code1 ends
code segment
assume cs:code
; 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
; general character out for emulator
chrout proc near
cmp flags.vtflg,0 ; emulating?
je chrou5 ; e = no
call fanskbi ; 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 foutprt ; output a carriage-return
mov al,lf ; followed by a line feed
call foutprt ; send the LF
pop ax
mov trans.seol,ah ; restore eol char
ret
chrou5: call foutprt
ret
chrout endp
; Screen dump entry from keyboad xlat
dmpscn proc near ; dump screen to file
ifndef no_graphics
cmp flags.vtflg,tttek ; doing Tektronix emulation?
je dmpscn2 ; e = yes, use Tek emulator
cmp tekflg,tek_active+tek_dec ; emulation a Tektronix?
jne dmpscn1 ; ne = no
dmpscn2:call tekdmp ; near-call Tek screen dump utility
clc
ret
endif ; no_graphics
dmpscn1:call dumpscr ; do buffer to file
clc ; do not exit Connect mode
ret
dmpscn 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 in vscreen.
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 bh,bh ; 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 ; set cursor
xor bh,bh ; page 0
int screen
mov dx,offset dmperr ; say no can do
mov ah,prstr
int dos
pop dx ; get original cursor position
mov ah,2 ; set cursor
xor bh,bh ; 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
les si,vs_ptr ; seg and offset of vscreen
sub si,vswidth*2 ; prep for inc below
dmp2: add si,vswidth*2 ; virtual screen width in bytes
push si
push cx ; save outer loop counter
push di
mov di,offset decbuf ; data segment memory
mov cl,byte ptr low_rgt ; number of columns on screen -1
inc cl
xor ch,ch
dmp3: mov ax,word ptr es:[si] ; read char + attribute
or al,al ; is it a null?
jnz dmp3c ; nz = no
mov al,' ' ; replace null with space
dmp3c: 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
mov cl,byte ptr low_rgt ; number of columns on screen - 1
inc cl
xor ch,ch
push es
mov ax,ds
mov es,ax ; set es to data segment for es:di
mov di,offset decbuf ; start of line
add di,cx ; plus length of line
dec di ; minus 1 equals end of line
mov al,' ' ; thing to scan over
std ; set scan backward
repe scasb ; scan until non-space
cld ; set direction forward
pop es
je dmp3a ; e = 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 decbuf ; array to be written
mov bx,dmphand ; need file handle
mov ah,write2 ; write the line
int dos
pop di
pop cx ; get line counter again
pop si ; screen offset
jc dmp3b ; c = error
loop dmp2 ; do next line
dmp3b: mov dx,offset dumpsep ; put in formfeed/cr/lf
mov bx,dmphand ; need file handle
mov cx,3 ; three bytes overall
mov ah,write2 ; write them
mov bx,dmphand ; file handle
int dos
mov bx,dmphand ; need file handle
mov ah,close2 ; close the file now
int dos
pop es
pop si
pop di
pop dx
pop cx
pop bx
pop ax
clc
ret
dumpscr endp
togmod proc FAR
call trnmod ; FAR callable trnmod
ret
togmod endp
; Toggle Mode Line
trnmod proc near
cmp inemulator,0 ; in terminal emulator?
je trnm1 ; e = no, no mode line
cmp flags.modflg,1 ; mode line enabled and owned by us?
jne trnm1 ; ne = no, don't touch it
cmp flags.vtflg,tttek ; Tek mode?
je trnm1 ; e = yes
test tekflg,tek_dec ; in Tek submode?
jnz trnm1 ; nz = yes, no mode line changes
test yflags,modoff ; mode line already off?
jnz trnm2 ; nz = yes, go turn on
or yflags,modoff ; say modeline is toggled off
cmp flags.vtflg,0 ; emulating none?
jne trnm0 ; ne = no
mov lastsec,-1 ; tickle tod clock
push dx
call fgetpcur ; get physical cursor
mov cursor,dx
pop dx
trnm0: 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
call fgetpcur ; get physical cursor
mov cursor,dx
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
cmp isps55,0 ; [HF]940206 Japanese PS/55 ?
je modl21 ; [HF]940206 e = no
cmp ps55mod,0 ; [HF]940206 can we use modeline?
jne modl21 ; [HF]940206 ne = yes
mov ax,1401h ; [HF]940206 user uses the modeline
mov ps55mod,al ; [HF]940206 save current status
int 16h ; [HF]940206 OK, now in our hands
modl21: push si
push di
push es
mov ax,ds
mov es,ax
mov si,offset modmaster ; master template
mov di,offset modbuf ; working copy
mov lastsec,-1 ; tickle tod clock
cld
modl20: lodsb
stosb
cmp al,'$' ; at end?
jne modl20 ; ne = no
mov bx,argadr ; get argument block
mov al,[bx].baudb ; get baud bits
mov si,offset unkbaud ; assume unknown baud
mov cx,size m_baud ; length of baud space
cmp al,baudnsiz ; beyond end of table?
jnb modl2 ; nb = yes, use default
mul cl
xor ah,ah
add ax,offset baudn
mov si,ax
modl2: mov di,offset modbuf.m_baud
cld
rep movsb ; copy in baud rate
mov bx,portval
mov al,[bx].parflg ; get parity code
and al,3 ; regular parity uses two bits
mov ah,al
shl al,1 ; each is 3 bytes long
add al,ah
xor ah,ah
add ax,offset parnams ; names of parity settings
mov si,ax
mov cx,3 ; each is 3 long
mov di,offset modbuf.m_par
push di
rep movsb
pop di
test [bx].parflg,PARHARDWARE ; using hardware parity?
jz modl2b ; z = no
mov al,'8' ; say 8 data bits
stosb
jmp short modl2a
modl2b: cmp byte ptr [di],'8' ; any parity?
jne modl2a ; ne = yes, use existing '7'
test flags.remflg,d8bit ; 8 bit display?
jnz modl2a ; nz = yes
mov al,'7'
stosb ; overwrite '8' with '7'
modl2a: mov si,offset remmsg ; assume remote echoing
test yflags,lclecho ; local echo on?
jz modl3 ; z = no
mov si,offset lclmsg ; say echo is local
modl3: mov cx,3 ; size of value
mov di,offset modbuf.m_echo
rep movsb
mov al,portno ; communications port
cmp al,' ' ; binary (non-printable)?
jae modl4 ; ae = no, ascii
add al,'0' ; convert to ascii
modl4: mov modbuf.m_prt,al ; fill in port number
mov al,portno
cmp repflg,0 ; REPLAY?
je modl5 ; e = no
mov si,offset repmsg ; say "REPLAY"
mov cx,repmsgl ; its length
mov di,offset modbuf.m_prt
mov al,' ' ; start with a space
stosb
mov dx,24 ; space to be filled
sub dx,cx ; amount we will use here
rep movsb ; copy string
mov cx,dx
rep stosb ; flesh out with spaces
jmp modl10
modl5: cmp al,'4' ; in networks material?
jbe modl10 ; be = no
ifndef no_tcp
cmp flags.comflg,'t' ; doing TCP/IP Telnet?
jne modl5d ; ne = no
mov si,offset tcphost ; name of host
mov di,offset modbuf.m_prt - 5 ; overwrite "port:"
ifdef nls_portuguese
dec di ; "porta:"
endif ; nls_portuguese
modl5c: mov ax,sescur ; ident of session
add al,'1' ; ascii, show as 1:nodename
mov ah,':'
stosw ; store that much
mov cx,28 ; bytes max
modl5a: lodsb
or al,al ; at null terminator?
jz modl5b ; z = yes
stosb
loop modl5a
modl5b: mov al,' ' ; fill out with spaces
rep stosb ; noop if cx == 0
jmp short modl5d ; done with tcp/ip
endif ; no_tcp
modl5d: mov bx,offset comptab ; table of comms ports
mov cl,[bx] ; number of entries
xor ch,ch
inc bx
modl6: mov dx,[bx] ; length of this entry
mov si,bx
add si,2 ; points to entry text string
add si,dx ; point to qualifier
cmp [si],al ; our port?
je modl7 ; e = yes
add bx,[bx] ; add text length
add bx,4 ; plus count and qualifier
loop modl6 ; next entry
jmp short modl10 ; no match, curious
modl7: mov si,bx ; point at entry
add si,2 ; point at string
mov cx,[bx] ; length of string
mov di,offset modbuf.m_prt
mov al,' ' ; start with a space
stosb
mov dx,17 ; space to be filled
ifdef nls_portuguese
dec dx
endif ; nls_portuguese
sub dx,cx ; amount we will use here
rep movsb ; copy string
cmp flags.comflg,'F' ; Fossil?
jne modl9 ; ne = no
mov al,'-' ; punctuation
stosb
mov ax,fossil_port ; port
inc ax ; count from one to user
push dx ; preserve reg for below
call dec2di ; write port
pop dx
sub dx,2 ; dash and digit
add di,2
cmp fossil_port,9 ; two digits?
jbe modl9 ; be = no
dec dx ; yes, one less slot
inc di
modl9: mov cx,dx
mov al,' '
rep stosb ; flesh out with spaces
modl10: 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 word ptr modbuf.m_prn,' '; assume not printing the screen
mov modbuf.m_prn+2,' '
test anspflg,prtscr+2 ; print the screen? (msz uses 1 & 2)
jz modl10a ; z = no
mov word ptr modbuf.m_prn,'RP' ; yes. display PRN at end of line
mov modbuf.m_prn+2,'N'
modl10a:mov modbuf.m_comp,' ' ; flag for not-compose
cmp grab,0 ; doing Compose grabbing?
je modl11 ; e = no
mov modbuf.m_comp,'C' ; flag for compose
modl11: cmp inemulator,0 ; in terminal emulator now?
jne modl11a ; ne = yes
pop es ; do nothing
pop di
pop si
ret
modl11a:push dx
cmp flags.vtflg,0 ; emulating?
je modl12 ; e = no
and yflags,not modoff ; update local flags (mode line on)
call fansdsl ; get extras from emulator
modl12: mov dx,offset modbuf ; mode line image ptr for putmod
call putmod ; display mode line
mov dx,cursor ; restore active cursor position
call fsetpos ; set cursor
pop dx
pop es
pop di
pop si
ret
modlin endp
fmodlin proc far
call modlin
ret
fmodlin endp
; toggle between text and graphics modes
vtans52 proc near
cmp flags.vtflg,0 ; emulating?
je vtans52a ; e = no
call ans52t ; call MSZ toggle-it routine
cmp flags.vtflg,tttek ; Tek now?
je vtans52a ; e = yes
test tekflg,tek_tek+tek_dec+TEK_SG ; Tek submode?
jnz vtans52a ; nz = yes
call scrini ; check on screen size changes
vtans52a:clc ; clear c bit so don't exit Connect
ret
vtans52 endp
ftrnprs proc far
call trnprs
ret
ftrnprs endp
trnprs proc near
push ax ; toggle ^ PrtSc screen to printer
test anspflg,prtscr ; are we currently printing?
jnz trnpr2 ; nz = yes, its on and going off
push bx
mov bx,prnhand ; file handle for system printer
mov ah,ioctl
mov al,7 ; get output status of printer
int dos
pop bx
jc trnpr1 ; c = printer not ready
cmp al,0ffh ; Ready status?
je trnpr2 ; e = Ready
trnpr1: call fvtbell ; Not Ready, complain
; pop ax
; stc ; say failure
; ret ; and ignore request
trnpr2: xor anspflg,prtscr ; flip the flag
test yflags,modoff ; mode line off?
jnz trnpr3 ; nz = yes
call fmodlin ; else rewrite mode line
trnpr3: pop ax
clc ; return carry clear (don't quit)
ret
trnprs endp
code ends
code1 segment
assume cs:code1
pntdead proc near ; display printer is inoperative msg
push ax
test yflags,modoff ; is mode line off?
jnz pntdea1 ; nz = off, skip msg
push bx
mov dx,offset pntmsg ; say printer not ready
call fputmod ; write on mode line
pop bx
pntdea1:pop ax
stc ; say printer not ready
ret
pntdead endp
endif ; no_terminal
;;;;; General screen management routines for IBM PC
; computes screen location to ax, given row and col in [dh,dl], resp.
scrloc proc near
push cx
mov cl,crt_cols
cmp inemulator,0 ; emulating?
je scrloc1 ; e = no
cmp flags.vtflg,0 ; emulating anything?
je scrloc1 ; e = no
mov cl,vswidth
scrloc1:mov al,dh ; get row
mul cl ; multiply by number of columns
add al,dl ; plus current column number
adc ah,0 ; ripple carry
shl ax,1 ; double for attributes
pop cx
ret
scrloc endp
; Routine to set cursor type. Pass cursor type in al: 0,4 = No cursor,
; 1 = Underline cursor, 2 = Block cursor. All cursors blink due to hardware.
; For EGA boards running in non-25 line mode the cursor emulation is turned
; off during cursor shape changing and restored afterward. It's another
; ega Feature. [jrd]
; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
csrtype proc near
push cx ; save the reg
mov cx,0F00H ; assume no cursor
test al,4 ; no cursor?
jz csrtyp6 ; z = no
xor al,al ; set type to invisible
csrtyp6:or al,al ; no cursor?
jz csrty2 ; z = yes, no cursor
cmp crt_mode,7 ; B&W card?
je csrty3 ; e = yes, different sizes
cmp crt_mode,18h ; Tseng UltraPAK mono board?
je csrty3 ; e = yes, use mono cursor
mov cx,0607H ; use CGA underline cursor
cmp al,2 ; Block?
jne csrty2 ; ne = no, set it now
csrty1: xor ch,ch ; make cursor a block
csrty2: cmp ega_mode,0 ; ega board active?
je csrty4 ; e = no
test tv_mode,10h ; DV active?
jnz csrty4 ; nz = yes, it messes with the cursor
cmp byte ptr low_rgt+1,23 ; standard screen length?
je csrty4 ; e = yes, use regular cursor setting
cmp byte ptr low_rgt+1,24 ; ANSI, standard screen length?
je csrty4 ; e = yes, use regular cursor setting
push es ; EGA. turn off cursor emulation
mov ax,40h ; 40:87h is ega Info byte
mov es,ax
push es:[87h] ; save Info byte around call
or byte ptr es:[87h],1 ; set emulation off (low bit = 1)
mov ah,1 ; video function for set cursor type
int screen
pop es:[87h] ; restore Info byte
pop es ; and our work register
pop cx
ret
csrty4: push ax
mov ah,1 ; video function for set cursor type
int screen ; regular cursor shape setting
pop ax
csrty5: pop cx
ret
csrty3: mov cx,0B0CH ; assume B&W underline cursor
cmp al,2 ; Block?
jne csrty2 ; ne = no, set it now
jmp short csrty1 ; make it a block
csrtype endp
fcsrtype proc far
call csrtype
ret
fcsrtype 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
scrmod proc near
push ax
push dx
mov ah,0fh ; get current video state
int screen
and al,not 80h ; strip "preserve regen" bit 80h
mov crt_mode,al ; store CRT mode value
mov crt_cols,ah ; store # of cols
mov dl,ah ; # of cols again
mov dh,crt_lins ; and # of rows (constant from msster)
cmp tv_mode,0 ; Topview active?
je scrmod2 ; e = no
test tv_mode,20h ; Japanese DOS active?
jnz scrmod2 ; nz = yes, do not do Int 15h
push cx
push bx
mov ah,12h ; TV, Get Object Length
mov bx,0901h ; object, BL = 01 = chars/line
int 15h
pop ax ; chars/line from stack dword
cmp al,10 ; keep things sane, chars per line
ja scrmod7 ; a = might be sane
pop ax ; clean stack
jmp scrmod2 ; wacko, ignore DV stuff
scrmod7:mov crt_cols,al ; TV windowed screen columns
pop ax ; clear rest of dword from stack
mov ah,12h ; send
mov bx,1 ; handle (0*256) + window (me, 1)
int 15h
pop bx ; handle low word
pop bx ; handle high word to BX for next call
mov ax,1024h ; TV Get Virtual Screen Info
int 15h ; can yield 8KB, yikes
scrmod1:cmp cx,80*25*2 ; get sanity for DV big DOS window
jbe scrmod1a ; be = reasonable size
shr cx,1 ; reduce size
jmp short scrmod1 ; and try again
scrmod1a:mov ax,cx ; CX is virtual screen size, bytes
mov bl,crt_cols ; divide by columns to get width
shl bl,1 ; get words (char and attribute)
div bl ; al = lines, ah = fractions of line
dec al ; count this from zero like the Bios
mov crt_lins,al ; visible screen lines -1 (24)
mov dh,al
mov dl,crt_cols ; visible screen columns (80)
pop bx
pop cx
jmp short scrmod4
scrmod2:cmp ega_mode,0 ; ega active?
je scrmod4 ; e = no
push es ; yes, permit different lengths
mov ax,40h ; refer to 40:84h for # ega rows
mov es,ax
mov ah,es:[84h] ; get number of rows - 1 (typ 24)
cmp ah,20 ; less than 20 rows?
jb scrmod3 ; b = yes, ignore this length
cmp ah,80 ; more than 80 rows?
ja scrmod3 ; a = yes, ignore this length
mov dh,ah ; use this length
mov dos_bottom,dh ; remember for DOS screen pager
ifndef no_terminal
cmp flags.vtflg,ttansi ; ANSI?
jne scrmod2b ; ne = no
inc dh ; make mode line a regular text line
mov flags.modflg,2 ; mode line enabled and owned by host
scrmod2b:cmp isps55,0 ; [HF]940206 is Japanese PS/55 ?
je scrmo2a ; [HF]940206 e = no
cmp ps55mod,0 ; [HF]940206 can we use modeline?
jne scrmo2a ; [HF]940206 ne = yes
inc dh ; [HF]940206 no, add modeline
endif ; no_terminal
scrmo2a:mov crt_lins,dh ; update our working constant
scrmod3:pop es
scrmod4:dec dl ; max text column, count from zero
dec dh ; max text row, count from zero
ifndef no_terminal
cmp flags.vtflg,ttgenrc ; no terminal emulation
je scrmod6 ; e = yes
cmp tekflg,tek_active+tek_sg ; doing special graphics?
jne scrmod4a ; ne = no
mov crt_cols,128 ; VT style special graphics uses this
scrmod4a:
cmp crt_cols,80 ; doing wide now?
ja scrmod5 ; a = yes
mov dl,80-1 ; assume 80 column width
test vtemu.vtflgop,deccol ; 132 column mode set?
jz scrmod6 ; z = no
scrmod5:mov dl,132-1 ; set to 132 column mode
endif ; no_terminal
scrmod6:mov low_rgt,dx ; save away window address
pop dx
pop ax
ret
scrmod endp
; Get screen segment. Returns screen segment in ax, and full address in es:di
scrseg proc near
xor di,di ; start at beginning of screen (0,0)
mov ax,0B800H ; video memory is here on color
cmp crt_mode,7 ; normal color modes?
jb scrse1 ; b = yes
mov ax,0B000H ; assume B&W card
cmp crt_mode,12 ;
jb scrse1
cmp crt_mode,18h ; Tseng UltraPAK mono in 132 col?
je scrse1 ; e = yes, use seg B000H
cmp crt_mode,56h ; Paradise EGA Mono in 132x43 mode?
je scrse1 ; e = yes, use seg B000H
cmp crt_mode,57h ; Paradise EGA Mono in 132x25 mode?
je scrse1 ; e = yes, use seg B000H
mov ax,0B800H ; video memory is here on color
cmp crt_mode,18 ; end of ordinary 640x480 graphics
ja scrse1 ; a = no, assume CGA segment
mov ax,0A000H ; graphics
scrse1: mov es,ax ; tell Topview our hardware address needs
mov tv_segs,es ; save our hardware screen address
mov tv_sego,di ; segment and offset form
or tv_mode,1 ; assume we're running under Topview
mov ah,tvhere ; query Topview for its presence
int screen
mov ax,es ; get its new segment for screen work
cmp ax,tv_segs ; same as hardware?
jne scrse2 ; ne = no, we are being mapped
cmp di,tv_sego ; check this too
jne scrse2 ; ne = no too. Use TV's work buf as screen
and tv_mode,not 1 ; else no Topview or no mapping
scrse2: mov tv_segs,es ; save segment
mov tv_sego,di ; and offset
ret
scrseg endp
; Synchronize a Topview provided virtual screen buffer with the image
; seen by the user. Requires cx = number of words written to screen
; (char & attribute bytes) and es:di = ENDING address of screen write.
; Changes ax and di. Skip operations for DESQview
scrsync proc near
cmp tv_mode,0 ; Topview mode active?
je scrsyn1 ; e = no, skip Bios call below
push ax
push cx
push di
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
pop di
pop cx
pop ax
scrsyn1:ret
scrsync endp
; The following two routines are used to turn off the display while we
; are reading or writing the screen in one of the color card modes.
; Turn screen off for (known) color card modes only. All regs preserved.
; Includes code for old procedure scrwait. 16 June 1987 [jrd]
scroff proc near
cmp 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 ; nb = yes - just return
cmp refresh,0 ; slow refresh?
jne scrofx ; ne = no wait
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
pop dx ; restore regs
pop ax
scrofx: ret
scroff endp
; Turn screen on for (known) color card modes only
; All registers are preserved.
scron proc near
cmp 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 ; nb = yes - just return
cmp refresh,0 ; slow refresh?
jne scronx ; ne = no wait
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
pop dx
pop ax
scronx: ret
scron endp
ifndef no_terminal
; 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). One full screen
; must be allocated to hold the current display, deduct this from lmax.
bufadj proc near
push bx
push cx
push dx
mov bx,rollwidth ; rollback 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
xor dx,dx ; high order dividend, clear it
cmp emsrbhandle,0 ; using EMS?
jle bufadj2 ; le = no (-1 means not used)
mov ax,1024 ; 1024 paragraphs per ems 16KB page
div bx ; divide by paragraphs per line
mov lineems,ax ; lines per ems page, remember
mul inipara ; times number of ems pages
jmp short bufadj3 ; ax has number of lines
; conventional memory
bufadj2:mov ax,inipara ; (BDT) compute the number of lines
div bx ; (BDT) in the buffer
bufadj3:mov lmax,ax ; max line capacity of the buffer
mov linee,ax ; (BDT) save as number of total lines
or ax,ax ; have any lines?
jz bufadj1 ; z = no, 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
sub lmax,bx ; minus master "current" screen
jg bufadj1 ; g = have some rollback space
mov lmax,0 ; say none
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
endif ; no_terminal
; Test for DESQview in operation, set tv_mode bit 10h to non-zero if so.
dvtest proc near
and tv_mode,not 30h ; assume no DV and no Japanese DOS
ifndef no_terminal
cmp isps55,0 ; [HF] 940130 Japanese PS/55 ?
je dvtest4 ; [HF] 940130 no
or tv_mode,30h ; [HF] 940205 say Japanese & DV
ret ; [HF] do not use Int 15h for Japan
endif ; no_terminal
dvtest4:xor bx,bx ; for version number
mov cx,'DE' ; DV signature
mov dx,'SQ'
mov ax,2B01h ; DOS set date (with illegal value)
int dos
cmp al,0ffh ; DOS should say invalid if no DV
je dvtest2 ; e = yes, invalid so no DV
cmp bx,2 ; DV version 2.00?
jne dvtest1 ; ne = no
xchg bh,bl ; get major version into bh
dvtest1:or tv_mode,10h ; say using DV
dvtest2:ret
dvtest endp
; Execute DESQview function call provided in BX.
dvcall proc near
push ax
mov ax,101ah ; switch to DV stack
int 15h
mov ax,bx ; function to do
int 15h
mov ax,1025h ; switch from DV stack
int 15h
pop ax
ret
dvcall endp
; Call this to release the cpu during idle times
dvpause proc near
cmp vtcpumode,0 ; timeslice-release enabled?
jne dvpaus2 ; ne = no
test tv_mode,10h ; in DV?
jz dvpaus1 ; z = no
push bx
mov bx,1000h ; say release control
call dvcall ; to DV
pop bx
dvpaus1:cmp byte ptr dosnum+1,5 ; DOS verson, major high, minor low
jb dvpaus2 ; b = too old for this operation
mov ax,1680h ; release current virtual machine
int 2fh ; time slice (Windows, OS/2, DPMI)
dvpaus2:ret
dvpause endp
; Screen clearing routine
; 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-206]. Preserves all registers.
atsclr proc near
cmp ax,bx ; correct order?
jbe atsclr9 ; be = yes
xchg ax,bx ; larger to bx
atsclr9:push ax ; save regs
push cx
push dx
mov dx,bx ; compute last screen offset from bx
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 ; +1 for span, +1 for round up
sar cx,1 ; make byte count a word count
jle atscl3 ; le = nothing to clear
push di ; save regs
push es ; save es
ifndef no_terminal
cmp inemulator,0 ; in terminal emulator now?
je atscl1 ; e = no
cmp flags.vtflg,0 ; emulating anything?
je atscl1 ; e = no, using DOS
les di,vs_ptr ; es:di is virtual screen
jmp short atscl2
endif ; no_terminal
atscl1: push ax ; save displacement
call scroff ; turn screen off if color card
call scrseg ; get address of screen into es:di
pop ax
atscl2: add di,ax ; location in buffer
mov ah,scbattr ; use current screen background attr
mov al,' ' ; use space for fill
push cx ; save word count for Topview
cld
rep stosw ; copy to screen
pop cx ; recover word count
ifndef no_terminal
cmp inemulator,0 ; in terminal emulator now?
je atscl2a ; e = no
cmp flags.vtflg,0 ; emulating anything?
jne atscl2b ; ne = yes
endif ; no_terminal
atscl2a:call scron ; turn screen back on if color card
call scrsync ; synch Topview
atscl2b:pop es
pop di
atscl3: pop dx
pop cx
pop ax ; back to regs at call time
ifndef no_terminal
cmp inemulator,0 ; in terminal emulator now?
je atscl6 ; e = no
cmp flags.vtflg,0 ; emulating anything?
je atscl6 ; e = no, using DOS
push dx ; do extended attributes
push ax
push bx
push cx
mov dx,ax ; starting place
mov al,dh ; row
mov cl,vswidth ; row char cells
mul cl
add al,dl ; plus starting column
adc ah,0 ; char cells to starting place
mov dx,ax ; save here
mov al,bh ; ending row
mul cl
add al,bl ; plus ending column
adc ah,0
mov bx,ax
sub bx,dx ; number of cells -1 to clear
inc bx
mov cx,bx ; cx = cells to clear
xchg bx,dx ; bx = start offset, dx=cells
push es
push di
les di,vsat_ptr ; where attributes are stored
add di,bx ; offset plus start byte
xor ax,ax
cld
shr cx,1
jnc atscl4
stosb
atscl4: rep stosw ; clear those bytes
;;; mov extattr,0 ; and the extension byte too
pop di
pop es
pop cx
pop bx
pop ax
mov dl,ah ; first row
mov dh,bh ; last row
call touchup ; repaint this part of the screen
pop dx ; finish cleaning stack
endif ; no_terminal
atscl6: ret
atsclr endp
ifndef no_terminal
; Screen-scrolling routines.
fhomwnd proc far ; "home" to start of the buffer
mov cl,byte ptr low_rgt+1 ; save this many lines
inc cl ; full text screen
xor ch,ch
call putcirc ; save them
mov linec,0 ; reset the current pointer
call getcirc ; now get the new screen
clc
ret
fhomwnd endp
fendwnd proc far ; "end" to end of the buffer
mov cl,byte ptr low_rgt+1 ; save this many lines
inc cl ; full text screen
xor ch,ch
call putcirc ; save them
mov ax,lcnt ; reset the current pointer
mov linec,ax ; save the results
call getcirc ; now get the new screen
clc
ret
fendwnd endp
fdnwpg proc far ; scroll down 1 page
mov cl,byte ptr low_rgt+1 ; save this many lines
inc cl ; full text screen
xor ch,ch
call putcirc ; save them
mov ax,linec ; reset the current pointer
add ax,cx
cmp ax,lcnt ; did we go past the end?
jbe dnwpg1 ; be = no, we're OK
mov ax,lcnt ; yup, back up
dnwpg1: mov linec,ax ; save the results
call getcirc ; now get the new screen
clc
ret
fdnwpg endp
fdnone proc far ; scroll down 1 line
mov cl,byte ptr low_rgt+1 ; save this many lines
inc cl ; full text screen
xor ch,ch
call putcirc ; save them
mov ax,linec ; reset the current pointer
inc ax ; to the next line
cmp ax,lcnt ; oops, did we go past the end?
jbe dnone1 ; be = no, we're OK
mov ax,lcnt ; yup, back up
dnone1: mov linec,ax ; save the results
call getcirc ; now get the new screen
clc
ret
fdnone endp
fupwpg proc far ; scroll up 1 page
mov cl,byte ptr low_rgt+1 ; save this many lines
inc cl ; full text screen
xor ch,ch
call putcirc ; save a full screen
mov ax,linec ; reset the current pointer
sub ax,cx ; to the previous page
jge upwpg1 ; ge = not past end, we're OK
xor ax,ax ; stop at the beginning of the buffer
upwpg1: mov linec,ax ; line counter to use
call getcirc ; get the new screen
clc
ret
fupwpg endp
fupone proc far ; scroll up 1 line
mov cl,byte ptr low_rgt+1 ; save this many lines
inc cl ; full text screen
xor ch,ch
call putcirc ; save them
mov ax,linec ; reset the current pointer
sub ax,1 ; to the previous line
jge upone1 ; ge = not past end, we're OK
xor ax,ax ; yup, back up
upone1: mov linec,ax ; save the results
call getcirc ; now get the new screen
clc
ret
fupone endp
; Horizontal scrolling keyboard verbs
frtpage proc far
mov cx,20 ; step size
call rtcommon
ret
frtpage endp
frtone proc far
mov cx,1
call rtcommon
ret
frtone endp
; Move screen to the right margin by CX columns
rtcommon proc near
push bx
mov bl,byte ptr cursor+1 ; current cursor row
xor bh,bh
mov al,linescroll[bx] ; horz scroll in effect for this line
pop bx
add al,handhsc ; plus hand scrolling now present
add al,crt_cols ; right most char on visible screen
adc ah,0
cmp ax,vswidth ; too far already?
ja rtcomm2 ; a = yes, do nothing
sub ax,vswidth ; available distance
neg ax
cmp ax,cx ; space vs desired scroll
jbe rtcomm1 ; be = less than desired, use space
mov ax,cx ; enough room, use desired scroll
rtcomm1:add handhsc,al ; indicate how much done by hand
call repaint
rtcomm2:clc
ret
rtcommon endp
flfpage proc far
mov cx,20 ; step size
call lfcommon
ret
flfpage endp
flfone proc far
mov cx,1 ; step size
call lfcommon
ret
flfone endp
; Move screen toward left margin by CX columns
lfcommon proc near
push bx
mov bl,byte ptr cursor+1 ; current cursor row
xor bh,bh
mov al,linescroll[bx] ; horz scroll in effect for this line
pop bx
add al,handhsc ; available distance to move
jz lfcomm2 ; z = no space to move
sub al,cl ; minus our desired jump
jge lfcomm1 ; ge = no overscroll the wrong way
add cl,al ; reduce cx request by overage
lfcomm1:sub handhsc,cl ; successful, new handhsc
call repaint
lfcomm2:clc
ret
lfcommon endp
; Scrolling routines. vtscru scrolls up, vtscrd scrolls down 'scroll'
; rows. Top lines are saved in the circular buffer before scrolling up.
; When running under an Environment control number of line positions moved
; to be less than scrolling region.
; All registers are preserved.
;
; Screen scroll up "scroll" lines (text moves up) for terminal emulator use.
vtscru proc near
push ax
push bx
push cx
push dx
push si
push di
mov al,mar_bot ; compute size of scroll
sub al,mar_top
inc al ; lines in scrolling region
mov dl,scroll ; desired scroll
xor dh,dh
cmp dl,al ; scrolling more than needed?
jbe vtscru1 ; be = no
mov dl,al ; limit scrolling
mov scroll,al
vtscru1:or dl,dl
jnz vtscru2
jmp vtscru9 ; z = nothing to do
vtscru2:cmp mar_top,0 ; scrolling the top screen line?
jne vtscru5 ; ne = no, do not save in roll back
mov cx,dx ; cx is how many lines
call putcirc ; put screen lines in circular buffer
add linec,cx ; (BDT) increment the current line
mov cx,linec ; new current line number
sub cx,lcnt ; minus # in buf = qty new lines added
jc vtscru3 ; c = not extending buffer
add lcnt,cx ; (BDT) increment the line counter
vtscru3:mov cx,lcnt ; (BDT) check: are we
cmp cx,lmax ; (BDT) beyond the end?
jb vtscru5 ; (BDT) b = no
sub cx,lmax ; (BDT) compute overflow count
add linef,cx ; (BDT) adjust the "first" line
mov cx,linef ; (BDT) check: time to wrap?
cmp cx,linee ; (BDT) ...
jb vtscru4 ; (BDT) b = no
sub cx,linee ; (BDT) yup
mov linef,cx ; (BDT) adjust it
vtscru4:mov cx,lmax ; (BDT) get the maximum line count
mov lcnt,cx ; (BDT) reset the line counter
mov linec,cx ; (BDT) reset the current line
vtscru5:mov di,word ptr vs_ptr ; offset of virtual screen
mov cl,vswidth
mov al,mar_top ; top line number (from 0)
mul cl ; times chars/line
add ax,ax ; char + attribute
add di,ax ; destination (mar_top)
mov al,dl ; number of lines to scroll
mov cl,vswidth
mul cl ; vswidth * total lines to scroll
mov bx,ax ; number of cells to clear
add ax,ax ; bytes
mov si,di
add si,ax ; src is that many bytes down screen
mov al,mar_bot ; lines in scrolling region
sub al,mar_top
inc al
sub al,dl ; minus scrolled portion
mul cl ; times words per line
mov cx,ax ; number of cells to copy
mov dh,scbattr ; need this for later (in seg data)
push cx ; save number of words for attribute
push es
push ds
mov ax,word ptr vs_ptr+2 ; segment of vscreen
mov ds,ax
mov es,ax
cld
rep movsw ; copy src to dest
mov cx,bx ; count of words to clear
mov ah,dh ; default attriubte
mov al,' ' ; filler for clearing a line
rep stosw ; store after new src
pop ds
pop es
; bx is number of words cleared
mov di,word ptr vsat_ptr ; offset of attributes
mov cl,vswidth ; char cells per attributes line
mov al,mar_top ; top line number (from 0)
mul cl ; times cells per line
add di,ax ; destination (mar_top)
mov si,di
mov al,dl ; number of lines to scroll
mul cl ; vswidth * total lines to scroll
mov bx,ax ; number of cells to clear
add si,bx ; src is that many bytes down screen
pop cx ; number of vscreen cells copied
push es
push ds
mov ax,word ptr vsat_ptr+2 ; segment of vsatt
mov ds,ax
mov es,ax
cld
rep movsb ; copy src to dest
mov cx,bx ; count of bytes to clear
xor al,al ; default attributes of none
rep stosb ; store after new src
pop ds
pop es
cmp writemode,0 ; use direct screen writing?
je vscru5a ; e = yes
ifndef no_graphics
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne vscru5b ; ne = no
endif ; no_graphics
vscru5a:cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne vtscru8 ; ne = no
ifndef no_graphics
call tekremcursor ; turn off text cursor
vscru5b:mov dosetcursor,-1 ; don't turn on automatically
mov al,' ' ; write space
mov ah,scbattr ; in normal colors
xor dl,dl ; at mar_top, left margin
mov dh,mar_top ; to set normal text mode for the
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne vscru5d ; ne = no
xor cl,cl ; no extended attribute
call ttxtchr ; graphics adapter
endif ; no_graphics
vscru5d:mov ax,0600h ; scroll up whole region
mov dh,mar_bot ; bottom row
mov dl,crt_cols
cmp isps55,0 ; [HF]940216 Japanese PS/55?
jne vscru5e ; [HF]940216 ne=yes, allowed > 80cols.
cmp dl,80 ; more than physical screen?
jbe vscru5e ; be = no
cmp dl,131 ; really wide screen
jae vscru5e ; ae = yes
mov dl,80 ; else 128 col fake text wide screen
vscru5e:dec dl ; right most physical col for scroll
mov ch,mar_top ; top row of scrolling region
xor cl,cl ; left most column
mov bh,scbattr ; attributes
mov bl,dh
sub bl,ch ; region size - 1 line
jz vscru2b ; z = region is 1 line, do one scroll
mov al,scroll ; number of lines to scroll, from msz
vscru2a:cmp al,bl ; want to scroll more that than?
jbe vscru2b ; be = no
push ax
mov al,bl ; limit to region - 1 for Windows
int screen ; and do in parts
pop ax
sub al,bl ; al = amount yet to scroll
jmp short vscru2a ; do next part
vscru2b:int screen ; scroll up that region
mov dx,cursor
mov dosetcursor,dx ; reminder of where to set cursor
jmp short vtscru9
vtscru8:mov dh,mar_bot ; real text mode
mov dl,mar_top ; setup touchup, lines changed
call touchup ; touch up real screen
vtscru9:pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
vtscru endp
; Screen-roll down. Move text down scroll lines, for terminal emulator only.
vtscrd proc near
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
les si,vs_ptr ; source is top line of virtual screen
mov al,mar_top ; top margin line (0..)
mov cl,vswidth ; chars across vscreen
mul cl
add ax,ax ; words to bytes
add si,ax ; offset of start of top line
mov bp,si ; remember top line for later
mov cl,mar_bot ; compute number of lines to move
sub cl,mar_top
inc cl ; qty of lines in region
mov ch,scroll
cmp ch,cl ; want to scroll more than region?
jbe vtscrd1 ; be = no
mov ch,cl ; set scroll to whole region
mov scroll,ch ; remember for attributes
vtscrd1:sub cl,ch ; less lines to be skipped
mov bl,ch ; save effective scroll for below
mov al,vswidth ; number of character cells
mul cl
mov cx,ax ; number of words in the movement
dec ax ; compute to end word
add ax,ax ; number of bytes
add si,ax ; go to the end
mov di,si
mov al,vswidth ; words in a line buffer
mul bl ; number of chars dest is below src
mov bx,ax ; save number of chars here for clear
add ax,ax ; number of bytes (char + attribute)
add di,ax ; destination offset
push ds
mov ax,es
mov ds,ax
std
rep movsw ; copy down the lines
cld
pop ds
mov di,bp ; fill top line in scrolling region
mov ah,scbattr
mov al,' '
mov cx,bx ; number of char cells to clear
rep stosw ; fill top line(s) with spaces
; do extended attributes the same way
les si,vsat_ptr ; source of extended attributes
mov al,mar_top ; top margin line (0..)
mov cl,vswidth ; attribute cells/line
mul cl
add si,ax ; offset of start of top line
mov bp,si ; remember top line for later
mov cl,mar_bot ; compute number of lines to move
sub cl,mar_top
inc cl ; qty of lines in region
mov ch,scroll
sub cl,ch ; less lines to be skipped
mov bl,ch ; save effective scroll for below
mov al,vswidth ; number of attribute cells/line
mul cl
mov cx,ax ; number of bytes in the movement
dec ax ; compute to end byte
add si,ax ; go to the end
mov di,si
mov al,vswidth ; number of attribute cells/line
mul bl ; number of cells dest is below src
mov bx,ax ; save number of bytes here for clear
add di,ax ; destination offset
push ds
mov ax,es
mov ds,ax
std
rep movsb ; copy down the lines
cld
pop ds
mov di,bp ; fill top line in scrolling region
xor al,al ; null attributes for filler
mov cx,bx ; number of attributes bytes to clear
rep stosb ; fill top line(s) with spaces
pop es
pop bp
cmp writemode,0 ; use direct screen writing?
je vscrd1 ; e = yes
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne vscrd3a ; ne = no
vscrd1:
ifndef no_graphics
cmp tekflg,tek_active+tek_sg ; special graphics mode?
je vscrd3 ; e = yes
endif ; no_graphics
mov dl,mar_top ; setup touchup, lines changed
mov dh,mar_bot
call touchup ; touch up real screen
jmp short vscrd8
ifndef no_graphics
vscrd3: call tekremcursor ; turn off text cursor
endif ; no_graphics
vscrd3a:mov dosetcursor,-1 ; don't turn on automatically
mov al,' ' ; write space
mov ah,scbattr ; in normal colors
ifndef no_graphics
xor dl,dl ; at mar_bot, left margin
mov dh,mar_bot ; to set normal text mode for the
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne vscrd3b ; ne = no
xor cl,cl ; no extended attribute
call ttxtchr ; graphics adapter
endif ; no_graphics
vscrd3b:mov ax,0700h ; scroll down whole region
mov ch,mar_top ; top margin line
xor cl,cl ; left most column
mov dh,mar_bot ; bottom margin line
mov dl,crt_cols
cmp isps55,0 ; [HF]940216 Japanese PS/55
jne vscrd3c ; [HF]940216 ne=yes, allowed > 80 cols
cmp dl,80 ; more than physical screen?
jbe vscrd3c ; be = no
cmp dl,131 ; really wide screen
jae vscrd3c ; ae = yes
mov dl,80 ; else 128 col fake text wide screen
vscrd3c:dec dl ; right most physical col for scroll
mov bh,scbattr ; attributes
mov bl,dh
sub bl,ch ; region size - 1 line
jz vscrd7 ; z = region is 1 line, do one scroll
mov al,scroll ; number of lines to scroll, from msz
vscrd7: cmp al,bl ; want to scroll more that than?
jbe vscrd2 ; be = no
push ax
mov al,bl ; limit to region-1 for Windows
int screen ; and do in parts
pop ax
sub al,bl ; get remainder
jmp short vscrd7 ; do next part
vscrd2: int screen ; scroll it down
mov dx,cursor
mov dosetcursor,dx ; reminder of where to set cursor
vscrd8: pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
vtscrd endp
; Put the top cx lines from the virtual screen in to the circular buffer
; starting at line index linec (counted from zero, modulo linee).
putcirc proc near
jcxz putcir6 ; z = no lines to save
cmp lmax,0 ; any buffer space?
jne putcir7 ; ne = yes, have some
putcir6:ret
putcir7:push ax
push bx
push cx
push dx
push si
push di
push es
cld
mov pageready,-1 ; ems page number currently active
mov si,word ptr vs_ptr ; offset of screen buffer
mov bx,linef ; index of the first line
add bx,linec ; add the current line counter
dec bx
putcir1:inc bx
cmp bx,linee ; at the end of the buffer now?
jb putcir2 ; b = no
sub bx,linee ; backup to start of buffer
putcir2:mov ax,bx ; line index
cmp emsrbhandle,0 ; EMS in use?
jg putcir3 ; g = yes
cmp xmsrhandle,0 ; XMS rollback in use?
je putcir3 ; e = no
call putxms ; do the put via xms
jmp short putcir4
putcir3:call emsfixup ; do expanded memory conversion work
mul ppl ; times paragraphs per line
add ax,iniseg ; plus initial seg of buffer
mov es,ax ; now we have the segment pointer
xor di,di ; buffer offset is always 0
push cx ; save the number of lines
mov cx,rollwidth ; get the number of characters to move
push si ; save starting vscreen offset
push ds ; get the offset of the screen
cld
mov ds,word ptr vs_ptr+2 ; seg of vscreen
rep movsw ; move them
pop ds ; restore DS
pop si ; vscreen offset
add si,vswidth*2 ; inc to next vscreen line
pop cx ; restore the line count
putcir4:loop putcir1 ; go back for more
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
clc
ret
putcirc endp
; Put CX lines into XMS based rollback buffer
putxms proc near
mul ppl ; line number times paragraphs/line
push cx
mov cx,4 ; have paragraphs, want bytes
xor dx,dx
putxms1:shl al,1
rcl ah,1
rcl dl,1 ; get bytes to dx:ax
loop putxms1 ; times 16
pop cx
mov word ptr xms.offset_dst,ax ; low order address
mov word ptr xms.offset_dst+2,dx ; high order
mov ax,rollwidth
shl ax,1 ; times two
mov word ptr xms.xms_count,ax ; byte count
mov ax,word ptr vs_ptr+2 ; src seg
mov word ptr xms.offset_src+2,ax
mov word ptr xms.offset_src+0,si ; low order
mov xms.handle_src,0 ; source is local
mov ax,xmsrhandle ; dest is rollback area
mov xms.handle_dst,ax
push si
mov si,offset xms ; ds:si is request block
mov ah,xmsmove
call dword ptr xmsep
pop si
add si,vswidth*2 ; inc to next vscreen line
ret
putxms endp
; Get CX lines from the circular buffer, non destructively, starting at
; line index linec (counted from zero, modulo linee) and put them at
; the top of the virtual screen. Fewer lines are written if the buffer
; holds fewer than CX.
getcirc proc near
or cx,cx ; check on qty
jnz getcir0 ; nz = some
ret
getcir0:cmp lmax,0 ; any buffer space?
jne getcir5 ; ne = yes, have some
ret
getcir5:push ax
push bx
push cx
push dx
push si
push di
push es
mov pageready,-1 ; ems page number currently active
les di,vs_ptr ; seg and offset of vscreen
mov bx,linef ; get the first line pointer
add bx,linec ; add the current line counter
dec bx
cld
getcir1:inc bx
cmp bx,linee ; at the end of the buffer now?
jb getcir2 ; b = no
sub bx,linee ; backup to start of buffer
getcir2:mov ax,bx ; line index
cmp emsrbhandle,0 ; EMS in use?
jg getcir3 ; g = yes
cmp xmsrhandle,0 ; XMS rollback in use?
je getcir3 ; e = no
call getxms ; get from XMS
jmp short getcir4
getcir3:call emsfixup ; do expanded memory conversion work
mul ppl ; times paragraphs per line
add ax,iniseg ; plus initial seg of buffer
xor si,si ; initial offset is always 0
push cx ; save the number of lines
mov cx,rollwidth ; get the number of characters to move
push di ; save vscreen offset
push ds ; save DS for a tad
mov ds,ax ; now we have the segment pointer
rep movsw ; move them
pop ds ; restore DS
pop di ; recover vscreen offset
add di,vswidth*2 ; next vscreen line
pop cx ; restore the line count
getcir4:
loop getcir1 ; go back for more
call repaint ; repaint screen
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
clc
ret
getcirc endp
getxms proc near
mul ppl ; line number times paragraphs/line
push cx
mov cx,4 ; have paragraphs, want bytes
xor dx,dx
getxms1:shl al,1
rcl ah,1
rcl dl,1 ; get bytes to dx:ax
loop getxms1 ; times 16
pop cx
mov word ptr xms.offset_src,ax ; low order address
mov word ptr xms.offset_src+2,dx ; high order
mov ax,rollwidth
shl ax,1 ; times two for words
mov word ptr xms.xms_count,ax ; byte count
mov ax,word ptr vs_ptr+2 ; dst seg
mov word ptr xms.offset_dst+2,ax
mov word ptr xms.offset_dst+0,di ; low order
mov xms.handle_dst,0 ; destination is local
mov ax,xmsrhandle ; source is rollback area
mov xms.handle_src,ax ; source is rollback area
push si
mov si,offset xms ; ds:si is request block
mov ah,xmsmove
call dword ptr xmsep
pop si
add di,vswidth*2 ; next vscreen line
ret
getxms endp
; Convert rollback line number in AX to line number in ems page, and invoke
; that page. Destroys dx, returns ax as line number in page.
emsfixup proc near
cmp emsrbhandle,0 ; EMS in use?
jg emsfix1 ; g = yes (-1 is not in use)
ret
emsfix1:xor dx,dx
div lineems ; line number / lines per ems page
push bx
mov bx,ax ; quotient, page number
mov ax,dx ; remainder, line in page
cmp bx,pageready ; is this page now present?
je emsfix2 ; e = yes
mov pageready,bx ; remember
push ax
mov ah,emsmapmem ; map logical page in bx
xor al,al ; to physical page zero
mov dx,emsrbhandle ; our ems rollback handle
int emsint
pop ax ; return ax as line in page
emsfix2:pop bx
ret
emsfixup endp
; Repaint screen from the vscreen buffer
repaint proc near
push dx
xor dl,dl ; top row
mov dh,crt_lins ; physical screen rows-1, incl status
cmp isps55,0 ; [HF]940209 Japanese PS/55?
je repain1 ; [HF]940209 e = no
cmp ps55mod,0 ; [HF]940209 system uses modeline?
jne repain1 ; [HF]940209 ne = no
dec dh ; [HF]940209 yes, don't touch modeline
repain1:call touchup
pop dx
ret
repaint endp
; Repaint part of screen from the vscreen buffer, with linescroll offset
; dh is bottom line number, dl is top line number (dh >= dl)
ftouchup proc far
call touchup
ret
ftouchup endp
touchup proc near ; get lines from virtual screen
cmp flags.vtflg,ttgenrc ; terminal type of none?
jne touch1 ; ne = no
ret
touch1: push ax
push bx
push cx
push dx
push si
push di
push es
mov cl,dh ; last row to change
sub cl,dl ; number of lines -1
cmp cl,crt_lins ; out of bounds value?
jbe touch1b ; be = no
xor cl,cl ; stay sane
touch1b:inc cl ; number of lines to update
xor ch,ch
cmp tekflg,tek_active+tek_sg ; special graphics mode?
je touch1c ; e = yes, skip text screen update
test tekflg,tek_active ; other graphics mode?
jnz touch9 ; nz = yes, no touchup
call scroff ; turn off text screen
mov es,tv_segs ; get the segment of the screen
mov di,tv_sego ; initial screen offset
touch1c:mov al,crt_cols ; physical screen width
mul dl ; chars into physical screen
add ax,ax ; chars to bytes
add di,ax ; offset of start of phy update area
mov si,word ptr vs_ptr
mov al,vswidth ; chars per line
mul dl ; ax = bytes to first vscreen line
add ax,ax ; chars to bytes
add si,ax ; si = starting vscreen line offset
mov bl,dl ; top line number
xor bh,bh ; index for linescroll
cld
push dx
mov dh,dl ; set row into dh, temporarily
touch2: push si ; save the current line pointer
push cx ; save the number of lines
mov cl,crt_cols ; get the number of characters to move
xor ch,ch
xor dl,dl
mov al,linescroll[bx] ; get horiz scroll for this line
add al,handhsc ; hand done shift, total to AL
cbw ; sign extend
or ax,ax ; sane?
jge touch2c ; ge = yes
xor ax,ax ; remove negative overshifts
touch2c:add si,ax ; offset into vscreen
add si,ax ; char cells to words
mov ah,dgwindcomp[bx]
test ah,2 ; soft font?
jz touch2g ; z = no
ifndef no_graphics
cmp tekflg,tek_active+tek_sg ; special graphics mode?
je touch2d ; e = yes
push ax
call dgsettek ; set special graphics mode now
pop ax
jmp short touch2d
endif ; no_graphics
touch2g:cmp writemode,0 ; use direct writing?
je touch2a ; e = yes
cmp tekflg,tek_active+tek_sg ; special graphics mode?
je touch2d ; e = yes
call tchbios ; Bios writing
jmp short touch4
touch2a:cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne touch3 ; ne = no
touch2d:
ifndef no_graphics
push bx
mov bl,al ; horizontal scroll for this line
xor bh,bh
test ah,1 ; is this line compressed?
jz touch2e ; z = no
mov cl,128 ; compressed, 5 dot chars, 128/line
touch2e:mov al,vswidth
mul dh ; cells in previous rows
add al,dl ; cells across to this column
adc ah,0
add bx,ax ; cells from start of screen
touch2b:push bx
push cx
push si
push es
shl bx,1 ; address words
les si,vs_ptr ; main vscreen
mov ax,es:[si+bx] ; obtain char and attribute
les si,vsat_ptr ; extended attributes
shr bx,1 ; count bytes, vs words above
mov cl,es:[bx+si] ; obtain extended attribute byte
pop es ; to get font indicator
pop si
call ttxtchr ; write character
pop cx
pop bx
inc dl ; next column
inc bx
loop touch2b
pop bx
jmp short touch4
endif ; no_graphics
touch3: push ds
mov ds,word ptr vs_ptr+2 ; segment of vscreen
rep movsw ; from vscreen+hsc to real screen+0
pop ds
touch4: pop cx ; restore the line count
pop si ; restore the buffer counter
inc bx ; for next line
add si,vswidth*2 ; point to next line
inc dh
dec cx
jz touch4a ; z = have done all lines
jmp touch2 ; do more lines
touch4a:pop dx
mov ah,byte ptr cursor+1 ; row of cursor
cmp ah,dl ; cursor before this line?
jb touch5 ; b = yes, skip cursor
cmp ah,dh ; cursor after this line?
ja touch5 ; a = yes, skip cursor
ifndef no_graphics
mov cursorst,0 ; say cursor has been zapped off
endif ; no_graphics
push dx
mov dx,cursor
mov bl,dh ; get row
xor bh,bh
sub dl,linescroll[bx] ; deduct horiz scroll for this line
sub dl,handhsc ; hand done shift
call setpcur ; reset the cursor
pop dx
touch5: cmp tekflg,tek_active+tek_sg ; special graphics mode?
je touch9 ; e = yes
cmp tv_mode,0h ; TV active?
je touch8 ; e = no
mov cl,dh ; tell Topview/Desqview
sub cl,dl ; number of lines -1
cmp cl,crt_lins ; out of bounds value?
jbe touch7 ; be = no
xor cl,cl ; stay sane
touch7: inc cl ; number of lines to update
mov al,crt_cols ; chars/line
mul cl
mov cx,ax ; cx = words changed
call scrsync ; synch Topview
touch8: call scron ; turn on the screen
touch9: pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
touchup endp
; Write screen via Bios. Enter with SI pointing at starting screen buffer
; offset, dh is current screen row, cx has chars to write across a line.
tchbios proc near
push bx
xor bh,bh ; video page zero
push dx
mov ah,3
int screen
mov temp,dx ; save current cursor
pop dx
mov cl,crt_cols
xor ch,ch
xor dl,dl ; column zero
cld
push ds
mov ds,word ptr vs_ptr+2 ; source is virtual screen buffer
add di,cx ; move DI to match si movemen
add di,di ; word's worth
tchbios1:push cx
mov ah,2 ; set cursor position to dx
int screen
lodsw ; char+attribute
mov bl,ah ; attribute
mov cx,1 ; one char
mov ah,9 ; write char at cursor position
int screen ; do the Bios Int 10h call
inc dl ; next column
pop cx
loop tchbios1
pop ds
push dx
mov dx,temp ; starting cursor position
mov ah,2 ; set it back there
int screen
pop dx
pop bx
ret
tchbios endp
; Character write/read and cursor manipulation routines for terminal emulator
; All registers other than returned values are preserved.
; Read char and attributes under virtual cursor (DH = row, DL = column).
; Returns AL = character, AH = video attributes, CL = logical attribute bit
; pair.
getatch proc near
push bx
push si
push es
mov al,vswidth ; width of vscreen line
mul dh ; count down rows (0..)
add al,dl ; add column
adc ah,0
add ax,ax ; times two for char and attrib
mov bx,ax ; address subscript
les si,vs_ptr ; main vscreen
mov ax,es:[si+bx] ; obtain char and attribute
les si,vsat_ptr ; extended attributes
shr bx,1 ; count bytes, vs words above
mov cl,es:[bx+si] ; obtain extended attribute byte
pop es
pop si
pop bx
ret
getatch endp
endif ; no_terminal
; Set virtual cursor postion
; DL = column, DH = row, both counted from 0,0 at upper left corner.
; If not displaced, handhsc = 0, then scroll left if virtual > crt_cols.
; If displaced, handhsc != 0, then scroll right if virtual < handhsc.
; For the D463/D470 only, set carry bit (for setatch) if the cursor is off
; the visible screen and horizontal scrolling is disabled.
setpos proc near
push ax
push bx
push cx
push dx ; save outside virtual cursor
mov cl,crt_cols ; physical screen width
push cx ; save here
ifndef no_terminal
cmp inemulator,0 ; emulating?
je setpos9 ; e = no, no virtual screen
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne setpos1 ; ne = no
mov bl,dh ; get row
xor bh,bh
test dgwindcomp[bx],1 ; is this line compressed?
jz setpos1 ; z = no
mov crt_cols,128 ; compressed, 5 dot chars, 128/line
setpos1:mov ch,vswidth ; leftmost legal margin (207)
sub ch,crt_cols ; minus screen physical width
xor cl,cl ; cl is flag for repainting needed (if != 0)
xchg handhsc,cl ; hand-done horiz scroll, clear it
or cl,cl ; need to undo it?
jz setpos2 ; z = no
call repaint ; repaint screen without hand scroll
xor cl,cl ; remove repaint indicator
setpos2:mov bl,dh ; current row
xor bh,bh
mov ah,linescroll[bx] ; current horz scroll
setpos3:mov al,dl ; virtual column where we ought to be
sub al,ah ; virtual - already scrolled
jc setpos4 ; c = cursor off screen to the left
cmp al,crt_cols ; beyond right physical screen?
jb setpos5 ; b = no, use this
mov cl,1 ; say need repaint
inc ah ; scroll screen left one column
jc setpos3a ; c = over did it
cmp ah,ch ; going beyond largest scroll?
jbe setpos3 ; be = no
setpos3a:mov ah,ch ; yes, stay here
jmp short setpos5 ; done, do real operation
setpos4:mov cl,1 ; say repaint needed
mov ah,dl ; reduce horz scroll
setpos5:or cl,cl ; repaint needed?
jnz setpos5c ; ne = yes
mov bl,byte ptr low_rgt+1 ; screen bottom
inc bl ; lines in emulation part
xor bh,bh
cmp linescroll[bx],ah ; status line, need to scroll?
jbe setpos8 ; be = already scrolled properly
mov linescroll[bx],ah ; modify status line
push dx
mov dl,bl
mov dh,bl
call touchup ; redraw status line
pop dx
jmp short setpos8 ; set cursor
setpos5c:test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jz setpos5a ; z = no
cmp dghscrdis,0 ; D463/D470 horz scroll disabled?
je setpos5a ; e = no, check auto vs manual
stc ; c = do not show on real screen
jmp short setposx ; skip screen update
setpos5a:test vtemu.vtflgop,vshscroll ; horizontal scrolling, manual?
jnz setpos9 ; nz = yes manual, else auto
setpos5b:mov bl,mar_top ; auto scrolling, top row
xor bh,bh
mov cl,mar_bot
sub cl,bl
xor ch,ch
inc cx ; lines in scrolling region
setpos6:cmp linescroll[bx],ah ; any change?
je setpos7 ; e = no
mov linescroll[bx],ah ; set scroll for this line
push dx
mov dl,bl
mov dh,bl
call touchup ; repaint this line
pop dx
setpos7:inc bx
loop setpos6 ; do all lines in window
setpos7a:push ax ; now do status line
push si
mov cl,byte ptr low_rgt+1 ; examine whole screen
inc cl ; lines in emulation part
xor ch,ch
mov bx,cx ; save for status line
mov si,offset linescroll
mov ah,[si] ; smallest horizontal shift found
cld
setpos10:lodsb ; current line scroll to al
cmp al,ah ; smaller than smallest?
ja setpos11 ; a = no
mov ah,al ; remember smallest
or ah,ah ; zero?
jz setpos11a ; can't get any smaller than this
setpos11:loop setpos10
; just status line
setpos11a:cmp linescroll[bx],ah ; status line, need to scroll?
je setpos12 ; e = already scrolled properly
mov linescroll[bx],ah ; modify status line
push dx
mov dl,bl
mov dh,bl
call touchup ; redraw status line
pop dx
setpos12:pop si
pop ax
setpos8:sub dl,ah ; virtual - horz scrolled column
endif ; no_terminal
setpos9:call setpcur ; set physical cursor
clc ; set status for ok to show
setposx:pop cx
mov crt_cols,cl
pop dx
pop cx
pop bx
pop ax
ret
setpos endp
; Read physical cursor position
; DL = column, DH = row, both counted from 0,0 at upper left corner
; CX = cursor lines
getpcur proc near
push ax
push bx
mov ah,3 ; get cursor position
xor bh,bh ; page 0
int screen
pop bx
pop ax
ret
getpcur endp
fgetpcur proc far
call getpcur
ret
fgetpcur endp
; Set physical cursor postion
; DL = column, DH = row, both counted from 0,0 at upper left corner
setpcur proc near
push dx
cmp dl,crt_cols ; out of bounds?
jb setpcur1 ; b = ok
cmp dl,207 ; off screen to left?
jbe setpcur0 ; be = no
xor dl,dl ; put at column zero
jmp short setpcur1
setpcur0:mov dl,crt_cols ; physical cols on screen
dec dl ; count from zero
setpcur1:
ifndef no_terminal
cmp inemulator,0 ; emulating?
je setpcur4 ; e = no, no virtual screen
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne setpcur4 ; ne = no
push ax
push es
mov ax,40h
mov es,ax
mov ax,es:[50h] ; current position
mov es:[50h],dx ; text page 0 cursor, keep it tracking
cmp ax,dx ; same?
pop es
pop ax
ifndef no_graphics
jne setpcur2 ; not same, draw cursor
cmp cursorst,0 ; is cursor off now?
jne setpcur3 ; ne = no, skip redrawing
setpcur2:
mov dosetcursor,dx ; reminder of where to set cursor
call tekremcursor ; ensure it's off
endif ; no_graphics
setpcur3:pop dx
ret
endif ; no_terminal
setpcur4:push ax
push es
mov ax,40h
mov es,ax
mov ax,es:[50h] ; current position
cmp ax,dx ; same?
pop es
jne setpcur5 ; ne = no
pop ax
pop dx
ret
setpcur5:push bx
mov ah,2 ; set cursor
xor bh,bh ; page 0
int screen
pop bx
pop ax
pop dx
ret
setpcur endp
; Read char and attributes under physical cursor.
; Returns AL = character, AH = video attributes
getpcha proc near
push bx
mov ah,8 ; read char and attributes
xor bh,bh ; page 0
int screen ; Bios video call
pop bx
ret
getpcha endp
; Write char and attribute to screen at cursor position, do not move cursor.
; AL = char, AH = video attribute, DL = column, DH = row, CL = logical
; attribute bits. Does not update physical screen.
qsetatch proc near
mov setnoshow,1 ; turn off physical screen update
jmp setatch ; call with same args
qsetatch endp
; Write char and attribute to screen at cursor position, do not move cursor.
; AL = char, AH = video attribute, DL = column, DH = row, CL = logical
; attribute bits. Turns off setnoshow at the end.
setatch proc near
push bx
push es
push cx ; save logical attribute
push ax ; save char and attribute
cmp setnoshow,0 ; show on real screen?
jne setatc1 ; ne = no, do just virtual screen
push cx
call setpos ; set cursor at dx location
pop cx
jc setatc1 ; c = do not show character
cmp inemulator,0 ; emulating a terminal now?
je setatc4 ; e = no
ifndef no_graphics
cmp flags.vtflg,tttek ; full Tek?
je setatc5 ; e = yes
cmp tekflg,tek_active+tek_sg ; special graphics mode?
jne setatc4 ; ne = no, text mode
setatc5:push dx
push si
push di
mov bl,dh ; get row
xor bh,bh
sub dl,linescroll[bx] ; deduct horizontal scroll
call ttxtchr ; display char in graphics mode
pop di
pop si
pop dx
jmp short setatc1
endif ; no_graphics
setatc4:
mov cx,1 ; one char
mov bl,ah ; attribute
xor bh,bh ; page 0
mov ah,9 ; write char, do not move cursor
int screen
setatc1:mov setnoshow,0 ; always reset this automatically
; write same material to vscreen
mov al,vswidth ; width of vscreen line
mul dh ; count across rows (0..)
xor bh,bh
mov bl,dl ; get position
add bx,ax ; add column
add bx,bx ; times two for char and attrib
pop ax ; recover char and attribute
pop cx ; recover logical attribute
ifndef no_terminal
cmp inemulator,0 ; in terminal emulator?
je setatc2 ; e = no, so no virtual screen
push di
les di,vs_ptr ; virtual screen
mov es:[di+bx],ax ; store char and attribute
push ax ; save ah attributes
les di,vsat_ptr ; attributes byte array
shr bx,1 ; bytes, vs words above
mov es:[bx+di],cl ; set extended attributes
pop ax
pop di
endif ; no_terminal
setatc2:pop es
pop bx
ret
setatch endp
ifndef no_terminal
; Get bold video attribute bit
; Returns AH = bold attribute bit (0 if not bold)
getbold proc near
and ah,att_bold
test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jnz getbold1 ; nz = yes
xor ah,userbold ; invert with user bold
getbold1:ret
getbold endp
; Set bold video attribute bit, current video attribute supplied in AH
setbold proc near
or ah,att_bold
cmp colunder,0ffh ; uninited?
je setbold2 ; e = yes, don't change here
or colunder,att_bold
setbold2:test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jnz setbold1 ; nz = yes
xor ah,userbold ; invert with user bold
cmp colunder,0ffh ; uninited?
je setbold1 ; e = yes, don't change here
push ax
mov ah,userbold
xor colunder,ah
pop ax
setbold1:ret
setbold endp
; Clear bold video attribute bit, current video attribute supplied in AH
clrbold proc near
and ah,not att_bold
cmp colunder,0ffh ; uninited?
je clrbold2 ; e = yes, don't change here
and colunder,not att_bold
clrbold2:test flags.vtflg,ttd463+ttd470+ttd217 ; D463/D470/D217?
jnz clrbold1 ; nz = yes
xor ah,userbold ; invert with user bold
cmp colunder,0ffh ; uninited?
je clrbold1 ; e = yes, don't change here
push ax
mov ah,userbold
or colunder,ah
pop ax
clrbold1:ret
clrbold endp
; Get blink video attribute bit
; Returns AH = blink attribute bit
getblink proc near
and ah,att_blink
ret
getblink endp
; Set blink video attribute bit, current video attribute supplied in AH
setblink proc near
or ah,att_blink
ret
setblink endp
; Clear blink video attribute bit, current video attribute supplied in AH
clrblink proc near
and ah,not att_blink
ret
clrblink endp
; Set extended attribute for protection in extattr and in CL.
setprot proc near ; set protected mode
or extattr,att_protect
or cl,att_protect ; and in cl
ret
setprot endp
; Clear extended attribute for protection in extattr and in CL.
clrprot proc near ; clear protected mode
and extattr,not att_protect
and cl,not att_protect
ret
clrprot endp
; Get underline video attribute bit from extattr
; Returns CL = underline attribute bit
getunder proc near
mov cl,extattr ; get extended attribute
and cl,att_uline ; return underline status bit
ret
getunder endp
; Set underline video attribute bit, current video attribute supplied in AH
; and extended attributes in extattr. Returns new AH and extattr in CL.
setunder proc near
test extattr,att_uline ; extended attributes, on already?
jz setund1 ; z = no
ret ; else do nothing
setund1:or extattr,att_uline ; set underline attribute for MSZ
or cl,att_uline
cmp crt_mode,7 ; monochrome display adapter mode?
je setund6 ; e = yes
cmp colunder,0ffh ; uninited?
je setund10 ; e = yes
and ah,att_blink ; preserve blink
or ah,colunder ; user specified underline coloring
test extattr,att_rev ; are we reversed per char?
jz setund8 ; z = no
call revideo
setund8:cmp reversed_screen,0 ; whole screen reversed too?
je setund9 ; e = no
call revideo
setund9:ret
setund10:push bx
push dx
mov bh,al ; preserve possible char in al
mov dl,scbattr ; screen fill
and dl,70h ; background colors
mov bl,extattr ; extended attributes
and bl,att_rev ; per char reversed video
mov dh,ah ; current character attributes
and dh,not 77h ; blink/bold attributes only
and ah,77h ; colors only
mov al,ah
shr al,1
shr al,1
shr al,1
shr al,1 ; background to lower nibble
and ah,7 ; foreground only
or bl,bl ; reversed video attribute?
jz setund3 ; z = no, normal
xchg ah,al ; real background color to al
setund3:xor al,ah ; modify background
or dl,dl ; case of black background?
jnz setund4 ; nz = no
mov al,ah
dec al
and al,7 ; background goes to (foreground-1)/8
or al,al ; still black?
jnz setund4 ; nz = no
mov al,7 ; force non-black (white foreground)
setund4:shl al,1 ; background to high nibble
shl al,1
shl al,1
shl al,1
or ah,al ; or new background
or bl,bl ; per char reversal?
jz setund5 ; z = no
rol ah,1 ; yes, flip fore/background again
rol ah,1
rol ah,1
rol ah,1
setund5:or ah,dh ; restore blink and bold
pop dx
mov al,bh ; restore possible char
pop bx
ret
setund6:push bx
mov bl,al ; preserve char in AL
call brkatt ; monochrome, break apart
mov ah,att_underline ; set mono underline coloring
or ah,al ; put back blink/bold
test extattr,att_rev ; are we reversed per char?
jz setund6a ; z = no
call revideo
setund6a:cmp reversed_screen,0 ; whole screen reversed too?
je setund6b ; e = no
call revideo
setund6b:mov al,bl ; restore char in AL
pop bx
ret
setunder endp
; Clear underline video attribute bit, current video attribute supplied in AH
; and extended attributes in extattr. Returns new AH and extattr in CL.
clrunder proc near
test extattr,att_uline ; extended attributes, off already?
jnz clrund1 ; nz = no
ret ; else do nothing
clrund1:and extattr,not att_uline ; clear underline attribute for MSZ
and cl,not att_uline
cmp crt_mode,7 ; monochrome display adapter mode?
je clrund6 ; e = yes, otherwise reverse video
cmp colunder,0ffh ; user spec underline inited?
je clrund10 ; e = no
and ah,att_blink ; preserve blink
or ah,att_normal ; current normal coloring
test extattr,att_rev ; are we reversed per char?
jz clrund1a ; z = no
call revideo
clrund1a:cmp reversed_screen,0 ; whole screen reversed too?
je clrund1b ; e = no
call revideo
clrund1b:ret
clrund6:push bx
mov bl,al ; preserve char in al
call brkatt ; mono, break apart attributes
mov ah,07h ; set normal coloring
or ah,al ; reassemble attributes
test extattr,att_rev ; are we reversed per char?
jz clrund6a ; z = no
call revideo
clrund6a:cmp reversed_screen,0 ; whole screen reversed too?
je clrund6b ; e = no
call revideo
clrund6b:mov al,bl ; restore char in AL
pop bx
ret
clrund10:push bx
push dx
mov bh,al ; save possible char in al
xor bl,bl
mov dl,scbattr ; screen fill
and dl,70h ; background colors
mov bl,extattr ; extended attributes
and bl,att_rev ; per char reversed video
mov dh,ah ; current char attributes
and dh,not 77h ; blink/bold attributes only
and ah,77h ; colors only
mov al,ah
shr al,1
shr al,1
shr al,1
shr al,1 ; background to lower nibble
and ah,7 ; foreground only
or bl,bl ; reversed video attribute?
jz clrund3 ; z = no, normal
xchg ah,al ; real background color to al
clrund3:or dl,dl ; case of black background?
jz clrund4 ; z = yes, leave it black (empty)
xor al,ah
shl al,1 ; background to high nibble
shl al,1
shl al,1
shl al,1
or ah,al ; or in new background
clrund4:or bl,bl ; per char reversal?
jz clrund5 ; z = no
rol ah,1 ; yes, reverse nibbles again
rol ah,1
rol ah,1
rol ah,1
clrund5:or ah,dh ; restore blink and bold
pop dx
mov al,bh ; restore possible char
pop bx
ret
clrunder endp
endif ; no_terminal
; Compute reversed video attributes, given displayables in AH and extended
; in extattr. Returns new attribute in AH and CL holding new extattr
setrev proc near
test extattr,att_rev ; reversed now?
jnz setrev2 ; nz = yes
call revideo ; do reversal
or extattr,att_rev ; update extended attribute
or cl,att_rev
setrev2:ret
setrev endp
; Compute un-reversed video attributes, given displayables in AH and extended
; in extattr. Returns new attribute in AH and CL holding new extattr
clrrev proc near
test extattr,att_rev ; reversed now?
jz clrrev1 ; z = no
call revideo ; do reversal
and extattr,not att_rev ; update extended attribute
and cl,not att_rev ; update extended attribute
clrrev1:ret
clrrev endp
; Compute reversed video attribute byte. Normally preserves blink/bold.
; Enter with AH = video attribute byte, returns new attribute byte in AH.
revideo proc near
push bx
mov bl,al ; preserve char in AL
call brkatt ; separate colors from blink/bold
rol ah,1 ; reverse foreground & background
rol ah,1 ; RGB bits
rol ah,1
rol ah,1
cmp crt_mode,7 ; monochrome?
jne revideo1 ; ne = no
test al,att_bold ; bold?
jz revideo1 ; z = no
test ah,7 ; black foreground now?
jnz revideo1 ; nz = no, something to brighten
and al,not att_bold ; remove bolding
revideo1:or ah,al ; reinsert bold/blink bits
mov al,bl ; restore char in AL
pop bx
ret
revideo endp
; This routine picks an attribute apart into its component "parts" - the
; base attribute for the screen and the "extras" - i.e., blink, intensity
; and underline.
; enter with ah = a cursor attribute
; return ah = base attribute for screen (07H normal, 70H reverse).
; al = "extra" attributes
; Note that there is a complementary routine, addatt, for putting attributes
; back together.
brkatt: mov al,ah ; copy displayables
and al,(att_blink+att_bold) ; get modifiers
and ah,not (att_bold+att_blink) ; strip blink/bold, leave color
ret
; This routine builds a cursor attribute given the base attribute for the
; screen background and the "extra" attributes we want (blink, etc.).
; enter with ah = base attribute for background (07H or 70H)
; al = "extra" attributes (89H for all three)
; return ah = base combined with "extras".
addatt: or ah,al ; OR the attributes
ret
ifndef no_terminal
; 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.
; Call: no arguments.
revscn proc near
push ax
push bx
push cx
push dx
xor reversed_screen,1 ; remember we did this
mov dh,byte ptr low_rgt+1 ; compute last screen offset in ax
inc dh ; one more row to catch mode line
mov dl,vswidth ; logical screen buffer
dec dl ; and we count from 0
call scrloc ; get screen offset into ax
mov cx,ax ; save it in cx for a minute
add cx,2
sar cx,1 ; in 16-bit words please
push di ; Save some more acs
push es
les di,vs_ptr ; seg and offset of vscreen
cld
revsc1: mov ax,es:[di] ; fetch a word
mov bl,al ; save the character
call revideo ; get reversed video attributes (AH)
mov al,bl ; restore character
stosw ; stuff into screen memory
loop revsc1 ; loop for entire screen
pop es ; restore segment register
pop di ; and destination index
pop dx
pop cx
pop bx
call repaint
pop ax
ret
revscn 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
test extattr,att_rev ; normal video currently?
jz setcol0 ; z = yes
mov al,ah ; make a copy
and ax,7788h ; strip bold,blink, keep both in al
rol ah,1 ; get colors in right parts
rol ah,1 ; of ah = back, al = foreground
rol ah,1
rol ah,1
call setcol0 ; set fore or background color
rol ah,1 ; reverse coloring again
rol ah,1
rol ah,1
rol ah,1
or ah,al ; put back blink and bold
ret
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
and ah,not 07H ; clear foreground bits
test bl,1 ; ANSI red?
jz setcol1 ; z = no
or ah,4 ; IBM red foreground bit
setcol1:test bl,2 ; ANSI & IBM green?
jz setcol2 ; z = no
or ah,2 ; IBM green foreground bit
setcol2:test bl,4 ; ANSI blue?
jz setcol3 ; z = no
or ah,1 ; IBM 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
and ah,not 70H ; clear background bits
test bl,1 ; ANSI red?
jz setcol5 ; z = no
or ah,40h ; IBM red background bit
setcol5:test bl,2 ; ANSI & IBM green?
jz setcol6 ; z = no
or ah,20h ; IBM green background bit
setcol6:test bl,4 ; ANSI blue?
jz setcol7 ; z = no
or ah,10h ; IBM blue background bit
setcol7:ret
setcolor endp
ifndef no_tcp
; Save terminal emulator, session is in BX.
; Delete older save buffer for this session, so that compressed vscreen
; can be saved properly.
termswapout proc far
cmp bx,6 ; legal session number?
jb termso0 ; b = yes
stc
ret
termso0:push ax
push bx
push cx
push si
push di
shl bx,1 ; to words
mov temp,bx ; save session ident
cmp tsave[bx],0 ; have a storage buffer?
je termso9 ; ne = no, create one now
shr bx,1 ; get original BL session indicator
call termswapdel ; delete old save area
shl bx,1 ; restore word indexing
termso9:
ifndef no_graphics
mov ax,31*2 ; softlist, 31 words
else
xor ax,ax
endif ; no_graphics
call getvssize ; get size of vscreen, compressed
add ax,bx ; accumulate new from bx
call getvasize ; size of attributes
add bx,ax ; new total to bx
add bx,savexlen ; plus length of MSX save area
add bx,saveylen ; plus MSY save area
add bx,savezlen ; plus MSZ area
add bx,saveplen ; plus parser in MSSCMD
add bx,saveulen ; plus MSU area
ifndef no_graphics
add bx,saveglen ; plus MSG area
endif ; no_graphics
add bx,15 ; round up
mov cl,4
shr bx,cl ; convert to paragraphs
mov cx,bx ; save request in cx
mov ah,alloc ; please, more space
int dos ; paragraph to ax, num paras to bx
cmp bx,cx ; given vs wanted
jae termso1 ; ae = got it
pop di
pop si
pop cx
pop bx
pop ax
stc ; fail
ret
termso1:
ifndef no_graphics
push temp
push ax
call tekend ; exit graphics mode
pop ax
pop temp
endif ; no_graphics
mov bx,temp ; get 2 * session number (sescur)
mov tsave[bx],ax ; save starting paragraph
push es
mov es,ax ; save area is destination
xor di,di ; offset of save area
ifndef no_graphics
mov si,seg softlist ; where softlist lives
push ds
mov ds,si
mov si,offset softlist
mov cx,31 ; number of entries
cld
rep movsw ; save segs of soft font in msgibm
pop ds
endif ; no_graphics
push es ; save tsave seg
push di ; save current dest ptr
mov cx,ds
mov es,cx
mov cx,size flginfo ; length of saved flags array
mov di,offset saveflag ; saved array
mov si,offset flags ; working array
rep movsb ; save
pop di ; tsave dest offset
pop es ; tsave seg
; virtual screen is saved as structure
; scr-len dw text screen length (typically 24 lines)
; with the items below repeated for each line (scr-len total lines)
; per-line dw saved chars on this line
; dw per-line dup (char & attribute)
; with the last saved char on each line being repeated to endofline on screen
push bx ; virtual screen saving
mov cl,crt_lins ; number of screen lines - 1
inc cl ; add status line to save block
xor ch,ch
mov ax,cx
cld
stosw ; store screen length as first word
xor bx,bx ; line counter
mov si,word ptr vs_ptr ; offset of vscreen
termso3:push cx ; save line loop counter
mov cx,word ptr rdbuf[bx] ; get number of saveable chars on line
mov ax,cx ; store char count as first word
stosw
mov ax,word ptr vs_ptr+2 ; get vscreen segment
push si
push ds
mov ds,ax
rep movsw ; copy saveable chars
pop ds
pop si
pop cx ; recover line counter
add bx,2 ; next line, get length info
add si,vswidth*2 ; next line, offset of vscreen line
loop termso3
pop bx ; end of vscreen saving
;
push bx ; virtual screen saving
mov cl,crt_lins ; number of screen lines - 1
inc cl ; do all lines
termso3b:xor ch,ch
mov ax,cx
cld
stosw ; store screen length as first word
xor bx,bx ; line counter
mov si,word ptr vsat_ptr ; offset of vsattr
termso7:push cx ; save line loop counter
mov cx,word ptr rdbuf[bx+120]; get num of saveable bytes on line
mov ax,cx ; store char count as first word
stosw
mov ax,word ptr vsat_ptr+2 ; get vsattr segment
push si
push ds
mov ds,ax
shr cx,1 ; get odd byte count info
jnc termso7a ; nc = even count
movsb
termso7a:rep movsw ; copy saveable bytes
pop ds
pop si
pop cx ; recover line counter
add bx,2 ; next line, get length info
add si,vswidth ; next line, offset of vsattr line
loop termso7
pop bx ; end of vsattr saving
;
mov si,offset saveyoff ; offset of MSY save area
mov cx,saveylen ; length of MSY save area
cld
shr cx,1 ; even/odd?
jnc termso4 ; nc = even
movsb ; the odd byte
termso4:rep movsw
mov si,offset savezoff ; offset of MSZ save area
mov cx,savezlen ; length of MSZ save area
shr cx,1
jnc termso5
movsb
termso5:rep movsw
mov si,offset savexoff ; offset of MSX save area
mov cx,savexlen ; length of MSX save area
cld
cli ; cautious about serial ints
shr cx,1 ; even/odd?
jnc termso6 ; nc = even
movsb ; the odd byte
termso6:rep movsw
sti
mov si,offset savepoff ; offset of MSSCMD parser save area
mov cx,saveplen ; length of the area
shr cx,1
jnc termso6a
movsb
termso6a:rep movsw
mov si,offset saveuoff ; offset of MSUIBM kbd save area
mov cx,saveulen ; length of the area
shr cx,1
jnc termso6b
movsb
termso6b:rep movsw
ifndef no_graphics
mov si,offset savegoff ; offset of MSG save area
mov cx,saveglen ; length of MSG save area
shr cx,1 ; graphics mode exited above
jnc termso6c
movsb
termso6c:rep movsw
endif ; no_graphics
pop es
mov ax,100h ; assume using 80 col screen
cmp dos_cols,80 ; startup screen width
jbe termso8 ; be = assume 80 columns
inc al ; say do 132 columns
termso8:push vtemu.vtflgop
or vtemu.vtflgop,vscompress ; turn off compressed mode
call chgdsp ; reset display width to startup
pop vtemu.vtflgop
pop di
pop si
pop cx
pop bx
pop ax
clc
ret
termswapout endp
; Restore terminal emulator, session is BX
; Delete save buffer after restoration.
termswapin proc far
cmp bx,6 ; valid session?
jb termsi0 ; b = yes
stc
ret
termsi0:push bx
shl bx,1 ; to words
cmp tsave[bx],0 ; have a storage buffer?
pop bx
jne termsi1 ; ne = yes, use it
mov vtinited,0 ; say not inited
stc ; fail
ret
termsi1:push ax
push bx
push cx
push si
push di
push es ; virtual screen restore
ifndef no_graphics
test tekflg,tek_active ; current graphics mode status
jz tswapin1a ; z = not in graphics mode
push bx
call tekend
pop bx
endif ; no_graphics
tswapin1a:
shl bx,1 ; address words
mov ax,tsave[bx] ; starting paragraph for save area
push ds
mov ds,ax ; save area is source
xor si,si ; offset of save area
ifndef no_graphics
mov di,seg softlist ; seg of destination
mov es,di
mov di,offset softlist
mov cx,31 ; number of entries
cld
rep movsw ; restore segs of soft font in msgibm
endif ; no_graphics
pop ds
les di,vs_ptr ; seg and offset of vscreen
mov ax,tsave[bx] ; starting paragraph of save area
push ds
mov ds,ax ; source segment is save area
lodsw ; get screen length
mov cx,ax ; counter of vscreen lines to do
tswapi2:push cx ; save line counter
lodsw ; get count of saved chars of line
dec ax ; omit repeated char til next step
mov cx,ax ; count for saved char writes
rep movsw ; copy saved chars except last one
mov cx,vswidth ; total line width (chars)
sub cx,ax ; minus those done
lodsw ; get last char (this repeats to end)
rep stosw ; repeat last char
pop cx ; recover line counter
loop tswapi2 ; do all text lines (omit status)
pop ds ; restore DS, SI is ready for nxt grp
; end of virtual screen restoration
; attributes, vsatt, for vscreen
les di,vsat_ptr ; seg and offset of vsatt
mov ax,tsave[bx] ; starting paragraph of save area
push ds
mov ds,ax ; source segment is save area
lodsw ; get screen length
mov cx,ax ; counter of vsattr lines to do
tswapi7:push cx ; save line counter
lodsw ; get count of saved bytes of line
dec ax ; omit repeated byte til next step
mov cx,ax ; count for saved byte writes
shr cx,1 ; do odd byte copy
jnc tswapi7a ; nc = even count
movsb
tswapi7a:rep movsw ; copy saved bytes except last one
mov cx,vswidth ; total line width (bytes)
sub cx,ax ; minus those done
lodsb ; get last byte (this repeats to end)
rep stosb ; repeat last byte
pop cx ; recover line counter
loop tswapi7 ; do all text lines (omit status)
pop ds ; restore DS, SI is ready for nxt grp
; end of virtual screen restoration
mov ax,ds ; regular data seg "data"
mov es,ax ; new data seg
mov di,offset saveyoff ; offset of MSY save area
mov cx,saveylen ; length of MSY save area
mov ax,tsave[bx] ; starting paragraph of save area
push ds
mov ds,ax ; source segment is save area
cld
shr cx,1 ; even/odd?
jnc termsi3 ; nc = even
movsb ; the odd byte
termsi3:rep movsw
mov di,offset savezoff ; offset of MSZ save area
mov cx,es:savezlen ; length of MSZ save area
shr cx,1
jnc termsi4
movsb
termsi4:rep movsw
mov di,offset savexoff ; offset of MSX save area
mov cx,es:savexlen ; length of MSX save area
cli ; cautious about serial ints
shr cx,1
jnc termsi5
movsb
termsi5:rep movsw
sti
mov di,offset savepoff ; offset of MSSCMD parser area
mov cx,es:saveplen ; length
shr cx,1
jnc termsi6
movsb
termsi6:rep movsw
mov di,offset saveuoff ; offset of MSUIBM kbd area
mov cx,es:saveulen ; length
shr cx,1
jnc termsi6a
movsb
termsi6a:rep movsw
ifndef no_graphics
mov di,offset savegoff ; offset of MSGIBM area
mov cx,es:saveglen ; length
shr cx,1
jnc termsi8
movsb
termsi8:rep movsw
endif ; no_graphics
pop ds
mov cx,ds
mov es,cx
mov cx,size flginfo ; length of saved flags array
mov si,offset saveflag ; saved array
mov di,offset flags ; working array
rep movsb ; restore
mov ah,savattr ; get saved coloring
mov scbattr,ah ; replace what DOS may have used
and tekflg,not tek_active ; say graphics is not active
pop es
pop di
pop si
pop cx
pop bx
pop ax
call termswapdel ; delete this saved area, BL=session
clc
ret
termswapin endp
; Remove saved terminal emulator buffers, BX is sescur (-1 means all)
termswapdel proc far
cmp bx,-1 ; all?
jne tswapdw ; ne = no, just one
mov cx,6 ; number of possible sessions
push bx
xor bx,bx ; session index
tswapd1:call tswapdw ; delete bufs for this session (BX)
inc bx
loop tswapd1 ; and all others
pop bx
ret
tswapdw proc far ; worker within termswapdel
push ax ; delete session BX
push bx
cmp bx,5 ; largest session
ja tswapd2 ; a = illegal, ignore
shl bx,1 ; to words
xor ax,ax ; clearing indicator
xchg ax,tsave[bx] ; paragraph of save area
or ax,ax ; anything there?
jnz tswapd3 ; nz = yes
tswapd2:pop bx
pop ax
stc
ret
tswapd3:
ifndef no_graphics
push es
push ax ; save seg of save buffer
push cx
mov es,ax ; seg of save buffer
xor si,si ; offset in save area of softlist
mov cx,31 ; number of entries
cld
tswapd4:lodsw ; saved segs of soft font in msgibm
or ax,ax ; any seg defined?
jz tswapd5 ; z = no
push es
mov es,ax ; set paragraph to es for DOS
mov ah,freemem
int dos
pop es
tswapd5:loop tswapd4
pop cx
pop es ; recover seg of save buffer from AX
mov ah,freemem ; free the memory
int dos
pop es
endif ; no_graphics
pop bx
pop ax
clc
ret
tswapdw endp
termswapdel endp
; Examine vscreen line by line. Count number of characters by excluding the
; trailing repetitions (keep first example) on each line, sum them. Add to
; the sum a word per line to hold the count of such characters and one more
; word to hold the screen length.
; Return the number of bytes in register bx for malloc-ing.
getvssize proc near
push ax
push cx
push dx
push di
push es
les di,vs_ptr ; pointer to vscreen
xor bx,bx ; line counter
mov cl,crt_lins ; lines on screen - 1
xor ch,ch
inc cl ; add status line
mov dx,cx ; accumulated count <cnt, line>
inc dx ; count screen size word itself
add di,(vswidth - 1) * 2 ; offset of last char on the line
getvssi1:push cx ; save line counter
mov cx,vswidth-1 ; chars on line - 1
mov ax,es:[di] ; get last char+attrib on the line
push di
sub di,2
std ; scan backward
repe scasw ; scan while equal (trim trailing rpt)
cld
pop di
je getvssi2 ; e = ended on all same char
inc cx ; ne case gobbles extra char
getvssi2:inc cx ; count the trailing char
mov word ptr rdbuf[bx],cx ; store number of words here
add dx,cx ; accumulate count of chars
add bx,2 ; next line
add di,vswidth*2 ; end of next line
pop cx ; line counter
loop getvssi1
add dx,dx ; chars to bytes accumulated
mov bx,dx ; return it in bx
pop es
pop di
pop dx
pop cx
pop ax
ret
getvssize endp
; Examine vsattr line by line. Count number of attributes by excluding the
; trailing repetitions (keep first example) on each line, sum them. Add to
; the sum a word per line to hold the count of such characters and one more
; word to hold the screen length. Stores temp length indicator in
; words rdbuf+120 et seq (one word per line).
; Return the number of bytes in register bx for malloc-ing.
getvasize proc near
push ax
push cx
push dx
push di
push es
les di,vsat_ptr ; pointer to vsattr
xor bx,bx ; line counter
mov cl,crt_lins ; lines on normal screen - 1
inc cl ; include status line
xor ch,ch
mov dx,cx ; accumulated count <cnt, line>
inc dx ; count screen size word itself
add dx,dx ; convert to bytes used
add di,vswidth - 1 ; offset of last attrib on the line
getvasi1:push cx ; save line counter
mov cx,vswidth -1 ; bytes on line - 1
mov ax,es:[di] ; get last attribute byte on the line
push di
dec di
std ; scan backward
repe scasb ; scan while equal (trim trailing rpt)
cld
pop di
je getvasi2 ; e = ended on all same byte
inc cx ; ne case gobbles extra byte
getvasi2:inc cx ; count the trailing byte
mov word ptr rdbuf[bx+120],cx; store number of bytes here
add dx,cx ; accumulate count of bytes
add bx,2 ; next line
add di,vswidth ; end of next line
pop cx ; line counter
loop getvasi1
mov bx,dx ; return bytes needed in bx
pop es
pop di
pop dx
pop cx
pop ax
ret
getvasize endp
endif ; no_tcp
;
; CHKDSP - procedure to check for hardware support of 132 cols
; Supported hardware:
; ATI EGA and VGA Wonder
; AT&T
; Everex Viewpoint EV-659, FVGA-673, EV-678, Micro Enhancer Deluxe
; IBM XGA
; Paradise AutoSwitch EGA Mono, VGA Professional, VGA Plus, VGA Plus 16
; STB VGA/EM (Tseng TVGA)
; STB VGA/EM Plus (Tseng 4000), VGA/EM-16, VGA/EM-16 Plus
; Tseng Labs EVA board w/132-col kit installed
; Tseng Labs UltraPAK mono/Herc board w/132 column modes.
; Tseng Labs ET4000 SVGA.
; VESA compatible Bios'.
; Video 7 Vega Deluxe w/ 132X25.COM driver installed and VGA board.
; The routine checks for the presence of a 132-column-capable adapter. If
; one is found its handler executes the desired mode setting and returns
; carry clear; it returns carry set otherwise.
; Adding new boards - place an identification string in the data segment,
; construct a mode setting routine and insert it in the call list below
; (setting 132 column mode is byte AL non-zero). Byte AH is non-zero to
; avoid saving old screen and running scrini; it is used to set the screen
; width when starting/exiting Connect mode
;
chgdsp proc near
ifndef no_graphics
or al,al ; 80 column mode?
jnz chgdsg1 ; nz = no, want 132 cols
test tekflg,tek_active ; graphics mode active?
jz chgdsp_start ; z = no
push ax
push dx
call tekend ; exit special graphics
call scrmod ; update video mode info
pop dx
pop ax
jmp short chgdsp_start ; set 80 col mode
chgdsg1:test vtemu.vtflgop,vscompress ; allowed to use graphics for it?
jnz chgdsp_start ; nz = no, use 132 column text mode
cmp tekflg,tek_active+tek_sg ; special graphics mode active?
je chgdsg3 ; e = yes, no change needed
mov cl,byte ptr low_rgt+1 ; examine whole screen
add cl,2 ; lines in emulation part + status
xor ch,ch
xor bx,bx
chgdsg2:or dgwindcomp[bx],1 ; set compressed mode flag non-zero
inc bx
loop chgdsg2
call dgsettek ; setup special graphics mode
chgdsg3:mov byte ptr low_rgt,131 ; 132 columns in special graphics
mov crt_cols,128 ; but 128 physical columns
ret
endif ; no_graphics
chgdsp_start:
push es ; save all we use
push ax
push bx
push cx
push dx
push si
push di
mov temp,ax ; save set/reset flag from msz
mov ax,sp ; do push sp test for XT vs AT/386
push sp ; XT pushes sp-2, AT's push old sp
pop cx ; recover pushed value, clean stack
xor ax,cx ; same?
jne chgdspnw ; ne = no, XT. Don't do Int 2fh
test tv_mode,10h ; DESQview active?
jz chgdspndv ; z = no
jmp chgdsx1 ; exit without screen change
chgdspndv:
cmp vchgmode,1 ; change permissions, disabled?
je chgdspnw ; e = 1 = disabled
mov ax,1683h ; Windows 3, get current virt machine
int 2fh
cmp ax,1683h ; virtual machine, if any
je chgdspok ; e = none
cmp vchgmode,2 ; DOS-only (2)?
jne chgdspok ; ne = no
chgdspnw:jmp chgdsx1 ; exit without screen change
chgdspok:mov ax,temp
cmp crt_cols,80 ; are we narrow?
jbe chgds3 ; be = narrow width now
or al,al ; resetting to narrow width?
jz chgds4 ; z = yes, do it
jmp chgdsx1 ; else we are there now
chgds3: or al,al ; resetting to narrow width?
jnz chgds4 ; nz = no, setting to wide
jmp chgdsx1 ; narrow width, we are there now
chgds4: or ah,ah ; are we connected now?
jnz chgds0 ; nz = no, skip flow control etc
mov ah,flowoff ; get xoff
or ah,ah ; flow control?
jz chgds4a ; z = none
call foutchr ; send it
chgds4a:cmp byte ptr temp+1,0 ; exiting Connect mode?
jne chgds0 ; ne = yes
mov ax,200 ; wait 200 millisec before video tests
call pcwait ; so don't mix screen and port intrpts
chgds0: call ckteva ; try Tseng Labs EVA
jnc chgds1 ; nc = found
call ckstbv ; try STB VEGA/EM
jnc chgds1 ; nc = found
call ckv7vd ; try Video 7 EGA Deluxe and VGA
jnc chgds1 ; nc = found
call ckatiw ; try ATI EGA Wonder
jnc chgds1 ; nc = found
call ckevrx ; try Everex Micro Enhancer Deluxe
jnc chgds1 ; nc = found
call ckevga ; try Everex EVGA-673
jnc chgds1 ; nc = found
call ckatt ; ATT boards
jnc chgds1 ; nc = found
call chkpa ; Paradise EGA/VGA boards
jnc chgds1 ; nc = found
call chkvesa ; VESA compatibles
jnc chgds1 ; nc = found
call ckxga ; IBM XGA
jnc chgds1 ; nc = found
mov si,offset cols80 ; name of 80 column file
cmp byte ptr temp,0 ; setting 80 cols?
je chgdsx2 ; e = yes
mov si,offset cols132 ; use 132 column file
chgdsx2:mov di,offset decbuf ; a temp buffer for path= usage
call strcpy
mov ax,di ; spath wants ptr in ax
call fspath
jc chgdsx ; c = file not found
mov si,ax ; crun wants ptr in si
call fcrun ; run the batch file, si = filespec
call fserini ; reengage serial port, mode changes
mov ax,0c06h ; clear kbd buffer and do function
mov dl,0ffh ; console input
int dos ; discard character(s)
; Perform mode change
chgds1: cmp byte ptr temp+1,0 ; do without serial port xon/xoff?
jne chgdsx1 ; ne = yes
cmp flags.modflg,1 ; is mode line enabled?
jbe chgdsx ; be = yes, and off or locally owned
mov flags.modflg,1 ; remove foreign ownership
chgdsx: mov ah,flowon ; get flow-on byte
or ah,ah ; using flow control?
jz chgdsx1 ; z = no
call foutchr ; send it
chgdsx1:mov al,crt_lins ; previous conditions
mov ah,crt_cols
push ax
call scrmod ; pick up current screen size
pop ax
ifndef no_tcp
cmp al,crt_lins ; screen size change?
jne chgdsx1a ; ne = yes
cmp ah,crt_cols
je chgdsx1b ; no
chgdsx1a:call winupdate ; window update req for TCP/IP Telnet
chgdsx1b:
endif ; no_tcp
pop di ; restore what we saved
pop si
pop dx
pop cx
pop bx
pop ax
pop es
ret ; return to caller
; Individual tests for various 132-column boards
; Tseng LABS EVA, UltraPAK, ET4000
ckteva: mov ax,0c000h ; seg addr for EVA
mov es,ax ; set into es register
mov di,76h ; offset of board's string
lea si,tsngid ; validation string
mov cx,tsnglen ; length of validiation string
cld
repe cmpsb ; compare strings
je ckteva2 ; e = strings match
mov ax,4d00h ; check for UltraPAK mono driver
int screen
cmp ax,5aa5h ; driver signature?
jne ckteva4 ; ne = no
mov ax,7 ; default to mono (7) for this board
cmp byte ptr temp,0 ; setting 132 columns?
je ckteva1 ; e = resetting to normal
mov ax,18h ; set to 132 cols (Set Mode 18H)
ckteva1:int screen
clc ; carry clear means success
ret
; an EVA board - check for 132 col kit
ckteva2:cmp byte ptr es:099h,0 ; check 132 col kit installed
jne catfnd ; ne = installed, do the mode change
ckteva3:stc ; indicate adapter not present
ret ; and exit
ckteva4:mov dx,03cdh ; ET4000 test
in al,dx ; Segment Select Register, get value
push ax
xor al,15h ; create test condition
jmp $+2
jmp $+2
out dx,al ; set condition
jmp $+2
jmp $+2
mov ah,al ; save condition
in al,dx ; get new condition
jmp $+2
jmp $+2
cmp ah,al ; did it work (same)?
pop ax
out dx,al ; restore original condition
jne ckteva3 ; ne = no, ET4000 not present
mov ax,3 ; default to cga 3
cmp byte ptr temp,0 ; setting 132 columns?
je ckteva5 ; e = resetting to normal
mov ax,23h ; set to 132 cols (Set Mode 23H)
ckteva5:int screen
clc
ret
;
ckstbv: mov ax,0c000h ; STB's VGA/EM, VGA/EM-16, EM-16 Plus
mov es,ax ;
mov di,70h ; where to look for signature
lea si,stbvid ; the signature
mov cx,stbvlen ;
cld ;
repe cmpsb ; test
je catfnd ; e = found
mov di,70h ; where to look for signature
lea si,stavid ; the signature
mov cx,stavlen
cld
repe cmpsb ; test
je catfnd ; e = found
stc ; else say not there
ret ;
; ATI EGA Wonder
ckatiw: mov ax,0c000h ; seg addr for EGA Wonder
mov es,ax ; set into es register
mov di,012fh ; offset of message in ROM
lea si,atiwid ; offset of message here
mov cx,atilen ; length of validation string
cld
repe cmpsb ; compare strings
je catfnd ; e = they match
lea si,atiwid2 ; alternative signature
mov di,30h ; start at this offset
mov cx,atilen2 ; alternative signature length
mov ax,es:[di] ; get first two bytes
cmp al,atiwid2 ; string starts here?
je ckatiw1 ; e = yes
inc di ; try next location, just in case
cmp ah,atiwid2 ; or here?
je ckatiw1 ; e = yes
stc ; strings differ
ret
ckatiw1:repe cmpsb ; check the whole string
je catfnd ; e = matches the whole thing
stc ; fail on mismatch
ret
catfnd: mov ax,0003h ; prepare to reset video mode
cmp byte ptr temp,0 ; are we setting or resetting?
je catfnd1 ; e is reset, exit
mov ax,0023h ; set to 132 cols (Set Mode 23H)
catfnd1:int screen
clc ; carry clear means success
ret
chkpa: mov ax,0c000h ; load Paradise ROM BIOS address
mov es,ax
mov ax,0057h ; assume 132x25 mono display needed
mov di,0009h ; load EGA board identifier index
lea si,pmega1 ; Paradise Autoswitch Mono ident
mov cx,pmegal1
cld
repe cmpsb ; do identification strings match?
je chgpa2 ; e = yes, check num of display lines
mov di,007dh ; no, load VGA board identifier index
lea si,p30id ; Paradise VGA, other flavors
mov cx,p30ln
repe cmpsb ; do identification strings match?
je chgpa1 ; e = yes, check for color mode
stc ; fail
ret
chgpa1: cmp crt_norm,3 ; is the "normal" screen in color?
ja chgpa2 ; a = no, orig assumption is correct
mov ax,0055h ; assume 132x25 color required
chgpa2: cmp crt_lins,25 ; is the "normal" screen 25 lines?
jna chgpa3 ; na = yes, check num of cols needed
dec ax ; change assumption to 132x43
chgpa3: cmp byte ptr temp,0 ; switching to a 132 column mode?
jne chgpa4 ; ne = yes
mov al,crt_norm ; load "normal" display mode
chgpa4: int screen ; issue BIOS call to change display
clc ; success
ret
; Video 7 Vega Deluxe
ckv7vd: mov ax,0c000h ; seg addr for Vega rom bios
mov es,ax ; set into es register
mov di,002ah ; offset of message in ROM
lea si,vid7id ; offset of message here
mov cx,vid7len
cld
repe cmpsb ; compare strings
je cnv7fn1 ; e = same
mov di,002ah ; offset of ident string
mov si,offset vid7id2 ; Video 7 VGA board
mov cx,vid7len2
repe cmpsb
je cnv7fn2 ; e = found
cnv7fx: stc ; strings are different
ret
;
cnv7fn1:test byte ptr es:[03ffeh],1 ; is this a 'Deluxe' Vega?
jz cnv7fx ; z = nope, can't do it
mov ah,35h ; DOS Get Vector
mov al,10h ; Bios video interrupt
int dos ; get it into es:bx
mov di,bx ; es:bx is returned int 10h entry pnt
sub di,5ah ; back offset to msg in 132X25.COM
lea si,vid7id ; offset of validation message
mov cx,vid7len ; length of validation string
cld
repe cmpsb ; Look for repeat of msg by 132X25.COM
jne cnv7fn2 ; if different
mov al,crt_mode ; prepare to reset video mode
xor ah,ah
cmp byte ptr temp,0 ; are we setting or resetting?
je cnv7fn2a ; e is reset
mov ax,0000h ; set to 132 cols (old 40x25)
cnv7fn1a:int screen
clc
ret
cnv7fn2:mov ax,6f00h ; check for VegaBios driver
int screen
cmp bx,'V7' ; Video 7 Bios presence response
jne cnv7fx ; ne = not there
mov ax,6f01h ; al gets monitor type (mono,color,ega)
int screen
mov bx,51h ; presume mono 132x25, page 0
cmp crt_lins,42 ; 43 lines active?
jb cnv7fn2a ; b = no
inc bx ; use bx = 52h for 132x43
cnv7fn2a:
cmp al,10h ; analogue fixed freq (IBM 85xx)?
je cnv7fx ; e = yes, no 132 columns
cmp al,2 ; 1 = mono, 2 = color, above = ega
jb cnv7fn3 ; b = mono or unknown
mov bx,4fh ; presume med res color 132x25
je cnv7fn3 ; e = med res color, al = 2
mov bx,41h ; ega high res 132x25, enhanced mons
cmp crt_lins,42 ; 43 lines active?
jb cnv7fn3 ; b = no
inc bx ; use bx = 42h for 132x43
cnv7fn3:mov ax,6f05h ; set special mode found in bl
cmp byte ptr temp,0 ; resetting to 80 column mode?
jne cnv7fn4 ; ne = no, setting 132x25
mov al,crt_norm ; get normal mode
xor ah,ah ; set mode
cmp crt_lins,42 ; 43 lines active?
jb cnv7fn4 ; b = no
mov bl,40h ; use Video 7 mode 40h 80x43 for color
mov ax,6f05h ; and do special mode set
cnv7fn4:int screen ; special mode is in bl
mov ax,0f00h ; a nop screen bios command
int screen
clc
ret
ckevrx: mov ax,0c000h ; seg addr for Everex EV-659
mov es,ax ; set into es register
mov di,0047h ; offset of message in ROM
lea si,evrxid ; offset of message here
mov cx,evrxlen ; length of validation string
cld
repe cmpsb ; compare strings
jne ckfnr2 ; ne = strings differ
mov ah,crt_lins ; we recognize either 44 or 25 rows
cmp ah,43 ; equal to 44-1 rows?
jne ckfnr1 ; ne = no
mov ax,0070h ; Everex extended mode ident
mov bl,09h ; prepare to reset video mode to 80x44
cmp byte ptr temp,0 ; are we setting or resetting?
je ckfnr4 ; e is reset, exit
mov bl,0bh ; 132x44
int screen
clc
ret
ckfnr1: cmp ah,24 ; equal to 25-1 rows?
je ckfnr3 ; e = yes
ckfnr2: stc ; return failure
ret
ckfnr3: mov ax,0003h ; prepare to reset video mode
cmp byte ptr temp,0 ; are we setting or resetting?
je ckfnr4 ; e is reset, exit
mov ax,0070h ; Everex extended mode ident
mov bl,0ah ; 132x25
ckfnr4: int screen
clc
ret
ckevga: mov ax,0c000h ; Everex FVGA-673, EV-678 rom segment
mov es,ax
mov di,76h ; offset in rom for board's id string
lea si,evgid ; id string
mov cx,evglen ; length of id string
cld
repe cmpsb ; do they match?
je ckevg0 ; e = yes
mov di,9dh ; offset in ROM for board's ID string
lea si,evvid ; ID string
mov cx,evvlen ; length of ID string
cld
repe cmpsb ; do they match?
jne ckevg2 ; ne = no
ckevg0: mov ax,3 ; prepare to reset video mode
cmp byte ptr temp,0 ; setting or resetting mode?
je ckevg1 ; e = resetting, exit
mov ax,0070h ; mode for 132x25
mov bl,0ah ; Everex mode 0ah
ckevg1: int screen
clc
ret
ckevg2: stc ; say board not found
ret
; AT&T EGA/VGA boards
ckatt: mov ax,0c000h ; seg of first signature
mov es,ax
mov si,offset attvdc6 ; first pattern
mov di,35h ; test area
cld
mov cx,attvdlen ; length
repe cmpsb
je ckatt2 ; e = found
mov cx,attvdlen ; try second signature, same length
mov si,offset attvdc7
mov ax,0e000h ; seg of second signature
mov es,ax
mov di,10h ; test area
repe cmpsb
je ckatt2 ; e = found
stc ; not found
ret
ckatt2: mov al,crt_norm ; old mode
xor ah,ah
cmp byte ptr temp,0 ; resetting to 80 col?
je ckatt3 ; e = yes
mov ax,0055h ; 132 cols, set mode 55h
ckatt3: int screen
clc
ret
; VESA compatibles
chkvesa:mov di,seg rdbuf ; es:di is buffer for results
mov es,di
mov di,offset rdbuf
mov ax,4f00h ; get SVGA information
int screen
cmp ax,4fh ; success?
jne chkvesax ; ne = no
cmp word ptr rdbuf,'EV' ; 'VESA'
jne chkvesax ; ne = no
cmp word ptr rdbuf+2,'AS'
jne chkvesax ; ne = no
mov ax,4f01h ; get mode info to es:di buffer
mov cx,109h ; 109h is 132x25 text
int screen
cmp ax,4fh ; success?
jne chkvesax ; ne = no
mov bx,3 ; assume 80 columns
cmp byte ptr temp,0 ; setting or resetting mode?
je chkvesa2 ; e = resetting
mov bx,109h ; mode for 132x25
chkvesa2:mov ax,4f02h ; set mode from bx
int screen
cmp ax,4fh ; success?
jne chkvesax ; ne = no
clc ; say success
ret
chkvesax:stc ; say failure
ret
; IBM XGA 132 columns
ckxga: push bp ; (old BIOSes are still around)
push ds ; set es to data segment
pop es
mov ax,1b00h ; get functionality table
xor bx,bx
mov di,offset decbuf ; es:di is 64 bytes of workspace
int screen
cmp al,1bh ; is this call supported?
jne ckxgax ; ne = no, fail
les bx,dword ptr decbuf ; get the address of the modes info
test byte ptr es:[bx+2],10h ; is mode 14h supported?
jz ckxman ; z = no, try manual method for now
mov ax,3 ; assume resetting to mode 3, 80x25
cmp byte ptr temp,0 ; setting 132 columns?
je ckxga1 ; e = no, resetting to 80 columns
mov ax,14h ; invoke IBM XGA mode 14h, 132x25
ckxga1: int screen
ckxga2: pop bp
clc ; say success
ret
ckxgax: pop bp
mov xga_reg_base,-2 ; flag saying no XGA Adapter found
stc ; say failure
ret
ckxman: call xgaman ; do tests/sets manually
pop bp
jnc ckxman1 ; nc = success
mov xga_reg_base,-2 ; flag saying no XGA Adapter found
ckxman1:ret
chgdsp endp
; XGA mode setting via going to the hardware manually
; Code furnished by Bert Tyler, National Institue of Health
xgaman proc near
cmp xga_reg_base,-2 ; has the XGA detector already failed?
je xgafail ; e = yes, fail again
cmp xga_reg_base,-1 ; have we already found the XGA?
je xga_loc ; e = no
jmp xga_do1 ; yes, process it
xga_loc:push es
mov ah,35h ; DOS get interrupt vector
mov al,15h ; Int 15h
int dos ; returns vector in es:bx
mov ax,es ; segment part
pop es
or ax,ax ; undefined vector?
jz xgafail ; z = yes
mov dx,-1 ; start with an invalid POS address
mov ax,0c400h ; look for POS base address
int 15h ; (Microchannel machines only)
jc xgafail ; c = error, not a MC machine
mov xgatmp1,dx ; save pos_base_address
xor cx,cx ; check all MCA slots & motherboard
cmp dx,-1 ; do we have a good POS?
jne xga_lp1 ; ne = yes, proceed with MCA checks
xgafail:stc ; fail
ret
xga_lp1:cli ; no interrupts, please
cmp cx,0 ; treat the motherboard differently?
jne xga_sk4 ; ne = yes
mov al,0dfh ; enable the motherboard for setup
mov dx,94h
out dx,al
jmp short xga_sk5
xga_sk4:mov ax,0c401h ; enable an MCA slot for setup
mov bx,cx ; this slot
int 15h
xga_sk5:mov dx,xgatmp1 ; get pos record for the slot
in ax,dx ; ID
mov xgatmp2,ax
add dx,2 ; compute IO Res Base
in al,dx ; get POS data byte1
and ax,0eh ; muck about with it to get reg base
shl ax,1
shl ax,1
shl ax,1
add ax,2100h
mov xga_reg_base,ax
cmp cx,0 ; treat the motherboard differently?
jne xga_sk6 ; ne = yes
mov al,0ffh ; enable the motherboard for normal
out 094h,al
jmp short xga_sk7
xga_sk6:mov ax,0c402h ; enable the MCA slot for normal
mov bx,cx ; this slot
int 15h
xga_sk7:sti ; interrupts on again
mov ax,xgatmp2 ; is an XGA adapter on this slot?
cmp ax,08fd8h
jae xga_sk8 ; ae = yes
jmp xga_lp2 ; try another slot
xga_sk8:cmp ax,08fdbh ; still within range?
jbe xga_sk9 ; be = yes
jmp xga_lp2 ; no, try another slot
xga_sk9:mov dx,xga_reg_base ; is there a monitor on this slot?
add dx,0ah
mov al,052h
out dx,al
mov dx,xga_reg_base
add dx,0bh
in al,dx
and al,0fh
cmp al,0fh
jne xga_ska ; ne = yes
jmp xga_lp2 ; no
xga_ska:mov dx,xga_reg_base ; is this XGA in VGA mode?
in al,dx
test al,1
jnz xga_do1 ; nz = yes, found it!
xga_lp2:inc cx ; try another adapter?
cmp cx,9 ; done all slots?
ja xga_no ; a = yes
jmp xga_lp1 ; no, try another slot
xga_no: jmp xgafail ; fail
; *finally* put the XGA into 132-column or 80-column mode
xga_do1:cmp byte ptr temp,0 ; setting 80-column mode?
jne xga_do2 ; ne = no, 132 columns
jmp xga_do3 ; do 80 column mode
; 132-column mode routine
xga_do2:mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,1550h
out dx,ax
mov ax,1450h
out dx,ax
mov ax,0454h
out dx,ax
mov ax,1202h ; select 400 scan lines
mov bl,30h
int screen
mov ax,0+3 ; set video mode 3
int screen
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov al,50h
out dx,al
inc dx
in al,dx
or al,1
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov al,50h
out dx,al
inc dx
in al,dx
and al,0fdh
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov al,50h
out dx,al
inc dx
in al,dx
and al,0fch
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
mov al,3
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,0154h
out dx,ax
mov ax,8070h
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov al,50h
out dx,al
inc dx
in al,dx
and al,0efh
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,11h
out dx,al
inc dx
in al,dx
and al,7fh
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,0
out dx,al
inc dx
mov ax,0a4h
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,1
out dx,al
inc dx
mov ax,83h
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,2
out dx,al
inc dx
mov ax,84h
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,3
out dx,al
inc dx
mov ax,83h
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,4
out dx,al
inc dx
mov ax,90h
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,5
out dx,al
inc dx
mov ax,80h
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,0a31ah
out dx,ax
mov ax,001bh
out dx,ax
mov dx,03d4h ; (the manual doesn't explain...)
mov ax,13h
out dx,al
inc dx
mov ax,42h
out dx,al
mov dx,03d4h ; (the manual doesn't explain...)
mov al,11h
out dx,al
inc dx
in al,dx
or al,80h
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov al,50h
out dx,al
inc dx
in al,dx
or al,3
out dx,al
mov dx,03c4h ; (the manual doesn't explain...)
mov ax,1
out dx,al
inc dx
in al,dx
or al,1
out dx,al
mov dx,03dah ; (the manual doesn't explain...)
in al,dx
mov dx,003c0h ; (the manual doesn't explain...)
mov al,13h
out dx,al
xor al,al
out dx,al
mov al,20h
out dx,al
mov ax,40h ; tell the BIOS we have 132 columns
mov es,ax
mov byte ptr es:[4ah],132 ; set Bios screen width data area
clc ; return success
ret
; Set 80 column mode
xga_do3:mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,01h
xor al,al
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,4
xor al,al
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,5
mov al,0ffh
out dx,al
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,0ff64h
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,1550h
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,1450h
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,0051h
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,0454h
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,7f70h
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
add dx,0ah
mov ax,202ah
out dx,ax
mov dx,xga_reg_base ; (the manual doesn't explain...)
;; add dx,00h
mov al,1
out dx,al
mov dx,03c3h ; (the manual doesn't explain...)
mov al,1
out dx,al
mov ax,1202h ; select 400 scan lines
mov bl,30h
int screen
mov ax,0+3 ; set video mode 3
int screen
clc ; return success
ret
xgaman 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
push bx
push di
mov di,500 ; 500 Hertz
mov bx,1 ; For 1 millisecond
call vtsound ; Do it
pop di ; Restore the ACs
pop bx
vclick1:ret
vclick endp
endif ; no_terminal
; Routine to do VT100-style bell, no arguments
fvtbell proc far
call vtbell
ret
fvtbell endp
vtbell proc near
cmp belltype,1 ; visual bell?
je vtbell1 ; e = yes
ja vtbell2 ; a = no bell
push di ; audible bell
push bx
mov di,880 ; 880 Hertz
mov bx,40 ; For 40 ms
call vtsound ; Do it
pop bx
pop di
ret
vtbell1:
ifndef no_terminal
call revscn ; reverse screen
push ax
mov ax,40 ; for 40 milliseconds
call pcwait
pop ax
call revscn ; put back
endif ; no_terminal
vtbell2:ret
vtbell endp
; Routine to make noise of arbitrary frequency for arbitrary duration.
; Similar to routine (with typo removed) in "IBM PC Assembly Language:
; A Guide for Programmers", Leo J. Scanlon, 1983 Robert J. Brady Co.,
; Bowie, MD., page 270. Modified by J R Doupnik to use 0.1 millsec interval.
; Call: di/ frequency in Hertz.
; bx/ duration in 1 millisecond units
vtsound proc near
push ax ; save regs
push cx
push dx
mov al,0B6H ; write timer mode register
out 43H,al
mov dx,14H ; timer divisor is
mov ax,4F38H ; 1331000/frequency
div di
out 42H,al ; write timer 2 count low byte
mov al,ah
out 42H,al ; write timer 2 count high byte
in al,61H ; get current port B setting
or al,3 ; turn speaker on
out 61H,al
mov ax,bx ; number of milliseconds to wait
call pcwait ; do the calibrated wait
in al,61H ; get current port B setting
and al,0fch ; turn off speaker and timer
out 61H,al
pop dx ; restore regs
pop cx
pop ax
ret
vtsound endp
code1 ends
end