        name msyz10
; File MSYZ10.ASM
; Last modification: 27 April 1986

; Kermit system dependent module for Heath/Zenith Z100

        public  term
        include mssdef.h


BIOS_SEG SEGMENT AT 40H         ; Define segment where BIOS really is
        ORG     4*3
BIOS_PRINT      LABEL FAR       ; Printer output
        ORG     6*3
BIOS_AUXOUT     LABEL FAR       ; AUX output routine
        ORG     26*3
BIOS_AUXFUNC    LABEL FAR       ; AUX: function
        ORG     27*3
BIOS_CONFUNC    LABEL FAR       ; CON: function
BIOS_SEG ENDS

; Function codes for BIOS_xxxFUNC
CHR_WRITE       EQU     0       ; Write character
CHR_READ        EQU     1       ; Read character
CHR_STATUS      EQU     2       ; Get status
  CHR_SFGS      EQU     0       ; Get status subfunction
  CHR_SFGC      EQU     1       ; Get config subfunction
CHR_CONTROL     EQU     3       ; Control function
  CHR_CFSU      EQU     0       ; Set new configuration parameters
  CHR_CFCI      EQU     1       ; Clear input buffer

; Scan code definitions used for translating back to Heath ESC sequences
entscan equ     08dh            ; enter key scan code
f0scan  equ     096h            ; F0 key
f1scan  equ     097h            ; F1 key
f2scan  equ     098h            ; F2 key
f3scan  equ     099h            ; F3 key
f4scan  equ     09ah            ; F4 key
f5scan  equ     09bh            ; F5 key
f6scan  equ     09ch            ; F6 key
f7scan  equ     09dh            ; F7 key
f8scan  equ     09eh            ; F8 key
f9scan  equ     09fh            ; F9 key
f10scn  equ     0a0h            ; F10 key
f11scn  equ     0a1h            ; F11 key
f12scn  equ     0a2h            ; F12 key
homscan equ     0a9h            ; Home key
upscan  equ     0a5h            ; Up arrow
dnscan  equ     0a6h            ; Down arrow
rtscan  equ     0a7h            ; Right arrow
lfscan  equ     0a8h            ; Left arrow
kpminus equ     0adh            ; keypad minus
kpdot   equ     0aeh            ; keypad period
kp0     equ     0b0h            ; keypad 0
kp1     equ     0b1h            ; keypad 1
kp2     equ     0b2h            ; keypad 2
kp3     equ     0b3h            ; keypad 3
kp4     equ     0b4h            ; keypad 4
kp5     equ     0b5h            ; keypad 5
kp6     equ     0b6h            ; keypad 6
kp7     equ     0b7h            ; keypad 7
kp8     equ     0b8h            ; keypad 8
kp9     equ     0b9h            ; keypad 9
sentscn equ     0cdh            ; shifted enter key
sf0scan equ     0d6h            ; shifted F0 key
sf1scan equ     0d7h            ; shifted F1 key
sf2scan equ     0d8h            ; shifted F2 key
sf3scan equ     0d9h            ; shifted F3 key
sf4scan equ     0dah            ; shifted F4 key
sf5scan equ     0dbh            ; shifted F5 key
sf6scan equ     0dch            ; shifted F6 key
sf7scan equ     0ddh            ; shifted F7 key
sf8scan equ     0deh            ; shifted F8 key
sf9scan equ     0dfh            ; shifted F9 key
sf10scn equ     0e0h            ; shifted F10 key
sf11scn equ     0e1h            ; shifted F11 key
sf12scn equ     0e2h            ; shifted F12 key
shomscn equ     0e9h            ; shifted Home key
supscan equ     0e5h            ; shifted Up arrow
sdnscan equ     0e6h            ; shifted Down arrow
srtscan equ     0e7h            ; shifted Right arrow
slfscan equ     0e8h            ; shifted Left arrow
skpmins equ     0edh            ; shifted keypad minus
skpdot  equ     0eeh            ; shifted keypad period
skp0    equ     0f0h            ; shifted keypad 0
skp1    equ     0f1h            ; shifted keypad 1
skp2    equ     0f2h            ; shifted keypad 2
skp3    equ     0f3h            ; shifted keypad 3
skp4    equ     0f4h            ; shifted keypad 4
skp5    equ     0f5h            ; shifted keypad 5
skp6    equ     0f6h            ; shifted keypad 6
skp7    equ     0f7h            ; shifted keypad 7
skp8    equ     0f8h            ; shifted keypad 8
skp9    equ     0f9h            ; shifted keypad 9

; Miscellaneous scan codes used for functions
prscan  equ     f12scn          ; print-screen scan code (F12)...
brkscan equ     0aah            ; Break key


modfrm  struc                           ; format of mode line
        db      'Esc chr: '
m_echr  db      2 dup (?)
        db      ', Speed: '
m_baud  db      4 dup (?)
        db      ', Parity: '
m_par   db      4 dup (?)
        db      ', Echo: '
m_echo  db      3 dup (?)
        db      ', Prn: '
m_prs   db      3 dup (?)
        db      ', Type '
m_hlp   db      2 dup (?)
        db      '? for Help$'
modfrm  ends

datas   segment public 'datas'
waste   db      100h dup(?)             ; assembler problem???

flags1  db      0                       ; internal flags
prtscr  equ     80h                     ; print screen pressed flag

; Key translations - F12 is printscreen
ckeys   db      brkscan,prscan,upscan,dnscan,lfscan,rtscan,homscan
        db      entscan,f0scan,f1scan,f2scan,f3scan,f4scan,f5scan,f6scan
        db      f7scan,f8scan,f9scan,f10scn,f11scn,kpminus
        db      kpdot,kp0,kp1,kp2,kp3,kp4,kp5,kp6,kp7,kp8,kp9
        db      supscan,sdnscan,slfscan,srtscan,shomscn
        db      sentscn,sf0scan,sf1scan,sf2scan,sf3scan,sf4scan,sf5scan,sf6scan
        db      sf7scan,sf8scan,sf9scan,sf10scn,sf11scn,skpmins
        db      skpdot,skp0,skp1,skp2,skp3,skp4,skp5,skp6,skp7,skp8,skp9
lckeys  equ     $-ckeys
;ckacts must parallel ckeys above...
ckacts  dw      trnbrk,trnprs,trnupw,trndnw,trnlfw,trnrgw,trnhom,trnkpn
        dw      trnf0,trnf1,trnf2,trnf3,trnf4,trnf5,trnf6,trnf7,trnf8,trnf9
        dw      trnf10,trnf11,trnkpn,trnkpn,trnkpn,trnkpn,trnkpn
        dw      trnkpn,trnkpn,trnkpn,trnkpn,trnkpn,trnkpn,trnkpn
        dw      trnupw,trndnw,trnlfw,trnrgw,trnhom,trnkps
        dw      trnsf0,trnsf1,trnsf2,trnsf3,trnsf4,trnsf5,trnsf6,trnsf7
        dw      trnsf8,trnsf9,trnsf10,trnsf11,trnkps,trnkps
        dw      trnkps,trnskp1,trnskp2,trnskp3,trnskp4,trnskp5,trnskp6
        dw      trnskp7,trnskp8,trnskp9

enascan db      ESC,'y?$'       ; Enable scan codes
disscan db      ESC,'x?$'       ; Disable scan codes
uptrn   db      esc,'A'
dntrn   db      esc,'B'
rgtrn   db      esc,'C'
lftrn   db      esc,'D'
enttrn  db      cr              ; enter key translation
homtrn  db      ESC,'H'         ; home key translation
dottrn  db      '.'             ; keypad . translation
mintrn  db      '-'             ; keypad - translation
kp0trn  db      '0'             ; keypad 0 translation
kp1trn  db      '1'             ; keypad 1 translation
kp2trn  db      '2'             ; keypad 2 translation
kp3trn  db      '3'             ; keypad 3 translation
kp4trn  db      '4'             ; keypad 4 translation
kp5trn  db      '5'             ; keypad 5 translation
kp6trn  db      '6'             ; keypad 6 translation
kp7trn  db      '7'             ; keypad 7 translation
kp8trn  db      '8'             ; keypad 8 translation
kp9trn  db      '9'             ; keypad 9 translation
senttrn db      cr              ; shifted enter key translation
shomtrn db      ESC,'H'         ; home key translation
sdottrn db      '.'             ; shifted keypad . translation
smintrn db      '-'             ; shifted keypad - translation
skp0trn db      '0'             ; shifted keypad 0 translation
skp1trn db      ESC,'L'         ; shifted keypad 1 translation
skp2trn db      ESC,'B'         ; shifted keypad 2 translation
skp3trn db      ESC,'M'         ; shifted keypad 3 translation
skp4trn db      ESC,'D'         ; shifted keypad 4 translation
skp5trn db      ESC,'H'         ; shifted keypad 5 translation
skp6trn db      ESC,'C'         ; shifted keypad 6 translation
skp7trn db      ESC,'@'         ; shifted keypad 7 translation
skp8trn db      ESC,'A'         ; shifted keypad 8 translation
skp9trn db      ESC,'N'         ; shifted keypad 9 translation
f0trn   db      ESC,'J'         ; F0 translation
f1trn   db      ESC,'S'         ; F1 translation
f2trn   db      ESC,'T'         ; F2 translation
f3trn   db      ESC,'U'         ; F3 translation
f4trn   db      ESC,'V'         ; F4 translation
f5trn   db      ESC,'W'         ; F5 translation
f6trn   db      ESC,'P'         ; F6 translation
f7trn   db      ESC,'Q'         ; F7 translation
f8trn   db      ESC,'R'         ; F8 translation
f9trn   db      ESC,'0I'        ; F9 translation
f10trn  db      ESC,'0J'        ; F10 translation
f11trn  db      ESC,'0K'        ; F11 translation
f12trn  db      ESC,'0L'        ; F12 translation
sf0trn  db      ESC,'E'         ; shifted F0 translation
sf1trn  db      ESC,'1A'        ; shifted F1 translation
sf2trn  db      ESC,'1B'        ; shifted F2 translation
sf3trn  db      ESC,'1C'        ; shifted F3 translation
sf4trn  db      ESC,'1D'        ; shifted F4 translation
sf5trn  db      ESC,'1E'        ; shifted F5 translation
sf6trn  db      ESC,'1F'        ; shifted F6 translation
sf7trn  db      ESC,'1G'        ; shifted F7 translation
sf8trn  db      ESC,'1H'        ; shifted F8 translation
sf9trn  db      ESC,'1I'        ; shifted F9 translation
sf10trn db      ESC,'1J'        ; shifted F10 translation
sf11trn db      ESC,'1K'        ; shifted F11 translation
sf12trn db      ESC,'1L'        ; shifted F12 translation


ourarg  termarg <>
modbuf  modfrm  <>                      ; mode line buffer

; some static data for mode line
unkbaud db      'Unk '                  ; must be 4 chars...
baudn   db      '45.5'
        db      '  50'
        db      '  75'
        db      ' 110'
        db      ' 135'
        db      ' 150'
        db      ' 300'
        db      ' 600'
        db      '1200'
        db      '1800'
        db      '2000'
        db      '2400'
        db      '4800'
        db      '9600'
        db      ' 19K'
        db      ' 38K'

baudnsiz  equ   16                      ; # of baud rates known (tbl size / 4)
parnams db      'Even'
        db      'Mark'
        db      'None'
        db      'Odd '                  ; must be 4 chars
        db      'Spc '
offmsg  db      'Off'
onmsg   db      'On '
lclmsg  db      'Lcl'
remmsg  db      'Rem'

datas   ends

code    segment public 'code'
        extrn   prtchr:near,outchr:near,putmod:near,clrmod:near,sendbr:near
        assume  cs:code,ds:datas

; This is from the dumb terminal emulator routine in MSXGEN.ASM.
; Had to use bios calls because DOS calls were losing chars.
term    proc    near
        mov     si,ax           ; this is source
        mov     di,offset ourarg ; place to store arguments
        mov     ax,ds
        push    es              ; save caller's extra segment address
        mov     es,ax           ; address destination segment
        mov     cx,size termarg
        rep     movsb           ; copy into our arg blk
        and     flags1,not (prtscr)     ; print screen mode disabled

        test    ourarg.flgs,emheath ; Are we to use Heath sequences?
        jnz     chkmod          ; no, do something else
        mov     ah,prstr
        mov     dx,offset enascan ; enable scan codes
        int     dos

chkmod: call    clrmod          ; clear mode line
        test    ourarg.flgs,modoff ; is mode line disabled?
        jnz     term1           ; yes, skip it
        call    modlin          ; turn on mode line

term1:  call    portchr         ; char at port?
         jnc    term3           ; no, keep going
        call    outtty          ; print on terminal

term3:  mov     ah,chr_status
        mov     al,chr_sfgs     ; get number of characters
        call    bios_confunc    ; check console
        cmp     bl,0
        jz      term1           ; no character, go on
        mov     ah,chr_read
        call    bios_confunc    ; read it
        cmp     al,ourarg.escc  ; escape char?
        je      term4           ; yes, exit
        push    ax              ; save char
        mov     ah,al
        call    trnout          ; translate if nec., output to port
        pop     ax
        jmp     term1           ; else echo and keep going

term4:  call    clrmod
        mov     ah,prstr
        mov     dx,offset disscan ; disable scan code generation
        int     dos
        pop     es
        ret

term    endp

; returns with carry on if a character is available

portchr proc    near
        call    prtchr                  ; character at port?
         jmp    short portc1            ; yes, go handle
        nop                             ; skip return is stupid
        clc                             ; no carry -> no character
        ret
portc1: and     al,7fh                  ; we don't worry about parity here
        stc                             ; have a character
        ret
portchr endp

; put the character in al to the screen
outtty  proc    near
        mov     ah,chr_write
        call    bios_confunc
        test    ourarg.flgs,capt ; capturing output?
        jz      outtt1          ; no, forget it
        call    ourarg.captr    ; else call the routine

outtt1: test    flags1,prtscr   ; print screen?
        jz      outtt2          ; no, try something else
        call    bios_print

outtt2: ret
outtty  endp

; send the character in al out to the serial port
; handle echoing also...
outprt  proc    near
        test    ourarg.flgs,lclecho     ; echoing?
        jz      outpr1                  ; no, forget it
        push    ax                      ; save char
        call    outtty                  ; print it
        pop     ax                      ; restore
outpr1: mov     ah,al                   ; this is where outchr expects it
        call    outchr                  ; output to the port
         nop
         nop
         nop                            ; skip returns...
        ret
outprt  endp

modlin  proc    near                    ; turn on mode line
        mov     al,ourarg.escc
        mov     modbuf.m_echr,' '       ; first char is initial space
        mov     modbuf.m_hlp,' '        ; goes here too.
        cmp     al,32                   ; printable?
        jnb     modl1                   ; yes, keep going
        add     al,40h                  ; made printable
        mov     modbuf.m_echr,'^'       ; note control char
        mov     modbuf.m_hlp,'^'
modl1:  mov     modbuf.m_echr+1,al      ; fill in character
        mov     modbuf.m_hlp+1,al
        mov     al,ourarg.baudb         ; get baud bits
        mov     si,offset unkbaud       ; assume unknown baud
        cmp     al,baudnsiz             ; too big?
        jnb     modl2                   ; yes, use default
        mov     cl,2                    ; each is 4 bytes long
        shl     al,cl
        mov     ah,0
        add     ax,offset baudn
        mov     si,ax
modl2:  mov     cx,size m_baud          ; length of baud space
        mov     di,offset modbuf.m_baud
        rep     movsb                   ; copy in baud rate
        mov     al,ourarg.parity        ; get parity code
        mov     cl,2                    ; each is 4 bytes long...
        shl     al,cl
        mov     ah,0
        add     ax,offset parnams       ; names of parity settings
        mov     si,ax
        mov     cx,4                    ; each is 4 long
        mov     di,offset modbuf.m_par
        rep     movsb
        mov     si,offset remmsg        ; assume remote echoing
        test    ourarg.flgs,lclecho     ; echoing?
        jz      modl4                   ; no, keep going
        mov     si,offset lclmsg
modl4:  mov     cx,3                    ; size of on/off
        mov     di,offset modbuf.m_echo
        rep     movsb
;       mov     al,'1'
;       cmp     portno,1                ; port 1?
;       je      modl5                   ; yes, keep going
;       mov     al,'2'
;modl5: mov     modbuf.m_prt,al         ; fill in port number
;       mov     cx,size modfrm          ; this is size of mode line
;       mov     si,offset modbuf        ; mode line image
        mov     si,offset offmsg        ; assume printer off
        test    flags1,prtscr           ; print screen enabled?
        jz      modl5                   ; no, keep going
        mov     si,offset onmsg
modl5:  mov     cx,3
        mov     di,offset modbuf.m_prs
        rep     movsb
        mov     dx,offset modbuf
        call    putmod
        ret                             ; and return
modlin  endp

; translate the scan code in ah according to the translate table
; given in ktrntab/krpltab, output to port.  If no translation,
; use ascii char in al. (should probably include shift state
; somewhere).  Shift state is in bl.
trnout  proc    near
        test    ourarg.flgs,havtt       ; translate table given?
        jz      trnou3                  ; no, just output character
        cmp     ourarg.klen,0           ; did they say we have one
        je      trnou3                  ; but we really don't?
        push    ax                      ; save original value
        xor     ah,ah                   ; Zero top half
        mov     di,ourarg.ktab
        mov     cx,ourarg.klen
        repne   scasw                   ; look for our key
        pop     ax                      ; recover character
        jne     trnou3                  ; not found, forget it
        sub     di,ourarg.ktab
        sub     di,2                    ; (minus 2 for pre-increment)
        mov     bx,ourarg.krpl
        mov     si,[bx][di]             ; and addr of replacement
        mov     cl,[si]                 ; get first byte (length)
        xor     ch,ch                   ; clear high-order byte
        inc     si                      ; point to translation string
trnou2: lodsb                           ; get a byte
        push    si
        push    cx                      ; save important registers
        call    outprt                  ; send to port
        pop     cx
        pop     si
        loop    trnou2                  ; send all chars
        ret                             ; and return
trnou3: xor     ah,ah                   ; get scan code
        mov     cx,lckeys               ; length of table
        mov     di,offset ckeys         ; table address
        repne   scasb
;       mov     al,0                    ; ascii code was 0...
        jne     trnou4                  ; not found, keep going
        sub     di,offset ckeys+1       ; get table offset
        shl     di,1                    ; shift for word offset
        jmp     ckacts[di]              ; jump to appropriate routine
trnou4: call    outprt                  ; just output single char
        ret                             ; and return

;trnmod:        test    flags,modoff            ; mode line already off?
;       jnz     trnm1                   ; yes, go turn on
;       call    clrmod                  ; no, clear mode line here
;       or      flags,modoff            ; turn on flag
;       ret                             ; and return
;trnm1: call    modlin                  ; turn on mode line
;       and     flags,not modoff        ; clear flag
;       ret                             ; and return

trnbrk:
        call    sendbr
        ret

trnprs: xor     flags1,prtscr           ; flip the flag
        and     ourarg.flgs,not modoff  ; turn on mode line
        call    modlin                  ; write into mode line
        ret                             ; and return

trn1ch: mov     cx,1                    ; length is always 1
        jmp     trnou2

; common entry for arrow keys
trn2ch: mov     cx,2                    ; length is always 2
        jmp     trnou2                  ; go send definition

trn3ch: mov     cx,3                    ; length is always 3
        jmp     trnou2

trnupw: mov     si,offset uptrn
        jmp     trn2ch

trndnw: mov     si,offset dntrn
        jmp     trn2ch

trnlfw: mov     si,offset lftrn
        jmp     trn2ch

trnrgw: mov     si,offset rgtrn
        jmp     trn2ch

trnhom: mov     si,offset homtrn
        jmp     trn2ch

trnent: mov     si,offset enttrn
        jmp     trn1ch

trnf0:  mov     si,offset f0trn
        jmp     trn2ch

trnf1:  mov     si,offset f1trn
        jmp     trn2ch

trnf2:  mov     si,offset f2trn
        jmp     trn2ch

trnf3:  mov     si,offset f3trn
        jmp     trn2ch

trnf4:  mov     si,offset f4trn
        jmp     trn2ch

trnf5:  mov     si,offset f5trn
        jmp     trn2ch

trnf6:  mov     si,offset f6trn
        jmp     trn2ch

trnf7:  mov     si,offset f7trn
        jmp     trn2ch

trnf8:  mov     si,offset f8trn
        jmp     trn2ch

trnf9:  mov     si,offset f9trn
        jmp     trn3ch

trnf10: mov     si,offset f10trn
        jmp     trn3ch

trnf11: mov     si,offset f11trn
        jmp     trn3ch

trnkpn: and     al,07fh                 ; strip high bits
        jmp     trnou4                  ; now output it

trnkps: and     al,03fh                 ; strip high bits (special case)
        jmp     trnou4

trnsf0: mov     si,offset sf0trn
        jmp     trn2ch

trnsf1: mov     si,offset sf1trn
        jmp     trn3ch

trnsf2: mov     si,offset sf2trn
        jmp     trn3ch

trnsf3: mov     si,offset sf3trn
        jmp     trn3ch

trnsf4: mov     si,offset sf4trn
        jmp     trn3ch

trnsf5: mov     si,offset sf5trn
        jmp     trn3ch

trnsf6: mov     si,offset sf6trn
        jmp     trn3ch

trnsf7: mov     si,offset sf7trn
        jmp     trn3ch

trnsf8: mov     si,offset sf8trn
        jmp     trn3ch

trnsf9: mov     si,offset sf9trn
        jmp     trn3ch

trnsf10: mov    si,offset sf10trn
        jmp     trn3ch

trnsf11: mov    si,offset sf11trn
        jmp     trn3ch

trnskp1: mov    si,offset skp1trn
        jmp     trn2ch

trnskp2: mov    si,offset skp2trn
        jmp     trn2ch

trnskp3: mov    si,offset skp3trn
        jmp     trn2ch

trnskp4: mov    si,offset skp4trn
        jmp     trn2ch

trnskp5: mov    si,offset skp5trn
        jmp     trn2ch

trnskp6: mov    si,offset skp6trn
        jmp     trn2ch

trnskp7: mov    si,offset skp7trn
        jmp     trn2ch

trnskp8: mov    si,offset skp8trn
        jmp     trn2ch

trnskp9: mov    si,offset skp9trn
        jmp     trn2ch

trnout  endp

code    ends
        end

