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