include "inc/cmdsys.plh"
include "inc/conio.plh"
sysflags nojitc // Keep tone() from compiling and sounding different
//
// Handy constants.
//
const FULLMODE     = 0
const MIXMODE      = 1
//
// Apple II ZP locations.
//
const a2rndnum = $4E // ZP location of RND
const a2rndl   = $4E
const a2rndh   = $4F
//
// Apple II hardware constants.
//
const WNDLEFT      = $20
const WNDWIDTH     = $21
const WNDTOP       = $22
const WNDBOTTOM    = $23
const CURSH        = $24
const CURSV        = $25
const TBASE        = $28
const CSW          = $36
const KSW          = $38
const CURSH80      = $057B
const store80dis   = $C000
const store80ena   = $C001
const showgraphics = $C050
const showtext     = $C051
const showfull     = $C052
const showmix      = $C053
const showpage1    = $C054
const showpage2    = $C055
const page1m       = $C054
const page1x       = $C055
const showlores    = $C056
const showhires    = $C057
const IOUdis       = $C07E
const IOUena       = $C07F
const keyboard     = $C000
const keystrobe    = $C010
const pushbttn1    = $C061
const pushbttn2    = $C062
const pushbttn3    = $C063
const speaker      = $C030
//
// Apple III hardware constants.
//
const ENV_REG      = $FFDF
//
// Predefined functions.
//
predef a2keypressed,a2getkey,a2putuprchars(cnt,chrs), a2ctrl(code,param)
predef a2clear(clr),a2gotoxy(x,y),a2viewport(left, top, width, height)
predef a2textmode(cols),a2grmode(mix),a2grcolor(color),a2grplot(x,y)
predef a2tone(duration, delay),a2rnd
//
// Exported function table.
//
word conio[]
//
// Function pointers.
//
word = @a2keypressed
word = @a2getkey
word = @a2putuprchars
word = @a2clear
word = @a2gotoxy
word = @a2viewport
word = @a2ctrl
word = @a2textmode
word = @a2grmode
word = @a2grcolor
word = @a2grplot
word = @a2tone
word = @a2rnd
//
// Screen row address arrays.
//
word txt1scrn[]     = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
word                = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
word                = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
word txt2scrn[]     = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
word                = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
word                = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
//
// Flags for current mode
//
const showcurs  = $01
const shiftlock = $02
const echo      = $04
const uppercase = $08
const txt80e    = $10 // IIe & //c 80 column
const txt80v    = $20 // VIDEX 80 column card
const txt80a    = $40 // ALS SmartTerm 80 column card
const txt80     = txt80e | txt80v | txt80a
byte flags
//
// UltraTerm extended mode heights
byte[] UltraTermHeight = 24, 24,  24, 24, 32, 48,  24,  32
//
// Apple 3 console codes.
//
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
byte a3keyqueue  = 0
//
// Random number for Apple 1 and III.
//
word randnum = 12345
//
// Native  routines.
//
asm equates
    !SOURCE "vmsrc/plvmzp.inc"
end
//
// def grscrn(rowaddrs)
//
asm a2grscrn(rowaddrs)
GRSCRN  =   $26
GRSCRNL =   GRSCRN
GRSCRNH =   GRSCRNL+1
    LDA ESTKL,X
    STA GRSCRNL
    LDA ESTKH,X
    STA GRSCRNH
    RTS
end
//
// def grcolor(color)
//
asm a2grcolor(color)
GRCLR   =   $30
    LDA #$0F
    AND ESTKL,X
    STA GRCLR
    ASL
    ASL
    ASL
    ASL
    ORA GRCLR
    STA GRCLR
    RTS
end
//
// def grplot(x, y)
//
asm a2grplot(x, y)
    STY IPY
    LDA ESTKL,X
    AND #$FE
    CMP ESTKL,X
    TAY
    LDA (GRSCRN),Y
    STA DSTL
    INY
    LDA (GRSCRN),Y
    STA DSTH
    LDY ESTKL+1,X
    LDA (DST),Y
    EOR GRCLR
    STA TMPL
    LDA #$FF
    ADC #$00
    EOR #$F0
    AND TMPL
    EOR GRCLR
    STA (DST),Y
    LDY IPY
    INX
    RTS
end
asm a2cout(chr)#0
LCRDEN  =       $C080
LCWTEN  =       $C081
ROMEN   =       $C082
LCRWEN  =       $C083
LCBNK2  =       $00
LCBNK1  =       $08
COUT    =       $FDED
        LDA     ESTKL,X
        ORA     #$80
        BIT     ROMEN
        JSR     COUT
        BIT     LCRDEN+LCBNK2
        INX
        RTS
end
//def a2putchars(cnt, chrs)
//    byte c
//
//    if cnt
//        if chrs & $FF00
//            for c = 0 to cnt-1; putc(^(chrs + c)); next
//        else
//            for c = 0 to cnt-1; putc(chrs); next
//        fin
//    fin
//    return ^CURSH
//end
asm a2putchars(cnt, chrs)
        LDA     ESTKH+1,X       ; CNTH
        BNE     EXA2PC          ; > 255
        LDA     ESTKL+1,X       ; CNTL
        BEQ     EXA2PC          ; == 0
        BIT     ROMEN
        LDA     ESTKH,X
        BEQ     ++
        STA     SRCH            ; SRC = CHRPTR
        LDA     ESTKL,X
        STA     SRCL
        LDY     #$00
-       STY     ESTKH+1,X
        TYA
        CMP     ESTKL+1,X
        BEQ     EXA2PC
        LDA     (SRC),Y
        ORA     #$80
        JSR     COUT
        LDY     ESTKH+1,X
        INY
        BNE     -
++
-       LDA     ESTKL,X         ; CHR
        ORA     #$80
        JSR     COUT
        DEC     ESTKL+1,X
        BNE     -
EXA2PC  INX
        BIT     LCRDEN+LCBNK2
        RTS
end
asm a2putuprchars(cnt, chrs)
TXTATTR =       $32
        LDA     ESTKH+1,X       ; CNTH
        BNE     EXA2UPC         ; > 255
        LDA     ESTKL+1,X       ; CNTL
        BEQ     EXA2UPC         ; == 0
        BIT     ROMEN
        LDA     TXTATTR
        STA     TMPL
        LDA     ESTKH,X
        BEQ     ++
        STA     SRCH            ; SRC = CHRPTR
        LDA     ESTKL,X
        STA     SRCL
        LDY     #$00
-       STY     ESTKH+1,X
        TYA
        CMP     ESTKL+1,X
        BEQ     EXA2UPC
        LDA     (SRC),Y
        ORA     #$80
        CMP     #'a'+128
        BCC     +
        CMP     #'z'+129
        BCS     +
        SBC     #$1F
        PHA
        LDA     #$3F            ; OUTPUT LC AS INV
        STA     TXTATTR
        PLA
+       JSR     COUT
        LDA     TMPL
        STA     TXTATTR
        LDY     ESTKH+1,X
        INY
        BNE     -
++      LDA     ESTKL,X         ; CHR
        ORA     #$80
        CMP     #'a'+128
        BCC     +
        CMP     #'z'+129
        BCS     +
        SBC     #$1F
        PHA
        LDA     #$3F
        STA     TXTATTR
        PLA
+
-       PHA
        JSR     COUT
        PLA
        DEC     ESTKL+1,X
        BNE     -
        LDA     TMPL
        STA     TXTATTR
EXA2UPC INX
        BIT     LCRDEN+LCBNK2
        RTS
end
asm vidcpy(dstrow, srcrow)#0
WNDLFT  =       $20
WNDWID  =       $21
        LDA     WNDLFT
        CLC
        ADC     ESTKL+1,X
        STA     DSTL
        LDA     #$00
        ADC     ESTKH+1,X
        STA     DSTH
        LDA     WNDLFT
        CLC
        ADC     ESTKL,X
        STA     SRCL
        LDA     #$00
        ADC     ESTKH,X
        STA     SRCH
        LDY     WNDWID
        DEY
-       LDA     (SRC),Y
        STA     (DST),Y
        DEY
        BPL     -
        INX
        INX
        RTS
end
asm vidxcpy(dstrow, srcrow)#0
PAGE1M  =       $C054
PAGE1X =        $C055
        LDA     WNDLFT
        LSR
        ADC     ESTKL+1,X
        STA     DSTL
        LDA     #$00
        ADC     ESTKH+1,X
        STA     DSTH
        LDA     WNDLFT
        LSR
        ADC     ESTKL,X
        STA     SRCL
        LDA     #$00
        ADC     ESTKH,X
        STA     SRCH
        LDA     WNDWID
        LSR
        ADC     #$00
        PHA
        TAY
        DEY
        STA     PAGE1X
-       LDA     (SRC),Y
        STA     (DST),Y
        DEY
        BPL     -
        PLA
        TAY
        DEY
        STA     PAGE1M
-       LDA     (SRC),Y
        STA     (DST),Y
        DEY
        BPL     -
        INX
        INX
        RTS
end
asm vid3cpy(dstrow, srcrow)#0
        LDA     ESTKL+1,X
        STA     DSTL
        LDA     ESTKH+1,X
        STA     DSTH
        LDA     ESTKL,X
        STA     SRCL
        LDA     ESTKH,X
        STA     SRCH
        LDY     #40
        DEY
-       LDA     (SRC),Y
        STA     (DST),Y
        DEY
        BPL     -
        INX
        INX
        RTS
end
//
// Apple 1 routines.
//
def a1keypressed
    return ^$D011 >= 128 ?? ^$D011 :: 0
end
def a1getkey
    while not a1keypressed
        randnum = randnum + 123
    loop
    return getc()
end
def a1putchars(cnt, chrs)
    byte c

    if chrs < 256
        for c = 1 to cnt
            putc(chrs)
        next
    else
        for c = 0 to cnt-1
            putc(chrs->[c])
        next
    fin
    return cnt
end
def a1clear(clr)
    byte l
    when clr
        is cleol
            break
        is cleos
        is cls
            for l = 0 to 23
                putln
            next
            break
    wend
    return 0
end
def a1gotoxy(x, y)
    //curshpos = x
    //cursvpos = y
    putln
    while x
        putc(' ')
        x = x - 1
    loop
    return 0
end
def a1viewport(left, top, width, height)
    return 0
end
def a1ctrl(code, param)#1
    return FALSE
end
def a1textmode(columns)
    return 40
end
def a1grmode(mix)
    return 0 // not supported
end
def a1tone(duration, delay)
    byte i

    while duration
        for i = delay downto 0; next
        duration--
    loop
    return 0
end
//
// Apple II routines.
//
def a2keypressed
    *a2rndnum++
    return ^keyboard >= 128 ?? ^keyboard :: 0
end
def a2getkey
    byte key

    repeat
        *a2rndnum++
        key = ^keyboard
        if key == $80 | keyctrll
            ^keystrobe
            flags = flags ^ shiftlock
            key   = 0
        fin
    until key >= 128
    ^keystrobe
    when key
        is $80 | keyctrln
            key = $DB // '['
            break
        is $9E // SHIFT+CTRL+N
            key = $FE // '~'
            break
        is $80 | keyctrlp
            key = $DC // '\'
            break
        is $80 // SHIFT+CTRL+P -> CTRL+@
            key = $FC // '|'
            break
        is $80 | keyctrlg
            key = $DF // '_'
            break
        is $80 | keyarrowleft
            if ^pushbttn3 < 128
                key = keydelete
            fin
            break
        is $80 | keyarrowright
            if ^pushbttn3 < 128
                key = keytab
            fin
            break
        otherwise
            if key >= $C0 and flags & shiftlock
                if ^pushbttn3 < 128
                    when key
                        is $C0
                            key = $D0 // P
                            break
                        is $DD
                            key = $CD // M
                            break
                        is $DE
                            key = $CE // N
                    wend
                else
                   key = key | $E0
                fin
            fin
    wend
    return (pushbttn2 & $80) | (key & $7F)
end
def a2egetkey
    byte key

    repeat
        *a2rndnum++
        key = ^keyboard
    until key >= 128
    ^keystrobe
    return (^pushbttn2 & $80) | (key & $7F)
end
def a2clear(clr)
    when clr
        is cleol // clear EOL
            call($FC9C, 0, 0, 0, 0) // CLEOL
            break
        is cls // home
            call($FC58, 0, 0, 0, 0) // HOME
            break
        is cleos // clear OES
            call($FC42, 0, 0, 0, 0) // CLREOP
            break
    wend
    return 0
end
def a2clear80(clr)
    when clr
        is cleol // clear EOL
            a2cout(29) // GS
            break
        is cls // home
            a2cout(12) // FF
            break
        is cleos // clear OES
            a2cout(11) // VT
            break
    wend
    return 0
end
def a2gotoxy(x, y)
    ^CURSH = x
    return call($FB5B, y + ^WNDTOP, 0, 0, 0) // TABV
end
def a2gotoxy80e(x, y)
    ^CURSH80 = x
    return call($FB5B, y + ^WNDTOP, 0, 0, 0) // TABV
end
def a2gotoxy80v(x, y)
    a2cout(30); a2cout(x + ' '); a2cout(y + ' ')
    return 0
end
def a2viewport(left, top, width, height)
    if !width or !height
        left   = 0
        top    = 0
        width  = flags & txt80 ?? 80 :: 40
        height = 24
    fin
    ^WNDLEFT   = left
    ^WNDWIDTH  = width
    ^WNDTOP    = top
    ^WNDBOTTOM = height + top
    return conio:gotoxy(0, 0)
end
def a2ctrl(code, param)#1
    word handled
    byte row

    handled = FALSE
    when code
        is ctrlattr
            ^$32 = param
            handled = TRUE
             break
        is ctrlecho
            if param
                flags = flags | echo
            else
                flags = flags & ~echo
            fin
            handled = TRUE
            break
        is ctrlcursor
            if param
                flags = flags | showcurs
            else
                flags = flags & ~showcurs
            fin
            handled = TRUE
            break
        is ctrlscroll
            if param > 0
                for row = ^WNDTOP to ^WNDBOTTOM - param - 1
                    vidcpy(txt1scrn[row], txt1scrn[row + param])
                next
            elsif param < 0
                for row = ^WNDBOTTOM - 1 downto ^WNDTOP - param
                    vidcpy(txt1scrn[row], txt1scrn[row + param])
                next
            fin
            handled = TRUE
            break
        is ctrlcase
            if not (flags & txt80)
                flags          = flags ^ uppercase
                conio:putchars = flags & uppercase ?? @a2putuprchars :: @a2putchars
            fin
            handled = TRUE
            break
    wend
    return handled
end
def a2ctrl80e(code, param)#1
    word handled
    byte row

    handled = FALSE
    when code
        is ctrlattr
            ^$32 = param
            handled = TRUE
             break
        is ctrlecho
            if param
                flags = flags | echo
            else
                flags = flags & ~echo
            fin
            handled = TRUE
            break
        is ctrlcursor
            if param
                flags = flags | showcurs
            else
                flags = flags & ~showcurs
            fin
            handled = TRUE
            break
        is ctrlscroll
            if param > 0
                for row = ^WNDTOP to ^WNDBOTTOM - param - 1
                    vidxcpy(txt1scrn[row], txt1scrn[row + param])
                next
            elsif param < 0
                for row = ^WNDBOTTOM - 1 downto ^WNDTOP - param
                    vidxcpy(txt1scrn[row], txt1scrn[row + param])
                next
            fin
            handled = TRUE
            break
    wend
    return handled
end
def a2ctrl80v(code, param)#1
    word handled
    byte row

    handled = FALSE
    when code
        is ctrlattr
            ^$32 = param
            handled = TRUE
            break
        is ctrlecho
            if param
                flags = flags | echo
            else
                flags = flags & ~echo
            fin
            handled = TRUE
            break
        is ctrlcursor
            when param
                is OFF
                    if flags & txt80v
                        ^$C0B0 = $0A
                        ^$C0B1 = $20
                    elsif flags & txt80a
                        a2cout(20) // Ctrl-T
                        a2cout('C')
                        a2cout('7')
                    fin
                    break
                is INVERSE
                    if flags & txt80v
                        ^$C0B0 = $0A
                        ^$C0B1 = $00
                    elsif flags & txt80a
                        a2cout(20) // Ctrl-T
                        a2cout('C')
                        a2cout('3')
                    fin
                    break
                otherwise
                    if flags & txt80v
                        ^$C0B0 = $0A
                        ^$C0B1 = $C0
                    elsif flags & txt80a
                        a2cout(20) // Ctrl-T
                        a2cout('C')
                        a2cout('3')
                    fin
            wend
            handled = TRUE
            break
        is ctrlscroll
            if param == UP
                a2cout(30); a2cout(' '); a2cout(^WNDBOTTOM + ' ' - 1); a2cout(10)
                handled = TRUE
            fin
            break
    wend
    return handled
end
def a2textmode(columns)
    byte height
    
    height = 24
    if columns == 0
        columns = (cmdsys:_sysflags_ & vid80col) ?? 80 :: 40
    fin
    if columns >= 80 and MACHID & MACHID_80COL
        //if not (flags & txt80)
            *CSW = $C300
        //fin
        if MACHID & $C0 == MACHID_IIE
            conio:clear    = @a2clear80
            conio:gotoxy   = @a2gotoxy80e
            conio:textctrl = @a2ctrl80e
            columns = 80
            flags = flags | txt80e
        else // MACHID_II
            conio:clear    = @a2clear80
            conio:gotoxy   = @a2gotoxy80v
            conio:textctrl = @a2ctrl80v
            conio:putchars = @a2putchars
            if ^$C304 == $1E // Try and identify different cards
                flags = flags | txt80a // ALS SmartTerm (hopefully)
                columns = 80
            else
                flags = flags | txt80v // Treat anything else as VIDEX
                ^$C059
                if columns > 80 and columns <= 88 \
                    and ^$C304 == $39 // Check for UltraTerm modes
                    a2cout(22); a2cout(columns - 80 + '0')
                    height = UltraTermHeight[columns - 81]
                else
                    a2cout(22); a2cout('1') // Ensure 80x24
                    columns = 80
                fin
            fin
        fin
    else
        if flags & txt80
            if flags & txt80e // IIe disable
                a2cout(21)
            elsif flags & txt80v // Videx disable
                a2cout(26); a2cout('1')
                ^$C058
            elsif flags & txt80a // ALS SmartTerm disable
                a2cout(20); a2cout('A'); a2cout('1')
            fin
            flags = flags & ~txt80
        fin
        call($FE89, 0, 0, 0, 0) // IN#0
        call($FE93, 0, 0, 0, 0) // PR#0
        call($FB2F, 0, 0, 0, 0) // INIT
        a2clear(cls)
        conio:putchars = flags & uppercase ?? @a2putuprchars :: @a2putchars
        conio:clear    = @a2clear
        conio:gotoxy   = @a2gotoxy
        conio:textctrl = @a2ctrl
        columns        = 40
    fin
    ^showtext
    ^showfull
    a2viewport(0, 0, columns, height)
    conio:clear(cls)
    return columns
end
def a2grmode(mix)
    a2textmode(40)
    call($FB2F, 0, 0, 0, 0) // initmode()
    call($FB40, 0, 0, 0, 0) // grmode()
    if !mix
        ^showfull
    fin
    a2clear(cls)
    return a2grscrn(@txt1scrn) // point to lo-res screen
end
def a2tone(duration, delay)
    byte i

    while duration
        ^speaker // toggle speaker
        for i = delay downto 0; next
        duration--
    loop
    return 0
end
def a2rnd
    *a2rndnum = ^a2rndh ^ ^a2rndl ^ (*a2rndnum << 1) + 125
    return *a2rndnum & $7FFF
end
//
// Apple III routines.
//
def cons_control(code, list)
    byte params[5]

    params.0 = 3
    params.1 = cmdsys.devcons
    params.2 = code
    params:3 = list
    return syscall($83, @params)
end
def cons_keyavail
    byte params[5]
    byte count

    params.0 = 3
    params.1 = cmdsys.devcons
    params.2 = 5
    params:3 = @count
    return syscall($82, @params) ?? 0 :: count
end
def cons_keyread
    byte params[8]
    byte key

    params.0 = 4
    params.1 = cmdsys.refcons
    params:2 = @key
    params:4 = 1
    params:6 = 0
    syscall($CA, @params)
    return params:6 ?? key :: 0
end
def a3keypressed
    byte count

    count = cons_keyavail
    if count
        a3keyqueue = cons_keyread
    fin
    return a3keyqueue ?? a3keyqueue | $80 :: 0
end
def a3getkey
    byte keycode
    repeat
        randnum = randnum + 123
        a3keypressed
        keycode = a3keyqueue
    until keycode
    a3keyqueue = 0
    return keycode
end
def a3putchar(chr)#0
    byte params[6]

    params.0 = 3
    params.1 = cmdsys.refcons
    params:2 = @chr
    params:4 = 1
    syscall($CB, @params)
end
def a3putchars(cnt, chrs)
    byte params[6]
    byte c

    params.0 = 3
    params.1 = cmdsys.refcons
    if chrs & $FF00
        params:2 = chrs
        params:4 = cnt
        syscall($CB, @params)
    else
        params:2 = @chrs
        params:4 = 1
        for c = 1 to cnt
            syscall($CB, @params)
        next
    fin
    return cnt
end
def a3clear(clr)
    when clr
        is cleol // clear EOL
            a3putchar(31) // GS
            break
        is cls // home
            a3putchar(28) // FF
            break
        is cleos // clear OES
            a3putchar(29) // VT
            break
    wend
    return 0
end
def a3gotoxy(x, y)
    char chrs[3]

    chrs[0] = 26
    chrs[1] = x
    chrs[2] = y
    a3putchars(3, @chrs)
    return 0
end
def a3viewport(left, top, width, height)
    if !width or !height
        //
        // Reset the full-screen viewport
        //
        left   = 0
        top    = 0
        width  = 40//textcols
        height = 24
    fin
    a3putchar(1) // Reset viewport
    a3putchar(26)
    a3putchar(left)
    a3putchar(top)
    a3putchar(2)
    a3putchar(26)
    a3putchar(left + width  - 1)
    a3putchar(top  + height - 1)
    a3putchar(3)
    return a3gotoxy(0, 0)
end
def a3ctrl(code, param)#1
    word handled
    byte row

    handled = FALSE
    when code
        is ctrlattr
            a3putchar(param == INVERSE ?? 18 :: 17)
            break
        is ctrlecho
            param = param ?? $80 :: 0
            cons_control(11, @param)
            handled = TRUE
            break
        is ctrlcursor
            a3putchar(param == OFF ?? 6 :: 5)
            handled = TRUE
            break
        is ctrlscroll
            if param > 0
                for row = 0 to 23 - param
                    vid3cpy(txt1scrn[row], txt1scrn[row + param])
                    vid3cpy(txt2scrn[row], txt2scrn[row + param])
                next
            elsif param < 0
                for row = 23 downto -param
                    vid3cpy(txt1scrn[row], txt1scrn[row + param])
                    vid3cpy(txt2scrn[row], txt2scrn[row + param])
                next
            fin
            handled = TRUE
            break
    wend
    return handled
end
def a3textmode(columns)
    a3putchar(16)
    if columns == 0 or columns >= 80
        a3putchar(2)
        columns = 80
    else
        a3putchar(0)
        columns = 40
    fin
    a3putchar(1) // Reset viewport
    a3putchar(28) // CLS
    a3ctrl(ctrlecho, ON)
    a3ctrl(ctrlcursor, OFF)
    return columns
end
def a3grmode(mix)
    byte i
    if mix
        mix = 19
    else
        mix = 23
    fin
    a3putchar(16); putc(1) // TEXT 40 COLOR MODE
    cons_control(17, @grcharset)
    a3viewport(0, 20, 40, 4)
    a3putchar(28)
    for i = 0 to mix
        memset(txt1scrn[i], $0000, 40) // text  screen
        memset(txt2scrn[i], $0000, 40) // color screen
    next
    return a2grscrn(@txt2scrn) // point to color screen
end
def a3tone(duration, pitch)
    byte env

    env = ^ENV_REG
    ^ENV_REG = env | $C0
    a2tone(duration, pitch)
    ^ENV_REG = env
    return 0
end
//
// Apple 1 and III combined routines.
//
def a13rnd
    randnum = (randnum << 1) + randnum + 123
    return randnum & $7FFF
end
//
// Machine specific initialization.
//
when MACHID & MACHID_MODEL
    is MACHID_III
        conio:keypressed = @a3keypressed
        conio:getkey     = @a3getkey
        conio:putchars   = @a3putchars
        conio:clear      = @a3clear
        conio:gotoxy     = @a3gotoxy
        conio:viewport   = @a3viewport
        conio:textctrl   = @a3ctrl
        conio:textmode   = @a3textmode
        conio:grmode     = @a3grmode
        conio:tone       = @a3tone
        conio:rnd        = @a13rnd
        break
    is MACHID_IIC
    is MACHID_IIE
        conio:getkey     = @a2egetkey
        conio:putchars   = @a2putchars
        break
    is MACHID_IIPLUS
    is MACHID_II
        flags            = flags | uppercase | shiftlock
        conio:putchars   = @a2putuprchars
        break
    is MACHID_I
        conio:keypressed = @a1keypressed
        conio:getkey     = @a1getkey
        conio:putchars   = @a1putchars
        conio:clear      = @a1clear
        conio:gotoxy     = @a1gotoxy
        conio:viewport   = @a1viewport
        conio:textctrl   = @a1ctrl
        conio:textmode   = @a1textmode
        conio:grmode     = @a1grmode
        conio:tone       = @a1tone
        conio:rnd        = @a13rnd
        break
wend
if cmdsys:_sysflags_ & vid80col; conio:textmode(80); fin
//
// Keep module in memory
//
return modkeep
done
