home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
msr313src.tar.gz
/
msr313src.tar
/
msytip.asm
< prev
next >
Wrap
Assembly Source File
|
1988-08-16
|
43KB
|
980 lines
REVLVL equ 5 ;Revision level 6-25-85
;=============================================================================
;
; MSYTIPRO.ASM This file contains system dependent terminal emulation routines
; for the H19 and Tektronix 4010 terminals.
;
; NOTE: ESC Z and ANSI mode don't work.
;
; Credits: Dan Smith Computing Center (303) 273-3396
; Colorado School of Mines
; Golden, Colorado 80241
; Joe Smith, now at TYMSHARE, 39100 Liberty St, Fremont CA 94538
;
;
; The following H19 escape codes are supported:
;
; Esc H Cursor home Esc L Insert line
; Esc C Cursor forward Esc M Delete line
; Esc D Cursor backward Esc N Delete character
; Esc B Cursor down Esc O Exit insert mode
; Esc A Cursor up Esc @ Enter insert mode
; Esc I Reverse index Esc p Enter reverse video mode
; Esc Y Direct cursor addressing Esc q Exit reverse video mode
; Esc E Clear display Esc j Save cursor position
; Esc J Erase to end of page Esc k Restore cursor position
; Esc K Erase to end of line
; Esc x4 Set block cursor Esc Z Identify as VT52
; Esc y4 Set underscore cursor
;
; The following H19 codes are not supported:
;
; Esc n Cursor position report Esc < Enter ANSI mode
; Esc b Erase beginning of display Esc [ Enter hold screen mode
; Esc l Erase entire line Esc \ Exit hold screen mode
; Esc o Erase beginning of line Esc F Enter graphics mode
; Esc z Reset to power up config. Esc G Exit graphics mode
; Esc r ? Modify baud rate Esc t Enter keypad shifted mode
; Esc x 1-3 Set modes 1 through 3 Esc u Exit keypad shifted mode
; Esc x 5-9 Set modes 5 through 9 Esc = Enter alt keypad mode
; Esc y 1-3 Reset modes 1 through 3 Esc > Exit alt keypad mode
; Esc y 5-9 Reset modes 5 through 9 Esc } Keyboard disable
; Esc v Wrap around at end of line Esc { Keyboard enable
; Esc w Discard at end of line Esc ] Transmit 25th line
; Esc Z Identify as H-19 Esc # transmit page
;
;=============================================================================
include mssdef.h
datas segment public 'datas'
extrn flags:byte
tekflag db 0 ;Flag for ESCape sequences
visible db 0 ;0 to move, 1 to draw a line
tek_hiy dw 0 ;Y coordinate in Tektronix mode
tek_loy db 0
tek_hix dw 0
tek_lox db 0
tek_lsb db 0 ; Low-order 2 bits of X + low Y (4014 mode)
arrtab db 48h,'A' ;Up arrow
db 50h,'B' ;Down arrow
db 4bh,'D' ;Left arrow
db 4dh,'C' ;Right arrow
arrtabl equ ($-arrtab) / 2 ;Number of keys in arrtab
spctab db 27,13,10,08,09,07,29,12
lspctab equ $-spctab
spcjmp dw outesc,outcr,outlf,outbs,outtab,beep,tekini,ffeed
esctab db 'YABCDEHIJKLMNO@pqjkxy' ;Recognized escape codes
db 'Z',12,1ah
lesctab equ $-esctab
escjmp dw movcur,curup,curdwn,currt ;Escape code routines. This
dw outbs,clrscr,curhom,revind ;array must parallel the codes
dw clreow,clreol,inslin,dellin ;listed above.
dw delchr,noins,entins,invvid
dw nrmvid,savecur,restcur,setm,resetm
dw sendid,escff,xhair
argadr dw 0
escchar db 0
videobuf dw 0de00h
ttstate dw 0
wcoord db 0
savrow db 0
insmod db 0
cursor dw 0
oldcur dw 0
xmult dw 9 ;Scale TEK to TI by 9/13
xdiv dw 13 ;so that 0-1023 converts to 0-708
ymult dw 5 ;Scale TEK to TI by 5/13
ydiv dw 13 ;so that 0-779 converts to 299-0
ybot dw 299 ;Bottom of screen is Y=299
oldx dw 0 ;Previous scaled coordinates
oldy dw 0
grseg dw 0
datas ends
code segment public
assume cs:code,ds:datas
extrn beep:near, prtchr:near, outchr:near
public term
;=============================================================================
; Main entry point for Tektronix 4010 - Heathkit H19 terminal emulation.
;=============================================================================
db 'term'
term proc near
mov argadr,ax ;Save address of argument block
call termini
term10: call inport ;Input from modem
jnc term20 ;No input available; Check keyboard
call outtty ;Print on terminal
term20: mov ah,1 ;See if a character has been typed
int 4ah ; on keyboard
jz term10 ;Jump if not
xor ah,ah ;Read char from keyboard buffer
int 4ah
cmp al,escchar ;See if the Esc character (^])
jz term30 ;Jump if it is
call outport ;Send character out comm port
jmp short term20 ;Make sure KB buffer doesnt overrun
term30: call termend
ret
term endp
;=============================================================================
; TERMINI Subroutine to initialize the terminal before starting emulation
;=============================================================================
termini proc near
mov bx,argadr ;Save escape char in local storage
mov al,[bx].escc
mov escchar,al
mov grseg,0d000h ;Assume green on a 3 plane system
int 4fh ;Get system configuration
test ax,4000h ;See if graphics plane 3 exists
jnz ti10 ;Jump if it does
mov grseg,0c000h ;Reset to plane 1 for a 1 plane system
ti10: mov ttstate,offset nstate
mov insmod,0 ;Turn off insert mode
mov ah,13h ;Necessary to clear screen in order to
int 49h ; get CRTC start address in sync with
mov word ptr cursor,0 ; cursor position for direct video
ret ; buffer access.
termini endp
;=============================================================================
; TERMEND Subroutine to clean up after terminal emulation.
;=============================================================================
termend proc near
;*; mov ah,13h ;Clear text screen
;*; int 49h
;*; mov ah,14h ;Clear graphics screen
;*; int 49h
ret
termend endp
;=============================================================================
; Routine to input a character from the modem port. If no character available
; this returns with the carry flag cleared. (NC)
;=============================================================================
inport proc near ;Input from the modem
call prtchr
jmp short ip10 ;Character available
nop ;Need 3 bytes
clc ;Indicate no character
ret
ip10: and al,7fh ;No parity here for terminal emulation
stc ;Indicate character available
ret
inport endp
;=============================================================================
; Subroutine to translate and send the character out the communication port
;=============================================================================
outport proc near
cmp flags.vtflg,1
jne op2 ;Jump if no Heath-19 emulation
or al,al
jz op5 ;Jump if a special key
op2: mov ah,al
jmp short op30
op5: mov cx,arrtabl ;Number of entries in translation table
mov si,offset arrtab ;Point to start of translation table
op10: cmp ah,[si]
jz op20 ;Jump if found key
add si,2 ;Point to next key scan code
loop op10
ret ;Scan code not found; don't send it
op20: mov ah,27
call outchr ;Send a leading escape char
nop ;Waste 3 bytes to ignore error
nop
nop
mov ah,[si+1] ;Get translated code value
op30: call outchr ;Output character in AH
nop ;Waste 3 bytes to ignore error
nop
nop
ret
outport endp
;=============================================================================
; Subroutine to send the character in AL to the screen. If Heath-19 emulation
; is on, the character will be interpreted according to H-19 and Tektronix 4010
; escape codes.
;=============================================================================
outtty proc near
cmp flags.vtflg,1
jne otty10 ;Jump if no Heath-19 emulation
mov dx,cursor ;These may need cursor...
cld ;Set here so its not required later
jmp ttstate ;Jump according to current state
otty10: mov dl,al ;Print char in al at cursor position
mov ah,2 ; using DOS
int 21h
ret
outtty endp
;=============================================================================
; Subroutine to process the character in AL according to the normal state
;=============================================================================
nstate proc near
cmp al,32 ;Special character?
jb conchar ;Yes, perform control char operation
cmp insmod,0 ;In insert mode?
je ns10 ;No, output normal
push ax ;Save character
call inschr ;Insert a blank in line
pop ax ;Restore character
ns10: jmp pchar ;Print char in AL
nstate endp
;=============================================================================
; Subroutine to handle the ASCII character below 32 in al
;=============================================================================
conchar proc near
mov di,offset spctab ;See if character is in table
mov cx,lspctab
repne scasb
jz cc10 ;Go process if it was
push ax ;Save char
mov al,'^'
call pchar ;Print caret
pop ax
add al,'A'-1 ;Make control character printable
jmp pchar ;Print, then return
cc10: sub di,offset spctab+1 ;Get index of char
shl di,1 ;Double for word offset
jmp spcjmp[di] ;And go handle
conchar endp
;=============================================================================
; special char routines. cursor is in dx, char in al
;=============================================================================
outlf proc near
inc dl ;Bump row
jmp setcur
outlf endp
outcr proc near
xor dh,dh ;Set col to 0
jmp setcur
outcr endp
outbs proc near
or dh,dh
jle setcur ;Col 0, can't back up
dec dh ;Back up col
jmp setcur ;And use if reasonable
outbs endp
outtab proc near
add dh,8 ;Tab is at most 8 columns
and dh,not 111b ;Round down to a multiple of 8
cmp dh,80 ;Out of range?
jb outta1 ;No, go set it
mov dh,80-1 ;Else just move to right margin
outta1: jmp setcur
outtab endp
outesc proc near
mov ttstate,offset estate ;Expect escape sequence.
ret
outesc endp
;=============================================================================
; Escape-char handling routines
;=============================================================================
estate proc near
mov ttstate,offset nstate ;Put state back to normal
mov di,offset esctab ;Escape char tbl
mov cx,lesctab ;Length of tbl
repne scasb ;Look for it in tbl
jz es10 ;Found, go use it
push ax
mov al,27 ;Output Esc character
call pchar
pop ax ;Output unrecognized escape code
jmp pchar
es10: sub di,offset esctab+1 ;Get offset into tbl
shl di,1 ;Convert to word offset
jmp escjmp[di] ;And go dispatch on it
estate endp
;=============================================================================
; Subroutine to print a character at the current cursor position and advance
; the cursor to the next position.
;=============================================================================
pchar proc near
push es ;Save ES
push ax ;Save char to print
mov dx,cursor ;Get row and column
call scrloc ;Map DX to ES:DI
pop ax ;Restore char to print
stosb ;Put into video buffer
pop es ;Restore segment
inc dh ;Bump col
jmp setcur ;Position cursor
pchar endp
;=============================================================================
; Subroutine to position the cursor. This routine will wrap lines and scroll
; the screen. The row is in DL, the column is in DH
;=============================================================================
setcur proc near
cmp dh,80 ;See if in range
jae sc20
cmp dl,24 ;Lines go from 0 to 23
jbe sc10 ;Not off end, keep going
push dx ;Save row/col
xor dx,dx
call dellin ;Scroll up one line by deleting top line
pop dx
mov dl,24 ;Go to bottom line again...
sc10: mov cursor,dx ;Save cursor pos
mov ah,2
int 49h ;Set cursor
sc20: ret
setcur endp
;=============================================================================
; Subroutine to move the cursor up and possibly scroll the screen down
;=============================================================================
revind proc near
cmp dl,0
jle rev10
dec dl ;back up a row
jmp setcur ;and go set cursor
rev10: xor dx,dx
jmp inslin ;Insert a line at top of screen
revind endp
;=============================================================================
; Subroutine to move the cursor up
;=============================================================================
curup proc near
cmp dl,0 ;w/in range?
jle curu10 ;no, skip this
dec dl ;else back up
curu10: jmp setcur ;and go set position
curup endp
;=============================================================================
; Subroutine to move the cursor down
;=============================================================================
curdwn proc near
inc dl
jmp setcur ;increment row (setcur can scroll!)
curdwn endp
;=============================================================================
; Subroutine to move the cursor 1 position to the right.
;=============================================================================
currt proc near
inc dh
jmp setcur
currt endp
;=============================================================================
; Subroutine to home cursor and clear screen
;=============================================================================
clrscr proc near
call curhom ;go home cursor
mov dx,cursor
jmp clreow ;then clear to end of window
clrscr endp
;=============================================================================
; Subroutine to home the cursor
;=============================================================================
curhom proc near
xor dx,dx ;move to 0,0
jmp setcur
curhom endp
;=============================================================================
; Subroutine to clear the screen from the cursor to the end of the window
;=============================================================================
clreow proc near
push es
call scrloc ;Map DX into ES:DI in the video buffer
mov cx,80*25 ;Number of chars on screen
sub cx,di ;Number from the cursor on
mov al,' ' ;Fill with blanks
rep stosb ;Fill screen
pop es
ret
clreow endp
;=============================================================================
; Subroutine to clear the screen from the cursor to the end of the line
;=============================================================================
clreol proc near
mov cx,80 ;Number of cols across screen
sub cl,dh ;Number from cursor on
jle eol10 ;Jump if past end
push es
call scrloc ;Map DX to ES:DI
mov al,' ' ;Fill end with blanks
rep stosb ;Blank end of line
pop es
eol10: ret
clreol endp
;=============================================================================
; Subroutine to insert a line at the row that the cursor is in.
;=============================================================================
inslin proc near
xor dh,dh ;Move to start of row
cmp dl,24
jae clreol ;Just clear bottom row
push ds
push es
call scrloc ;Map DX to ES:DI
mov ds,videobuf ;Set DS to video buffer
mov cx,24*80 ;Number of chars on screen
sub cx,di ;Number of chars past current row
push di ;Save current row address
mov di,25*80-1 ;Point to last char
mov si,24*80-1 ;Point 1 line up
std ;Auto decrement
rep movsb ;Move lines down
cld ;Auto increment
mov cx,80 ;Number of chars on original line
pop di ;Restore pointer to start of line
mov al,' ' ;Fill with blanks
rep stosb ;Blank line
pop es
pop ds
ret
inslin endp
;=============================================================================
; Subroutine to scroll the screen up over the current line
;=============================================================================
dellin proc near
xor dh,dh ;Move to start of row
cmp dl,24
jae clreol ;Just clear bottom row
push ds
push es
call scrloc ;Map DX to ES:DI
mov ds,videobuf ;Set DS to video buffer
mov cx,24*80 ;First char of last row
sub cx,di ;Number of chars past current row
mov si,di
add si,80 ;Source is one line down
rep movsb ;Move chars up
mov cx,80 ;Number of chars on last line
mov al,' ' ;Fill with blanks
rep stosb ;Blank line
pop es
pop ds
ret
dellin endp
;=============================================================================
; Subroutine to delete the current character by scrolling to the left
;=============================================================================
delchr proc near
push ds
push es
call scrloc ;Map dx to es:di
mov ds,videobuf
mov cx,79 ;Last char on line
sub cl,dh
jz dch20 ;Jump if on last char
mov si,di
inc si ;Source is 1 char to right
rep movsb ;Move chars to left
dch20: mov byte ptr [di],' '
pop es
pop ds
ret
delchr endp
;=============================================================================
; Subroutine to insert a character at the cursor position
;=============================================================================
inschr proc near
push ds
push es
mov cx,79 ;This is last col to move, +1 for length
sub cl,dh ;Compute distance to end
jle ichr20 ;Nothing to move...
mov dh,78 ;This is address of last col to move
call scrloc ;Compute pos
mov ds,videobuf
mov si,di
inc di ;Destination is one byte over...
std ;Remember to move us backwards
rep movsb ;Move chars to right
cld
ichr20: pop es
pop ds
ret
inschr endp
;=============================================================================
; Subroutine to turn off insert mode.
;=============================================================================
noins proc near
mov insmod,0 ;Turn off insert mode
ret
noins endp
;=============================================================================
; Subroutine to process ESC Y (The direct cursor addressing command)
;=============================================================================
movcur proc near
mov wcoord,0 ;Want two coordinates...
mov ttstate,offset cstate
ret
movcur endp
;=============================================================================
; Subroutine to get a coordinate
;=============================================================================
cstate proc near
sub al,32 ;Coordinates offset by 32
cmp wcoord,0 ;See if first coord already received
jnz cs10 ;Jump if it was
inc wcoord ;Indicate first was received
mov savrow,al ;Save first coordinate (row)
ret
cs10: mov ttstate,offset nstate ;Reset state
mov dh,al ;Put column in DH
mov dl,savrow ;Get saved row
jmp setcur ;Position cursor
cstate endp
;=============================================================================
; Subroutine to enter insert mode.
;=============================================================================
entins proc near
mov insmod,0ffh ;enter insert mode...
ret ;and return
entins endp
;=============================================================================
; Subroutine to enter inverse video mode
;=============================================================================
invvid proc near
ret
invvid endp
;=============================================================================
; Subroutine to exit inverse video mode
;=============================================================================
nrmvid proc near
ret
nrmvid endp
;=============================================================================
; Subroutine to handle the set mode command. Sequence = ESC x (1,2,3,4,5...)
;=============================================================================
setm proc near ;Here if ESC x entered
mov ttstate,offset mstate ;Wait for value
ret
mstate: mov ttstate,offset nstate ;Put state back to normal
cmp al,'4'
jz uscurs ;Set underscore cursor
push ax
mov al,27 ;Output Esc character
call pchar
mov al,'x' ;Output set mode character
call pchar
pop ax ;Output unrecognized mode code
jmp pchar
setm endp
;=============================================================================
; Subroutine to handle the reset mode command. Sequence = ESC y (1,2,3,4,5...)
;=============================================================================
resetm proc near ;Here if ESC y entered
mov ttstate,offset rstate ;Wait for value
ret
rstate: mov ttstate,offset nstate ;Put state back to normal
cmp al,'4'
jz blcurs ;Set block cursor
push ax
mov al,27 ;Output Esc character
call pchar
mov al,'x' ;Output set mode character
call pchar
pop ax ;Output unrecognized mode code
jmp pchar
resetm endp
;=============================================================================
; Subroutine to set the underscore cursor
;=============================================================================
uscurs proc near
mov cx,4a0bh
mov ah,1
int 49h
ret
uscurs endp
;=============================================================================
; Subroutine to set a block cursor
;=============================================================================
blcurs proc near
mov cx,400bh
mov ah,1
int 49h
ret
blcurs endp
;=============================================================================
; save cursor in DX
;=============================================================================
savecur proc near
mov oldcur,dx
ret
savecur endp
;=============================================================================
; restore cursor onto screen
;=============================================================================
restcur proc near
mov dx,oldcur
jmp setcur
restcur endp
;=============================================================================
; Computes screen location to es:di, given col and row in dx.
; Trashes ax,bx
;=============================================================================
scrloc proc near
mov al,dl ;Get row
xor ah,ah
shl ax,1 ;Row * 2
mov bx,ax
shl ax,1 ;Row * 4
shl ax,1 ;Row * 8
add ax,bx ;Row * 10
shl ax,1 ;Row * 20
shl ax,1 ;Row * 40
shl ax,1 ;Row * 80
add al,dh
adc ah,0
mov di,ax
mov es,videobuf
ret
scrloc endp
;=============================================================================
;
; 12-Dec-84 Joe Smith, CSM Computing Center, Golden CO 80401
;
; Description of Tektronix commands
;
; ESCAPE-CONTROL-E (ENQ) requests a status report
; ESCAPE-FORMFEED erases the screen.
; ESCAPE-CONTROL-Z turns on the crosshairs (not on 4006 or 4025)
; ESCAPE-A-E enables the interactive plotter
; ESCAPE-A-F turns off the interactive plotter
; ESCAPE-M-L-2 Selects color 2 for drawing lines on 4113
; ESCAPE-M-T-: Selects color 10 for drawing text on 4113
; CONTROL-] (GS) turns on plot mode, the first move will be with beam off.
; CONTROL-UNDERLINE (US) turns off plot mode. (CR also works for all but 4025.)
; CONTROL-X switches HDSGVT from TEKTRONIX mode to NORMAL alpha mode.
;
; The plot commands are characters which specify the absolute position to move
; the beam. All moves except the one immediately after the GS character
; (Control-]) are with a visible trace.
;
; For 4010-like devices - The positions are from 0 to 1023 for both X and Y,
; altho only 0 to 780 are visible for Y due to screen geometry. The screen is
; 10.23 by 7.80 inches, and coordinates are sent as 1 to 4 characters.
;
; For 4014-like devices - The positions are from 0 to 4096, but each movement
; is a multiple of 4 positions unless the high-resolution LSBXY are sent. This
; makes it compatible w/the 4010 in that a full sized plot fills the screen.
;
; HIX,HIY = High-order 5 bits of position
; LOX,LOY = Middle-order 5 bits of position
; LSBXY = Low-order 2 bits of X + low-order 2 bits of Y (4014 mode)
;
; Hi Y Lo Y Hi X LSBXY Characters sent (Lo-X always sent)
; ---- ---- ---- ----- ----------------------------------
; Same Same Same Same Lo-X
; Same Same Same Diff LSB, Lo-Y, Lo-X 4014
; Same Same Diff Same Lo-Y, Hi-X, Lo-X
; Same Same Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
; Same Diff Same Same Lo-Y, Lo-X
; Same Diff Same Diff LSB, Lo-Y, Lo-X 4014
; Same Diff Diff Same Lo-Y, Hi-X, Lo-X
; Same Diff Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
; Diff Same Same Same Hi-Y, Lo-X
; Diff Same Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
; Diff Same Diff Same Hi-Y, Lo-Y, Hi-X, Lo-X
; Diff Same Diff Diff Hi-Y, LSB, Lo-Y, Hi-X, Lo-X 4014
; Diff Diff Same Same Hi-Y, Lo-Y, Lo-X
; Diff Diff Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
; Diff Diff Diff Same Hi-y, Lo-Y, Hi-X, Lo-X
; Diff Diff Diff Diff Hi-y, LSB, Lo-Y, Hi-X, Lo-X 4014
; Offset for byte: 40 140 140 40 100
;
; Note that LO-Y must be sent if HI-X has changed so the TEKTRONIX knows that
; the HI-X byte (in the range of 40-77 octal) is HI-X and not HI-Y. LO-Y must
; also be sent if LSBXY has changed, so that the 4010 will ignore LSBXY and
; accept LO-Y. The LSBXY byte is 140 + MARGIN*20 + LSBY*4 + LSBX. (MARGIN=0)
;
;============================================================================
;============================================================================
; Subroutine to initialize tektronix emulation. Called when GS char received
;============================================================================
tekini proc near
mov visible,0 ;Next move is invisible
mov tekflag,1
mov ttstate,offset xystate ;Go to ystate next
ret
tekini endp
;============================================================================
; Subroutine to clear the graphics screen. Called when a Form feed is received
;============================================================================
ffeed proc near
mov ah,14h ;Clear only graphics (not text)
int 49h
ret
ffeed endp
;============================================================================
; Subroutine to clear the graphics and the text screen. Called if Esc FF rec.
;============================================================================
escff proc near
mov ah,13h ;Erase both text and graphics screen
int 49h
mov ah,14h
int 49h
mov ttstate,offset nstate
ret
escff endp
;=============================================================================
; Subroutine to send an identification code back. (Esc Z)
;=============================================================================
sendid proc near
mov al,esc
call outport
mov al,'\'
call outport
mov al,'K'
call outport
mov ttstate,offset nstate
ret
sendid endp
;=============================================================================
; Subroutine to turn on the crosshairs. (Esc ^Z)
;=============================================================================
xhair proc near
mov ttstate,offset nstate
ret
xhair endp
;=============================================================================
; Subroutine to extract the X,Y coordinates for Tektronix emulation.
; Expecting HIY because LOX was seen tekflag = 1
; Expecting HIX because LOY was seen tekflag = 0
; Written by Joe Smith, CSM
;=============================================================================
xystate proc near
cmp al,29 ;Process Pen up command
jz tekini
cmp al,13 ;Exit graphics mode on CR,LF,US
je go2text
cmp al,10
je go2text
cmp al,1fh
je go2text
cmp al,18h
je go2text
cmp al,20h ;Control char?
jl tek20 ;Ignore it
cmp al,40h
jl tek30 ;20-3F are HIX or HIY
cmp al,60h ;40-5F are LOX (causes beam movement)
jl tek50 ;60-7F are LOY
;Extract low-order 5 bits of Y coordinate, set ESCFLAG=6
mov ah,tek_loy ;Copy previous LOY to MSB (in case 4014)
mov tek_lsb,ah
and al,1Fh ;LOY is 5 bits
mov tek_loy,al
cmp tekflag,0 ;2nd LOY in a row?
je tek20 ;Yes, then LSB is valid
mov tek_lsb,0 ;1st one, clear LSB
mov tekflag,0 ;LOY seen, expect HIX (instead of HIY)
tek20: ret
;Extract high-order 5 bits (X or Y, depending on ESCFLAG)
tek30: and ax,1Fh ;Just 5 bits
mov cl,5
shl ax,cl ;Shift over 5 bits
cmp tekflag,1 ;Looking for HIY?
jne tek40 ;No, HIX
mov tek_hiy,ax ;Yes, this byte has HIY
ret ;Keep ESCFLAG=4
tek40: mov tek_hix,ax ;This byte has HIX (because ESCFLAG=6)
mov tekflag,1 ;Reset to look for HIY next time
ret
;Extract low-order X, do beam movement
tek50: and al,1Fh ;Just 5 bits
mov tek_lox,al
mov ax,tek_hix ;Combine HIX*32
or al,tek_lox ;with LOX
mov bx,tek_hiy ;Same for Y
or bl,tek_loy
mov cl,visible ;0=move, 1=draw
call tekdraw
go2visi:mov visible,1 ;Next movement is with a visible trace
mov tekflag,1 ;Reset to look for HIY next time
ret
go2text:mov ttstate,offset nstate
ret
xystate endp
;=============================================================================
;
; Routine to draw a line on the screen, using TEKTRONIX coordinates.
; X coordinate in AX, 0=left edge of screen, 1023=right edge of screen.
; Y coordinate in BX, 0=bottom of screen, 779=top of screen.
; Visiblity flag in CL, 0=move invisible, 1=draw a line.
;
; The TI-PRO has (719,299) as the coordinate of the lower-right corner.
; Calculate endpoint X=(9/13)*(HIX*32+LOX), Y=299-(5/13)*(HIY*32+LOY)
;
; The IBM-PC has (639,199) as the coordinate of the lower-right corner.
; Calculate endpoint X=(12/20)*(HIX*32+LOX), Y=199-(5/20)*(HIY*32+LOY)
;
;=============================================================================
tekdraw proc near
imul xmult ;Multiply by 9
idiv xdiv ;Divide by 13
push ax ;X is now between 0 and 708
mov ax,bx
imul ymult ;Multiply by 5
idiv ydiv ;Divide by 13
mov bx,ybot ;Y is now between 0 and 299
sub bx,ax ;Put new Y in right reg
pop ax ;Put new X in right reg
or cl,cl
jnz td10 ;Jump if line is visible
mov oldx,ax ;Update last coordinates
mov oldy,bx
ret
td10: mov si,oldx ;Previous position
mov di,oldy
mov oldx,ax ;Update position
mov oldy,bx
jmp line ;Plot line
tekdraw endp
;=============================================================================
; LINE Subroutine to plot line with endpoints in BX,CX and SI,DI. The method
; used is an adaptation of octantal dynamic differential analyzer(DDA).
; SI,DI = Start X,Y coordinates. AX,BX = End X,Y coordinates.
;
;=============================================================================
line proc near
cmp ax,si ;Compare X1 to X2
jl plusx ;Jump if X1 is to left of X2
xchg ax,si ;Swap points so point 1 is to left
xchg bx,di ; This mirrors quadrants 2,3 to 1,4
plusx: sub si,ax ;Get delta X into SI
sub di,bx ;Get delta Y into DI
; Left-hand coordinate in (AX,BX), delta movement in (SI,DI)
; Map X1,Y1 in AX,BX to offset into the video buffer in BX and bit pos in AX
shl bx,1 ;2*Y
shl bx,1 ;4*Y
mov bp,bx ;Save 4*Y
shl bx,1 ;8*Y
shl bx,1 ;16*Y
shl bx,1 ;32*Y
add bp,bx ;DX = 36*Y
shl bx,1 ;64*Y
shl bx,1 ;128*Y
sub bx,bp ;128Y - 36Y = 92*Y
mov cl,al ;Low 4 bits of X position
and cl,0Fh
shr ax,1 ;Divide by 8 bits per byte
shr ax,1
shr ax,1
and ax,0fffeh ;Truncate down to word boundary
add bx,ax
mov ax,8000h ;Start with set bit on left edge
shr ax,cl ;Shift it over the correct amount
;AX has bit in position, BX has word address, SI has delta-X, DI has delta-Y
mov bp,92 ;Offset from 1 pixel to one below it
or di,di ;See if delta y is below zero
jg line10 ;Yes, already on quadrant 3
neg di ;Get absolute value of delta y
neg bp ;Move toward top of screen
line10: push ds
mov ds,grseg
cmp di,si ;Compare delta-Y with delta-X
jg line30 ;Greater than +/- 45 degrees
; Here when slope is less than +/- 45 degrees
line20: mov cx,si ;Number of pixels to plot = delta x
inc cx ; + 1
mov dx,si ;Initialize line error to -(deltax)/2
shr dx,1 ;
neg dx ;
line2a: or [bx],ax ;Turn on pixel pointed to by BX and Al
ror ax,1 ;Increment X direction
jnc line2b ;
add bx,2 ;
line2b: add dx,di ;Add delta y to line error
jl line2c ;Jump for next pixel if error < 0
add bx,bp ;Go up (or down) one pixel
sub dx,si ;Subtract delta x from line error
line2c: loop line2a ;Set next pixel
pop ds
ret
; Here when slope is greater than +/- 45 degrees
line30: mov cx,di ;Number of pixels to plot = delta y
inc cx ; + 1 (Delta Y was negated above)
mov dx,di ;Initialize line error to -(deltay)/2
shr dx,1 ;
neg dx ;
line3a: or [bx],ax ;Turn on pixel pointed to by BX and Al
add bx,bp ;Move up (or down) 1 pixel
add dx,si ;Add delta x to line error
jl line3c ;Jump for next pixel if error < 0
ror ax,1 ;Time to increment X direction
jnc line3b ;
add bx,2 ;
line3b: sub dx,di ;Subtract delta y from line error
line3c: loop line3a ;Set next pixel
pop ds
ret
line endp
code ends
end