   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\     Idle:    EQUB _FirstC:   EQUB _FirstV:  EQUB _Idle
 2080\     FirstC:  EQUB _LastC:    EQUB _LastV:   EQUB _Idle
 2090\     FirstV:  EQUB _LastVC:   EQUB _LastV:   EQUB _Idle
 2100\     LastC:   EQUB _LastC:    EQUB _LastCV:  EQUB _Idle
 2110\     LastV:   EQUB _LastVC:   EQUB _LastV:   EQUB _Idle
 2120\     LastCV:  EQUB _LastVC:   EQUB _LastV:   EQUB _Idle
 2130\     LastVC:  EQUB _LastC:    EQUB _LastCV:  EQUB _Idle
 2140 
 2150 
 2160 
 2170\State      ButL      Last    Input  Output                  NextState
 2180\Idle       Any       X       X      X                          Idle
 2190\                             C      C_beg                      FirstC
 2200\                             V      V_beg                      FirstV
 2210.Idle   PLP \ State 0
 2220  Lda BegTab,Y:Jsr NextWrch
 2230  Rts
 2240 
 2250\FirstC       X       C       X      del,Last_sa,X              Idle
 2260\                             C      del,Last_beg,C_mid         LastC
 2270\                             V      del,Last_beg,V_mid         LastV
 2280.FirstC PLP \ State 1
 2290  Bmi FirstC_sa
 2300.FirstC_beg
 2310  Lda #del:Jsr NextWrch
 2320  OPT FNLdy(LastChar):Lda BegTab,Y:Jsr NextWrch
 2330  OPT FNLdy(ThisChar):Lda MidTab,Y:Jsr NextWrch
 2340  Rts
 2350.FirstC_sa
 2360  Lda #del:Jsr NextWrch
 2370  OPT FNLdy(LastChar):Lda SATab,Y:Jsr NextWrch
 2380  OPT FNLda(ThisChar):Jsr NextWrch
 2390  Rts
 2400 
 2410\FirstV       X       V       X      del,V_sa,X                 Idle
 2420\                             C      del,V_beg,C_mid            LastVC
 2430\                             V      del,V_beg,V_mid            LastV
 2440.FirstV PLP \ State 2
 2450  PHP:Jmp FirstC \ Code entries identical for now
 2460  Rts
 2470 
 2480\LastC        C       C       C      C_mid                      LastC
 2490\                             V      V_mid                      LastCV
 2500\                             X      del,Last_end,X             Idle
 2510.LastC  PLP \ State 3
 2520  Bpl LastC_mid
 2530  Lda #del:Jsr NextWrch
 2540  OPT FNLdy(LastChar):Lda EndTab,Y:Jsr NextWrch
 2550.LastC_mid
 2560  OPT FNLdy(ThisChar):Lda MidTab,Y:Jsr NextWrch
 2570  Rts
 2580 
 2590\LastV       C/V      V       V      V_mid                      LastV
 2600\                             C      C_mid                      LastVC
 2610\                             X      del,Last_end,X             Idle
 2620.LastV  PLP \ State 4
 2630  PHP:Jmp LastC \ code entries same for now
 2640  Rts
 2650 
 2660\LastCV       C       V       X      del,del,ButL_end,Last_end,X  Idle
 2670\                             C      C_mid                      LastVC
 2680\                             V      V_mid                      LastV
 2690.LastCV PLP \ State 5
 2700  Bpl LastCV_mid
 2710  Lda #del:Jsr NextWrch:Jsr NextWrch
 2720  OPT FNLdy(ButLastChar):Lda EndTab,Y:Jsr NextWrch
 2730  OPT FNLdy(LastChar):Lda EndTab,Y:Jsr NextWrch
 2740.LastCV_mid
 2750  OPT FNLdy(ThisChar):Lda MidTab,Y:Jsr NextWrch
 2760  Rts
 2770 
 2780\LastVC       V       C       X      del,Last_end,X            Idle
 2790\                             C      C_mid                     LastC
 2800\                             V      V_mid                     LastCV
 2810.LastVC PLP \ State 6
 2820  Bpl LastVC_mid
 2830  Lda #del:Jsr NextWrch
 2840  OPT FNLdy(LastChar):Lda EndTab,Y:Jsr NextWrch
 2850.LastVC_mid
 2860  OPT FNLdy(ThisChar):Lda MidTab,Y:Jsr NextWrch
 2870  Rts
 2880 
 2890 
 2900.NumericStateMachine  \ #### NOW ONLY EVER CALLED FROM WITHIN MyWrch NOW!!!
 2910  PHX:PHY:PHA
 2920  OPT FNLda(NumberReverseFlag):Cmp #True:Bne ignore
 2930  \ Test for in vdu seq - Br if true to ignore_num SHOULDN'T BE NEEDED NOW
 2940  Lda #&DA:Ldx #0:Ldy #255: \Jsr OsByte:Ldx &26A  \ GOES BANG HERE???
 2950  Cpx #0:Beq dont_ignore
 2960.ignore
 2970    PLA:PLY:PLX
 2980    Jsr RawWrch
 2990    Rts
 3000.dont_ignore
 3010  PLA:PHA
 3020  Cmp #127:Bne not_delnum
 3030  Jsr procdel
 3040  Bra done_num
 3050.not_delnum
 3060  Jsr procvdu
 3070.done_num
 3080  PLA:PLY:PLX
 3090  Rts
 3100 
 3110.procvdu
 3120  OPT FNLdy(Idx):Cpy #0:Beq nonnum
 3130  Jsr procnum
 3140  Rts
 3150.nonnum
 3160  Cmp #ASC("0"):Bcc zz2
 3170  Cmp #ASC("9")+1:Bcs zz2
 3180  Ldy #0:Sta (Buff),Y
 3190  Iny:OPT FNSty(Idx)
 3200.zz2
 3210  Jsr RawWrch
 3220  Rts
 3230 
 3240.procnum
 3250  Cmp #ASC("0"):Bcc zz1
 3260  Cmp #ASC("9")+1:Bcs zz1
 3270  Jsr procreverse
 3280  Rts
 3290.zz1
 3300  Ldy #0:OPT FNSty(Idx)
 3310  Jsr RawWrch
 3320  Rts
 3330 
 3340.procreverse
 3350  PHA
 3360  Jsr procdelbuf
 3370  PLA
 3380  OPT FNLdy(Idx):Sta (Buff),Y
 3390  OPT FNInc(Idx)
 3400  Jsr procwritebuf
 3410  Rts
 3420 
 3430.procdel
 3440  OPT FNLdy(Idx):Cpy #0:Bne nondel
 3450    Lda #127:Jsr RawWrch:Rts
 3460.nondel
 3470  Jsr procdelbuf
 3480  OPT FNLdy(Idx):Dey:OPT FNSty(Idx):Cpy #0
 3490  Beq ww1
 3500    Jsr procwritebuf
 3510    Rts
 3520.ww1
 3530  Rts
 3540 
 3550.procdelbuf
 3560  Lda #127
 3570  OPT FNLdy(Idx)
 3580.dellp
 3590  Jsr RawWrch
 3600  Dey:Bne dellp
 3610  Rts
 3620 
 3630.procwritebuf
 3640  OPT FNLdy(Idx)
 3650.wrlp
 3660  Dey
 3670  Lda (Buff),Y
 3680  Jsr RawWrch
 3690  Cpy #0
 3700  Bne wrlp
 3710  Rts
 3720 
 3730.CharType
 3740  OPT FNload("TypeTab",256)
 3750.BegTab
 3760  OPT FNhalfload("BegTab",128)
 3770.EndTab
 3780  OPT FNhalfload("EndTab",128)
 3790.SATab
 3800  OPT FNhalfload("SATab",128)
 3810.MidTab
 3820  OPT FNhalfload("MidTab",128)
 3830.FontDef
 3840EQUB 23:EQUB 48:EQUB 0:EQUB 0:EQUB 8:EQUB 8:EQUB 0:EQUB 0:EQUB 0:EQUB 0:EQUB 232:EQUB 140
 3850EQUB 23:EQUB 49:EQUB 16:EQUB 16:EQUB 16:EQUB 16:EQUB 16:EQUB 16:EQUB 16:EQUB 0:EQUB 232:EQUB 76
 3860EQUB 23:EQUB 50:EQUB 18:EQUB 18:EQUB 28:EQUB 16:EQUB 16:EQUB 16:EQUB 16:EQUB 0:EQUB 232:EQUB 204
 3870EQUB 23:EQUB 51:EQUB 42:EQUB 42:EQUB 52:EQUB 32:EQUB 32:EQUB 32:EQUB 32:EQUB 0:EQUB 232:EQUB 44
 3880EQUB 23:EQUB 52:EQUB 112:EQUB 64:EQUB 32:EQUB 16:EQUB 32:EQUB 64:EQUB 120:EQUB 0:EQUB 232:EQUB 172
 3890EQUB 23:EQUB 53:EQUB 0:EQUB 56:EQUB 68:EQUB 68:EQUB 68:EQUB 68:EQUB 56:EQUB 0:EQUB 232:EQUB 108
 3900EQUB 23:EQUB 54:EQUB 28:EQUB 4:EQUB 4:EQUB 4:EQUB 4:EQUB 4:EQUB 4:EQUB 0:EQUB 232:EQUB 236
 3910EQUB 23:EQUB 55:EQUB 34:EQUB 34:EQUB 34:EQUB 34:EQUB 34:EQUB 20:EQUB 8:EQUB 0:EQUB 232:EQUB 28
 3920EQUB 23:EQUB 56:EQUB 16:EQUB 40:EQUB 68:EQUB 68:EQUB 68:EQUB 68:EQUB 68:EQUB 0:EQUB 232:EQUB 156
 3930EQUB 23:EQUB 57:EQUB 24:EQUB 36:EQUB 36:EQUB 28:EQUB 4:EQUB 4:EQUB 4:EQUB 0:EQUB 10:EQUB 18
 3940  OPT FNload("FontDef", &320)
 3950.FontEnd
 3960 
 3970]
 3980NEXT Pass
 3990OSCLI("SAVE $.Arabic.Object.StateMC "+STR$~(Q%)+" "+STR$~(O%)+" "+STR$~(R%-&8000+&3000)+" "+STR$~(R%-&8000+&3000))
 4000D%=WrchHandlerInit:J%=CurrentState:K%=AlphabetHandler
 4010CHAIN"$.Arabic.Source.Copy"
 4020END
 4030DEFFNx(low, high)
 4040FOR B=low TO high
 4050  [OPT Pass:EQUB &00:]
 4060NEXT B
 4070=Pass
 4080 
 4090DEFFNv(char)
 4100[OPT Pass:EQUB &40:]
 4110=Pass
 4120 
 4130DEFFNc(low, high)
 4140FOR B=low TO high
 4150  [OPT Pass:EQUB &80:]
 4160NEXT B
 4170=Pass
 4180 
 4190DEFFNhalfload(File$,Size)
 4200LOCAL I
 4210FOR I = 0 TO 127:[OPT Pass:EQUB I:]:NEXT I
 4220  OSCLI("Load $.Arabic.Object."+File$+" "+STR$~(O%))
 4230  P%=P%+Size:O%=O%+Size
 4240=Pass
 4250DEFFNload(File$,Size)
 4260  OSCLI("Load $.Arabic.Object."+File$+" "+STR$~(O%))
 4270  P%=P%+Size:O%=O%+Size
 4280=Pass
 4290DEFFNRelocate(from, to, ram)
 4300IF (ram+to-from)>=&100 THEN =FNLongRelocate(from, to, ram)
 4310[OPT Pass
 4320  Ldx #0:Ldy #ram   \ Y is pointer, X is counter
 4330.copy
 4340  Lda from,X: Sta (data),Y
 4350  Iny
 4360  Inx:Cpx #to-from:Bne copy
 4370]
 4380=Pass
 4390 
 4400DEFFNAddr(offset)
 4410IF offset >= &100 THEN =FNLongAddr(offset)
 4420[OPT Pass
 4430  PHP:PHA:Ldx &F4:Lda &DF0,X:Tay:Ldx #offset:PLA:PLP
 4440]
 4450=Pass
 4460 
 4470DEFFNJmp(offset)  : REM Jumps to private ram - absolute NOT indirect.
 4480IF offset >= &100 THEN =FNLongJmp(offset)
 4490[OPT Pass
 4500  PHP:PHA:PHX
 4510  Ldx &F4:Lda &DF0,X:Sta very_temp+1:Lda #offset:Sta very_temp
 4520  PLX:PLA:PLP
 4530  Jmp (very_temp)
 4540]
 4550=Pass
 4560 
 4570DEFFNJmpI(offset)  : REM Jumps VIA private ram - indirect.
 4580offset=FNdynamic(offset)
 4590IF offset >= &100 THEN =FNLongJmpI(offset)
 4600[OPT Pass
 4610  PHP:PHA:PHX
 4620  Ldx &F4:Lda &DF0,X:Sta very_temp+1:Lda #offset:Sta very_temp
 4630  Lda (very_temp):Pha:Inc very_temp:Bne P%+4:Inc very_temp+1
 4640  Lda (very_temp):Sta very_temp+1:Pla:Sta very_temp
 4650  PLX:PLA:PLP
 4660  Jmp (very_temp)
 4670]
 4680=Pass
 4690 
 4700DEFPROCConsts
 4710REM ************************* SEE FNENTER!!!!
 4720                                  REM MyXXX's are initialised here for
 4730                                  REM 2-pass assembly in Basic.
 4740OsByte = &FFF4
 4750ENDPROC
 4760 
 4770DEFFNVector(N)
 4780 = &200 + 2*N
 4790 
 4800DEFPROCVars
 4810  zp0 = FNzp(2,"zp0:StateMC"):zp1=zp0+1  : REM Explicitly stacked and unstacked
 4820REM All these below should be in private workspace & relocated.
 4830ThisChar = FNRmb(1)
 4840LastChar = FNRmb(1)
 4850ButLastChar = FNRmb(1)
 4860CurrentState = FNRmb(1)
 4870StateMachineActive = FNRmb(1)
 4880TmpVar = FNzp(1,"TmpVar"):REM Stacked and unstacked
 4890HisWrch = FNRmb(2)
 4900Buff = FNzp(2,"Buff") : REM Points to BuffSpace - should use directly... ARGH SEE NEXT LINE
 4910REM Currently Buff is stacked/unstacked on extry/exit.
 4920SavedBuff = FNRmb(2)
 4930BuffSpace = FNRmb(16) : REM  ***** UNSAFE - no bounds check when used!
 4940Idx = FNRmb(1) : REM Should be in private space
 4950ENDPROC
 4960 
 4970DEFFNzp(N,N$)
 4980LOCAL I
 4990  I = N%
 5000  N% = N% + N
 5010  IF N% > Z% THEN PRINT"ERROR: Using too much zero page.":END
 5020  PRINT"Zero page in StateMC is ";N$;" at &";~I
 5030  = I
 5040 
 5050DEFFNRmb(N)
 5060LOCAL I
 5070  I = M%
 5080  M% = M% + N
 5090  = I OR &10000
 5100 
 5110DEFFNEnter   : REM Called once on entry to Rom
 5120REM **** THIS VERSION USES DIFFERENT LOCAL SLAVE STORAGE BECAUSE THE
 5130REM **** CHANCES ARE THAT ANYONE ELSE USING FNENTER WILL CALL OSWRCH...
 5140               REM Sets uplocal data area for easy access
 5150[OPT Pass
 5160  Lda data:PHA
 5170  Lda data+1:PHA
 5180  Ldx &F4:Lda &DF0,X
 5190  Sta data+1
 5200  Stz data
 5210  OPT FNEnterStack
 5220]
 5230=Pass
 5240 
 5250DEFFNdynamic(x)
 5260REMIF (x AND &FFFF0000) <> &10000 THEN PRINT"This is not a dynamic-space variable":STOP
 5270= x AND &FFFF
 5280 
 5290DEFFNLda(variable_offset):variable_offset=FNdynamic(variable_offset)
 5300[OPT Pass
 5310  PHY:Ldy #variable_offset:Lda (data),Y:PLY
 5320]
 5330=Pass
 5340 
 5350DEFFNSta(variable_offset):variable_offset=FNdynamic(variable_offset)
 5360[OPT Pass
 5370  PHY:Ldy #variable_offset:Sta (data),Y:PLY
 5380]
 5390=Pass
 5400 
 5410DEFFNAdc(variable_offset):variable_offset=FNdynamic(variable_offset)
 5420[OPT Pass
 5430  PHY:Ldy #variable_offset:Adc (data),Y:PLY
 5440]
 5450=Pass
 5460 
 5470DEFFNInc(variable_offset):variable_offset=FNdynamic(variable_offset)
 5480[OPT Pass
 5490  Phx:PHY:Ldy #variable_offset:Lda (data),Y:Tax:Inx:Txa:Sta (data),Y:PLY:Plx
 5500]
 5510=Pass
 5520 
 5530DEFFNLdy(variable_offset):variable_offset=FNdynamic(variable_offset)
 5540[OPT Pass
 5550  Pha:PHY:Ldy #variable_offset:Lda (data),Y:PLY:Tay:Pla
 5560]
 5570=Pass
 5580 
 5590DEFFNSty(variable_offset):variable_offset=FNdynamic(variable_offset)
 5600[OPT Pass
 5610  Pha:PHY:Ldy #variable_offset:Pla:Pha:Sta (data),Y:PLY:Pla
 5620]
 5630=Pass
 5640 
 5650DEFFNExit :REM Called once on exit from Rom
 5660[OPT Pass
 5670  OPT FNExitStack
 5680  Pla: Sta data+1
 5690  Pla: Sta data
 5700]
 5710=Pass
 5720DEFFNbreakno(Num)
 5730[OPT Pass
 5740  Lda #0:Sta table:Lda #1:Sta table+1
 5750  Lda #0:Sta (table):Inc table:Bne P%+4:Inc table+1
 5760  Lda #Num:Sta (table):Inc table:Bne P%+4:Inc table+1
 5770]
 5780=Pass
 5790 
 5800DEFFNbreakstring(Str$)
 5810LOCAL s:DIM s LEN(Str$):$s=Str$
 5820FOR idx = 0 TO LEN(Str$)-1
 5830  [OPT Pass: Lda #(s?idx):Sta (table):Inc table:Bne P%+4:Inc table+1:]
 5840NEXT
 5850=Pass
 5860 
 5870DEFFNdobreak
 5880[OPT Pass
 5890  Lda #0:Sta (table)
 5900  Jsr &100 \ Return address for possible debug help later
 5910]
 5920=Pass
 5930 
 5940DEFFNStack(Reg)
 5950[OPT Pass
 5960  Lda Reg:Pha
 5970]
 5980=Pass
 5990 
 6000DEFFNUnstack(Reg)
 6010[OPT Pass
 6020  Pla:Sta Reg
 6030]
 6040=Pass
 6050 
 6060DEFFNEnterStack
 6070[OPT Pass
 6080STA &101:STX &102:STY &103
 6090  OPT FNStack(TmpVar)
 6100  OPT FNStack(Buff) \ This could be calculated on the fly anyway...
 6110  OPT FNStack(Buff+1)
 6120  OPT FNLda(SavedBuff):Sta Buff
 6130  OPT FNLda(SavedBuff+1):Sta Buff+1
 6140LDA &101:LDX &102:LDY &103
 6150]
 6160=Pass
 6170 
 6180DEFFNExitStack
 6190[OPT Pass
 6200  Lda Buff+1: OPT FNSta(SavedBuff+1)
 6210  Lda Buff: OPT FNSta(SavedBuff)
 6220  OPT FNUnstack(Buff+1)
 6230  OPT FNUnstack(Buff)
 6240  OPT FNUnstack(TmpVar)
 6250]
 6260=Pass
 6270 
 6280DEFFNdebug(C$)
 6290=Pass
 6300[OPT Pass
 6310   PHA:PHA:Lda #ASC(C$):Sta &90:PLA:PLA
 6320]
 6330=Pass
