;+ This is MSGP98.ASM
;
;  Tektronix 4014 emulator for NEC-PC9801
;  Author: Hirofumi Fujii (KEK On-line group)
;
; Last edited 17-Apr-1991
; 17-Apr-1991   Joe (and Rikitake) pointed out that tek_gtxt: should be
;               'tek_gtxt proc near'.
; 09-Mar-1991   Joe pointed out that CAN is reserved word for MASM 5.
;               CAN -> CL_CAN
;               SUB -> CL_SUB
; 01-Sep-1990	Start TEK4105 coding
; 09-Aug-1990	Add protection for coordinates in TEK40_DEV_COOD.
; 24-Jul-1990	for MS-Kermit v3.02
; 10-Jul-1990	ESC[1;30m gives white line for gnuplot v2.0
; 25-Jun-1990	Support for ESC [ XX ; YY ; .. ; ZZ m
; 30-May-1989   Fixed bug in background color.
;               Reset command resets color to default (color in command mode).
; 21-Apr-1989   Cooked logging is added
; 13-Feb-1989	Fill 0FFh of all RAM of the GGDC when tek4014_save is called.
 
GGDC_STS_PORT	equ	0A0h
GGDC_CMD_PORT	equ	0A2h
GGDC_PRM_PORT	equ	0A0h
 
GGDC_BLUE_PLANE		equ	04000h
GGDC_RED_PLANE		equ	08000h
GGDC_GREEN_PLANE	equ	0C000h
 
GGDC_GIN_PLANE		equ	04000h
GGDC_GCUR_PLANE		equ	04000h
 
CPU_BLUE_PLANE	equ	0A800h
CPU_RED_PLANE	equ	0B000h
CPU_GREEN_PLANE	equ	0B800h
 
TEK_X_MAX	equ	4095
TEK_Y_MAX	equ	3071
TEK_DX		equ	56
TEK_DY		equ	112
 
TEK41_NO_ACT	equ	0
TEK41_XY_TYPE	equ	1
TEK41_INT_TYPE	equ	2
TEK41_STR_TYPE	equ	3
TEK41_IAR_TYPE	equ	4
 
TEK41_ARGBUF_SIZE	equ	512
TEK41_FABUF_SIZE	equ	1024
 
BELL		equ	007h
BS		equ	008h
HT		equ	009h
LF		equ	00Ah
VT		equ	00Bh
FF		equ	00Ch
CR		equ	00Dh
CL_CAN		equ	018h
CL_SUB		equ	01Ah
ESCAPE		equ	01Bh
FS		equ	01Ch
GS		equ	01Dh
RS		equ	01Eh
US		equ	01Fh
 
HIY		equ	020h
EXT		equ	060h
LOY		equ	060h
HIX		equ	020h
LOX		equ	040h
 
X_OFS		equ	64
Y_OFS		equ	8
 
IN_REPEAT	equ	1
SIXEL_YMAX	equ	378		; 24 x 16 - 6
SIXEL_XMAX	equ	639
 
	include	msxp98.h
 
	public	tek4014,tek4014_ini,tek4014_reset
	public	tek4014_save, tek4014_restore, tek4014_modlin
	public	tek4014_color
	public	tekstat
	public	gdisp_on, gdisp_off, set_gcolor
	public	sixel, sixel_in, sixel_clear
	public	sixel_rollup, sixel_rolldown
	public	set_gpalette
 
data 	segment	public 'data'
 
	extrn	vt100_flags:byte, vt100_lflag:byte, vt100_gflag:byte
	extrn	vtgrph_flg:byte
	extrn	display_mode:byte
	extrn	gnrm_color:byte, gbck_color:byte	; in MSYP98.ASM
	extrn	def_color:byte, scn_color:byte
 
gdisp_mode	db	0		; digital(0)/analogue(1) display
gplane_nums	db	3		; number of graphic planes (3 or 4)
gplane_actv	dw	15		; active plane mask
gplane_segm	dw	0A800h		; CPU segment address of G-VRAM
		dw	0B000h
		dw	0B800h
		dw	0E000h
;
pc98_mouse_type	db	1
pc98_mouse_init	db	0
pc98_mouse_char	db	0,'1','2','3'
;
tek_dialog_area	db	0
tek_dialog_vsbl	db	0
;
; Color mode
; <int1> 0: no change       <int2>  0: no change    <int3> 0:nochange
;        1: RGB [0-100]             1: opake               1:color
;        2: CMY [0-100]             2: sub                 2:monochrome
;        3: HLS                     3: add
;        4: RGB [0-255]
;
tek_cmode_1	db	3
tek_cmode_2	db	1
tek_cmode_3	db	1
		db	0		; for alignment
;
; Window and Viewport (Ordering is important.)
;
tek_wnx1	dw	0
tek_wnx2	dw	4095
tek_wny1	dw	0
tek_wny2	dw	3071
;
tek_vpx1	dw	0
tek_vpx2	dw	4095
tek_vpy1	dw	0
tek_vpy2	dw	3071
;
; Transformation Matrix from Window to Viewport.
; 16-bit fixed decimal point number.
;
tek_w2v_mat	dw	8 dup (?)
;
; Window/Viewport for GIN (Viewport must be first)
;
gin_vpx1	dw	0
gin_vpx2	dw	479
gin_vpy1	dw	0
gin_vpy2	dw	359
;
gin_wnx1	dw	0
gin_wnx2	dw	4095
gin_wny1	dw	0
gin_wny2	dw	3071
;
; Viewport to Window transformation matrix
;
gin_v2w_mat	dw	8 dup (?)
;
;
; Character vectors
;
tek_gtxt_ang	dw	0
tek_gtxt_w	dw	39
tek_gtxt_h	dw	52
tek_gtxt_s	dw	13
tek_gtxt_dr	db	2, 0		; graph text dir for GDC
tek_gtxt_ux	dw	52
tek_gtxt_uy	dw	0
tek_gtxt_vx	dw	0
tek_gtxt_vy	dw	52
;
sixel_replace	db	1, 0
sixel_state	db	0
sixel_char	db	0
sixel_on	db	0
sixel_off	db	0
sixel_x		dw	0
sixel_y		dw	0
repeat_count	dw	0
sixel_byte	dw	0
sixel_segm	dw	0
;
vt_buf		db	8 dup (?)
vt_dialog_clr	db	7,ESCAPE,"[2J",ESCAPE,"[H"
;
tek_zero	dw	0		; Zero for clearing mode line
tek_cur_x	dw	0		; TEK current position x
tek_cur_y	dw	0		; TEK current position y
tek_req_x	dw	0		; TEK requested position x
tek_req_y	dw	0		; TEK requested position y
;
tek_lncol	dw	1		; TEK line color
tek_txcol	dw	1		; TEK text color
tek_facol	dw	1		; TEK fill area color
;
loc_x		dw	0		; locator position in DC
loc_y		dw	0
loc_mov		dw	0
;
tek_npnt	dw	0
;
line_type	dw	0
line_type_table	dw	0FFFFh
		dw	08888h
		dw	0E4E4h
		dw	0F0F0h
		dw	0FF00h
		dw	0927Ch
		dw	0FF18h
		dw	0CCCCh
;
marker_type	dw	0
;
tek41_cmd	dw	0
tek41_func	dw	0
tek41_nget	dw	0
tek41_narg	dw	0
tek41_nreq	db	0		; next requested data type
tek41_nact	db	0		; next action
tek41_argt	db	8 dup (0)
tek41_ival	dw	0
;
tek_P_prv	db	0,0
tek_P_num	dw	0
tek_P_pnt	dw	0
tek_P_buf	dw	32 dup (0)
;
tek_vseq	db	0
tek_cur_HIY	db	0
tek_cur_EXT	db	0
tek_cur_LOY	db	0
tek_cur_HIX	db	0
tek_cur_LOX	db	0
;
tek_mod		db	0		; 0=Alpha,1=Vector,2=Plot,3=Increment
tek_esc		db	0		; 1=TEK in esc-seq, 2= in CSI-seq
tek_byp		db	0		; 1=Bypass mode
tek_cur		db	0		; 0=Alpha cursor off, 1=on
tek_pen		db	0		; 0=Pen Up, 1=Pen down
tek_hgt		db	0		; 0=Normal, 1=HighLight
;
tek_inpanel	db	0
tek_panel_bnd	db	0
tek_famod	db	0
tek_fapat	db	0
;
tek_col0	db	0,1,2,3,4,5,6,7	; default color index table
;
; Default Tek mode color table (R,G,B)  [0-255]
;
tek_col_def	db	000h,000h,000h	;  0:black
		db	0ffh,0ffh,0ffh	;  1:white
		db	0ffh,000h,000h	;  2:red
		db	000h,0ffh,000h	;  3:green
		db	000h,000h,0ffh	;  4:blue
		db	000h,0ffh,0ffh	;  5:cyan
		db	0ffh,000h,0ffh	;  6:magenta
		db	0ffh,0ffh,000h	;  7:yellow
		db	0ffh,0afh,000h	;  8:orange
		db	0afh,0ffh,000h	;  9:yellow-green
		db	000h,0ffh,0afh	; 10:green-cyan
		db	000h,0afh,0ffh	; 11:blue-cyan
		db	0afh,000h,0ffh	; 12:blue-magenta
		db	0ffh,000h,0afh	; 13:red-magenta
		db	07fh,07fh,07fh	; 14:dark-gray
		db	0afh,0afh,0afh	; 15:light-gray
;
; Tek mode color table (R,G,B)  [0-255]
;
tek_col		db	000h,000h,000h	;  0:black
		db	0ffh,0ffh,0ffh	;  1:white
		db	0ffh,000h,000h	;  2:red
		db	000h,0ffh,000h	;  3:green
		db	000h,000h,0ffh	;  4:blue
		db	000h,0ffh,0ffh	;  5:cyan
		db	0ffh,000h,0ffh	;  6:magenta
		db	0ffh,0ffh,000h	;  7:yellow
		db	0ffh,0afh,000h	;  8:orange
		db	0afh,0ffh,000h	;  9:yellow-green
		db	000h,0ffh,0afh	; 10:green-cyan
		db	000h,0afh,0ffh	; 11:blue-cyan
		db	0afh,000h,0ffh	; 12:blue-magenta
		db	0ffh,000h,0afh	; 13:red-magenta
		db	07fh,07fh,07fh	; 14:dark-gray
		db	0afh,0afh,0afh	; 15:light-gray
;
; Sixel mode color table (R,G,B)  [0-255]
; Note that only plane #3 is used for sixel.
;
sixel_col0	db	000h,000h,000h	;  0:black
		db	000h,000h,000h	;  1
		db	000h,000h,000h	;  2
		db	000h,000h,000h	;  3
		db	0ffh,0ffh,0ffh	;  4
		db	0ffh,0ffh,0ffh	;  5
		db	0ffh,0ffh,0ffh	;  6
		db	0ffh,0ffh,0ffh	;  7
		db	000h,000h,000h	;  8
		db	000h,000h,000h	;  9
		db	000h,000h,000h	; 10
		db	000h,000h,000h	; 11
		db	0ffh,0ffh,0ffh	; 12
		db	0ffh,0ffh,0ffh	; 13
		db	0ffh,0ffh,0ffh	; 14
		db	0ffh,0ffh,0ffh	; 15
;
sixel_col	db	000h,000h,000h	;  0:black
		db	000h,000h,000h	;  1
		db	000h,000h,000h	;  2
		db	000h,000h,000h	;  3
		db	0ffh,0ffh,0ffh	;  4
		db	0ffh,0ffh,0ffh	;  5
		db	0ffh,0ffh,0ffh	;  6
		db	0ffh,0ffh,0ffh	;  7
		db	000h,000h,000h	;  8
		db	000h,000h,000h	;  9
		db	000h,000h,000h	; 10
		db	000h,000h,000h	; 11
		db	0ffh,0ffh,0ffh	; 12
		db	0ffh,0ffh,0ffh	; 13
		db	0ffh,0ffh,0ffh	; 14
		db	0ffh,0ffh,0ffh	; 15
;
tek41_col	db	0,7,2,4,1,5,3,6
		db	7,7,2,4,1,5,3,6
;
disp_bank	db	0
actv_bank	db	0
;
tek41_larg	dw	0
tek41_argbuf	db	TEK41_ARGBUF_SIZE dup (?)
		dw	0				; for guard
tek41_lstr	dw	0		; string length
tek41_nchr	dw	0		; number of char gotten
tek41_liar	dw	0		; INT array size
tek41_niar	dw	0		; number of INT gotten
tek41_faadr	dw	0
tek41_numbnd	dw	0
tek41_nfa	dw	0
tek41_lfa	dw	0
tek41_fabuf	db	TEK41_FABUF_SIZE dup (?)
;
scan_n		dw	0				; number of lines
scan_x		dw	0
scan_y		dw	0
scan_ofs	dw	0		; offset address in the graphic plane
scan_xstr	dw	0
scan_xlen	dw	0
scan_xmin	dw	0
scan_xmax	dw	0
scan_ymin	dw	0
scan_ymax	dw	0
;
scan_buf	db	80 dup (?)
scan_fil	db	0, 0
;
pc98_x1		dw	0
pc98_y1		dw	0
pc98_x2		dw	0
pc98_y2		dw	0
;
HLS_n1		dw	0
HLS_n2		dw	0
;
ggdc_buff	db	80 dup (?)
loc_x_buff	db	32 dup (?)
loc_y_buff	db	32 dup (?)
alp_cur_buff	db	48 dup (?)
;
alp_cur_font	db	000h,000h,000h,000h,000h,07eh,07eh,000h
;
GDC_plane_address	db	040h, 080h, 0C0h, 000h
col_indx_tab_N	db	0, 2, 4, 6, 1, 3, 5, 7	; color index for Normal
col_indx_tab_H	db	7, 2, 4, 6, 1, 3, 5, 7	; color index for HighLight
;
ext_gin		db	023h,000h,0FFh,000h
ent_gin		db	021h,000h			; complement
		db	078h,008h
		db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
		db	0FFh,000h
gin_ans		db	006h,020h,020h,020h,020h,020h,00Dh,004h
;
ggdc_solid	db	078h,008h
		db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
		db	0FFh,000h
ggdc_on		db	00Dh,000h,0FFh,000h
ggdc_off	db	00Ch,000h,0FFh,000h
;
ggdc_set	db	04Bh,001h,000h			; CSFORM
		db	070h,004h,000h,000h,000h,019h	; SCROLL
		db	023h,000h			; WRITE MODE SET
		db	0FFh				; terminator
;
bit_on	db	080h, 040h, 020h, 010h, 008h, 004h, 002h, 001h
bit_off	db	07Fh, 0BFh, 0DFh, 0EFh, 0F7h, 0FBh, 0FDh, 0FEh
;------------------------------------------------------------------------------
; 8 x 8 marker font
;
; offset
;
mark_dx		dw	-4
mark_dy		dw	4
;
gmark88	db	000h,000h,000h,008h,000h,000h,000h,000h	; dot
	db	000h,000h,008h,01ch,008h,000h,000h,000h ; small plus
	db	008h,008h,008h,07fh,008h,008h,008h,000h ; large plus
	db	041h,022h,014h,07fh,014h,022h,041h,000h	; star
	db	01ch,022h,041h,041h,041h,022h,01ch,000h	; circle
	db	041h,022h,014h,008h,014h,022h,041h,000h	; cross
	db	07fh,041h,041h,041h,041h,041h,07fh,000h	; square
	db	008h,014h,022h,041h,022h,014h,008h,000h	; 
	db	07fh,041h,049h,05dh,049h,041h,07fh,000h	; square-dot
	db	008h,014h,02ah,05dh,02ah,014h,008h,000h	;
	db	07fh,063h,055h,049h,055h,063h,07fh,000h	; square-cross
;------------------------------------------------------------------------------
; text font table (8 x 8)
;
gfont88	db      000h,000h,000h,000h,000h,000h,000h,000h	; space
	db	008h,008h,008h,008h,000h,000h,008h,000h	; !
	db	022h,022h,022h,000h,000h,000h,000h,000h	; "
	db	024h,024h,07eh,024h,07eh,024h,024h,000h	; #
	db      008h,07eh,009h,03eh,048h,03fh,008h,000h	; $
        db      043h,021h,010h,008h,004h,042h,061h,000h	; %
        db      006h,009h,009h,006h,049h,031h,04eh,000h	; &
        db      018h,010h,008h,000h,000h,000h,000h,000h	; '
        db      010h,008h,004h,004h,004h,008h,010h,000h	; (
        db      004h,008h,010h,010h,010h,008h,004h,000h	; )
        db      000h,022h,014h,07fh,014h,022h,000h,000h ; *
        db      000h,008h,008h,07fh,008h,008h,000h,000h	; +
        db      000h,000h,000h,000h,00ch,008h,004h,000h	; ,
        db      000h,000h,000h,03eh,000h,000h,000h,000h	; -
        db      000h,000h,000h,000h,000h,00ch,00ch,000h	; .
        db      040h,020h,010h,008h,004h,002h,001h,000h	; /
        db      03ch,062h,052h,05ah,046h,046h,03ch,000h	; 0
        db      008h,00ch,008h,008h,008h,008h,01ch,000h	; 1
        db      01ch,022h,020h,018h,004h,002h,03eh,000h	; 2
        db      03eh,020h,010h,018h,020h,022h,01ch,000h	; 3
        db      010h,018h,014h,012h,03fh,010h,010h,000h	; 4
        db      03eh,002h,01eh,022h,020h,022h,01ch,000h	; 5
        db      018h,004h,002h,01eh,022h,022h,01ch,000h	; 6
        db      03eh,020h,010h,008h,004h,004h,004h,000h	; 7
        db      03ch,042h,042h,03ch,042h,042h,03ch,000h	; 8
        db      01ch,022h,022h,03ch,020h,010h,008h,000h	; 9
        db      000h,00ch,00ch,000h,00ch,00ch,000h,000h	; :
        db      000h,00ch,00ch,000h,00ch,008h,004h,000h	; ;
        db      020h,010h,008h,004h,008h,010h,020h,000h	; <
        db      000h,000h,07eh,000h,07eh,000h,000h,000h	; =
        db      002h,004h,008h,010h,008h,004h,002h,000h	; >
        db      03ch,042h,030h,008h,008h,000h,008h,000h	; ?
        db      03ch,042h,071h,049h,039h,002h,03ch,000h	; @
        db      01ch,022h,022h,03eh,022h,022h,022h,000h	; A
        db      01fh,022h,022h,01eh,022h,022h,01fh,000h	; B
        db      01ch,022h,002h,002h,002h,022h,01ch,000h	; C
        db      01fh,022h,022h,022h,022h,022h,01fh,000h	; D
        db      03eh,002h,002h,01eh,002h,002h,03eh,000h	; E
        db      03eh,002h,002h,01eh,002h,002h,002h,000h	; F
        db      01ch,022h,002h,002h,072h,022h,01ch,000h	; G
        db      022h,022h,022h,03eh,022h,022h,022h,000h	; H
        db      01ch,008h,008h,008h,008h,008h,01ch,000h	; I
        db      070h,020h,020h,020h,022h,022h,01ch,000h	; J
        db      042h,022h,012h,00eh,012h,022h,042h,000h	; K
        db      002h,002h,002h,002h,002h,002h,03eh,000h	; L
        db      041h,063h,055h,049h,041h,041h,041h,000h	; M
        db      042h,046h,04ah,052h,062h,042h,042h,000h	; N
        db      01ch,022h,022h,022h,022h,022h,01ch,000h	; O
        db      01eh,022h,022h,01eh,002h,002h,002h,000h	; P
        db      03ch,042h,042h,042h,052h,022h,05ch,000h	; Q
        db      01eh,022h,022h,01eh,012h,022h,042h,000h	; R
        db      01ch,022h,002h,01ch,020h,022h,01ch,000h	; S
        db      03eh,008h,008h,008h,008h,008h,008h,000h	; T
        db      022h,022h,022h,022h,022h,022h,01ch,000h	; U
        db      041h,041h,022h,022h,014h,014h,008h,000h	; V
        db      041h,041h,041h,041h,049h,055h,022h,000h	; W
        db      041h,022h,014h,008h,014h,022h,041h,000h	; X
        db      041h,022h,014h,008h,008h,008h,008h,000h	; Y
        db      03eh,020h,010h,008h,004h,002h,03eh,000h	; Z
        db      038h,008h,008h,008h,008h,008h,038h,000h	; [
        db      001h,002h,004h,008h,010h,020h,040h,000h	; backslash
        db      00eh,008h,008h,008h,008h,008h,00eh,000h	; ]
        db      008h,014h,022h,000h,000h,000h,000h,000h	; ^
        db      000h,000h,000h,000h,000h,000h,07fh,000h	; _
	db	018h,008h,000h,000h,000h,000h,000h,000h	; left quote
	db	000h,000h,01ch,020h,03ch,022h,07ch,000h	; a
	db	002h,002h,01ah,026h,022h,022h,01eh,000h	; b
	db	000h,000h,01ch,022h,002h,002h,03ch,000h	; c
        db	020h,020h,02ch,032h,022h,022h,03ch,000h	; d
	db	000h,000h,01ch,022h,01eh,002h,03ch,000h	; e
	db	038h,044h,004h,01eh,004h,004h,004h,000h	; f
	db	000h,000h,01ch,022h,022h,03ch,022h,01ch	; g
	db	002h,002h,01ah,026h,022h,022h,022h,000h	; h
	db	008h,000h,008h,008h,008h,008h,010h,000h	; i
	db	020h,000h,020h,020h,020h,020h,022h,01ch	; j
	db	002h,002h,022h,012h,01ah,026h,042h,000h	; k
	db	008h,008h,008h,008h,008h,008h,010h,000h	; l
	db	000h,000h,037h,049h,049h,049h,041h,000h	; m
	db	000h,000h,03ah,046h,042h,042h,042h,000h	; n
	db	000h,000h,01ch,022h,022h,022h,01ch,000h	; o
	db	000h,000h,01eh,022h,022h,01eh,002h,002h	; p
	db	000h,000h,01ch,022h,022h,03ch,020h,060h	; q
	db	000h,000h,03ah,046h,002h,002h,002h,000h	; r
	db	000h,000h,03ch,002h,01ch,020h,01eh,000h	; s
	db	008h,008h,03eh,008h,008h,008h,030h,000h	; t
	db	000h,000h,022h,022h,022h,022h,05ch,000h	; u
	db	000h,000h,022h,022h,022h,014h,008h,000h	; v
	db	000h,000h,041h,041h,049h,049h,036h,000h	; w
	db	000h,000h,022h,014h,008h,014h,022h,000h	; x
	db	000h,000h,022h,022h,022h,03ch,022h,01ch	; y
	db	000h,000h,03eh,010h,008h,004h,03eh,000h	; z
	db	030h,008h,010h,00eh,010h,008h,030h,000h	; {
	db	008h,008h,008h,000h,008h,008h,008h,000h	; |
	db	006h,008h,004h,038h,004h,008h,006h,000h	; }
	db	000h,040h,03ch,002h,000h,000h,000h,000h	; ~
	db	012h,049h,024h,012h,049h,024h,012h,049h	; del
;---------------------------------------------------------------------------
func41	dw	'LE'
	dw	tek41_exec_LE
	db	0,0,0,0,0,0
;
	dw	'LP'
	dw	tek41_exec_LP
	db	2,TEK41_XY_TYPE,TEK41_INT_TYPE,0,0,0
;
	dw	'LV'
	dw	tek41_exec_LV
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'LZ'
	dw	tek41_exec_LZ
	db	0,0,0,0,0,0
;
	dw	'KA'
	dw	tek41_exec_KA
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'LG'			; draw
	dw	tek41_exec_LG
	db	1,TEK41_XY_TYPE,0,0,0,0
;
	dw	'LF'			; move
	dw	tek41_exec_LF
	db	1,TEK41_XY_TYPE,0,0,0,0
;
	dw	'LH'			; marker
	dw	tek41_exec_LH
	db	1,TEK41_XY_TYPE,0,0,0,0
;
	dw	'LT'			; graphic text
	dw	tek41_exec_LT
	db	1,TEK41_STR_TYPE,0,0,0,0
;
	dw	'MC'			; set graphtext size
	dw	tek41_exec_MC
	db	3,TEK41_INT_TYPE,TEK41_INT_TYPE,TEK41_INT_TYPE,0,0
;
	dw	'ML'			; set line color index
	dw	tek41_exec_ML
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'MM'			; set marker type
	dw	tek41_exec_MM
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'MP'			; set fill pattern
	dw	tek41_exec_MP
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'MR'			; set graphtext rotation
	dw	tek41_exec_MR
	db	2,TEK41_INT_TYPE,TEK41_INT_TYPE,0,0,0
;
	dw	'MT'			; set text color index
	dw	tek41_exec_MT
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'MV'			; set line style
	dw	tek41_exec_MV
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'NM'			; set prompt mode
	dw	tek41_exec_none
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	'RW'			; set window
	dw	tek41_exec_RW
	db	2,TEK41_XY_TYPE,TEK41_XY_TYPE,0,0,0
;
	dw	'TG'			; set surface color map
	dw	tek41_exec_TG
	db	2,TEK41_INT_TYPE,TEK41_IAR_TYPE,0,0,0
;
	dw	'TM'			; set color mode
	dw	tek41_exec_TM
	db	3,TEK41_INT_TYPE,TEK41_INT_TYPE,TEK41_INT_TYPE,0,0
;
	dw	'%!'			; set command
	dw	tek41_exec_SETCOM
	db	1,TEK41_INT_TYPE,0,0,0,0
;
	dw	0
	dw	tek41_exec_unknown
	db	0,0,0,0,0,0
;----------------------------------------------
tek_stat_msg	db	CR,LF,"  Tek status: "
tek_pmode_msg	db	"        "
		db	"  color mode: "
tek_cmode_msg	db	"3 1 1 "
		db	"  mouse: "
tek_mouse_msg	db	"      "
		db	CR,LF,"  Tek Last Unknown command: "
tek_unkwn_msg	dw	'  '
		db	"  Tek Last Ignored command: "
tek_ignor_msg	dw	'  '
tek_test1_msg	db	' '
tek_test2_msg	db	' '
tek_test3_msg	db	' '
tek_test4_msg	db	' '
		db	'$'
;----------------------------------------------
data	ends
 
code	segment	public 'code'
 
	extrn	vt100_modlin:near
	extrn	outcapt:near
	extrn	set_cur_color:near
	extrn	set_cursor:near		; in MSZP98
	extrn	text_scrn:near		; in MSZP98
	extrn	pc98_bell:near
 
	assume	cs:code,ds:data,es:nothing
 
TEK41_W2V	PROC	NEAR
;
; Input  (ax,bx) -- coordinate in window
;          [si]  -- transformation matrix
; Output (ax,bx) -- coordinate in viewport
;
; format of the transformation matrix
;   xv = (xw - wx0)*mx + vx0
;   yv = (yw - wy0)*my + vy0
;
;   [si   ]  mx_l
;   [si+ 2]  mx_h
;   [si+ 4]  wx0
;   [si+ 6]  vx0
;   [si+ 8]  my_l
;   [si+10]  my_h
;   [si+12]  wy0
;   [si+14]  vy0
;
	push	cx
	push	dx
	push	si
	push	di
;
	mov	di,bx			; save y
;
	sub	ax,[si+ 4]
	push	ax			; save (x-wx0)
	xor	cx,cx
	cmp	ax,0
	jge	tek41_w2v_1
	mov	cl,1
	neg	ax
tek41_w2v_1:
	mul	WORD PTR [si]		; low word
	mov	bx,dx
	pop	ax
	mul	WORD PTR [si+ 2]	; high word
	add	bx,ax
	jcxz	tek41_w2v_2
	neg	bx
tek41_w2v_2:
	add	bx,[si+ 6]
;
	mov	ax,di			; get y
	mov	di,bx			; save result x
	sub	ax,[si+12]
	push	ax			; save (y-wy0)
	xor	cx,cx
	cmp	ax,0
	jge	tek41_w2v_3
	mov	cl,1
	neg	ax
tek41_w2v_3:
	mul	WORD PTR [si+ 8]	; low word
	mov	bx,dx
	pop	ax
	mul	WORD PTR [si+10]	; high word
	add	bx,ax
	jcxz	tek41_w2v_4
	neg	bx
tek41_w2v_4:
	add	bx,[si+14]
	mov	ax,di
;
	pop	di
	pop	si
	pop	dx
	pop	cx
;
	ret
TEK41_W2V	ENDP
;-----------------------------------------------------------------------
; TEK4010/4014 terminal emulator
;-----------------------------------------------------------------------
TEK40_DEV_COOD	PROC	NEAR
;
;  Transform TEK4014 coordinates to PC9801 device coordinates
;	Inputs:
;	  AX: TEK4014 X coordinate ( to be replaced by device x )
;	  BX: TEK4014 Y coordinate ( to be replaced by device y )
;	Outputs:
;	  AX: Device X coordinate
;	  BX: Device Y coordinate
;
	push	si
	mov	si,offset tek_w2v_mat
	call	tek41_w2v
	pop	si
;
	push	cx
	cmp	bx,399
	jle	tek40_dev_cood_1
	mov	bx,399
tek40_dev_cood_1:
	mov	cx,399
	sub	cx,bx
	xchg	bx,cx
	cmp	ax,639
	jle	tek40_dev_cood_2
	mov	ax,639
tek40_dev_cood_2:
	pop	cx
	ret
;
TEK40_DEV_COOD	ENDP
;
;
TEK40_GIN	PROC	NEAR
;
;  Request locator
;
;  If we are using mouse, set the position
;
	mov	pc98_mouse_type,0
	test	vtgrph_flg,MOUSE_BIT		; mouse on ?
	jz	tek40_gin_00			; no.
tek40_gin_m01:
	mov	ax,0				; init mouse
	mov	bx,0
	int	33h
	cmp	ax,-1				; mouse available ?
	jne	tek40_gin_00
	cmp	bx,2				; MS-mouse ?
	jne	tek40_gin_m02			; ne=no.
	mov	pc98_mouse_type,2
	jmp	tek40_gin_m03
tek40_gin_m02:
	mov	pc98_mouse_type,1
tek40_gin_m03:
	mov	cx,loc_x
	mov	dx,loc_y
	mov	ax,4				; locate mouse
	int	33h
tek40_gin_00:
	mov	si,offset ent_gin		; write mode is complement
	call	send_to_GGDC
	mov	loc_mov,3
;
;	Draw X axis
;
tek40_gin_01:
	test	loc_mov,1
	jz	tek40_gin_02
	mov	di,offset loc_x_buff
	mov	ax,gin_vpx1
	mov	bx,loc_y
	mov	cx,GGDC_GIN_PLANE		; locator graphic plane
	call	gcsrw
	mov	ax,gin_vpx2
	sub	ax,gin_vpx1
	mov	bx,0
	call	gline
	mov	byte ptr [di],0FFh
	mov	si,offset loc_x_buff
	call	send_to_GGDC
;
;	Draw Y axis
;
tek40_gin_02:
	test	loc_mov,2
	jz	tek40_gin_10
	mov	di,offset loc_y_buff
	mov	ax,loc_x
	mov	bx,399
	sub	bx,gin_vpy2
	mov	cx,GGDC_GIN_PLANE
	call	gcsrw
	mov	ax,0
	mov	bx,gin_vpy2
	sub	bx,gin_vpy1
	call	gline
	mov	byte ptr [di],0FFh
	mov	si,offset loc_y_buff
	call	send_to_GGDC
;
tek40_gin_10:
	cmp	pc98_mouse_type,0		; using mouse ?
	jne	tek40_gin_m10			; ne=yes.
	jmp	tek40_gin_11
tek40_gin_m10:
	mov	ax,3
	int	33h
	cmp	pc98_mouse_type,1		; NEC type ?
	jne	tek40_gin_m12			; ne=no.
	and	ax,01h
	and	bx,02h
	or	bx,ax				; MS-mouse method
tek40_gin_m12:
	and	bx,03h
	cmp	bx,0
	jne	tek40_gin_m14
	cmp	cx,loc_x
	jne	tek40_gin_m14
	cmp	dx,loc_y
	jne	tek40_gin_m14
	mov	ah,01h				; sense keyboard buffer
	int	BIOS
	cmp	bh,0
	je	tek40_gin_m10
	mov	ah,00h				; read keyboard buffer
	int	BIOS
	jmp	tek40_gin_ex
tek40_gin_m14:
	mov	loc_x,cx
	mov	loc_y,dx
	cmp	bx,0
	je	tek40_gin_m16
	mov	ax,bx
	mov	bx,offset pc98_mouse_char
	add	bx,ax
	mov	al,[bx]
	jmp	tek40_gin_ex
;
tek40_gin_m16:
	mov	si,offset loc_x_buff
	call	send_to_GGDC
	mov	si,offset loc_y_buff
	call	send_to_GGDC
	mov	loc_mov,3
	jmp	tek40_gin_01
;
;	If we are using mouse, read mouse.
;	Otherwise, scan Keyboard
;
tek40_gin_11:
	mov	dx,1
	mov	ah,1			; sense keyborad buffer
	int	18h			; BIOS call
	cmp	bh,0
	je	tek40_gin_11
;
	mov	ah,2			; sense shift keys
	int	18h
	test	al,1			; SHIFT key pressed ?
	jz	tek40_gin_12
	mov	dx,4
tek40_gin_12:
	test	al,16			; CTRL key pressed ?
	jz	tek40_gin_13
	mov	dx,8
tek40_gin_13:
;
	mov	ah,0			; read keyboard buffer
	int	18h
;
	mov	loc_mov,0
;
	cmp	ax,03A00h		; UP
	je	tek40_gin_up
	cmp	ax,03D00h
	je	tek40_gin_down
	cmp	ax,03B00h
	je	tek40_gin_left
	cmp	ax,03C00h
	je	tek40_gin_right
;
;	Alpha-Numeric key.
;
	jmp	tek40_gin_ex
;
tek40_gin_up:
	sub	loc_y,dx
	cmp	loc_y,9-Y_OFS
	jge	tek40_gin_y
	mov	loc_y,9-Y_OFS
	jmp	tek40_gin_y
tek40_gin_down:
	add	loc_y,dx
	cmp	loc_y,399-Y_OFS
	jle	tek40_gin_y
	mov	loc_y,399-Y_OFS
tek40_gin_y:
;	erase X axis
	mov	si,offset loc_x_buff
	or	loc_mov,1
	jmp	tek40_gin_xy
;
tek40_gin_left:
	sub	loc_x,dx
	cmp	loc_x,X_OFS
	jge	tek40_gin_x
	mov	loc_x,X_OFS
	jmp	tek40_gin_x
tek40_gin_right:
	add	loc_x,dx
	cmp	loc_x,511+X_OFS
	jle	tek40_gin_x
	mov	loc_x,511+X_OFS
tek40_gin_x:
	mov	si,offset loc_y_buff
	or	loc_mov,2
tek40_gin_xy:
	call	send_to_GGDC
	jmp	tek40_gin_01
;
tek40_gin_ex:
;
;	set-up answerback
;
	mov	si,offset gin_ans
	mov	[si+1],al		; Keyboard character
;
	mov	si,offset gin_v2w_mat
	mov	ax,loc_x
	mov	bx,399
	sub	bx,loc_y
	call	tek41_w2v
	shr	ax,1
	shr	ax,1			; convert to 10-bit address
	shr	bx,1
	shr	bx,1			; convert to 10-bit address
;
	mov	si,offset gin_ans
	push	bx			; save Y
;
	mov	bx,ax
	mov	cx,5			; set shift count
	shr	ax,cl			; get HiX
	and	ax,01Fh			; mask higher bits
	or	al,020h			; convert to character
	mov	[si+2],al		; set HiX
	and	bx,01Fh			; get LoX
	or	bl,020h			; convert to character
	mov	[si+3],bl		; set LoX
;
	pop	bx			; restore Y
;
	mov	ax,bx
	mov	cx,5			; set shift count
	shr	ax,cl			; get HiY
	and	ax,01Fh			; mask higher bits
	or	al,020h			; convert to character
	mov	[si+4],al		; set HiY
	and	bx,01Fh			; get LoY
	or	bl,020h			; convert to character
	mov	[si+5],bl		; set LoY
;
;	Erase cross hair cursor
;
	mov	si,offset loc_x_buff
	call	send_to_GGDC
	mov	si,offset loc_y_buff
	call	send_to_GGDC
;
;	Reset write mode
;
	mov	si,offset ext_gin
	call	send_to_GGDC
;
	mov	tek_byp,1		; set bypass mode
	mov	si,offset gin_ans
	xor	cx,cx
	mov	cl,[si]
	inc	si
	ret
TEK40_GIN	ENDP
 
TEK40_CURON	PROC	NEAR
	push	ax
	push	bx
	push	cx
	push	si
	push	di
;
	mov	si,offset alp_cur_font
	mov	di,offset alp_cur_buff
	mov	byte ptr [di],078h	; TEXTW
	mov	byte ptr [di+1],8	; number of parameters
	add	di,2
	cld
	mov	cx,8
	push	es
	push	ds
	pop	es
	rep	movsb
	pop	es
	mov	ax,tek_cur_x
	mov	bx,tek_cur_y
	call	tek40_dev_cood
	mov	cx,GGDC_GCUR_PLANE	; cursor graphic plane
	call	gcsrw
	mov	byte ptr [di],21h	; write in COMPLEMENT mode
	mov	byte ptr [di+1],0
	add	di,2
	mov	byte ptr [di],04Ch	; VEXTW
	mov	byte ptr [di+1],3	; number of parameters
	mov	byte ptr [di+2],012h	; normal text dir=2
	mov	byte ptr [di+3],07h
	mov	byte ptr [di+4],0
	mov	byte ptr [di+5],068h	; TEXTE
	mov	byte ptr [di+6],0
	mov	byte ptr [di+7],0FFh	; terminator
	mov	si,offset alp_cur_buff
	call	send_to_GGDC
	mov	tek_cur,1
;
	pop	di
	pop	si
	pop	cx
	pop	bx
	pop	ax
	ret
TEK40_CURON	ENDP
 
TEK40_CUROFF	PROC	NEAR
	cmp	tek_cur,0
	je	tek40_curoff_ex
	push	si
	mov	si,offset alp_cur_buff
	call	send_to_GGDC
	pop	si
	mov	tek_cur,0
tek40_curoff_ex:
	ret
TEK40_CUROFF	ENDP
 
TEK4014_INI	PROC	NEAR
	call	tek4014_reset
	mov	si,offset ggdc_off
	call	send_to_GGDC
	ret
TEK4014_INI	ENDP
 
TEK4014_COLOR	PROC	NEAR
;
;  Set color index table
;  [si]   foreground color
;  [si+1] background color
;
	push	ax
	push	di
;
	push	si
	mov	al,[si+1]		; background color
	xor	ah,ah
	mov	si,offset gnrm_color
	add	si,ax
	add	si,ax
	add	si,ax
	mov	di,offset tek_col	; index 0 is background color
	mov	al,[si]
	mov	[di],al
	mov	al,[si+1]
	mov	[di+1],al
	mov	al,[si+2]
	mov	[di+2],al
;
	push	cx
	mov	cx,4
	mov	di,offset sixel_col
tek4014_color_sxb:
	mov	al,[si]
	mov	[di],al			; R
	mov	[di+24],al		; R
	mov	al,[si+1]
	mov	[di+1],al		; G
	mov	[di+25],al		; G
	mov	al,[si+2]
	mov	[di+2],al		; B
	mov	[di+26],al		; B
	add	di,3
	loop	tek4014_color_sxb
	pop	cx
;
	pop	si
;
	push	si
	mov	al,[si]			; foreground color
	xor	ah,ah
	mov	si,offset gnrm_color
	add	si,ax
	add	si,ax
	add	si,ax
	mov	di,offset tek_col
	add	di,3			; index 1 is foreground color
	mov	al,[si]
	mov	[di],al
	mov	al,[si+1]
	mov	[di+1],al
	mov	al,[si+2]
	mov	[di+2],al
;
	push	cx
	mov	cx,4
	mov	di,offset sixel_col
	add	di,12			; start from index 4
tek4014_color_sxf:
	mov	al,[si]
	mov	[di],al			; R
	mov	[di+24],al		; R
	mov	al,[si+1]
	mov	[di+1],al		; G
	mov	[di+25],al		; G
	mov	al,[si+2]
	mov	[di+2],al		; B
	mov	[di+26],al		; B
	add	di,3
	loop	tek4014_color_sxf
	pop	cx
;
	pop	si
;@@	mov	[di+7],al
;@@	mov	al,[si+1]
;@@	mov	[di],al
;@@	mov	di,offset sixel_col
;@@	mov	al,[si]
;@@	mov	[di+4],al
;@@	mov	[di+5],al
;@@	mov	[di+6],al
;@@	mov	[di+7],al
;@@	mov	al,[si+1]
;@@	mov	[di],al
;@@	mov	[di+1],al
;@@	mov	[di+2],al
;@@	mov	[di+3],al
	pop	di
	pop	ax
	ret
TEK4014_COLOR	ENDP
 
tek40_color	proc	near
;
; set color
; input ax
;
	push	ax			; save register
	cmp	ax,0			; normal intensity [0] ?
	jne	tek40_color_1		; ne=no
	mov	tek_hgt,0		; set normal intensity
	jmp	tek40_color_ex
tek40_color_1:
	cmp	ax,1			; high intensity [1] ?
	jne	tek40_color_2		; ne=no
	mov	tek_hgt,1		; set high intensity
	jmp	tek40_color_ex
tek40_color_2:
	cmp	ax,30			; forground color [30-37] ?
	jl	tek40_color_bk
	cmp	ax,37
	jg	tek40_color_bk
	sub	ax,30			; OK, convert to color index
	push	bx
	mov	bx,offset col_indx_tab_N
	add	bx,ax
	cmp	tek_hgt,0		; HighLight ?
	je	tek40_color_fg1		; e=no
	add	bx,8
tek40_color_fg1:
	mov	al,[bx]
	pop	bx
	mov	tek_lncol,ax
	mov	tek_txcol,ax
	mov	tek_facol,ax
	jmp	tek40_color_ex
tek40_color_bk:
	cmp	ax,40			; background color [40-47] ?
	jl	tek40_color_ex
	cmp	ax,47			; bug fixed [30-May-1989]. Was 37.
	jg	tek40_color_ex
	sub	ax,40
	push	si
	mov	si,offset col_indx_tab_N
	add	si,ax
	mov	al,[si]
	mov	si,offset scn_color
	mov	[si+1],al
	call	tek4014_color
	mov	si,offset tek_col
	call	set_gpalette
	pop	si
tek40_color_ex:
	pop	ax			; restore ax
	ret
tek40_color	endp
 
TEK4014_RESET	PROC	NEAR
;
;  Hardware initialization
;
tek4014_reset_lp01:
	in	al,GGDC_STS_PORT
	xor	al,024h
	test	al,024h			; VSYNC & GDC Empty ?
	jne	tek4014_reset_lp01
;
	mov	al,disp_bank
	out	0A4h,al			; set display bank
	mov	al,actv_bank
	out	0A6h,al			; set active bank
	mov	al,02h			; color mode
	out	068h,al			; set mode F/F
	mov	al,08h			; 400 line mode
	out	068h,al			; set mode F/F
	mov	si,offset ggdc_set	; CSFORM & SCROLL
	call	send_to_GGDC
;
	cmp	display_mode,0
	je	tek4014_reset_02
	mov	gdisp_mode,1
	mov	gplane_nums,4
	jmp	tek4014_reset_03
tek4014_reset_02:
	mov	gdisp_mode,0
	mov	gplane_nums,3
tek4014_reset_03:
	mov	al,gdisp_mode		; display mode
	out	6ah,al
;
	call	gcls
;
;  Software reset
;
; Set color mode
;
	mov	tek_cmode_1,3
	mov	tek_cmode_2,1
	mov	tek_cmode_3,1
;
	push	si
	mov	si,offset def_color
	call	set_cur_color
	call	tek4014_color
	pop	si
;
; Set Windows
;
	mov	tek_wnx1,0
	mov	tek_wnx2,TEK_X_MAX
	mov	tek_wny1,0
	mov	tek_wny2,TEK_Y_MAX
;
	mov	gin_wnx1,0
	mov	gin_wnx2,TEK_X_MAX
	mov	gin_wny1,0
	mov	gin_wny2,TEK_Y_MAX
;
; Set Viewports
;
	mov	tek_vpx1,X_OFS
	mov	tek_vpx2,(X_OFS+479)
	mov	tek_vpy1,Y_OFS
	mov	tek_vpy2,(Y_OFS+359)
;
	mov	gin_vpx1,X_OFS
	mov	gin_vpx2,(X_OFS+479)
	mov	gin_vpy1,Y_OFS
	mov	gin_vpy2,(Y_OFS+359)
;
; Set Transformation Matricies
;
	push	si
	push	di
	mov	si,offset tek_wnx1
	mov	di,offset tek_w2v_mat
	call	set_tek41_mat
	mov	si,offset gin_vpx1		; viewport to window for GIN
	mov	di,offset gin_v2w_mat
	call	set_tek41_mat
	pop	di
	pop	si
;
; Set text parameters
;
	mov	tek_gtxt_ang,0
	mov	tek_gtxt_w,39
	mov	tek_gtxt_h,52
	mov	tek_gtxt_s,13
	mov	tek_gtxt_dr,2
	mov	tek_gtxt_ux,52		; w+s
	mov	tek_gtxt_uy,0
	mov	tek_gtxt_vx,0
	mov	tek_gtxt_vy,52		; h
;
; Set current position
;
	mov	tek_cur_x,0
	mov	tek_cur_y,TEK_Y_MAX
	mov	ax,TEK_DY
	sub	tek_cur_y,ax
	mov	line_type,0
	mov	marker_type,0
	mov	tek_byp,0
	mov	tek_lncol,1		; line color is white
	mov	tek_txcol,1		; text color is white
	mov	tek_facol,1		; fill area color is white
	mov	tek_hgt,0		; Normal Intensity
	mov	tek_esc,0
	mov	tek_inpanel,0
	mov	tek41_cmd,0
;
;	Set locator position at the center of the screen
;
	push	bx
	mov	ax,(TEK_X_MAX+1)
	shr	ax,1
	mov	bx,(TEK_Y_MAX+1)
	shr	bx,1
	call	tek40_dev_cood
	mov	loc_x,ax
	mov	loc_y,bx
	pop	bx
;
;	Set color index table
;
	push	cx
	push	di
	push	si
	push	es
;
	push	ds
	pop	es
	mov	si,offset tek_col_def	; source
	mov	di,offset tek_col	; destination
	mov	cx,48			; 16 colors x 3
	cld
	rep	movsb
	mov	si,offset tek_col
	call	set_gpalette
;
;	Set dialog area
;
	mov	tek_dialog_area,0
	mov	tek_dialog_vsbl,0
;
	pop	es
	pop	si
	pop	di
	pop	cx
;
	call	tek40_curon
;
	ret
TEK4014_RESET	ENDP
 
TEK4014_SAVE	PROC	NEAR
;
;@@	mov	si,offset tek_col0
	call	set_gpalette
;
	mov	si,offset ggdc_solid
	call	send_to_GGDC
	mov	si,offset ggdc_off
	call	send_to_GGDC
;
; Clear mode line
;
	push	dx
	mov	dx,offset tek_zero
	call	vt100_modlin
	pop	dx
;
	push	ax
	xor	ax,ax		; restore cursor attributes
	call	set_cursor
	mov	ax,1
	call	text_scrn	; text screen ON
	pop	ax
;
	ret
TEK4014_SAVE	ENDP
 
 
TEK4014_RESTORE	PROC	NEAR
;@@	push	ax
;@@	mov	ax,1		; disable text cursor
;@@	call	set_cursor
;@@	pop	ax
;
	push	ax
	mov	al,display_mode
	cmp	al,gdisp_mode
	je	tek4014_restore_1
	mov	gdisp_mode,0
	mov	gplane_nums,3
	cmp	al,0
	je	tek4014_restore_2
	mov	gdisp_mode,1
	mov	gplane_nums,4
tek4014_restore_2:
	mov	al,gdisp_mode
	out	6ah,al
tek4014_restore_1:
	pop	ax
;
	call	gdisp_on
;
	mov	si,offset tek_col
	call	set_gpalette
	ret
TEK4014_RESTORE	ENDP
 
 
TEK4014_MODLIN	PROC	NEAR
	call	vt100_modlin
	ret
TEK4014_MODLIN	ENDP
 
; Tek4014/Tek4105 emulator by H.Fujii (KEK)
;
; Carry Set if parameters need to be passed to VT100.
; In this case, CX contains number of characters and [SI] contains the
; string.
;
TEK4014	PROC	NEAR
	cmp	vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT)
	jne	tek4014_01		; ne = no.
	call	outcapt			; log it
tek4014_01:
	call	tek40_curoff
	cmp	tek_byp,0		; bypass mode ?
	je	tek40_00		; e = No.
	mov	bl,al			; Bypass mode
	and	bl,07Fh			; Mask 8th bit
	cmp	bl,020h			; control character ?
	jge	tek40_ex		; ge = No.
	mov	tek_byp,0		; Off the bypass mode
tek40_00:
	cmp	tek_esc,0		; in ESC sequence ?
	je	tek40_01		; e = No.
	jmp	tek40_esc
tek40_01:
	cmp	tek_mod,0		; Alpha mode ?
	jne	tek40_02
	jmp	tek40_alp
tek40_02:
	cmp	tek_mod,1		; Vector mode ?
	jne	tek40_03
	jmp	tek40_vct
tek40_03:
	cmp	tek_mod,2		; Point plot mode ?
	jne	tek40_04
	jmp	tek40_vct
tek40_04:
	cmp	tek_mod,3
	jne	tek40_05
	jmp	tek40_inc
tek40_05:
	call	pc98_bell		; Program error !!!
tek40_ex:
	cmp	tek_esc,0		; in ESC seq ?
	jne	tek40_ex1		; ne=yes.
	cmp	tek_dialog_area,0	; Disable dialog ?
	jne	tek40_ex1		; ne=no, dialog is VT screen
	cmp	tek_mod,0		; in alpha mode ?
	jne	tek40_ex1		; ne=no
	call	tek40_curon
tek40_ex1:
	mov	ah,0
	mov	cx,0
	clc				; normal return
	ret
;-----------------------------------------------------------------------
; ESC sequence
;-----------------------------------------------------------------------
tek40_esc:
	cmp	tek_esc,1		; just entered ?
	je	tek40_esc1		; e=yes.
	cmp	tek_esc,2		; in CSI mode ?
	jne	tek40_esc_n2		; ne=no.
	jmp	tek40_esc2
tek40_esc_n2:
	cmp	tek_esc,3		; in 20C ?
	jne	tek40_esc_n3
	jmp	tek40_esc3
tek40_esc_n3:
	jmp	tek40_esc4
;
tek40_esc1:
	cmp	al,020h			; C0 character ?
	jb	tek40_esc_C0		; b=yes.
	jmp	tek40_esc_GL
;
tek40_esc_C0:
tek40_esc_0C:
	cmp	al,FF			; FF ?
	jne	tek40_esc_n0C		; ne=no.
	test	vtgrph_flg,GCLRWAIT_BIT
	jz	tek40_esc_0C_2
	push	ax
	push	bx
	call	pc98_bell
tek40_esc_0C_1:
	mov	ax,0100h
	int	BIOS
	cmp	bh,0
	je	tek40_esc_0C_1
	mov	ax,0
	int	BIOS
	pop	bx
	pop	ax
tek40_esc_0C_2:
	call	gcls			; ESC FF clears screen
	mov	tek_esc,0		; ESC seq done
	mov	tek_mod,0		; enter alpha mode
	mov	tek_cur_x,0
	mov	tek_cur_y,TEK_Y_MAX
	sub	tek_cur_y,TEK_DY
	jmp	tek40_ex
tek40_esc_n0C:
;
	cmp	al,CL_SUB		; SUB (1A) ?
	jne	tek40_esc_n1A		; ne=no.
	call	tek40_gin
	mov	tek_esc,0
	mov	tek_mod,0
	mov	ah,0
	clc
	ret				; EIXT with gin answerback
tek40_esc_n1A:
	mov	tek_esc,0		; any other C0 characters are
	jmp	tek40_C0		; treated as a single C0 character
;
tek40_esc_GL:
	cmp	al,'['
	je	tek40_esc_5B
	ja	tek40_esc_5C
	mov	tek_esc,3		; in TEK4105 command mode
	xor	ah,ah
	mov	tek41_cmd,ax
	jmp	tek40_ex
tek40_esc_5B:
	mov	tek_esc,2		; in CSI mode
	mov	bx,offset tek_P_buf
	mov	tek_P_pnt,bx
	mov	word ptr [bx],0
	mov	tek_P_num,0
	mov	tek_P_prv,0
	jmp	tek40_ex
tek40_esc_5C:
	jmp	tek40_esc_ex
;
; ANSI CSI sequence
;
tek40_esc2:
	cmp	al,'0'
	jl	tek40_esc2_01
	cmp	al,'9'
	jg	tek40_esc2_01
	xor	ah,ah
	sub	al,'0'
	mov	bx,tek_P_pnt
	mov	cx,[bx]
	shl	cx,1
	shl	cx,1
	add	cx,[bx]
	shl	cx,1
	add	ax,cx
	mov	[bx],ax
	jmp	tek40_ex
tek40_esc2_01:
	cmp	al,'?'
	jne	tek40_esc2_02
	mov	tek_P_prv,al
	jmp	tek40_ex
tek40_esc2_02:
	cmp	al,';'
	jne	tek40_esc2_03
	add	tek_P_pnt,2
	mov	bx,tek_P_pnt
	mov	word ptr [bx],0
	inc	tek_P_num
	jmp	tek40_ex
tek40_esc2_03:
	cmp	al,'h'
	jne	tek40_esc2_04
	jmp	tek40_esc_ex
tek40_esc2_04:
	cmp	al,'l'
	jne	tek40_esc2_05
	jmp	tek40_vtchg
tek40_esc2_05:
	cmp	al,'m'
	jne	tek40_esc2_06
	push	ax
	push	cx
	push	si
	mov	si,offset tek_P_buf
	mov	cx,tek_P_num		; number of parameters
	inc	cx
tek40_esc2_05a:
	mov	ax,[si]			; get color code
	call	tek40_color
	add	si,2
	loop	tek40_esc2_05a		; loop over all parameters
	pop	si
	pop	cx
	pop	ax
	jmp	tek40_esc_ex
tek40_esc2_06:
	jmp	tek40_esc_ex
;
tek40_esc3:
;
; 20C mode
;
	cmp	al,020h			; C0 character ?
	jae	tek40_esc3_01		; ae = no.
	jmp	tek40_C0
tek40_esc3_01:
	mov	bx,tek41_cmd
	mov	bh,al
	xchg	bh,bl
	mov	tek41_cmd,bx		; stored it.
	mov	tek_esc,4		; enter Tek41 command mode
	mov	tek41_narg,0
	mov	tek41_nget,0
	mov	tek41_larg,0
;
; analyze command and set number of arguments and argument types
;
	mov	ax,bx
	mov	bx,offset func41
tek41_ana_03:
	mov	cx,[bx]
	cmp	ax,cx
	je	tek41_ana_01
	cmp	cx,0
	jne	tek41_ana_05
	add	bx,2
	mov	cx,[bx]
	mov	tek41_func,cx
	xchg	ah,al			; change to character order
	mov	tek_unkwn_msg,ax
	xchg	ah,al
	jmp	tek40_ex
tek41_ana_05:
	add	bx,10
	jmp	tek41_ana_03
tek41_ana_01:
	add	bx,2
	mov	cx,[bx]
	mov	tek41_func,cx
	add	bx,2
	mov	cl,[bx]
	inc	bx
	xor	ch,ch
	mov	tek41_narg,cx
	cmp	cx,0
	je	tek41_ana_02
	push	si
	mov	si,offset tek41_argt
tek41_ana_04:
	mov	al,[bx]
	mov	[si],al
	inc	bx
	inc	si
	loop	tek41_ana_04
	pop	si
tek41_ana_02:
	jmp	tek41_next
;
tek40_esc4:
	cmp	al,20h			; C0 character ?
	jae	tek40_esc4_02		; ae=no.
	cmp	al,ESCAPE		; one of ESC,FS,GS,RS,US ?
	jl	tek40_esc4_01		; l=no.
	mov	tek_esc,0		; terminate the command
	jmp	tek40_C0		; and treat as C0
tek40_esc4_01:
	jmp	tek40_ex		; ignore any other C0 character.
tek40_esc4_02:
	cmp	tek41_nreq,TEK41_XY_TYPE
	jne	tek40_esc4_03
	jmp	tek41_xy
tek40_esc4_03:
	cmp	tek41_nreq,TEK41_INT_TYPE
	jne	tek40_esc4_04
	jmp	tek41_int
tek40_esc4_04:
	cmp	tek41_nreq,TEK41_STR_TYPE
	jne	tek40_esc4_05
	jmp	tek41_str
tek40_esc4_05:
	cmp	tek41_nreq,TEK41_IAR_TYPE
	jne	tek40_esc4_06
	jmp	tek41_int
tek40_esc4_06:
	jmp	tek40_ex			; Unknown command, ignore.
;
tek40_esc_ex:
	mov	tek_esc,0
	jmp	tek40_ex
 
; receive and convert Tek41 type xy-coordinate
; note that xy-coordinate system is the same as Tek401x.
;
tek41_xy:
	jmp	tek40_vct	; goto Tek40 type vector format analyzer
tek41_xy1:
	mov	cx,tek41_larg	; check the room for storage
	add	cx,4
	cmp	cx,TEK41_ARGBUF_SIZE
	jae	tek41_xy2	; ae = room is full
	mov	bx,offset tek41_argbuf
	add	bx,tek41_larg
	mov	ax,tek_req_x
	mov	[bx],ax		; store it in buffer
	mov	ax,tek_req_y
	mov	[bx+2],ax
	add	tek41_larg,4	; update buffer length
tek41_xy2:
	inc	tek41_nget	; icrement number of argument we get
	jmp	tek41_next
;
; receive and convert Tek41 type integer
;    7 6 5 4 3 2 1 0             7 6 5 4 3 2 1 0
;   +-+-+-+-+-+-+-+-+           +-+-+-+-+-+-+-+-+
;   |P|1|   value   |     ...   |P|0|1|S| value |   where S=1 if int >= 0
;   +-+-+-+-+-+-+-+-+           +-+-+-+-+-+-+-+-+
;
tek41_int:
	mov	ah,al		; copy to AH
	mov	bx,tek41_ival	; get previous value
	test	al,040h		; Hi byte ?
	jz	tek41_int1	; z=no
	mov	cx,6		; shift count
	shl	bx,cl		; shift-left previous value by 6 bits
	and	ah,03Fh
	or	bl,ah
	mov	tek41_ival,bx	; store it
	jmp	tek40_ex	; and continue
tek41_int1:
	mov	cx,4
	shl	bx,cl
	and	ah,00Fh
	or	bl,ah
	test	al,010h		; check sign bit
	jnz	tek41_int2	; nz=positive
	neg	bx		; negative integer
tek41_int2:
	mov	ax,bx
	mov	tek41_ival,ax	; store it
	mov	cx,tek41_larg	; check the room for storage
	add	cx,2
	cmp	cx,TEK41_ARGBUF_SIZE
	jae	tek41_int3	; ae = room is full
	mov	bx,offset tek41_argbuf
	add	bx,tek41_larg
	mov	[bx],ax		; store it in buffer
	add	tek41_larg,2	; update buffer length
tek41_int3:
	cmp	tek41_nact,TEK41_INT_TYPE	; processing single INT ?
	jne	tek41_int4	; ne=no.
	inc	tek41_nget	; increment number of arg. we get
	jmp	tek41_next	; setup for next argument
tek41_int4:
	cmp	tek41_nact,TEK41_STR_TYPE	; processing string ?
	jne	tek41_int5	; ne=no.
	mov	tek41_lstr,ax	; set character length
	mov	tek41_nchr,0	; clear the filled size
	mov	tek41_nreq,TEK41_STR_TYPE	; next data is character
	jmp	tek40_ex	; and continue
tek41_int5:
	cmp	tek41_nact,TEK41_IAR_TYPE	; processing INT array ?
	jne	tek41_int8
	cmp	tek41_nreq,TEK41_INT_TYPE	; beginning of array ?
	jne	tek41_int6
	mov	tek41_liar,ax	; set array length
	mov	tek41_niar,0	; clear the filled size
	mov	tek41_ival,0	; clear the buffer
	mov	tek41_nreq,TEK41_IAR_TYPE	; next data is INT array elem.
	jmp	tek40_ex	; and continue
tek41_int6:
	inc	tek41_niar
	mov	cx,tek41_niar
	cmp	cx,tek41_liar
	jge	tek41_int7
	mov	tek41_ival,0	; clear the buffer
	jmp	tek40_ex
tek41_int7:
	inc	tek41_nget
	jmp	tek41_next
tek41_int8:
	jmp	tek40_ex	; PROGRAM ERROR !!!
;
tek41_str:
	mov	cx,tek41_larg	; check the room
	inc	cx
	cmp	cx,TEK41_ARGBUF_SIZE
	jae	tek41_str1	; ae = room is full
	mov	bx,offset tek41_argbuf
	add	bx,tek41_larg
	mov	[bx],al
	inc	tek41_larg	; update buffer length
tek41_str1:
	inc	tek41_nchr
	mov	cx,tek41_nchr
	cmp	cx,tek41_lstr
	jge	tek41_str2
	jmp	tek40_ex
tek41_str2:
	inc	tek41_nget
	jmp	tek41_next
;
; setup next argument for Tek41xx
;
tek41_next:
	mov	cx,tek41_nget	; number of arg. we have
	cmp	cx,tek41_narg	; enough ?
	jl	tek41_next1	; l=no, not.
	mov	tek41_nreq,TEK41_NO_ACT	; yes, we have enough, no more.
	jmp	tek41_exec	; execute the command.
tek41_next1:
	mov	bx,offset tek41_argt
	add	bx,cx
	mov	al,[bx]		; argument type
	mov	tek41_nact,al	; set next action
	cmp	al,TEK41_XY_TYPE
	jne	tek41_next2
	mov	tek41_nreq,TEK41_XY_TYPE	; next data type is XY-type
	mov	tek_vseq,0	; initialize vector format seq.
	jmp	tek40_ex
tek41_next2:
	cmp	al,TEK41_INT_TYPE
	jne	tek41_next3
	mov	tek41_nreq,TEK41_INT_TYPE	; next data type is INT
	mov	tek41_ival,0
	jmp	tek40_ex
tek41_next3:
	cmp	al,TEK41_STR_TYPE
	jne	tek41_next4
	mov	tek41_nreq,TEK41_INT_TYPE	; next data type is INT
	mov	tek41_ival,0
	mov	tek41_lstr,0
	mov	tek41_nchr,0
	jmp	tek40_ex
tek41_next4:
	cmp	al,TEK41_IAR_TYPE
	jne	tek41_next5
	mov	tek41_nreq,TEK41_INT_TYPE	; next data type is INT
	mov	tek41_ival,0
	mov	tek41_liar,0
	mov	tek41_niar,0
	jmp	tek40_ex
tek41_next5:
	jmp	tek40_ex			; PROGRAM ERROR !!!
;
; execute the Tek41 command
;
tek41_exec:
	mov	bx,tek41_func
	jmp	bx
;
tek41_exec_MC:
	mov	bx,offset tek41_argbuf
	mov	ax,[bx]			; text width
	mov	tek_gtxt_w,ax
	mov	ax,[bx+2]		; text height
	mov	tek_gtxt_h,ax
	mov	ax,[bx+4]		; text spacing
	mov	tek_gtxt_s,ax
	call	set_gtxt_vect
	jmp	tek41_exec_done
;
tek41_exec_ML:
	mov	ax,tek41_ival
;@@	call	tek41_getcol	; convert to tek41 color index
	mov	tek_lncol,ax
	jmp	tek41_exec_done
;
tek41_exec_MT:
	mov	ax,tek41_ival
;@@	call	tek41_getcol	; convert to tek41 color index
	mov	tek_txcol,ax
	jmp	tek41_exec_done
;
tek41_exec_MM:
	mov	ax,tek41_ival
	mov	marker_type,ax
	jmp	tek41_exec_done
;
tek41_exec_MP:
	mov	ax,tek41_ival
	cmp	ax,0
	jg	tek41_exec_MP2
	je	tek41_exec_MP1
	neg	ax
;@@	call	tek41_getcol	; convert to tek41 color index
tek41_exec_MP1:
	mov	tek_facol,ax
	mov	tek_famod,0
tek41_exec_MP2:
	jmp	tek41_exec_done
;
tek41_exec_MV:
	mov	ax,tek41_ival
	and	ax,07h
	mov	line_type,ax
	jmp	tek41_exec_done
;
tek41_exec_MR:
	mov	bx,offset tek41_argbuf
	mov	ax,[bx]			; rotation angle
	mov	cx,[bx+2]
	cmp	cx,0
	je	tek41_exec_MR_1
	jg	tek41_exec_MR_2
	neg	cx
	sar	ax,cl
	jmp	tek41_exec_MR_1
tek41_exec_MR_2:
	sal	ax,cl
tek41_exec_MR_1:
	cmp	ax,0
	jge	tek41_exec_MR_3
	add	ax,360
	jmp	tek41_exec_MR_1
tek41_exec_MR_3:
	cmp	ax,360
	jl	tek41_exec_MR_4
	sub	ax,360
	jmp	tek41_exec_MR_3
tek41_exec_MR_4:
	mov	tek_gtxt_ang,ax
	call	set_gtxt_vect
	jmp	tek41_exec_done
;
tek41_exec_KA:
	mov	ax,tek41_ival
	mov	tek_dialog_area,al
	jmp	tek41_exec_done
;
tek41_exec_LV:
	mov	ax,tek41_ival
	mov	tek_dialog_vsbl,al
	call	text_scrn
	jmp	tek41_exec_done
;
tek41_exec_LZ:
	mov	si,offset vt_dialog_clr
	xor	cx,cx
	xor	ax,ax
	mov	cl,[si]
	inc	si
	stc
	ret
;
tek41_exec_SETCOM:
	cmp	tek41_ival,0
	je	tek41_exec_nSETCOM
	mov	ah,1		; change the mode to VT
	mov	al,0
	xor	cx,cx
	mov	tek41_cmd,0
	mov	tek_esc,0
	ret
tek41_exec_nSETCOM:
tek41_exec_unknown:
	mov	tek41_cmd,0	; unknown command
	jmp	tek40_ex
;
tek41_exec_none:
	mov	ax,tek41_cmd
	xchg	ah,al
	mov	tek_ignor_msg,ax
	jmp	tek41_exec_done
;
tek41_exec_LG:
	cmp	tek_inpanel,0
	je	tek41_exec_LG1
	jmp	tek40_vct_fa
tek41_exec_LG1:
	mov	ax,line_type
	call	tek_ltyp
	mov	ax,tek_cur_x
	mov	bx,tek_cur_y
	call	tek40_dev_cood
	mov	pc98_x1,ax
	mov	pc98_y1,bx
	mov	ax,tek_req_x
	mov	bx,tek_req_y
	call	tek40_dev_cood
	call	tek_draw
	jmp	tek41_exec_LF1
tek41_exec_LH:
	cmp	tek_inpanel,0
	je	tek41_exec_LH1
	jmp	tek40_vct_fa
tek41_exec_LH1:
	mov	ax,tek_req_x
	mov	bx,tek_req_y
	call	tek40_dev_cood
	call	tek_mark
	jmp	tek41_exec_LF1
tek41_exec_LF:
	cmp	tek_inpanel,0
	je	tek41_exec_LF1
	jmp	tek40_vct_fa
tek41_exec_LF1:
	mov	ax,tek_req_x
	mov	tek_cur_x,ax
	mov	ax,tek_req_y
	mov	tek_cur_y,ax
	jmp	tek41_exec_done
;
tek41_exec_LT:
	cmp	tek_inpanel,0
	je	tek41_exec_LT1
	jmp	tek40_ex
tek41_exec_LT1:
	mov	cx,tek41_nchr		; get number of characters
	mov	si,offset tek41_argbuf
	add	si,2			; 1st 2-bytes contains num of char
	call	tek_gtxt		; draw graphic text
	jmp	tek41_exec_done
;
; Begin Panel Boundary
;
tek41_exec_LP:
	mov	si,offset tek41_fabuf
	cmp	tek_inpanel,0		; already in panel mode ?
	jne	tek41_exec_LP_c1	; ne=Yes. Close the previous polygon
	jmp	tek41_exec_LP_1
tek41_exec_LP_c1:
	mov	ax,tek41_lfa
	add	si,ax
	mov	bx,tek41_faadr		; get the address of the 1st point
	mov	ax,[bx+2]		; get 1st X
	mov	[si],ax			; add it to the last point
	mov	ax,[bx+4]		; get 1st Y
	mov	[si+2],ax		; add it to the last point
	add	tek41_lfa,4		; update buffer length
;
	cmp	tek_panel_bnd,0		; draw boundary ?
	je	tek41_exec_LP_c2	; e=no.
	mov	ax,[si]			; get the 1st X
	mov	bx,[si+2]		; get the 1st Y
	xchg	ax,pc98_x2
	xchg	bx,pc98_y2
	mov	pc98_x1,ax
	mov	pc98_y1,bx
	mov	ax,pc98_x2
	mov	bx,pc98_y2
	push	si			; save buffer address
	call	tek_draw
	pop	si
tek41_exec_LP_c2:
	add	si,4			; update buffer address
	jmp	tek41_exec_LP_2
tek41_exec_LP_1:
	mov	scan_xmin,639
	mov	scan_xmax,0
	mov	scan_ymin,399
	mov	scan_ymax,0
	mov	tek41_lfa,0
tek41_exec_LP_2:
	mov	tek41_faadr,si
	mov	ax,1			; 1st point
	mov	[si],ax
	mov	ax,tek_req_x
	mov	bx,tek_req_y
	mov	tek_cur_x,ax
	mov	tek_cur_y,bx
	call	tek40_dev_cood
	mov	[si+2],ax
	mov	[si+4],bx
	mov	pc98_x2,ax
	mov	pc98_y2,bx
	cmp	ax,scan_xmin
	jge	tek41_exec_LP_3
	mov	scan_xmin,ax
tek41_exec_LP_3:
	cmp	ax,scan_xmax
	jle	tek41_exec_LP_4
	mov	scan_xmax,ax
tek41_exec_LP_4:
	cmp	bx,scan_ymin
	jge	tek41_exec_LP_5
	mov	scan_ymin,bx
tek41_exec_LP_5:
	cmp	bx,scan_ymax
	jle	tek41_exec_LP_6
	mov	scan_ymax,bx
tek41_exec_LP_6:
	add	tek41_lfa,6
	mov	tek_inpanel,1
	mov	ax,tek41_ival
	mov	tek_panel_bnd,al		; set panel boundary mode
	test	al,1
	jz	tek41_exec_LP_ex
	mov	ax,line_type
	call	tek_ltyp
tek41_exec_LP_ex:
	jmp	tek41_exec_done
;
tek41_exec_LE:
	mov	tek_inpanel,0
;
	mov	si,offset tek41_fabuf
	mov	ax,tek41_lfa
	add	si,ax
	mov	bx,tek41_faadr
	mov	ax,[bx+2]		; get 1st X
	mov	[si],ax			; add it to the last point
	mov	ax,[bx+4]		; get 1st Y
	mov	[si+2],ax		; add it to the last point
	xor	ax,ax			; terminator
	mov	[si+4],ax		; set terminator
	add	tek41_lfa,6		; update buffer length
;
	cmp	tek_panel_bnd,0
	je	tek41_exec_LE6
	mov	ax,[si]
	mov	bx,[si+2]
	xchg	ax,pc98_x2
	xchg	bx,pc98_y2
	mov	pc98_x1,ax
	mov	pc98_y1,bx
	mov	ax,pc98_x2
	mov	bx,pc98_y2
	call	tek_draw
;
tek41_exec_LE6:
	mov	si,offset tek41_fabuf
	call	tek_fill
tek41_exec_LE_ex:
	jmp	tek41_exec_done
;
tek41_exec_RW:
	push	ax
	push	bx
;
; Check the variables
;
	mov	si,offset tek41_argbuf
	mov	ax,[si]			; x1
	mov	bx,[si+4]		; x2
	cmp	ax,bx
	jl	tek41_exec_RW1
	jmp	tek41_exec_RW_ERR
tek41_exec_RW1:
	mov	ax,[si+2]		; y1
	mov	bx,[si+6]		; y2
	cmp	ax,bx
	jl	tek41_exec_RW2
	jmp	tek41_exec_RW_ERR
tek41_exec_RW2:
;
; Check OK. Do it.
;
	mov	ax,[si]
	mov	tek_wnx1,ax
	mov	ax,[si+2]
	mov	tek_wny1,ax
	mov	ax,[si+4]
	mov	tek_wnx2,ax
	mov	ax,[si+6]
	mov	tek_wny2,ax
;
	push	si
	push	di
	mov	si,offset tek_wnx1
	mov	di,offset tek_w2v_mat
	call	set_tek41_mat		; set the transformation matrix
	pop	di
	pop	si
	jmp	tek41_exec_RW_ex
;
tek41_exec_RW_ERR:
tek41_exec_RW_ex:
	pop	bx
	pop	ax
	jmp	tek41_exec_done
;
tek41_exec_TM:
	push	bx
	mov	bx,offset tek41_argbuf
	mov	ax,[bx]
	cmp	ax,0
	je	tek41_exec_TM1
	mov	tek_cmode_1,al
tek41_exec_TM1:
	add	bx,2
	mov	ax,[bx]
	cmp	ax,0
	je	tek41_exec_TM2
	mov	tek_cmode_2,al
tek41_exec_TM2:
	add	bx,2
	mov	ax,[bx]
	cmp	ax,0
	je	tek41_exec_TM3
	mov	tek_cmode_3,al
tek41_exec_TM3:
	pop	bx
	jmp	tek41_exec_done
;
tek41_exec_TG:
	push	si
	mov	si,offset tek41_argbuf
	mov	ax,[si]			; ignore surface number
tek41_exec_TG1:
	mov	ax,[si+2]		; array size
	cmp	ax,4			; must be multiple of 4
	jge	tek41_exec_TG2
	jmp	tek41_exec_TG_ex
tek41_exec_TG2:
	shr	ax,1
	shr	ax,1			; number of colors
	mov	cx,ax
	add	si,4
tek41_exec_TG_L1:
	cmp	cx,0
	jg	tek41_exec_TG_L2
	jmp	tek41_exec_TG_do
tek41_exec_TG_L2:
	mov	ax,[si]			; get index
	cmp	ax,0
	jge	tek41_exec_TG3
	jmp	tek41_exec_TG_nx
tek41_exec_TG3:
	cmp	ax,15
	jle	tek41_exec_TG4
	jmp	tek41_exec_TG_nx
tek41_exec_TG4:
	cmp	tek_cmode_1,1		; RGB [0-100] mode ?
	jne	tek41_exec_TG5
	jmp	tek41_exec_TG_RGB1
tek41_exec_TG5:
	cmp	tek_cmode_1,2		; CMY [0-100] mode ?
	jne	tek41_exec_TG6
	jmp	tek41_exec_TG_CMY
tek41_exec_TG6:
	cmp	tek_cmode_1,3		; HLS mode ?
	jne	tek41_exec_TG7
	jmp	tek41_exec_TG_HLS
tek41_exec_TG7:
	cmp	tek_cmode_1,4		; RGB [0-255] mode ?
	jne	tek41_exec_TG8
	jmp	tek41_exec_TG_RGB2
tek41_exec_TG8:
	jmp	tek41_exec_TG_ex	; other cases are not supported yet.
tek41_exec_TG_HLS:
	push	si
	add	si,2
	call	HLS_to_RGB
	pop	si
	jmp	tek41_exec_TG_RGB1
tek41_exec_TG_CMY:
	push	bx
	mov	ax,100
	mov	bx,[si+2]
	sub	ax,bx
	mov	[si+2],ax
	mov	ax,100
	mov	bx,[si+4]
	sub	ax,bx
	mov	[si+4],ax
	mov	ax,100
	mov	bx,[si+6]
	sub	ax,bx
	mov	[si+6],ax
	pop	bx
tek41_exec_TG_RGB1:
	push	bx
	push	dx
	mov	bx,655
	mov	ax,[si+2]		; get R
	mul	bx
	mov	al,ah
	xor	ah,ah
	mov	[si+2],ax
	mov	ax,[si+4]		; G
	mul	bx
	mov	al,ah
	xor	ah,ah
	mov	[si+4],ax
	mov	ax,[si+6]		; B
	mul	bx
	mov	al,ah
	xor	ah,ah
	mov	[si+6],ax
	pop	dx
	pop	bx
tek41_exec_TG_RGB2:
	push	bx
	mov	bx,offset tek_col
	mov	ax,[si]			; get index
	add	bx,ax
	add	bx,ax
	add	bx,ax
	mov	ax,[si+2]
	mov	[bx],al
	mov	ax,[si+4]
	mov	[bx+1],al
	mov	ax,[si+6]
	mov	[bx+2],al
	pop	bx
tek41_exec_TG_nx:
	dec	cx
	add	si,8			; 4 integers are processed.
	jmp	tek41_exec_TG_L1
tek41_exec_TG_do:
	mov	si,offset tek_col
	call	set_gpalette
tek41_exec_TG_ex:
	pop	si
;
tek41_exec_done:
	mov	tek41_cmd,0
	mov	tek_esc,0
	jmp	tek40_ex
;
tek40_vtchg:
	cmp	tek_P_prv,'?'
	jne	tek40_vtchg_ex
	cmp	tek_P_buf,38
	jne	tek40_vtchg_ex
	mov	ah,1
	mov	al,0
	mov	cx,0
	clc
	ret
tek40_vtchg_ex:
	jmp	tek40_esc_ex
 
;  Alpha mode: If printable character, then put the character at
;  current position.
;---------
tek40_alp:
;---------
	and	al,07Fh
	cmp	al,' '		; C0 character ?
	jae	tek40_alp_01	; ae=no.
	jmp	tek40_C0
tek40_alp_01:
	cmp	tek_dialog_area,0	; dialog on graphic screen ?
	je	tek40_alp_02	; e = yes.
	mov	si,offset vt_buf
	mov	[si],al
	mov	cx,1
	stc			; set carry to pass the char. to VT
	ret
tek40_alp_02:
	sub	al,' '
	xor	ah,ah
	shl	ax,1
	shl	ax,1
	shl	ax,1
	mov	si,offset gfont88
	add	si,ax
	mov	di,offset ggdc_buff
	mov	byte ptr [di],078h	; TEXTW
	mov	byte ptr [di+1],8	; number of parameters
	add	di,2
	cld
	mov	cx,8
	push	es
	push	ds
	pop	es
	rep	movsb
	pop	es
;	add	di,8
	mov	ax,tek_cur_x
	mov	bx,tek_cur_y
	call	tek40_dev_cood
	push	di
;@@	mov	cx,GGDC_GREEN_PLANE	; cursor graphic plane
	xor	cx,cx
	call	gcsrw
	mov	byte ptr [di],20h
	mov	byte ptr [di+1],0
	add	di,2
	mov	byte ptr [di],04Ch	; VEXTW
	mov	byte ptr [di+1],3	; number of parameters
	mov	byte ptr [di+2],012h	; normal text dir=2
	mov	byte ptr [di+3],07h
	mov	byte ptr [di+4],0
	mov	byte ptr [di+5],068h	; TEXTE
	mov	byte ptr [di+6],0
	mov	byte ptr [di+7],0FFh	; terminator
	mov	si,offset ggdc_buff
;@@	call	send_to_GGDC
	mov	ax,tek_txcol		; set text color
	pop	di
	call	GGDC_color
	mov	ax,TEK_DX
	add	tek_cur_x,ax
	jmp	tek40_ex
;--------
tek40_C0:
;--------
	cmp	al,ESCAPE		; need to handle in this module?
	jl	tek40_C01		; l=no. May go to vt
	jmp	tek40_C02
tek40_C01:
	cmp	tek_dialog_area,0	; dialog on graphics ?
	je	tek40_C01_1		; e=yes.
	mov	tek_esc,0
	mov	tek_mod,0
	mov	si,offset vt_buf
	mov	[si],al
	mov	cx,1
	stc				; set carry to pass AL to VT
	ret
tek40_C01_1:
	mov	tek_esc,0
	mov	tek_mod,0
	cmp	al,BELL
	jne	tek40_n07
	call	pc98_bell
	jmp	tek40_ex
tek40_n07:
	cmp	al,BS
	jne	tek40_n08
	sub	tek_cur_x,TEK_DX
	cmp	tek_cur_x,0
	jge	tek40_08_01
	mov	tek_cur_x,0
tek40_08_01:
	mov	tek_esc,0
	jmp	tek40_ex
tek40_n08:
;
	cmp	al,HT
	jne	tek40_n09
	add	tek_cur_x,TEK_DX
	cmp	tek_cur_x,TEK_X_MAX
	jle	tek40_09_01
	mov	tek_cur_x,TEK_X_MAX
tek40_09_01:
	mov	tek_esc,0
	jmp	tek40_ex
tek40_n09:
;
	cmp	al,LF
	jne	tek40_n0A
	sub	tek_cur_y,TEK_DY
	cmp	tek_cur_y,0
	jge	tek40_0A_01
	mov	tek_cur_y,TEK_Y_MAX
	sub	tek_cur_y,TEK_DY
tek40_0A_01:
	mov	tek_esc,0			; ESC seq done
	jmp	tek40_ex
tek40_n0A:
;
	cmp	al,VT
	jne	tek40_n0B
	jmp	tek40_ex
tek40_n0B:
	cmp	al,CR
	jne	tek40_n0D
	mov	tek_cur_x,0
	mov	tek_mod,0			; enter alpha mode
	mov	tek_esc,0			; ESC seq done
	jmp	tek40_ex
tek40_n0D:
;
	cmp	al,CL_CAN
	jne	tek40_n18
	mov	tek_mod,0
	mov	tek_esc,0
;
; Leave tektronix mode if tek4010 enabled
;
	test	vt100_flags,AUTOTEK_BIT
	jz	tek40_18_01
	mov	ah,1			; pass no character
	mov	al,0
	mov	cx,0
	clc
	ret
tek40_18_01:
	jmp	tek40_ex
tek40_n18:
;
; ESC, FS, GS, RS, US must be analyzed in TeK module
;
tek40_C02:
	cmp	al,ESCAPE
	jne	tek40_n1B
	mov	tek_esc,1			; initiate ESC sequence
	jmp	tek40_ex
tek40_n1B:
;
	cmp	al,FS
	jne	tek40_n1C
	mov	tek_mod,2			; enter point plot mode
	mov	tek_vseq,0			; reset xy order sequence
	mov	di,offset ggdc_buff
	mov	byte ptr [di],078h		; TEXTW command
	mov	byte ptr [di+1],2		; number of parameters
	mov	word ptr [di+2],0FFFFh		; set line type to solid
	mov	byte ptr [di+4],0FFh		; terminator
	mov	si,offset ggdc_buff
	call	send_to_GGDC
	mov	tek_esc,0			; ESC seq done
	jmp	tek40_ex
tek40_n1C:
;
	cmp	al,GS
	jne	tek40_n1D
	mov	tek_mod,1			; enter graph mode
	mov	tek_npnt,0			; reset number of points
	mov	tek_vseq,0
	mov	ax,line_type
	call	tek_ltyp
	mov	tek_esc,0			; ESC seq done
	jmp	tek40_ex
tek40_n1D:
;
	cmp	al,RS
	jne	tek40_n1E
	mov	tek_mod,3			; enter incremental plot mode
	mov	tek_pen,0			; reset pen state
	mov	di,offset ggdc_buff
	mov	byte ptr [di],078h		; TEXTW command
	mov	byte ptr [di+1],2		; number of parameters
	mov	word ptr [di+2],0FFFFh		; set line type to solid
	mov	byte ptr [di+4],0FFh		; terminator
	mov	si,offset ggdc_buff
	call	send_to_GGDC
	mov	tek_esc,0			; ESC seq done
	jmp	tek40_ex
tek40_n1E:
;
	cmp	al,US
	jne	tek40_n1F
	mov	tek_mod,0			; enter alpha mode
	mov	line_type,0
	mov	tek_esc,0			; ESC seq done
	jmp	tek40_ex
tek40_n1F:
	mov	tek_esc,0		; Unknonw C0 character
	jmp	tek40_ex

;---------
tek40_vct:
;---------
	and	al,07Fh			; Mask 8th bit
	cmp	al,' '			; Control character ?
	jae	tek40_vct_01		; ae = No.
	cmp	al,ESCAPE
	jae	tek40_vct_C0
	cmp	al,CR
	jne	tek40_vct_n0D
	cmp	tek_dialog_area,0	; disable dialog ?
	je	tek40_vct_C0		; e=yes.
tek40_vct_n0D:
	jmp	tek40_ex		; any other C0 characters are ignored.
tek40_vct_C0:
	jmp	tek40_C0		; Yes. control character.
tek40_vct_01:
	mov	ah,al
	and	ah,060h
	and	al,01Fh
;
	cmp	tek_vseq,0
	jne	tek40_vct_02
tek40_vct_HIY:
	cmp	ah,HIY			; HIY data ?
	jne	tek40_vct_EXT
	mov	tek_cur_HIY,al		; Yes. Fill HIY
	mov	tek_vseq,1		; Next is EXT
	jmp	tek40_vct_end
tek40_vct_02:
	cmp	tek_vseq,1		; EXT order?
	jne	tek40_vct_03
tek40_vct_EXT:
	cmp	ah,EXT			; EXT data ?
	jne	tek40_vct_LOY
	mov	tek_cur_LOY,al		; Yes. Temporary store to LOY
	mov	tek_vseq,2		; Next is LOY
	jmp	tek40_vct_end
tek40_vct_03:
	cmp	tek_vseq,2		; LOY order ?
	jne	tek40_vct_04
tek40_vct_LOY:
	cmp	ah,LOY			; LOY data ?
	jne	tek40_vct_HIX
	mov	ah,tek_cur_LOY		; Yes. LOY/EXT appears twice.
	mov	tek_cur_EXT,ah		; Previous is EXT and current is LOY
	mov	tek_cur_LOY,al
	mov	tek_vseq,3		; Next is HIX
	jmp	tek40_vct_end
tek40_vct_04:
	cmp	tek_vseq,3		; HIX order ?
	jne	tek40_vct_05
tek40_vct_HIX:
	cmp	ah,HIX			; HIX data ?
	jne	tek40_vct_LOX		; No. Test LOX data
	mov	tek_cur_HIX,al		; Yes. Set HIX
	mov	tek_vseq,4		; Next is LOX
	jmp	tek40_vct_end
tek40_vct_05:
	cmp	tek_vseq,4		; LOX order ?
	jne	tek40_vct_ERR
tek40_vct_LOX:
	cmp	ah,LOX			; LOX data ?
	jne	tek40_vct_ERR		; No. This is error
	mov	tek_cur_LOX,al		; Yes. Set LOX
	mov	tek_vseq,0		; GS seq done
	jmp	tek40_get_xy
tek40_vct_ERR:
	call	pc98_bell
	mov	tek_vseq,0
	mov	tek_npnt,0
	cmp	tek_esc,4		; in Tek41 command ?
	jne	tek40_vct_ERR1		; ne = no.
	mov	tek_req_x,0
	mov	tek_req_y,0
	jmp	tek41_xy1
tek40_vct_ERR1:
	jmp	tek40_vct_end
;
;  Convert TEK xy representation to the binary (x,y)
;
tek40_get_xy:
	mov	al,tek_cur_HIY		; get HIY
	xor	ah,ah			; clear higher byte
	mov	cl,5			; number of shifts
	shl	ax,cl			; HIY done
	or	al,tek_cur_LOY		; add LOY
	shl	ax,1
	shl	ax,1
	mov	bl,tek_cur_EXT		; get EXT
	shr	bl,1
	shr	bl,1
	and	bl,3			; Lower 2 bits have meaning
	or	al,bl			; all done.
	mov	tek_req_y,ax		; set requested y
;
	mov	al,tek_cur_HIX		; get HIX
	xor	ah,ah			; clear higher byte
	mov	cl,5			; number of shifts
	shl	ax,cl			; HIX is set
	or	al,tek_cur_LOX		; add LOX
	shl	ax,1
	shl	ax,1
	mov	bl,tek_cur_EXT		; get EXT
	and	bl,3			; Only lower 2 bits have meaning
	or	al,bl			; all done.
	mov	tek_req_x,ax		; set requested x
;
	cmp	tek_esc,4		; in TeK41 command ?
	jne	tek40_get_xy1		; ne = no.
	jmp	tek41_xy1
tek40_get_xy1:
	cmp	tek_inpanel,0		; in Panel mode ?
	je	tek40_get_xy2		; e = no.
	jmp	tek40_vct_fa
tek40_get_xy2:
;
	cmp	tek_mod,1
	je	tek40_vec_ln
	jmp	tek40_vct_pt
tek40_vec_ln:
	cmp	tek_npnt,0
	jne	tek40_vct_ln01
	mov	tek_npnt,1
	jmp	tek40_vct_do1
;
tek40_vct_ln01:
;
;	Not the first point. Draw line.
;
	mov	ax,tek_cur_x
	mov	bx,tek_cur_y
	call	tek40_dev_cood
	mov	pc98_x1,ax
	mov	pc98_y1,bx
	mov	ax,tek_req_x
	mov	bx,tek_req_y
	call	tek40_dev_cood
	mov	pc98_x2,ax
	mov	pc98_y2,bx
	call	tek_draw
	jmp	tek40_vct_do1
;
; Point plot mode
;
tek40_vct_pt:
	mov	ax,tek_req_x
	mov	bx,tek_req_y
	call	tek40_dev_cood
	call	tek_mark
;
tek40_vct_do:
	mov	di,si
;@@	call	send_to_GGDC
	call	GGDC_color
tek40_vct_do1:
	mov	ax,tek_req_x
	mov	tek_cur_x,ax
	mov	ax,tek_req_y
	mov	tek_cur_y,ax
	jmp	tek40_vct_end
;
tek40_vct_fa:
	mov	ax,tek_req_x
	mov	bx,tek_req_y
	call	tek40_dev_cood
	mov	cx,tek41_lfa
	add	cx,10			; requested length
	cmp	cx,TEK41_FABUF_SIZE	; have enough room ?
	jbe	tek40_vct_fa1		; be=yes
	jmp	tek40_vct_fa2
tek40_vct_fa1:
	push	si
	mov	si,offset tek41_fabuf
	add	si,tek41_lfa
	mov	[si],ax
	mov	[si+2],bx
	add	tek41_lfa,4
	mov	si,tek41_faadr
	mov	cx,[si]
	inc	cx
	mov	[si],cx			; increment number of points
	pop	si
	cmp	ax,scan_xmin
	jge	tek40_vct_fa1_1
	mov	scan_xmin,ax
tek40_vct_fa1_1:
	cmp	ax,scan_xmax
	jle	tek40_vct_fa1_2
	mov	scan_xmax,ax
tek40_vct_fa1_2:
	cmp	bx,scan_ymin
	jge	tek40_vct_fa1_3
	mov	scan_ymin,bx
tek40_vct_fa1_3:
	cmp	bx,scan_ymax
	jle	tek40_vct_fa1_4
	mov	scan_ymax,bx
tek40_vct_fa1_4:
tek40_vct_fa2:
	cmp	tek_panel_bnd,0
	je	tek40_vct_end
	xchg	ax,pc98_x2
	xchg	bx,pc98_y2
	mov	pc98_x1,ax
	mov	pc98_y1,bx
	mov	ax,pc98_x2
	mov	bx,pc98_y2
	call	tek_draw
tek40_vct_end:
	jmp	tek40_ex
;
; Incremental Plot
;
tek40_inc:
	and	al,07Fh			; mask 8th bit
	cmp	al,'A'			; move to right?
	jne	tek40_inc_NA		; ne = no
	inc	tek_cur_x
	jmp	tek40_inc_do
tek40_inc_NA:
	cmp	al,'B'			; move to left?
	jne	tek40_inc_NB		; ne = no.
	dec	tek_cur_x
	jmp	tek40_inc_do
tek40_inc_NB:
	cmp	al,'D'			; move to up?
	jne	tek40_inc_ND		; ne = no.
	inc	tek_cur_y
	jmp	tek40_inc_do
tek40_inc_ND:
	cmp	al,'H'			; move to down?
	jne	tek40_inc_NH		; ne = no.
	dec	tek_cur_y
	jmp	tek40_inc_do
tek40_inc_NH:
	cmp	al,'E'			; move to right up
	jne	tek40_inc_NE
	inc	tek_cur_x
	inc	tek_cur_y
	jmp	tek40_inc_do
tek40_inc_NE:
	cmp	al,'J'
	jne	tek40_inc_NJ
	dec	tek_cur_x
	dec	tek_cur_y
	jmp	tek40_inc_do
tek40_inc_NJ:
	cmp	al,'F'
	jne	tek40_inc_NF
	dec	tek_cur_x
	inc	tek_cur_y
	jmp	tek40_inc_do
tek40_inc_NF:
	cmp	al,'I'
	jne	tek40_inc_NI
	inc	tek_cur_x
	dec	tek_cur_y
	jmp	tek40_inc_do
tek40_inc_NI:
	cmp	al,' '
	jne	tek40_inc_NS
	mov	tek_pen,0
	jmp	tek40_ex
tek40_inc_NS:
	cmp	al,'P'
	jne	tek40_inc_NP
	mov	tek_pen,1
	jmp	tek40_ex
tek40_inc_NP:
	mov	tek_mod,0		; Enter alpha mode
	jmp	tek40_00
tek40_inc_do:
	cmp	tek_pen,0
	jne	tek40_inc_do1
	jmp	tek40_ex
tek40_inc_do1:
	mov	di,offset ggdc_buff
	mov	ax,tek_cur_x
	mov	bx,tek_cur_y
	call	tek40_dev_cood
;@@	mov	cx,GGDC_GREEN_PLANE
	xor	cx,cx
	call	gcsrw
	mov	byte ptr [di],20h
	mov	byte ptr [di+1],0
	add	di,2
;
	mov     byte ptr [di],4ch		; VECTW command
	mov	byte ptr [di+1],9		; number of parameters
;
	mov	byte ptr [di+2],0		; dir
	mov	word ptr [di+3],0		; abs(d_x)
	mov	word ptr [di+5],0		; 2*abs(d_y)-abs(d_x)
	mov	word ptr [di+7],0		; 2*abs(d_y)-2*abs(d_x)
	mov	word ptr [di+9],0		; 2*abs(d_y)
;
	mov	byte ptr [di+11],6ch		; VECTE command
	mov	byte ptr [di+12],0		; with no parameters
	add	di,13				; update address
;
	mov	byte ptr [di],0FFh		; set terminator
	mov	si,offset ggdc_buff
	mov	ax,tek_lncol			; set line color
;
	mov	di,si
;@@	call	send_to_GGDC
	call	GGDC_color
	jmp	tek40_ex
;
TEK4014	ENDP
;
tek_ltyp	proc	near
;
; Set line type in AX
;
	shl	ax,1
	mov	si,offset line_type_table
	add	si,ax
	mov	ax,[si]
	mov	di,offset ggdc_buff
	mov	byte ptr [di],078h	; TEXTW command
	mov	byte ptr [di+1],2	; number of parameters
	mov	word ptr [di+2],ax	; line type
	mov	byte ptr [di+4],0FFh	; terminator
	mov	si,offset ggdc_buff
	call	send_to_GGDC
	ret
tek_ltyp	endp
;
tek_draw	proc	near
;
; Draw line between from (pc98_x1,pc98_y1) to (ax,bx)
;
	push	ax
	push	bx
	mov	di,offset ggdc_buff
	mov	ax,pc98_x1
	mov	bx,pc98_y1
	xor	cx,cx
	call	gcsrw
	mov	byte ptr [di],20h
	mov	byte ptr [di+1],0
	add	di,2
	pop	bx
	pop	ax
	sub	ax,pc98_x1
	sub	bx,pc98_y1
	call	gline
	mov	byte ptr [di],0FFh
	mov	si,offset ggdc_buff
	mov	ax,tek_lncol
	mov	di,si
	call	GGDC_color
	ret
tek_draw	endp
;
tek_mark	proc	near
;
;  Put marker at (ax,bx) given in device coordinate
;
	cmp	marker_type,0		; marker type 0 ?
	je	tek_mark_0		; e=yes
	jmp	tek_mark_n0
tek_mark_0:
	xor	cx,cx
	call	gcsrw
	mov	byte ptr [di],20h
	mov	byte ptr [di+1],0
	add	di,2
;
	mov     byte ptr [di],4ch		; VECTW command
	mov	byte ptr [di+1],9		; number of parameters
;
	mov	byte ptr [di+2],0		; dir
	mov	word ptr [di+3],0		; abs(d_x)
	mov	word ptr [di+5],0		; 2*abs(d_y)-abs(d_x)
	mov	word ptr [di+7],0		; 2*abs(d_y)-2*abs(d_x)
	mov	word ptr [di+9],0		; 2*abs(d_y)
;
	mov	byte ptr [di+11],6ch		; VECTE command
	mov	byte ptr [di+12],0		; with no parameters
	add	di,13				; update address
;
	mov	byte ptr [di],0FFh		; set terminator
	mov	si,offset ggdc_buff
	mov	ax,tek_lncol			; set line color
	mov	di,si
	jmp	tek_mark_do
tek_mark_n0:
	push	ax
	push	bx
	mov	ax,marker_type
	xor	ah,ah
	shl	ax,1
	shl	ax,1
	shl	ax,1
	mov	si,offset gmark88
	add	si,ax
	mov	di,offset ggdc_buff
	mov	byte ptr [di],078h	; TEXTW
	mov	byte ptr [di+1],8	; number of parameters
	add	di,2
	cld
	mov	cx,8
	push	es
	push	ds
	pop	es
	rep	movsb
	pop	es
;@@	add	di,8
	mov	byte ptr [di],0ffh	; set terminator
	mov	si,offset ggdc_buff
	call	send_to_GGDC
	pop	bx
	pop	ax			; remember x position
	add	ax,mark_dx
	add	bx,mark_dy
	mov	di,offset ggdc_buff
	xor	cx,cx
	call	gcsrw
	mov	byte ptr [di],20h
	mov	byte ptr [di+1],0
	add	di,2
	mov	byte ptr [di],04Ch	; VECTW
	mov	byte ptr [di+1],3	; number of parameters
	mov	byte ptr [di+2],012h	; normal text dir=2
	mov	byte ptr [di+3],07h
	mov	byte ptr [di+4],0
	mov	byte ptr [di+5],068h	; TEXTE
	mov	byte ptr [di+6],0
	mov	byte ptr [di+7],0FFh	; terminator
	mov	di,offset ggdc_buff
	mov	si,di
	mov	ax,tek_lncol		; set marker color
tek_mark_do:
	call	GGDC_color
	ret
tek_mark	endp
;
tek_gtxt	proc	near
;
; Write Graphic Text
;	cx	number of characters
;	[si]	strings
;
tek_gtxt1:
	cmp	cx,0
	jg	tek_gtxt2
	jmp	tek_gtxt_ex
tek_gtxt2:
	push	cx
	push	si
;
	mov	al,[si]
	and	al,07Fh
	cmp	al,' '
	jae	tek_gtxt3
	mov	al,' '
tek_gtxt3:
	sub	al,' '
	xor	ah,ah
	shl	ax,1
	shl	ax,1
	shl	ax,1
	mov	si,offset gfont88
	add	si,ax
	mov	di,offset ggdc_buff
	mov	byte ptr [di],078h	; TEXTW
	mov	byte ptr [di+1],8	; number of parameters
	add	di,2
	cld
	mov	cx,8
	push	es
	push	ds
	pop	es
	rep	movsb
	pop	es
;	add	di,8
	mov	byte ptr [di],0FFh	; set terminator
	mov	si,offset ggdc_buff
	call	send_to_GGDC
;
	mov	ax,tek_cur_x
	mov	bx,tek_cur_y
	call	tek40_dev_cood
	mov	di,offset ggdc_buff
;@@	mov	cx,GGDC_GREEN_PLANE	; cursor graphic plane
	xor	cx,cx
	call	gcsrw
	mov	byte ptr [di],20h
	mov	byte ptr [di+1],0
	add	di,2
	mov	byte ptr [di],04Ch	; VEXTW
	mov	byte ptr [di+1],3	; number of parameters
	mov	al,010h			; normal text
	or	al,tek_gtxt_dr		; set text dir
	mov	byte ptr [di+2],al
	mov	byte ptr [di+3],07h
	mov	byte ptr [di+4],0
	mov	byte ptr [di+5],068h	; TEXTE
	mov	byte ptr [di+6],0
	mov	byte ptr [di+7],0FFh	; terminator
	mov	si,offset ggdc_buff
	mov	di,si
;@@	call	send_to_GGDC
	mov	ax,tek_lncol		; set text color
	call	GGDC_color
	mov	ax,tek_gtxt_ux
	add	tek_cur_x,ax
	mov	ax,tek_gtxt_uy
	add	tek_cur_y,ax
;
	pop	si
	pop	cx
	inc	si
	dec	cx
	jmp	tek_gtxt1
tek_gtxt_ex:
	ret
tek_gtxt	endp
;
; Routines for Fill Area
;
scan_clr	proc	near
;
; Purpose: Clear the scan buffer, scan_buf.
; Input:   none
; Output:  none
;
	push	ax
	push	cx
	push	di
	push	es
;
	cld
	mov	cx,40			; size of the scan buffer in words
	mov	di,offset scan_buf
	push	ds
	pop	es			; es = ds
	xor	ax,ax			; data
	rep	stosw			; string clear
;
	pop	es
	pop	di
	pop	cx
	pop	ax
	ret
scan_clr	endp
;
scan_cross	proc	near
;
; Purpose:  calculate the cross point of the line and scan_y
; Input:    san_y, [si], scan_xmin, scan_xmax, bit_on
; Output:   scan_buf
; WorkArea: pc98_x1, pc98_y1, pc98_x2, pc98_y2
;
	push	ax
	push	bx
	push	dx
;
	mov	ax,[si+2]		; y1
	mov	bx,[si+6]		; y2
	cmp	bx,ax			; y2 > y1 ?
	jg	scan_cross_1		; g=yes
	mov	pc98_y1,bx
	mov	pc98_y2,ax
	mov	ax,[si+4]
	mov	bx,[si]
	jmp	scan_cross_2
scan_cross_1:
	mov	pc98_y1,ax
	mov	pc98_y2,bx
	mov	ax,[si]
	mov	bx,[si+4]
scan_cross_2:
	mov	pc98_x1,ax
	mov	pc98_x2,bx
	mov	ax,scan_y
	cmp	ax,pc98_y1		; scan_y >= y1
	jge	scan_cross_3		; ge=yes
	jmp	scan_cross_ex
scan_cross_3:
	cmp	ax,pc98_y2		; scan_y < y2
	jl	scan_cross_4		; l=yes
	jmp	scan_cross_ex
scan_cross_4:
	sub	ax,pc98_y1		; ax = scan_y - y1
	mov	bx,pc98_x2
	sub	bx,pc98_x1		; bx = x2 - x1
	imul	bx			; dx:ax =(scan_y - y1)*(x2-x1)
	mov	bx,pc98_y2
	sub	bx,pc98_y1		; bx = y2 - y1
	idiv	bx			; dx:ax =(scan_y-y1)*(x2-x1)/(y2-y1)
	add	ax,pc98_x1
	cmp	ax,scan_xmin		; scan_x < xmin ?
	jge	scan_cross_5		; ge = no
	mov	ax,scan_xmin
scan_cross_5:
	cmp	ax,scan_xmax		; scan_x > xmax ?
	jle	scan_cross_6		; le = no
	mov	ax,scan_xmax
scan_cross_6:
	push	ax
	and	ax,07h
	mov	bx,offset bit_on
	add	bx,ax
	mov	dl,[bx]
	pop	ax
	mov	bx,offset scan_buf
	shr	ax,1
	shr	ax,1
	shr	ax,1
	add	bx,ax
	xor	[bx],dl
scan_cross_ex:
	pop	dx
	pop	bx
	pop	ax
	ret
scan_cross	endp
;
scan_fill	proc	near
;
; fill the scan line
;
	push	ax
	push	bx
	push	cx
	push	dx
	push	si
;
	mov	si,offset scan_buf
	add	si,scan_xstr
	mov	dx,0ff00h		; dh:fill, dl:no-fill
	mov	cx,scan_xlen
scan_fill_1:
	mov	al,[si]
	cmp	al,0
	jne	scan_fill_2
	mov	[si],dl
	jmp	scan_fill_5
scan_fill_2:
	push	cx
	mov	cx,8
	mov	bx,offset bit_on
scan_fill_3:
	mov	ah,[bx]
	and	ah,al
	cmp	ah,0
	je	scan_fill_4
	xchg	dh,dl
scan_fill_4:
	mov	ah,[bx]
	and	ah,dl
	or	[si],ah
	inc	bx
	loop	scan_fill_3
	pop	cx
scan_fill_5:
	inc	si
	loop	scan_fill_1
	pop	si
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
scan_fill	endp
;
scan_put	proc	near
;
; Put the scan line to the graphic screen
;
	push	es
	cld
	mov	dx,1
	xor	ch,ch
	mov	cl,gplane_nums
	mov	bx,offset gplane_segm
scan_put1:
	push	bx
	push	cx
	mov	ax,[bx]
	mov	es,ax
	mov	di,scan_ofs
	mov	si,offset scan_buf
	add	si,scan_xstr
	mov	cx,scan_xlen
	test	tek_facol,dx
	jz	scan_put3
scan_put2:
	lodsb
	or	es:[di],al
	inc	di
	loop	scan_put2
	jmp	scan_put4
scan_put3:
	lodsb
	xor	al,0ffh
	and	es:[di],al
	inc	di
	loop	scan_put3
scan_put4:
	pop	cx
	pop	bx
	add	bx,2
	shl	dx,1
	loop	scan_put1
scan_put_ex:
	pop	es
	ret
scan_put	endp
;
tek_fill	proc	near
;
; Fill area
;
	mov	ax,scan_ymin
	mov	scan_y,ax
	shl	ax,1
	shl	ax,1
	add	ax,scan_y		; ax=scan_y*5
	mov	cx,4
	shl	ax,cl			; ax=scan_y*80
	mov	scan_ofs,ax
	mov	ax,scan_xmin
	mov	cx,3
	shr	ax,cl
	mov	scan_xstr,ax		; start byte address in x
	add	scan_ofs,ax
	mov	ax,scan_xmax
	mov	cx,3
	shr	ax,cl
	sub	ax,scan_xstr
	inc	ax
	mov	scan_xlen,ax
;
	cmp	gdisp_mode,0
	je	tek_fill_1
	jmp	tek_fill_GC1
tek_fill_1:
	mov	ax,scan_y
	cmp	ax,scan_ymax
	jle	tek_fill_2
	jmp	tek_fill_ex
tek_fill_2:
	call	scan_clr			; clear the scan buffer
	mov	si,offset tek41_fabuf		; position of the line
;
tek_fill_3:
	mov	cx,[si]				; get number of points
	jcxz	tek_fill_5
	add	si,2
tek_fill_4:
	call	scan_cross
	add	si,4
	loop	tek_fill_4
	add	si,4
	jmp	tek_fill_3
tek_fill_5:
	call	scan_fill
	call	scan_put
	inc	scan_y
	add	scan_ofs,80
	jmp	tek_fill_1
;
tek_fill_GC1:
	cld
	mov	al,0C0h		; GRCG on, RMW mode, all planes are active
	out	7Ch,al
	mov	cx,4
	mov	dx,1
tek_fill_GC2:
	test	tek_facol,dx
	jz	tek_fill_GC3
	mov	al,0FFh
	jmp	tek_fill_GC4
tek_fill_GC3:
	mov	al,0
tek_fill_GC4:
	out	7Eh,al		; write tile reg.
	shl	dx,1
	loop	tek_fill_GC2
;
	push	es
tek_fill_GC5:
	mov	ax,scan_y
	cmp	ax,scan_ymax
	jg	tek_fill_GC7
	call	scan_clr			; clear the scan buffer
	mov	si,offset tek41_fabuf		; position of the line
tek_fill_GC8:
	mov	cx,[si]				; number of lines
	jcxz	tek_fill_GC9
	add	si,2
tek_fill_GC6:
	call	scan_cross
	add	si,4
	loop	tek_fill_GC6
	add	si,4
	jmp	tek_fill_GC8
tek_fill_GC9:
	call	scan_fill
	mov	di,scan_ofs
	mov	ax,gplane_segm
	mov	es,ax
	mov	si,offset scan_buf
	add	si,scan_xstr
	mov	cx,scan_xlen
	rep	movsb
	inc	scan_y
	add	scan_ofs,80
	jmp	tek_fill_GC5
tek_fill_GC7:
	mov	al,040h				; GRCG off
	out	7Ch,al
	pop	es
;
tek_fill_ex:
	ret
tek_fill	endp
;
tek41_getcol	proc	near
;
; convert tek41 color index to normal index
;
	push	bx
	and	ax,0fh
	mov	bx,offset tek41_col
	add	bx,ax
	mov	ax,[bx]
	pop	bx
	ret
tek41_getcol	endp
;
set_gcolor	proc	near
;
; set graphic color
;
	push	ax
	push	si
	mov	al,vt100_gflag
	and	al,07Fh			; mask text screen ctrl bit
	cmp	al,0
	jne	set_gcolor_n0
	mov	si,offset gnrm_color
	jmp	set_gcolor_do
set_gcolor_n0:
	cmp	al,1
	jne	set_gcolor_n1
	mov	si,offset gbck_color
	jmp	set_gcolor_do
set_gcolor_n1:
	cmp	al,2
	jne	set_gcolor_n2
	mov	si,offset sixel_col
	jmp	set_gcolor_do
set_gcolor_n2:
	cmp	al,3
	jne	set_gcolor_n3
	mov	si,offset sixel_col
	jmp	set_gcolor_do
set_gcolor_n3:
	cmp	al,4
	jne	set_gcolor_n4
	mov	si,offset tek_col
	jmp	set_gcolor_do
set_gcolor_n4:
	cmp	al,5
	jne	set_gcolor_n5
	mov	si,offset tek_col
	jmp	set_gcolor_do
set_gcolor_n5:
	jmp	set_gcolor_ex
set_gcolor_do:
	call	set_gpalette
	call	gdisp_on
	mov	al,1
	test	vt100_gflag,80h
	jz	set_gcolor_do1
	mov	al,tek_dialog_vsbl
set_gcolor_do1:
	call	text_scrn
set_gcolor_ex:
	pop	si
	pop	ax
	ret
set_gcolor	endp
;
sixel_clear	proc	near
	call	gcls
	ret
sixel_clear	endp
 
sixel_in	proc	near
	call	gcls
	mov	si,offset sixel_col
	call	set_gpalette
	call	gdisp_on
	mov	sixel_x,0
	mov	sixel_y,0
	mov	sixel_state,0
	mov	repeat_count,0
	ret
sixel_in	endp
;
sixel	proc	near
	cmp	sixel_state,IN_REPEAT
	jne	sixel_1
	cmp	al,'0'
	jb	sixel_1
	cmp	al,'9'
	ja	sixel_1
	xor	ah,ah
	sub	al,'0'
	push	ax
	mov	ax,repeat_count
	add	repeat_count,ax
	mov	cx,3
	shl	ax,cl
	add	repeat_count,ax			; repeat_count *= 10
	pop	ax
	add	repeat_count,ax
	jmp	sixel_ex
sixel_1:
	cmp	al,07Eh
	ja	sixel_2
	cmp	al,03Fh
	jb	sixel_2				; b=no. special char.
	mov	sixel_state,0
	xor	ah,ah
	sub	al,03Fh
	call	sixel_put
	mov	sixel_state,0			; clear the sixel state
	mov	repeat_count,0			; clear the repeat counter
	jmp	sixel_ex
sixel_2:
	cmp	al,'!'				; repeat count prefix ?
	jne	sixel_3				; ne = no.
	mov	sixel_state,IN_REPEAT		; yes, set repeat count flag
	mov	repeat_count,0			;   and clear the counter
	jmp	sixel_ex
sixel_3:
	cmp	al,'$'				; Graphic CR ?
	jne	sixel_4				; ne = no.
	mov	sixel_x,0			; yes, go to left margin
	mov	sixel_state,0			; clear the sixel state
	mov	repeat_count,0			; and clear the counter
	jmp	sixel_ex
sixel_4:
	cmp	al,'-'				; Graphic NL ?
	jne	sixel_5				; ne = no.
	mov	sixel_x,0			; yes, go to left margin
	xor	cx,cx				; and move Y by repeat count
sixel_4_1:
	add	sixel_y,6
	inc	cx
	cmp	cx,repeat_count
	jl	sixel_4_1
	mov	sixel_state,0
	mov	repeat_count,0
	jmp	sixel_ex
sixel_5:
	cmp	al,020h				; character ?
	jb	sixel_ex			; b=no. it's control char.
	cmp	al,07Fh				; DEL/C1/GR ?
	jae	sixel_ex			; e=yes. ignore it.
	mov	sixel_state,0
	mov	repeat_count,0
sixel_ex:
	ret
sixel	endp
;
; put sixel character in AL to the graphic screen
;
sixel_put	proc	near
	push	si
	push	es
	mov	sixel_char,al		; save the sixel character
	cmp	sixel_y,SIXEL_YMAX
	jle	sixel_put_1
	mov	ax,sixel_y
	sub	ax,SIXEL_YMAX
	mov	cx,ax
	call	sixel_scroll
	mov	sixel_y,SIXEL_YMAX
sixel_put_1:
	cmp	sixel_x,SIXEL_XMAX
	jle	sixel_put_2
	jmp	sixel_put_6
sixel_put_2:
	mov	sixel_segm,CPU_GREEN_PLANE
	mov	ax,sixel_y
	add	sixel_segm,ax
	shl	ax,1
	shl	ax,1
	add	sixel_segm,ax		; sixel_segm = sixel_y*5 + segm_0
	mov	ax,sixel_x
	shr	ax,1
	shr	ax,1
	shr	ax,1
	mov	sixel_byte,ax		; sixel_byte = sixel_x / 8
	mov	ax,sixel_x
	and	ax,07h			; ax = sixel_x % 8
	cmp	ax,0			; byte boundary ?
	jne	sixel_put_2_1		; ne = no, not.
	cmp	repeat_count,8		; repeat_count >= 8 ?
	jl	sixel_put_2_1		; l = no, not.
	jmp	sixel_put_byte1
sixel_put_2_1:
	mov	bx,offset bit_on
	add	bx,ax
	mov	cl,[bx]
	mov	sixel_on,cl		; bit mask to ON the graphic bit
	mov	bx,offset bit_off
	add	bx,ax
	mov	cl,[bx]
	mov	sixel_off,cl		; bit mask to OFF the graphic bit
	mov	ax,sixel_segm
	mov	es,ax
	mov	cx,6			; repeat count
	cld
	mov	si,sixel_byte
	mov	al,sixel_char
	mov	dl,1
sixel_put_3:
	test	al,dl
	jz	sixel_put_4
	mov	bh,sixel_on
	or	es:[si],bh
	jmp	sixel_put_5
sixel_put_4:
	cmp	sixel_replace,1		; replace mode?
	jne	sixel_put_5		; ne=no.
	mov	bh,sixel_off
	and	es:[si],bh
sixel_put_5:
	shl	dl,1
	add	si,80
	loop	sixel_put_3
sixel_put_6:
	add	sixel_x,1
	dec	repeat_count
	jmp	sixel_put_7
;
sixel_put_byte1:
	mov	ax,sixel_segm
	mov	es,ax
	mov	cx,6			; repeat count
	cld
	mov	si,sixel_byte
	mov	al,sixel_char
	mov	dl,1
sixel_put_byte3:
	test	al,dl
	jz	sixel_put_byte4
	mov	bh,0ffh
	mov	es:[si],bh
	jmp	sixel_put_byte5
sixel_put_byte4:
	cmp	sixel_replace,1		; replace mode?
	jne	sixel_put_byte5		; ne=no.
	mov	bh,0
	mov	es:[si],bh
sixel_put_byte5:
	shl	dl,1
	add	si,80
	loop	sixel_put_byte3
sixel_put_byte6:
	add	sixel_x,8
	sub	repeat_count,8
;
sixel_put_7:
	cmp	repeat_count,0
	jle	sixel_put_8
	jmp	sixel_put_1
sixel_put_8:
	mov	repeat_count,0
	pop	es
	pop	si
	ret
sixel_put	endp
;
sixel_scroll	proc	near
;
; scroll up  CX lines
;
	push	bx
	push	si
	push	di
	push	es
	push	ds
;
	cld
;
	mov	si,0			; offset of the top of the buffer
	mov	di,0			; for both dest. and source.
	mov	ax,cx
	add	ax,cx
	shl	ax,1
	add	ax,cx			; ax = n * 5, number of para.
	mov	bx,ax			; save it for later use
	mov	ax,(CPU_BLUE_PLANE+1)	; top of the buffer
	mov	es,ax			; dest. segm.
	add	ax,bx
	mov	ds,ax			; source segm.
	mov	cx,32760		; number of words of the buffer
	rep	movsw			; move words
	mov	si,0			; clear offsets
	mov	di,0			;  for both dest. and source
	mov	ax,CPU_GREEN_PLANE
	mov	ds,ax			; source segm.
	sub	ax,bx
	mov	es,ax			; dest. segm.
	mov	cx,16000		; scroll with status line
	mov	ax,bx			; ax = n * 5
	shl	ax,1
	shl	ax,1
	shl	ax,1			; ax = n * 40
	sub	cx,ax
	rep	movsw
;
	pop	ds
	pop	es
	pop	di
	pop	si
	pop	bx
	ret
sixel_scroll	endp
 
sixel_rollup	proc	near
	push	bx
	push	si
	push	di
	push	es
	push	ds
;
	mov	ax,cx
	shl	ax,1
	shl	ax,1
	add	ax,cx			; ax = n * 5
	mov	bx,ax			; bx = ax = n * 5
	shl	ax,1
	shl	ax,1
	shl	ax,1			; ax = n * 40
;
; copy top n-lines to the save buffer
;
	cld
	mov	si,0
	mov	di,0
	push	ax
	mov	ax,(CPU_BLUE_PLANE+1)	; top segment
	mov	ds,ax
	mov	ax,(CPU_GREEN_PLANE+2000)	; save-buffer segment
	mov	es,ax
	pop	ax			; ax = n * 40
	mov	cx,ax
	rep	movsw
;
; roll-up n-lines
;
	mov	si,0
	mov	di,0
	push	ax
	mov	ax,(CPU_BLUE_PLANE+1)
	mov	es,ax			; destination
	add	ax,bx
	mov	ds,ax			; source
	mov	cx,32760
	rep	movsw
;
	mov	si,0
	mov	di,0
	mov	ax,CPU_GREEN_PLANE
	mov	es,ax
	add	ax,bx
	mov	ds,ax
	mov	cx,15360
	pop	ax
	sub	cx,ax
	rep	movsw
;
;  Copy saved n-lines to the bottom
;
	mov	si,0
	mov	di,0
	push	ax
	mov	ax,(CPU_GREEN_PLANE+1920)
	sub	ax,bx
	mov	es,ax			; destination
	mov	ax,(CPU_GREEN_PLANE+2000)
	mov	ds,ax			; source
	pop	ax
	mov	cx,ax
	rep	movsw
;
	pop	ds
	pop	es
	pop	di
	pop	si
	pop	bx
	ret
sixel_rollup	endp
 
sixel_rolldown	proc	near
	push	bx
	push	si
	push	di
	push	es
	push	ds
;
	mov	ax,cx
	shl	ax,1
	shl	ax,1
	add	ax,cx		; ax = n * 5
	mov	bx,ax		; bx = n * 5, save it for later use
	shl	ax,1
	shl	ax,1
	shl	ax,1		; ax = n * 40
;
;  Copy bottom n-lines to the save buffer
;
	cld
	mov	si,0
	mov	di,0
	push	ax
	mov	ax,(CPU_GREEN_PLANE+1920)	; 1920 = (24x16)lines x 5 segm.
	sub	ax,bx
	mov	ds,ax		; source segm.
	mov	ax,(CPU_GREEN_PLANE+2000)	; save segm.
	mov	es,ax		; destination
	pop	ax		; ax = n * 40
	mov	cx,ax
	rep	movsw		; store n-lines to save segm.
;
;  Rolldown n-lines
;
	std
	mov	si,30718	; bottom offset address (word boundary)
	mov	di,30718
	push	ax
	mov	ax,CPU_GREEN_PLANE
	mov	es,ax		; destination
	sub	ax,bx
	mov	ds,ax		; source
	mov	cx,15360	; cx = 24 x 16 x 40 words
	rep	movsw		; reverse move in Green segm.
;
	mov	si,0FFEEh	; bottom offset address (word boundary)
	mov	di,0FFEEh
	mov	ax,(CPU_BLUE_PLANE+1)
	mov	es,ax
	sub	ax,bx
	mov	ds,ax
	mov	cx,32760	; number of words in the buffer
	pop	ax		; ax = n * 40
	sub	cx,ax
	rep	movsw
;
	cld
	mov	si,0
	mov	di,0
	push	ax
	mov	ax,(CPU_GREEN_PLANE+2000)
	mov	ds,ax
	mov	ax,(CPU_BLUE_PLANE+1)
	mov	es,ax
	pop	ax		; ax = n * 40
	mov	cx,ax
	rep	movsw
;
	pop	ds
	pop	es
	pop	di
	pop	si
	pop	bx
	ret
sixel_rolldown	endp
;------------------------------------------------------------------------------
tekstat		proc	near
	push	ax
	mov	si,offset tek_cmode_msg
	mov	al,tek_cmode_1
	add	al,'0'
	mov	[si],al
	mov	al,tek_cmode_2
	add	al,'0'
	mov	[si+2],al
	mov	al,tek_cmode_3
	add	al,'0'
	mov	[si+4],al
;
	mov	si,offset tek_mouse_msg
	test	vtgrph_flg,MOUSE_BIT
	jz	tekstat_m01
	mov	al,'o'
	mov	[si],al
	mov	al,'n'
	mov	[si+1],al
	mov	al,' '
	mov	[si+2],al
	jmp	tekstat_m02
tekstat_m01:
	mov	al,'o'
	mov	[si],al
	mov	al,'f'
	mov	[si+1],al
	mov	[si+2],al
tekstat_m02:
	mov	al,' '
	mov	[si+3],al
	mov	al,pc98_mouse_type
	add	al,'0'
	mov	[si+4],al
;
	mov	si,offset tek_pmode_msg
	mov	al,tek_mod
	add	al,'0'
	mov	[si],al
	mov	al,tek_esc
	add	al,'0'
	mov	[si+1],al
	mov	si,offset tek_stat_msg
	pop	ax
	ret
tekstat		endp
;----------------------------------------------------------------------------
set_tek41_mat	proc	near
;
; set the transformation matrix.
; parameter consistency must be checked before call.
; Input  [si] window xmin,xmax,ymin,ymax; viewport xmin,xmax,ymin,ymax
; Output [di] transformation matrix
;
	push	ax
	push	bx
	push	dx
;
	mov	ax,[si+10]	; viewport xmax
	sub	ax,[si+ 8]	; viewport (xmax-xmin)
	inc	ax
	xor	dx,dx
	mov	bx,[si+ 2]	; window xmax
	sub	bx,[si   ]	; window (xmax-xmin)
	inc	bx
	div	bx
	mov	[di+ 2],ax
	xor	ax,ax
	div	bx
	mov	[di   ],ax
;
	mov	ax,[si+14]	; viewport ymax
	sub	ax,[si+12]	; viewport (ymax-ymin)
	inc	ax
	xor	dx,dx
	mov	bx,[si+ 6]	; window ymax
	sub	bx,[si+ 4]	; window (ymax-ymin)
	inc	bx
	div	bx
	mov	[di+10],ax
	xor	ax,ax
	div	bx
	mov	[di+ 8],ax
;
	mov	ax,[si   ]	; get window xmin
	mov	[di+ 4],ax
	mov	ax,[si+ 4]	; get window ymin
	mov	[di+12],ax
	mov	ax,[si+ 8]	; get viewport xmin
	mov	[di+ 6],ax
	mov	ax,[si+12]	; get viewport ymin
	mov	[di+14],ax
;
	pop	dx
	pop	bx
	pop	ax
	ret
set_tek41_mat	endp
;------------------------------------------------------------------------------
send_to_GGDC	proc	near
;
;  send commands and parameters
;  to graphic GDC
;    inputs	DS:[SI]	address of the list
;
	push	ax
	push	cx
	push	si
	cld
send_to_GGDC_loop1:
	lodsb
	cmp	al,0ffh
	je	send_to_GGDC_exit
	push	ax
send_to_GGDC_loop2:
	in	al,GGDC_STS_PORT
	test	al,2
	jne	send_to_GGDC_loop2
	pop	ax
	out	GGDC_CMD_PORT,al
	lodsb
	mov	cl,al
	mov	ch,0
	cmp	cx,0
	je	send_to_GGDC_loop1
send_to_GGDC_loop3:
	lodsb
	push	ax
send_to_GGDC_loop4:
	in	al,GGDC_STS_PORT
	test	al,2
	jne	send_to_GGDC_loop4
	pop	ax
	out	GGDC_PRM_PORT,al
	loop	send_to_GGDC_loop3
	jmp	send_to_GGDC_loop1
send_to_GGDC_exit:
	pop	si
	pop	cx
	pop	ax
	ret
send_to_GGDC	endp
;------------------------------------------------------------------------------
GGDC_color	proc	near
;
;  send DS:[SI] to graphic GDC with
;  color index.
;
;  inputs
;    ax:  color index
;    si:  buffer address (used by send_to_GGDC)
;    di:  CSR pointer
;
	push	bx
	push	cx
	push	dx
	push	di
;
	mov	bx,[di+3]
	push	bx
	mov	bx,[di+5]
	push	bx
;
	xor	ch,ch
	mov	cl,gplane_nums
	mov	bx,offset GDC_plane_address
	mov	dx,1
GGDC_color_1:
	and	byte ptr [di+3],3Fh		; mask plane address
	push	ax
	mov	al,[bx]
	or	byte ptr [di+3],al		; add plane address
	pop	ax
	inc	bx
	test	dx,gplane_actv
	jz	GGDC_color_4			; skip if non-active plane
	test	dx,ax				; test color bit
	jz	GGDC_color_2
	mov	byte ptr [di+5],23h 		; write mode = SET
	jmp	GGDC_color_3
GGDC_color_2:
	mov	byte ptr [di+5],22h		; write mode = CLEAR
GGDC_color_3:
	call	send_to_GGDC
GGDC_color_4:
	shl	dx,1
	loop	GGDC_color_1
;
	pop	bx
	mov	[di+5],bx
	pop	bx
	mov	[di+3],bx
;
	pop	di
	pop	dx
	pop	cx 
	pop	bx
	ret
GGDC_color	endp

;-----------------------------------------------------------------------
; Get digitized color index in AL from (r,g,b)
; si: (r,g,b) table
;
get_dig_color	proc	near
	push	cx
	mov	ch,ah		; save AH
	mov	ah,[si]		; get red
	mov	cl,6
	shr	ah,cl
	and	ah,02h
	mov	al,ah
	mov	ah,[si+1]	; get green
	mov	cl,5
	shr	ah,cl
	and	ah,04h
	or	al,ah
	mov	ah,[si+2]	; get blue
	mov	cl,7
	shr	ah,cl
	and	ah,01h
	or	al,ah
	mov	ah,ch		; restore AH
	pop	cx
	ret
get_dig_color	endp

HLS_value	proc	near
;
; input         HLS_n1	n1  [0-100]
;               HLS_n2	n2  [0-100]
;               AX : hue
; output        AX : value
;
	push	bx
	push	dx
;
HLS_value_1:
	cmp	ax,360
	jle	HLS_value_2
	sub	ax,360
	jmp	HLS_value_1
HLS_value_2:
	cmp	ax,0
	jge	HLS_value_3
	add	ax,360
	jmp	HLS_value_2
HLS_value_3:
	cmp	ax,60
	jl	HLS_value_4
	cmp	ax,180
	jl	HLS_value_5
	cmp	ax,240
	jl	HLS_value_6
	mov	ax,HLS_n1
	jmp	HLS_value_ex
HLS_value_5:
	mov	ax,HLS_n2
	jmp	HLS_value_ex
HLS_value_6:
	mov	bx,ax
	mov	ax,240
	sub	ax,bx
HLS_value_4:
	mov	bx,ax
	mov	ax,HLS_n2
	sub	ax,HLS_n1
	imul	bx
	mov	bx,60
	idiv	bx
	add	ax,HLS_n1
HLS_value_ex:
	pop	dx
	pop	bx
	ret
HLS_value	endp

HLS_to_RGB	proc	near
;
;  input [si]	Hue [0-360]
;        [si+2]	Lightness [0-100]
;        [si+4] Satulation [0-100]
;
	push	ax
	push	bx
	push	dx
;
	mov	ax,[si+4]		; get s
	cmp	ax,0			; if( s==0 ) then monochrome
	jne	HLS_to_RGB_1		; ne=no
	jmp	HLS_to_RGB_nomo
HLS_to_RGB_1:
	mov	bx,[si+2]		; get l
	mul	bx			; dx:ax=l*s  (dx should be 0)
	mov	bx,100
	div	bx			; ax=(l*s)/100
	cmp	WORD PTR [si+2],50	; if( l>50 ) then case_2
	jg	HLS_to_RGB_2
	mov	bx,[si+2]		; bx=l
	jmp	HLS_to_RGB_3
HLS_to_RGB_2:
	mov	bx,[si+4]		; bx=s
	sub	bx,ax			; bx=s-l*s/100
	mov	ax,[si+2]		; ax=l
HLS_to_RGB_3:
	add	ax,bx			; ax=ax+bx
	mov	HLS_n2,ax
	mov	bx,[si+2]		; bx=l
	shl	bx,1			; bx=2*l
	sub	bx,ax			; bx=2*l-ax
	mov	HLS_n1,bx
	mov	ax,[si]			; ax=hue
	push	ax
	call	HLS_value
	mov	[si],ax
	pop	ax
	push	ax
	mov	bx,120
	sub	ax,bx			; ax=hue-120
	call	HLS_value
	mov	[si+2],ax
	pop	ax
	mov	bx,120
	add	ax,bx			; ax=hue+120
	call	HLS_value
	mov	[si+4],ax
	jmp	HLS_to_RGB_ex
HLS_to_RGB_nomo:
	mov	ax,[si+2]
	mov	[si],ax
	mov	[si+4],ax
HLS_to_RGB_ex:
	pop	dx
	pop	bx
	pop	ax
	ret
HLS_to_RGB	endp
;-----------------------------------------------------------------------
; Set graphic color palette
; si: points the color index table (8 colors)
;
set_gpalette	proc	near
	push	ax
	push	bx
	push	cx
;
	cmp	gdisp_mode,0	; digital display ?
	jne	set_gpalette_A	; ne=no.
	jmp	set_gpalette_D
;--------------
set_gpalette_A:
;--------------
	push	si
	mov	cx,16
	mov	bx,0
set_gpalette_A1:
	push	cx
	mov	al,bl
	out	0A8h,al			; set color index
	lodsb
	mov	cx,4
	shr	al,cl
	and	al,0Fh
	out	0ACh,al			; set red
	lodsb
	mov	cx,4
	shr	al,cl
	and	al,0Fh
	out	0AAh,al			; set green
	lodsb
	mov	cx,4
	shr	al,cl
	and	al,0Fh
	out	0AEh,al			; set blue
	pop	cx
	inc	bx
	loop	set_gpalette_A1
;
	pop	si
	jmp	set_gpalette_ex
;
;--------------
set_gpalette_D:
;--------------
	push	si
	add	si,9			; index #3
	call	get_dig_color
	mov	ah,al
	mov	cl,4
	shl	ah,cl
	pop	si
	push	si
	add	si,21			; index #7
	call	get_dig_color
	or	al,ah
	out	0A8h,al			; set palette #3 and #7
	pop	si
;
	push	si
	add	si,3			; index #1
	call	get_dig_color
	mov	ah,al
	mov	cl,4
	shl	ah,cl
	pop	si
	push	si
	add	si,15			; index #5
	call	get_dig_color
	or	al,ah
	out	0AAh,al			; set palette #1 and #5
	pop	si
;
	push	si
	add	si,6			; index #2
	call	get_dig_color
	mov	ah,al
	mov	cl,4
	shl	ah,cl
	pop	si
	push	si
	add	si,18			; index #6
	call	get_dig_color
	or	al,ah
	out	0ACh,al			; set palette #2 and #6
	pop	si
;
	push	si
	call	get_dig_color
	mov	ah,al
	mov	cl,4
	shl	ah,cl
	pop	si
	push	si
	add	si,12
	call	get_dig_color
	or	al,ah
	out	0AEh,al			; set palette #0 and #4
	pop	si
;
set_gpalette_ex:
	pop	cx
	pop	bx
	pop	ax
	ret
set_gpalette	endp
 
set_gtxt_vect	proc	near
	push	ax
	push	bx
	push	cx
	mov	bx,tek_gtxt_w
	add	bx,tek_gtxt_s
	mov	cx,tek_gtxt_h
	mov	ax,tek_gtxt_ang
	cmp	ax,45
	jge	set_gtxt_vect_n1
	jmp	set_gtxt_vect_1
set_gtxt_vect_n1:
	cmp	ax,135
	jge	set_gtxt_vect_n2
	jmp	set_gtxt_vect_2
set_gtxt_vect_n2:
	cmp	ax,225
	jge	set_gtxt_vect_n3
	jmp	set_gtxt_vect_3
set_gtxt_vect_n3:
	cmp	ax,315
	jge	set_gtxt_vect_1
	jmp	set_gtxt_vect_4
set_gtxt_vect_1:
	mov	tek_gtxt_dr,2
	mov	tek_gtxt_ux,bx
	mov	tek_gtxt_uy,0
	mov	tek_gtxt_vx,0
	mov	tek_gtxt_vy,cx
	jmp	set_gtxt_vect_5
set_gtxt_vect_2:
	neg	cx
	mov	tek_gtxt_dr,4
	mov	tek_gtxt_ux,0
	mov	tek_gtxt_uy,bx
	mov	tek_gtxt_vx,cx
	mov	tek_gtxt_vy,0
	jmp	set_gtxt_vect_5
set_gtxt_vect_3:
	neg	bx
	neg	cx
	mov	tek_gtxt_dr,6
	mov	tek_gtxt_ux,bx
	mov	tek_gtxt_uy,0
	mov	tek_gtxt_vx,0
	mov	tek_gtxt_vy,cx
	jmp	set_gtxt_vect_5
set_gtxt_vect_4:
	neg	bx
	mov	tek_gtxt_dr,0
	mov	tek_gtxt_ux,0
	mov	tek_gtxt_uy,bx
	mov	tek_gtxt_vx,cx
	mov	tek_gtxt_vy,0
set_gtxt_vect_5:
	pop	cx
	pop	bx
	pop	ax
	ret
set_gtxt_vect	endp
;------------------------------------------------------------------------------
gcsrw	proc	near
;
; fill CSRW parameters in the buffer [di]
;   Inputs
;     ax: x position
;     bx: y position
;     cx: plane offset / 256
;     di: buffer address ( to be broken )
;   Outputs
;     di: next buffer address
;
	push	ax
	push	bx
	push	cx
	mov	byte ptr [di],49h		; fill CSRW command
	mov	byte ptr [di+1],3		; number of parameters
	push	ax				; save x value
	push	cx				; save plane number
	mov	cl,4				; shift counts
	shr	ax,cl				; ax = x / 16
	mov     cx,bx				; save y value
	shl	bx,1				; bx = y * 2
	shl	bx,1				; bx = bx * 2 = y * 4
	add	bx,cx				; bx = bx + y = y * 5
	mov	cl,3				; shift counts
	shl	bx,cl				; bx = bx * 8 = y * 40
	add	ax,bx				; ax = x / 16 + y * 40
	mov	byte ptr [di+2],al		; set EAD_L
	mov	al,ah				; discard EAD_L
	xor	ah,ah				; clear higher byte
	pop	bx				; recall plane offset
	mov	bl,bh				; mov to lower byte
	xor	bh,bh				; clear higher byte
	add	ax,bx				; add plane offset
	mov	byte ptr [di+3],al		; set EAD_M
	mov	al,ah				; discard EAD_M
	xor	ah,ah				; clear higher byte
	pop	bx				; recall x
	and	bx,000fh			; lower 4 bits of x (dAD)
	mov	cl,4				; shift counts
	shl	bx,cl				; shift 4 bits
 	add	ax,bx				; add to EAD_H
	mov	byte ptr [di+4],al		; set dAD+EAD_H
	add	di,5				; set next pointer
	pop	cx
	pop	bx
	pop	ax
	ret
gcsrw	endp
;------------------------------------------------------------------------------
gline	proc	near
;
;  Draw line from current position to the displacement (AX,BX)
;  Inputs:
;    ax: delta_x
;    bx: delta_y
;    di: buffer address
;  Outputs:
;    di: next buffer address
;
	push	ax
	push	bx
	push	cx
	mov     byte ptr [di],4ch		; VECTW command
	mov	byte ptr [di+1],9		; number of parameters
;
;   determine direction (cx)
;
	mov	cx,8				; Line function with dir=0
	cmp	ax,0				; if delta_x = 0 then
	je	gln0				;   goto gln0
	jl	gln1				; else if delta_x < 0 goto gln1
	jmp	gln2				; else goto gln2
gln0:
	cmp	bx,0				;
	jge	gln2				; if delta_y >= 0 goto gln2
gln1:
	neg	ax				; delta_x = -delta_x
	neg	bx				; delta_y = -delta_y
	add	cx,4				; dir >= 4
gln2:
	cmp	bx,0				;
	jg	gln3				; if delta_y > 0 goto gln3
	neg	bx				; delta_y = -delta_y
	xchg	ax,bx				;
	add	cx,2				; dir >= 2 or 6
gln3:
	cmp	ax,bx				;
	jl	gln4				; if delta_x < delta_y goto gln4 
	inc	cx				; dir = 1, 3, 5, or 7
	jmp	gln5
gln4:
	xchg	ax,bx
gln5:
;
;     end of direction determination.
;     ax: abs(d_x)
;     bx: abs(d_y)
;     cx: line_code + dir
;
	mov	byte ptr [di+2],cl		; P1 ready
	mov	word ptr [di+3],ax		; abs(d_x)
	mov	cx,bx				; cx = abs(d_y)
	add	cx,bx				; cx = 2*abs(d_y)
	push	cx				; save 2*abs(d_y) for later use
	sub	cx,ax				; cx = 2*abs(d_y)-abs(d_x)
	mov	word ptr [di+5],cx		; send it
	sub	cx,ax				; cx = 2*abs(d_y)-2*abs(d_x)
	mov	word ptr [di+7],cx		; send it
	pop	cx				; recall 2*abs(d_y)
	mov	word ptr [di+9],cx		; send it
;
	mov	byte ptr [di+11],6ch		; VECTE command
	mov	byte ptr [di+12],0		; with no parameters
	add	di,13				; update address
	pop	cx
	pop	bx
	pop	ax
	ret
gline	endp
;-----------------------------------
gdisp_on	proc	near
	push	ax
	push	si
	mov	al,gdisp_mode
	out	6ah,al
	mov	si,offset ggdc_on
	call	send_to_GGDC
	pop	si
	pop	ax
	ret
gdisp_on	endp
;-----------------------------------
gdisp_off	proc	near
	push	si
	mov	si,offset ggdc_off
	call	send_to_GGDC
	pop	si
	ret
gdisp_off	endp
;-----------------------------------
gcls	proc	near
	push	ax
	push	bx
	push	cx
	push	di
	push	si
	push	es
;
	mov	si,offset ggdc_off		; off the graphic GDC
	call	send_to_GGDC
;
	cld					; normal direction
	xor	ch,ch
	mov	cl,gplane_nums
	mov	bx,offset gplane_segm	; GDC segment address
gcls_1:
	mov	ax,[bx]				; get segment
	mov	es,ax				; and set it to ES
	xor	ax,ax				; store 0
	mov	di,ax				; offset address is 0
	push	cx				; save counter
	mov	cx,16000			; number of words of G-VRAM
	rep	stosw				; store it
	pop	cx				; remember number of planes
	add	bx,2				; next segment address
	loop	gcls_1
;
	mov	si,offset ggdc_on		; on the graphic GDC
	call	send_to_GGDC
;
	pop	es
	pop	si
	pop	di
	pop	cx
	pop	bx
	pop	ax
	ret
gcls	endp
 
code	ends
	end
