   10REM SAVE"$.Arabic.Source.StateMC"
   20very_temp = T%
   30PROCConsts
   40True = 0:False = 1
   50PROCVars
   60data=FNzp(2,"data:StateMC")
   70ContextAnalyseFlag = H%: NumberReverseFlag = I%
   80OsWrCh = &FFEE
   90WrchV = &200+7*2
  100ExtWrch = &FF00+7*3
  110DIM O% &BFFF-P%
  120del = 127
  130_Idle    = 0
  140_FirstC  = 1
  150_FirstV  = 2
  160_LastC   = 3
  170_LastV   = 4
  180_LastCV  = 5
  190_LastVC  = 6
  200R%=P%:Q%=O%
  210FOR Pass=4 TO 6+L% STEP 2+L%
  220P%=R%:O%=Q%
  230[OPT Pass
  240\ Because we are pushed for time, this will go via 3-byte vector...
  250.ArabicFont
  260  OPT FNStack(zp0):OPT FNStack(zp1)
  270  Lda #FontDef MOD 256:Sta zp0
  280  Lda #FontDef DIV 256:Sta zp1
  290.InitFont
  300  Lda (zp0):Jsr OsWrCh
  310  Inc zp0:Bne qq1:Inc zp1:.qq1
  320  Lda zp0:Cmp #FontEnd MOD 256:Bne InitFont
  330  Lda zp1:Cmp #FontEnd DIV 256:Bne InitFont
  340  OPT FNUnstack(zp1):OPT FNUnstack(zp0)
  350  Rts
  360 
  370.WrchHandlerInit
  380  OPT FNEnter
  390  Lda WrchV:OPT FNSta(HisWrch)
  400  Lda WrchV+1:OPT FNSta(HisWrch+1)
  410  Lda #ExtWrch MOD 256:Sta WrchV
  420  Lda #ExtWrch DIV 256:Sta WrchV+1
  430  Lda #MyWrch MOD 256:Sta &D9F+3*7+0
  440  Lda #MyWrch DIV 256:Sta &D9F+3*7+1
  450  Lda &F4:Sta &D9F+3*7+2
  460  Lda #0:OPT FNSta(CurrentState)
  470  Lda #False:OPT FNSta(StateMachineActive)
  480  Lda #0:Sta Buff
  490  Ldx &F4:Lda &DF0,X:Clc:Adc #1:Sta Buff+1 Number buffer MUST BE second page
  500  Lda #0:OPT FNSta(Idx)
  510OPT FNdebug("T")
  520  OPT FNExit
  530  Rts
  540 
  550.notalph
  560  Rts
  570 
  580.AlphabetHandler
  590  Cmp #71:Bne notalph
  600  Cpx #0:Bmi notalph
  610  Cpx #21:Bne notarabic
  620  Jsr ArabicFont
  630  OPT FNEnter
  640  Lda #True:OPT FNSta(StateMachineActive)
  650  OPT FNExit
  660  Lda #0
  670  Rts
  680.notarabic
  690\ Tweak variables to say 'don't table-lookup arabic chars'
  700   PHA:PHX:PHY
  710   OPT FNEnter
  720   Lda #False:OPT FNSta(StateMachineActive)
  730   OPT FNExit
  740   PLY:PLX:PLA
  750  Rts
  760 
  770.NextWrch
  780  Jsr NumericStateMachine
  790  Rts
  800.RawWrch
  810Jmp &E7E6 \ For now...
  820  OPT FNJmpI(HisWrch)
  830 
  840.MyWrch
  850  PHX:PHY:PHA
  860\Lda &90:\Cmp #ASC("T"):.zzpp \Bne zzpp
  870PLA:PHA
  880OPT FNdebug("A")
  890  TAY:OPT FNEnter:TYA
  900  OPT FNSta(ThisChar)
  910OPT FNdebug("B")
  920  OPT FNLda(StateMachineActive):Cmp #True:Bne DoRaw
  930OPT FNdebug("C")
  940  Lda #&DA:Ldx #0:Ldy #255: \Jsr OsByte:Ldx &26A  \ GOES BANG HERE TOO!!!!!!
  950OPT FNdebug("D")
  960  Cpx #0:Beq NotInVDUSeq
  970.DoRaw
  980OPT FNdebug("E")
  990  OPT FNLda(ThisChar)
 1000  TAY:OPT FNExit:TYA:PLA:PHY
 1010  PLA:PLY:PLX
 1020OPT FNdebug("U")
 1030  Jsr RawWrch
 1040OPT FNdebug("T")
 1050  Rts
 1060.NotInVDUSeq
 1070OPT FNdebug("G")
 1080\ Entry to state-machine.
 1090\ CurrentState initialised to Idle (0)
 1100  OPT FNLda(ContextAnalyseFlag):Cmp #True:Beq checkQ
 1110  OPT FNLda(ThisChar)
 1120OPT FNdebug("H")
 1130  Tay:Lda SATab,Y  \ Actually, not SATab but that corresponding to
 1140                   \ current arabic alphabet (Arabic1 - Arabic4)
 1150  Jsr NextWrch
 1160OPT FNdebug("I")
 1170  Jmp MyWrchExit
 1180.checkQ
 1190OPT FNdebug("J")
 1200\ We forgot the concept of 'NUL' characters which don't change the
 1210\ state machine, whatever state it is in.  CHR$(0) is the obvious
 1220\ example; less obvious ones are complete VDU 23 sequences and
 1230\ colour changes etc.   As the state machine only ever sees the first
 1240\ byte of any of these multi-byte sequences anyway, it ought to be
 1250\ possible to cause an early exit.  Almost special case but not quite -
 1260\ the characters causing the exit can be flagged in a table - ideally
 1270\ TypeTab if we can find a spare bit which does not affect any other
 1280\ tests...
 1290  OPT FNLdy(ThisChar)
 1300  Lda CharType,Y
 1310  Sta TmpVar
 1320  Bit TmpVar \ &40 -> V, &80 -> N
 1330  Bmi SetC:Bvs VSet
 1340  \ Neither - Set N
 1350  Clc:Lda #&80:Bra SetOK
 1360OPT FNdebug("K")
 1370.SetC
 1380OPT FNdebug("L")
 1390  \ &80 set - set C, clear N (V will be clear)
 1400  Sec:Lda #&00:Bra SetOK
 1410.VSet
 1420OPT FNdebug("M")
 1430  Clc:Lda #&00 \ - clear C,N (V will be set)
 1440  \ V is set if bit6 is set, i.e. VowelBit
 1450  \ C is set if bit7 is set, i.e. ConsonantBit
 1460  \ N is set if neither bit6 nor bit7 set, i.e. NeitherBit
 1470.SetOK
 1480OPT FNdebug("N")
 1490  PHP
 1500  PLA:Sta TmpVar:PHA
 1510  Lda #(ReturnToHere-1) DIV 256:Pha
 1520  Lda #(ReturnToHere-1) MOD 256:Pha
 1530  Lda TmpVar:PHA
 1540  OPT FNLda(CurrentState):Tax
 1550  Lda StateTab_high,X:Pha
 1560  Lda StateTab_low,X :Pha
 1570OPT FNdebug("O")
 1580  Rts \ Enter with C,V,N & Y=ThisChar set up.
 1590.ReturnToHere
 1600OPT FNdebug("P")
 1610  PLP
 1620  \ Load up next state from table
 1630  \ Copy Last into ButLast
 1640  \ Copy ThisChar into Last
 1650  \ Return...
 1660  Lda #0    \ C set => 0
 1670  Bcs CState
 1680  Php:Clc:Adc #1:Plp     \ V set => 1
 1690  Bvs VState
 1700  Clc:Adc #1     \ neither set => 2
 1710.CState:.VState
 1720OPT FNdebug("Q")
 1730  Clc:OPT FNAdc(CurrentState):OPT FNAdc(CurrentState):OPT FNAdc(CurrentState)
 1740  Tay:Lda CTransTab,Y
 1750  OPT FNSta(CurrentState)
 1760  OPT FNLda(LastChar):OPT FNSta(ButLastChar)
 1770  OPT FNLda(ThisChar):OPT FNSta(LastChar)
 1780OPT FNdebug("R")
 1790.MyWrchExit
 1800  OPT FNExit \ *************** MAIN EXIT POINT
 1810OPT FNdebug("S")
 1820  PLA:PLY:PLX
 1830OPT FNdebug("T")
 1840  Rts                          \ <<<<<<< Return from Wrch ????
 1850 
 1860 
 1870.StateTab_low
 1880  EQUB (Idle-1)   MOD 256
 1890  EQUB (FirstC-1) MOD 256
 1900  EQUB (FirstV-1) MOD 256
 1910  EQUB (LastC-1)  MOD 256
 1920  EQUB (LastV-1)  MOD 256
 1930  EQUB (LastCV-1) MOD 256
 1940  EQUB (LastVC-1) MOD 256
 1950 
 1960.StateTab_high
 1970  EQUB (Idle-1)   DIV 256
 1980  EQUB (FirstC-1) DIV 256
 1990  EQUB (FirstV-1) DIV 256
 2000  EQUB (LastC-1)  DIV 256
 2010  EQUB (LastV-1)  DIV 256
 2020  EQUB (LastCV-1) DIV 256
 2030  EQUB (LastVC-1) DIV 256
 2040 
 2050.CTransTab \ Table of state transition
 2060\     State          OnC             OnV            OnX
 2070\                                                       
