DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦7d0800859⟧ TextFile

    Length: 32125 (0x7d7d)
    Types: TextFile
    Names: »msgp98.asm«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z« 
        └─⟦31f2d420d⟧ 
            └─⟦this⟧ »msgp98.asm« 

TextFile

;+ This is MSGP98.ASM
;
;  Tektronix 4014 emulator for NEC-PC9801
;  Author: Hirofumi Fujii (KEK On-line group)

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

BEL             equ     007h
BS              equ     008h
HT              equ     009h
LF              equ     00Ah
VT              equ     00Bh
FF              equ     00Ch
CR              equ     00Dh
CAN             equ     018h
SUB             equ     01Ah
ESC             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

        public  tek4014,tek4014_ini
        public  tek4014_save, tek4014_restore, tek4014_modlin

datas   segment public 'datas'

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
;
loc_x           dw      0
loc_y           dw      0
loc_mov         dw      0
;
tek_npnt        dw      0
;
line_type       dw      0
line_type_table dw      0FFFFh
                dw      0C3C3h
                dw      083C1h
                dw      08181h
                dw      0A0F0h
;
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_key         db      1,0
;
tek_mod         db      0               ; 0=Alpha,1=Vector
tek_esc         db      0               ; 1=TEK in esc-seq
tek_byp         db      0               ; 1=Bypass mode
                db      0
;
disp_bank       db      0
actv_bank       db      0
;
ggdc_buff       db      80 dup (?)
loc_x_buff      db      32 dup (?)
loc_y_buff      db      32 dup (?)
;
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_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
;
;------------------------------------------------------------------------------
; 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
;
datas   ends

code    segment public 'code'
        assume  cs:code,ds:datas

;-----------------------------------------------------------------------
; 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    cx
        mov     cx,3
        shr     bx,cl
        mov     cx,399
        sub     cx,bx
        xchg    bx,cx
        mov     cx,3
        shr     ax,cl
        pop     cx
        ret
;
TEK40_DEV_COOD  ENDP
;

TEK40_GIN       PROC    NEAR
;
;  Request locator
;
        mov     si,offset ent_gin               ; write mode is complement
        call    send_to_GGDC
;
;       Set initial device coordinate
;
        mov     ax,tek_cur_x
        mov     bx,tek_cur_y
        call    tek40_dev_cood
        mov     loc_x,ax
        mov     loc_y,bx
        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,0
        mov     bx,loc_y
        mov     cx,GGDC_RED_PLANE               ; Use Red plane
        call    gcsrw
        mov     ax,511
        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_11
        mov     di,offset loc_y_buff
        mov     ax,loc_x
        mov     bx,9
        mov     cx,GGDC_RED_PLANE
        call    gcsrw
        mov     ax,0
        mov     bx,390
        call    gline
        mov     byte ptr [di],0FFh
        mov     si,offset loc_y_buff
        call    send_to_GGDC
;
;       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
        jge     tek40_gin_y
        mov     loc_y,9
        jmp     tek40_gin_y
tek40_gin_down:
        add     loc_y,dx
        cmp     loc_y,399
        jle     tek40_gin_y
        mov     loc_y,399
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,0
        jge     tek40_gin_x
        mov     loc_x,0
        jmp     tek40_gin_x
tek40_gin_right:
        add     loc_x,dx
        cmp     loc_x,511
        jle     tek40_gin_x
        mov     loc_x,511
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     ax,loc_x
        shl     ax,1                    ; tek x = loc_x * 2
        mov     bx,ax
        mov     cx,5                    ; set shift count
        shr     ax,cl                   ; get HiX
        and     ax,01Fh                 ; mask higher bits
        or      al,HIX                  ; convert to character
        mov     [si+2],al               ; set HiX
        and     bx,01Fh                 ; get LoX
        or      bl,LOX                  ; convert to character
        mov     [si+3],bl               ; set LoX
        mov     bx,loc_y
        mov     ax,399
        sub     ax,bx                   ; ax = 399 - loc_y
        shl     ax,1                    ; tek y = ( 399 - loc_y ) * 2
        mov     bx,ax
        mov     cx,5                    ; set shift count
        shr     ax,cl                   ; get HiY
        and     ax,01Fh                 ; mask higher bits
        or      al,HIY                  ; convert to character
        mov     [si+4],al               ; set HiY
        and     bx,01Fh                 ; get LoY
        or      bl,LOY                  ; convert to character
        mov     [si+5],bl               ; set LoY
;
;       Erase 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

TEK4014_INI     PROC    NEAR
;
;  Hardware initialization
;
tek4014_ini_lp01:
        in      al,GGDC_STS_PORT
        xor     al,024h
        test    al,024h                 ; VSYNC & GDC Empty ?
        jne     tek4014_ini_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     al,07h                  ; makes green plane to white
        out     0AEh,al
        mov     si,offset ggdc_set      ; CSFORM & SCROLL
        call    send_to_GGDC
;
;  Software reset
;
        mov     tek_cur_x,0
        mov     tek_cur_y,3119
        mov     ax,112
        sub     tek_cur_y,ax
        mov     line_type,0
        mov     tek_byp,0
;
        ret
TEK4014_INI     ENDP


TEK4014_SAVE    PROC    NEAR
        mov     si,offset ggdc_off
        call    send_to_GGDC
;
;  Enable text screen
;
        mov     al,0Dh
        out     062h,al
        ret
TEK4014_SAVE    ENDP


TEK4014_RESTORE PROC    NEAR
;
;  Disable text screen
;
        mov     al,0Ch
        out     062h,al
;
        mov     si,offset ggdc_on
        call    send_to_GGDC
        ret
TEK4014_RESTORE ENDP


TEK4014_MODLIN  PROC    NEAR
        ret
TEK4014_MODLIN  ENDP


TEK4014 PROC    NEAR
        cmp     tek_byp,0
        je      tek40_00
        mov     bl,al
        and     bl,07Fh
        cmp     bl,020h
        jge     tek40_ex
        mov     tek_byp,0
tek40_00:
        cmp     tek_esc,0
        je      tek40_01
        jmp     tek40_esc
tek40_01:
        cmp     tek_mod,0
        jne     tek40_02
        jmp     tek40_alp
tek40_02:
        cmp     tek_mod,1
        jne     tek40_03
        jmp     tek40_vct
tek40_03:
tek40_ex:
        mov     cx,0
        ret
;
tek40_esc:
tek40_esc_0C:
        cmp     al,FF
        jne     tek40_esc_1A
        call    gcls
        mov     tek_esc,0               ; ESC seq done
        mov     tek_mod,0               ; enter alpha mode
        mov     tek_cur_x,0
        mov     tek_cur_y,3119
        sub     tek_cur_y,112
        jmp     tek40_ex
tek40_esc_1A:
        cmp     al,SUB
        jne     tek40_esc_07
        call    tek40_gin
        mov     tek_esc,0
        mov     tek_mod,0
        ret                             ; cx and si have gin answerback
tek40_esc_07:
        cmp     al,BEL
        jne     tek40_esc_08
        jmp     tek40_ex
tek40_esc_08:
        cmp     al,BS
        jne     tek40_esc_09
        sub     tek_cur_x,56
        cmp     tek_cur_x,0
        jge     tek40_esc_08_01
        mov     tek_cur_x,0
tek40_esc_08_01:
        mov     tek_esc,0
        jmp     tek40_ex
tek40_esc_09:
        cmp     al,HT
        jne     tek40_esc_0A
        add     tek_cur_x,56
        cmp     tek_cur_x,4095
        jle     tek40_esc_09_01
        mov     tek_cur_x,4095
tek40_esc_09_01:
        mov     tek_esc,0
        jmp     tek40_ex
tek40_esc_0A:
        cmp     al,LF
        jne     tek40_esc_0B
        sub     tek_cur_y,112
        cmp     tek_cur_y,0
        jge     tek40_esc_0A_01
        mov     tek_cur_y,3119
        sub     tek_cur_y,112
tek40_esc_0A_01:
        mov     tek_esc,0                       ; ESC seq done
        jmp     tek40_ex
tek40_esc_0B:
        cmp     al,VT
        jne     tek40_esc_0D
        jmp     tek40_ex
tek40_esc_0D:
        cmp     al,CR
        jne     tek40_esc_1B
        mov     tek_cur_x,0
        mov     tek_mod,0                       ; enter alpha mode
        mov     tek_esc,0                       ; ESC seq done
        jmp     tek40_ex
;
tek40_esc_1B:
        cmp     al,ESC
        jne     tek40_esc_1C
        mov     tek_esc,1                       ; initiate ESC sequence
        jmp     tek40_ex
;
tek40_esc_1C:
        cmp     al,FS
        jne     tek40_esc_1D
        mov     tek_esc,0                       ; ESC seq done
        jmp     tek40_ex
tek40_esc_1D:
        cmp     al,GS
        jne     tek40_esc_1E
        mov     tek_mod,1                       ; enter graph mode
        mov     tek_npnt,0                      ; reset number of points
        mov     tek_vseq,0
        mov     ax,line_type
        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              ; set line type
        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_esc_1E:
        cmp     al,RS
        jne     tek40_esc_1F
        jmp     tek40_ex
tek40_esc_1F:
        cmp     al,US
        jne     tek40_esc_ex
        mov     tek_mod,0                       ; enter alpha mode
        mov     line_type,0
        mov     tek_esc,0                       ; ESC seq done
        jmp     tek40_ex
tek40_esc_ex:
        mov     tek_esc,0
        jmp     tek40_ex

;  Alpha mode: If printable character, then put the character at
;  current position.

tek40_alp:
        and     al,07Fh
        cmp     al,' '
        jae     tek40_alp_01
        jmp     tek40_esc_07
tek40_alp_01:
        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
        mov     cx,GGDC_GREEN_PLANE     ; green plane
        call    gcsrw
        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,56
        add     tek_cur_x,ax
        jmp     tek40_ex
;
tek40_vct:
        and     al,07Fh
        cmp     al,' '
        jae     tek40_vct_01
        jmp     tek40_esc_07
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
        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
        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
        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
        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:
        mov     tek_vseq,0
        mov     tek_npnt,0
        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_npnt,0
        je      tek40_vct_ln01

;       Not the first point. Draw line.

        mov     di,offset ggdc_buff
        mov     ax,tek_cur_x
        mov     bx,tek_cur_y
        call    tek40_dev_cood
        mov     cx,GGDC_GREEN_PLANE
        push    ax
        push    bx
        call    gcsrw
        mov     ax,tek_req_x
        mov     bx,tek_req_y
        call    tek40_dev_cood
        pop     cx
        sub     bx,cx                           ; delta y
        pop     cx
        sub     ax,cx                           ; delta x
        call    gline
        mov     byte ptr [di],0FFh              ; set terminator
        mov     si,offset ggdc_buff
        call    send_to_GGDC
tek40_vct_ln01:
        mov     ax,tek_req_x
        mov     tek_cur_x,ax
        mov     ax,tek_req_y
        mov     tek_cur_y,ax
        mov     tek_npnt,1
tek40_vct_end:
        jmp     tek40_ex

TEK4014 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
;-----------------------------------
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
;
        add     di,11                           ; update address
        mov     byte ptr [di],6ch               ; VECTE command
        mov     byte ptr [di+1],0               ; with no parameters
        add     di,2                            ; update address
        pop     cx
        pop     bx
        pop     ax
        ret
gline   endp
;-----------------------------------
gcls    proc    near
        push    ax
        push    cx
        push    di
        push    si
        push    es
;
        mov     si,offset ggdc_off
        call    send_to_GGDC
;
        mov     cx,16000
        mov     ax,0B800h               ; green plane
        mov     es,ax
        xor     ax,ax
        mov     di,ax
        cld
        rep     stosw
;
        mov     si,offset ggdc_on
        call    send_to_GGDC
;
        pop     es
        pop     si
        pop     di
        pop     cx
        pop     ax
        ret
gcls    endp

code    ends
        end