*
* MBX routines for XBasic
*
 
       DEF  MBINIT,KEYI,JOYI
       DEF  STGAME,STTALK,ALLOC
       DEF  TRAIN,MATCH,CLRTK
       DEF  MATCHS,DFGRP
*
*  Equates
*
 
NUMASG EQU  >2008
NUMREF EQU  >200C
STRASG EQU  >2010
STRREF EQU  >2014
XMLLNK EQU  >2018
KSCAN  EQU  >201C
VSBW   EQU  >2020
VMBW   EQU  >2024
VSBR   EQU  >2028
VMBR   EQU  >202C
ERR    EQU  >2034
CFI    EQU  >12B8
S      EQU  10
 
*
* Constants/Variables/Flags
*
MAINWS EQU  >20BA
IRQWS  BSS  >20
SIXTN  DATA 16
$ONE   DATA >100
QSTART EQU  >A000
$QUADR DATA >A000
$QUBIT DATA 0    bit queue
THRFF  DATA >3FFF
STARTF DATA >FFFF
$WTIMR DATA 0    IRQ timeout timer
TRAINS DATA 0    train
ABORTS DATA 0    abort listen success
LISTNS DATA 0    listen success
ALLOCS DATA 0    Alloc templates success
MATCHS DATA 0    Match success, 0 = successful
MCERT  BYTE 0    certainty of match
MWORD  BYTE 0    word number of match
MIKEST DATA 0    Mike status: 0=on, else off
MBXSTT DATA >FFFF MBX status: 0=available, else off
KEYMOD DATA 0    flag to tell if we're reading 2 keys: 0=1 key
KEY1   BYTE 0    return value of key #1
KEY2   BYTE 0    return value of key #2
$JOY1Y BYTE 0    joy stick values...
$JOY1X BYTE 0
$JOY1Z BYTE 0
$JOY1B BYTE 0
$JOY2Y BYTE 0
$JOY2X BYTE 0
$JOY2Z BYTE 0
$JOY2B BYTE 0
$TSLOT BYTE 0    number of template slots
$JYMSK BYTE >F0  joystick mask byte
$JYCNT BYTE 4
$JOYCT BYTE 0
$PARAM BYTE 0
SEVEN  BYTE 7
EIGHT  BYTE 8
 
* Completion flags: nonzero=pending, zero=completed
 
MATCHC DATA 0    Match word complete
MBEXC  DATA 0    MBX ID
SETGMC DATA 0    Set game
SETTKC DATA 0    Set talker
ALLOCC DATA 0    allocate templates
LISTNC DATA 0    listen
ABORTC DATA 0    abort listen
TRAINC DATA 0    train
 
TSTDFG DATA 0,1,2,3,4
 
DFGRP  LI   S,STACK
       CLR  R1
       LI   R2,5
       LI   R3,TSTDFG
       BL   @$DFGRP
       JMP  RETGPL
 
MBINIT LI   S,STACK
       BL   @INTXPD
RETGPL LWPI >83E0
       B    @>6A
 
KEYI   LI   S,STACK
       LI   R1,6
       BL   @$KEYI
       JMP  RETGPL
 
JOYI   LI   S,STACK
       BL   @$JOYI
       JMP  RETGPL
 
STGAME LI   S,STACK
       LI   R1,>0100
       MOVB R1,@$PARAM
       BL   @$SETGM
       JMP  RETGPL
 
STTALK LI   S,STACK
       LI   R1,>0100
       MOVB R1,@$PARAM
       BL   @$SETLK
       JMP  RETGPL
 
ALLOC  LI   S,STACK
TEN    EQU  $+2
       LI   R1,>0A00
       MOVB R1,@$PARAM
       BL   @$ALLCT
       JMP  RETGPL
 
CLRTK  LI   S,STACK
       BL   @$CLRTK
RETGP2 JMP  RETGPL
 
TRAIN  LI   S,STACK
       SB   @$PARAM,@$PARAM
TRAINZ BL   @$LSTEN
       LIMI 2
TRAIN$ ABS  @LISTNC
       JNE  TRAIN$
       LIMI 0
       BL   @$TRAIN
       LIMI 2
TRAINX ABS  @TRAINC
       JNE  TRAINX
       LIMI 0
       BL   @$LSTEN
       LIMI 2
TRAINA ABS  @LISTNC
       JNE  TRAINA
       LIMI 0
       BL   @$TRAIN
       LIMI 2
TRAINY ABS  @TRAINC
       JNE  TRAINY
       LIMI 0
       AB   @$ONE,@$PARAM
       CB   @TEN,@$PARAM
       JNE  TRAINZ
       JMP  RETGP2
 
MATCH  LI   S,STACK
       BL   @$LSTEN
       LIMI 2
MATCHA ABS  @LISTNC
       JNE  MATCHA
       LIMI 0
       CLR  R1
       BL   @$MATCH
       LIMI 2
MATCHB ABS  @MATCHC
       JNE  MATCHB
       LIMI 0
       JMP  RETGP2
 
* QUEUE
*
* xmit/recv queue handler
$TXRQU MOV  R11,*S+
       BL   @IRQ
       MOV  @$WTIMR,@$WTIMR
       JNE  $TXRQ2
       SETO @MBXSTT
       JMP  EXITZ
$TXRQ2 BL   @TXQUE
       BL   @$CLRQU
       B    @DEQUE2
TXREX
* Interrupt MBX
IRQ
IRQX   LI   R12,6
       SBZ  16
       SBO  15
       SBO  17
       SBZ  15
       SBO  16
       MOV  @THRFF,@$WTIMR
IRQ0   DEC  @$WTIMR
       JEQ  IRQ2
       TB   3
       JEQ  IRQ0
       SBO  15
       MOV  @THRFF,@$WTIMR
IRQ1   DEC  @$WTIMR
       JEQ  IRQ2
       TB   3
       JNE  IRQ1
       CLR  @MBXSTT
       JMP  IRQ3
IRQ2   SETO @MBXSTT
IRQ3   SBZ  16
IRQ4   RT
 
* xmit queue
 
TXQUE  MOV  R11,*S+
       LI   R2,QSTART
TXQ0   C    R2,@$QUADR
       JEQ  TXQ1
       LI   R9,16
       MOV  *R2+,R0
       BL   @TXD
       JMP  TXQ0
TXQ1   MOV  @$QUBIT,R9
       JEQ  TXQEND
       MOV  *R2,R0
       BL   @TXD
TXQEND LI   R9,1
       LI   R0,>8000
       BL   @TXD
EXITZ  DECT S
       MOV  *S,R11
       RT
* xmit
TXD$   MOV  R2,R0
TXD$$  LI   R9,8
TXD
TXDX   LI   R12,6
TXD0   SLA  R0,1
       JOC  OUT1
       SBO  15
       SBO  16
       JMP  TXW1
OUT1   SBZ  15
       SBO  16
TXW1   TB   3
       JEQ  TXW1
TXW2   TB   3
       JNE  TXW2
       DEC  R9
       JNE  TXD0
       SBO  15
       SBZ  16
       SBO  17
TXD2   RT
* DEQUEUE
*
MATCHW CLR  @MATCHC
       MOV  R7,R7
       JEQ  MATCH2
       SETO @MATCHS
       JMP  TOPDQ
MATCH2 CLR  @MATCHS
       BL   @RXD7
       MOVB R5,@MWORD
       BL   @RXD7
       MOVB R5,@MCERT
       JMP  TOPDQ
MIKEON MOVB R7,R7
       JEQ  MIKEOF
       CLR  @MIKEST
       JMP  TOPDQ
MIKEOF SETO @MIKEST
       JMP  TOPDQ
MBEXID CLR  @MBEXC
       MOVB R7,R7
       JEQ  MBEXOF
       CLR  @MBXSTT
       JMP  TOPDQ
MBEXOF SETO @MBXSTT
ENDR   JMP  TOPDQ
* main deque
DEQUE  MOV  R11,*S+
DEQUE2
TOPDQ  LI   R7,4
       BL   @RXD
       MOV  R5,R7
       ANDI R7,>1000
       ANDI R5,>F00
       CI   R5,>E00
       JH   TOPDQ
       SRL  R5,7
       LI   R9,ZEROA
       A    R5,R9
       B    *R9
*
ZEROA  JMP  ENDDQ
       JMP  KEYR
       JMP  JOYR
       JMP  SETGAM
       JMP  SETTLK
       JMP  ALLCTM
       JMP  LISTEN
       JMP  ABRTLS
       JMP  TRAINW
       JMP  MATCHW
       JMP  TOPDQ    string synthesis (not implemented!)
       JMP  TOPDQ    buffer status
       JMP  MIKEON
       JMP  TOPDQ    read memory from MBX
       JMP  MBEXID
*
KEYR   BL   @RXD8
       MOVB R5,@KEY1
KEYR2  ABS  @KEYMOD
       JEQ  TOPDQ
       BL   @RXD8
       MOVB R5,@KEY2
       JMP  TOPDQ
*
JOYR   CLR  R4
NXTBYT AB   @$ONE,R4
       BL   @RXD8
NXTMSK AB   @$ONE,@$JOYCT
       CB   @$JOYCT,@EIGHT
       JL   JSCAN
       SB   @$JOYCT,@$JOYCT
JSCAN  MOVB @$JYMSK,R1
       MOVB @$JOYCT,R0
       SRL  R0,8
       MOV  R0,R0
       JEQ  NSHF
       SLA  R1,0
NSHF   CI   R1,>8000
       JL   NXTMSK
       MOVB @$JOYCT,R7
       SRL  R7,8
       MOVB R5,@$JOY1Y(R7)
       CI   R7,3
       JEQ  JBUTN
       CI   R7,7
       JNE  JNXT
JBUTN  MOVB R5,R5
JNXT   CB   R4,@$JYCNT
       JL   NXTBYT
       JMP  TOPDQ
*
SETGAM BL   @RXD7
       MOVB R5,@$TSLOT
       CLR  @SETGMC
       JMP  TOPDQ
*
SETTLK BL   @RXD7
       MOVB R5,@$TSLOT
       CLR  @SETTKC
       JMP  TOPDQ
*
ALLCTM CLR  @ALLOCC
       MOV  R7,@ALLOCS
       JEQ  TOPDQ
       SETO @ALLOCS
       JMP  TOPDQ
*
LISTEN CLR  @LISTNC
       MOV  R7,@LISTNS
       JEQ  TOPDQ
       SETO @LISTNS
       JMP  TOPDQ
*
ABRTLS CLR  @ABORTC
       CLR  @LISTNC
       SETO @LISTNS
       MOV  R7,@ABORTS
       JEQ  TOPDQ
       SETO @ABORTS
TOPDQQ JMP  TOPDQ
*
TRAINW CLR  @TRAINC
       MOV  R7,@TRAINS
       JEQ  TOPDQQ
       SETO @TRAINS
       JMP  TOPDQQ
*
ENDDQ  B    @EXITZ
* recv data from MBX
RXD8   LI   R7,8
       JMP  RXD
RXD7   LI   R7,7
RXD
RXDX   LI   R9,4
       CLR  R5
       SBO  16
RXD0   CLR  R1
RWD1   STCR R2,4
       STCR R6,4
       CB   R2,R6
       JNE  RWD1
       SRL  R2,8
       MOVB @NIBB(R2),R1
       CI   R1,>0300
       JH   RXD0
       SBZ  15
       MOV  R9,R0
       SLA  R0,1
       SRL  R1,0
       SOC  R1,R5
       DEC  R9
RXD1   CLR  R1
RWD2   STCR R2,4
       STCR R6,4
       CB   R2,R6
       JNE  RWD2
       SRL  R2,8
       INV  R2
       ANDI R2,>F
       MOVB @NIBB(R2),R1
       CI   R1,>0300
       JH   RXD1
       SBO  15
       MOV  R9,R0
       SLA  R0,1
       SRL  R1,0
       SOC  R1,R5
       DEC  R9
       JNE  RXD0
RXD2   STCR R2,4
       SRL  R2,8
       CI   R2,>F
       JNE  RXD2
       SBZ  16
       SLA  R5,8
RXD3   RT
NIBB   BYTE >FF,>FF,>FF,>FF
       BYTE >FF,>FF,>FF,>03
       BYTE >FF,>FF,>FF,>02
       BYTE >FF,>01,>00,>FF
* ENQUE
*
ENQUE8 LI   R0,8
ENQUEM SRL  R1,8
ENQUE  MOV  R11,*S+
       MOV  R0,R4
       MOV  @SIXTN,R0
       S    R4,R0
       SLA  R1,0
       MOV  R1,R3
       MOV  @$QUBIT,R5
       A    R4,R5
       C    R5,@SIXTN
       JHE  PART
       MOV  @$QUBIT,R0
       JEQ  NOSHFT
       SRL  R1,0
       MOV  R1,R3
NOSHFT MOV  @$QUADR,R2
       SOC  R3,*R2
       A    R4,@$QUBIT
       JMP  ENDE
PART   MOV  R5,R4
       MOV  R1,R5
       MOV  @$QUBIT,R0
       SRL  R1,0
       MOV  R1,R3
       MOV  @SIXTN,R0
       S    @$QUBIT,R0
       SLA  R5,0
       MOV  @$QUADR,R2
       SOC  R3,*R2+
       INCT @$QUADR
       CLR  *R2
       SOC  R5,*R2
       MOV  R4,@$QUBIT
       S    @SIXTN,@$QUBIT
ENDE   B    @EXITZ
*
* enque command
ENQCMD MOV  R11,*S+
       MOVB @HUFF1(R2),R0
       SLA  R2,1
       MOVB @HUFFC(R2),R1
       SRL  R0,8
       CI   R0,8
       JLE  ENQCT
       MOV  R2,R9
       BL   @ENQUE8
       MOVB @HUFFC+1(R9),R1
       SRL  R9,1
       MOVB @HUFF1(R9),R0
       SB   @EIGHT,R0
       SRL  R0,8
ENQCT  BL   @ENQUEM
       DECT S
       MOV  *S,R11
       RT
*
HUFF1  BYTE >01,>0B,>0B,>0C,>08,>0C
       BYTE >0C,>06,>04,>06,>0C,>05
       BYTE >0C,>05,>08,>06,>02,>05
       BYTE >0A,>0A,>0A,>0B,>0B,>0C
       BYTE >0C,>0C,>06,>06,>0B
HUFFC  BYTE >01,>00,>01,>03,>01,>02
       BYTE >01,>0D,>03,>00,>01,>0F
       BYTE >01,>0E,>03,>00,>01,>00
       BYTE >01,>00,>01,>09,>07,>00
       BYTE >01,>0B,>06,>00,>02,>00
       BYTE >09,>00,>01,>00,>05,>00
       BYTE >00,>03,>00,>02,>00,>01
       BYTE >01,>00,>01,>01,>01,>0C
       BYTE >01,>08,>01,>0A,>02,>00
       BYTE >08,>00,>00,>01
* IRQRTN
*
IRQRTN LWPI IRQWS
       MOV  @MAINWS+20,S
       INCT S
       MOV  @STARTF,R0
       JNE  IRQRT1
       ABS  @MBXSTT
       JNE  IRQRT2
IRQRT1 BL   @$TXRQU
       ABS  @MBXSTT
       JNE  IRQRT2
       CLR  @STARTF
IRQRT2 LWPI >83E0
       RT
*
* Init MBX for training
INTXPD MOV  R11,*S+
       LIMI 0
       SETO @STARTF
INTX1  BL   @$CLRQU
       LI   R2,IRQRTN
       MOV  R2,@>83C4
       BL   @$MBXID
       LIMI 2
MBWAIT ABS  @MBEXC
       JNE  MBWAIT
       LIMI 0
       LI   R2,IRQRTN
       MOV  R2,@>83C4
       JMP  EXITS
*
* clear queue
$CLRQU MOV  R11,*S+
       CLR  @$QUBIT
       LI   R2,QSTART
       MOV  R2,@$QUADR
       CLR  *R2
       JMP  EXITS
* CMDS
*
* init keypad
$KEYI  MOV  R11,*S+
$KEYI2 MOV  R1,R6
       CLR  @KEYMOD
       ANDI R1,>80
       JEQ  $KEYI3
       SETO @KEYMOD
$KEYI3 LI   R2,1
       LIMI 0
       BL   @ENQCMD
       LI   R0,8
MATCH1 MOV  R6,R1
       BL   @ENQUE
EXITS  DECT S
       MOV  *S,R11
       RT
* init joyst
$JOYI  MOV  R11,*S+
       MOVB @SEVEN,@$JOYCT
       LI   R2,2
       LIMI 0
       BL   @ENQCMD
       MOVB @$JYMSK,R1
       BL   @ENQUE8
       LI   R0,8
       MOVB @$JYCNT,R1
       BL   @ENQUEM
       MOVB @$JYCNT,R1
       ANDI R1,>0FFF
       MOVB R1,@$JYCNT
       JMP  EXITS
* set game code
$SETGM SETO @SETGMC
       LI   R2,3
       JMP  SETGM1
* set talker
$SETLK SETO @SETTKC
       LI   R2,4
       JMP  SETLK1
* allocate templates
$ALLCT SETO @ALLOCC
       LI   R2,5
       JMP  ALLCT1
* clear templates
$CLRTK LI   R2,6
       JMP  CLRTK1
* define word group
$DFGRP MOV  R11,*S+
       MOV  R1,R6
       MOV  R2,R7
       MOV  R3,R8
       LI   R2,7
       LIMI 0
       BL   @ENQCMD
       LI   R0,3
       MOV  R6,R1
       BL   @ENQUE
       LI   R0,5
       MOV  R7,R1
       BL   @ENQUE
       MOV  R7,R6
WORDS  LI   R0,7
       MOV  *R8,R1
       BL   @ENQUE
       INCT R8
       DEC  R6
       MOV  R6,R6
       JGT  WORDS
       JMP  EXITS
* listen cmd
$LSTEN ABS  @LISTNC
       JNE  LSTENA
       ABS  @ALLOCS
       JEQ  LSTENE
       CLR  @LISTNC
       SETO @LISTNS
LSTENA RT
LSTENE SETO @LISTNC
       CLR  @LISTNS
       LI   R2,8
CLRTK1
ABRTL1 JMP  LSTEN1
* abort listen cmd
$ABRTL SETO @ABORTC
       SETO @ABORTS
       LI   R2,9
       JMP  LSTEN1
* train cmd
$TRAIN SETO @TRAINC
       SETO @TRAINS
       LI   R2,>A
SETGM1
SETLK1
ALLCT1
CLRWD1 MOV  R11,*S+
       LIMI 0
       BL   @ENQCMD
       LI   R0,7
SCLST1 MOVB @$PARAM,R1
       B    @ENQCT
* match cmd
$MATCH MOV  R11,*S+
       SETO @MATCHC
       SETO @MATCHS
       MOV  R1,R6
       LI   R2,>B
       LIMI 0
       BL   @ENQCMD
       LI   R0,3
       B    @MATCH1
* clear word
$CLRWD LI   R2,>C
       JMP  CLRWD1
* set cluster count
$SCLST MOV  R11,*S+
       LI   R2,>19
       LIMI 0
       BL   @ENQCMD
       LI   R0,4
       JMP  SCLST1
MIKE1
XINIT1
LSTEN1 MOV  R11,*S+
       LIMI 0
       BL   @ENQCMD
EXITY  DECT S
       MOV  *S,R11
       RT
* MBX ID cmd
$MBXID MOV  R11,*S+
       SETO @MBEXC
       LI   R2,>15
       LIMI 0
       BL   @ENQCMD
       JMP  EXITY
* init MBX
$XINIT LI   R2,>16
       JMP  XINIT1
* mike toggle
$MIKE  LI   R2,>1C
       JMP  MIKE1
 
STACK  EQU  $
       END
