   10REM SAVE"$.Arabic.Source.Main"
   20HelpHandler = A%:CommandHandler = B%:FlipHandler = C%:WrchHandlerInit = D%
   30CopyHandlerInit = E%:ArabicByteHandler=F%:FlipHandlerInit=G%
   40very_temp=T%
   50N%=&70:Z%=&8F:M%=0   : REM Argh! These have to be reset on each phase!
   60                      REM - previously they were in 'MakeRom'
   70HelpSWI = 9
   80UnrecSWI = 4
   90OsByteSWI = &07
  100InitSWI = &27 : REM &FF,&FE seems to be ignored???
  110REM &27 Ought to have been OK but it doesn't seem to work...
  120REM     ... the Rom crashes during initialisation if you use it.
  130SpaceSWI = 2 : REM Master should really use &22 for high-address space
  140               REM but not while debugging as this is easier to look at.
  150REM Acorn Arabic (AROM) Master Source File -- Sat,10 Oct 1987.16:56:20 --
  160Copyright$ = "(C) ESP & Acorn Computers, 1986"
  170L%=0
  180REM Edinburgh Software Products, 1 Castle Street, Edinburgh  EH2 3AH.
  190ON ERROR GOTO 210
  200GOTO 310
  210ON ERROR OFF
  220REPORT:PRINT" at line ";ERL
  230PRINT">L.";ERL
  240*fx 138,0,255
  250FOR I=1 TO 9
  260*fx 138,0,251
  270NEXT
  280*fx 138,0,11
  290*fx 138,0,13
  300END
  310InternalVersion = 0 :REM 1 on first live release
  320ReleaseNo       = 1
  330MasterVersionNo = 2
  340Version$        = STR$(MasterVersionNo)+"."+STR$(ReleaseNo)+"."+STR$(InternalVersion)
  350HelpName$       = "Arabic V"+Version$
  360RomName$        = "ARABIAN"
  370 
  380IF HIMEM<>&B800 THEN PROCHiBasic
  390 
  400                :REM (used later to work out how many pages to claim)
  410 
  420PROCAssemble
  430CHAIN"$.Arabic.Source.Cli"
  440END
  450 
  460DEFPROCPoke(N$)
  470LOCAL N
  480LOCAL I
  490DIM N LEN(N$)+1
  500$N=N$
  510FOR I=0 TO LEN(N$)-1
  520  OSCLI("FX 138,0,"+STR$(N?I))
  530NEXT
  540ENDPROC
  550 
  560DEFPROCHiBasic
  570Return$=CHR$(13)
  580PROCPoke("OLD"+Return$+"RUN"+Return$)
  590ON ERROR GOTO 610
  600*CB
  610PRINT"You need access to *CB"
  620*FX 15
  630END
  640 
  650ENDPROC
  660  
  670DEFPROCAssemble
  680DIM Code &4000
  690PROCConsts
  700PROCVars
  710FOR Pass = 4 TO 6+L% STEP 2+L%
  720O%=Code:P%=&8000
  730[OPT Pass
  740.RomStart
  750  OPT FNRomHeader
  760\ Seperate assembly places other modules below...
  770]
  780NEXT Pass
  790IF P% >= &C000 THEN PRINT"ERROR: Rom too large!":END
  800OSCLI("SAVE $.Arabic.Object.MAINOBJ "+STR$~(Code)+" "+STR$~(O%)+" 3000 3000")
  810ENDPROC
  820 
  830DEFFNRomHeader
  840[OPT Pass
  850  NOP:NOP:NOP  \ Arabic Rom is not a language so needs no language entry
  860  Jmp ServiceHandler
  870  EQUB &81                \ Service Rom, 6502 code.
  880  EQUB CopyrightString-RomStart
  890  EQUB InternalVersion
  900  EQUS RomName$: EQUB 0
  910  EQUS HelpName$
  920.CopyrightString
  930  EQUB 0
  940  EQUS "(C) Edinburgh Software Products/Acorn Computers Plc., 1986"
  950  EQUB 0
  960.ServiceHandler
  970  PHP:PHX:PHY:PHA
  980\Jmp Debug:.DebugReturn \ Not a subrt to keep stack untouched...
  990  Cmp #HelpSWI: Bne NotHelp
 1000  Jsr HelpHandler
 1010  Bra DebugDone
 1020.NotHelp
 1030  Cmp #UnrecSWI: Bne NotComm
 1040  Jsr CommandHandler
 1050  Bcs DebugDone
 1060  PLA:Lda #0:PHA  \ Set Returned A = 0 to say command accepted
 1070  Bra DebugDone
 1080.NotComm
 1090  Cmp #InitSWI: Bne NotInit
 1100  Jsr WrchHandlerInit  \ Other initialisations to be inserted here.
 1110  Jsr CopyHandlerInit \ which calls FNEnter so be careful not to add it
 1120  Jsr FlipHandlerInit \ here too as it is not recursive
 1130  Bra DebugDone
 1140.NotInit
 1150  Cmp #SpaceSWI: Bne NotSpace
 1160  Ldx &F4:Tya:Sta &DF0,X:Iny   \ Claim 256 Bytes & remember where it is
 1170                               \ IN THAT ORDER!!!
 1180  INY \ Extra page for number reversal buffer !
 1190  Plx:Pla:Phy:Phx  \ Save incremented Y back on stack
 1191  LDA very_temp:PHA:LDA very_temp+1:PHA
 1200  Dey:Dey:Sty very_temp+1:Lda #0:Sta very_temp
 1210  Ldy #0
 1220.clrlp
 1230  Sta (very_temp),Y
 1240  Iny:Bne clrlp
 1250  Inc very_temp+1
 1260.clrlp2
 1270  Sta (very_temp),Y
 1280  Iny:Bne clrlp2
 1281  PLA:STA very_temp+1:PLA:STA very_temp
 1290  Bra DebugDone
 1300.NotSpace
 1310  Cmp #OsByteSWI:Bne NotByte
 1320   Lda &EF:Ldx &F0:Ldy &F1
 1330   Cmp #70:Bne not_trapped_osbyte
 1340   Cpx #21:Bne not_trapped_osbyte \ 21 is Arabic COUNTRY code.
 1350   Jsr ArabicByteHandler\(Y)
 1360   Pla:Lda #0:Pha
 1370   Bra DebugDone
 1380.not_trapped_osbyte
 1390   Bra DebugDone
 1400.NotByte
 1410  Bra Done
 1420.DebugDone
 1430\Jmp ExitDebug:.ExitReturn
 1440.Done
 1450  PLA:PLY:PLX:PLP
 1460  Rts
 1470.Debug
 1480  PLA:PHA:Cmp #&30:Beq dontdebug:Cmp #&15:Beq dontdebug
 1490  Lda #ASC(">"):Jsr &E7E6
 1500  PLA:PLY:PLX:PLP:PHP:PHX:PHY:PHA
 1510  Lda #ASC("A"):Jsr &E7E6:Lda #ASC("="):Jsr &E7E6
 1520  PLA:PHA:Jsr PHEX:Lda #32:Jsr &E7E6
 1530  Lda #ASC("Y"):Jsr &E7E6:Lda #ASC("="):Jsr &E7E6
 1540  PLA:PLY:PHY:PHA:Tya:Jsr PHEX:Lda #32:Jsr &E7E6
 1550  Lda #ASC("X"):Jsr &E7E6:Lda #ASC("="):Jsr &E7E6
 1560  PLA:PLY:PLX:PHX:PHY:PHA:Txa:Jsr PHEX:Lda #32:Jsr &E7E6
 1570  Lda #ASC("S"):Jsr &E7E6:Lda #ASC("="):Jsr &E7E6
 1580  Tsx:Txa:Jsr PHEX
 1590  Lda #10:Jsr &E7E6:Lda #13:Jsr &E7E6
 1600.dontdebug
 1610  PLA:PLY:PLX:PLP:PHP:PHX:PHY:PHA
 1620  Jmp DebugReturn
 1630 
 1640.ExitDebug
 1650  Lda #ASC("<"):Jsr &E7E6
 1660  PLA:PLY:PLX:PLP:PHP:PHX:PHY:PHA
 1670  Lda #ASC("A"):Jsr &E7E6:Lda #ASC("="):Jsr &E7E6
 1680  PLA:PHA:Jsr PHEX:Lda #32:Jsr &E7E6
 1690  Lda #ASC("Y"):Jsr &E7E6:Lda #ASC("="):Jsr &E7E6
 1700  PLA:PLY:PHY:PHA:Tya:Jsr PHEX:Lda #32:Jsr &E7E6
 1710  Lda #ASC("X"):Jsr &E7E6:Lda #ASC("="):Jsr &E7E6
 1720  PLA:PLY:PLX:PHX:PHY:PHA:Txa:Jsr PHEX
 1730  Lda #10:Jsr &E7E6:Lda #13:Jsr &E7E6
 1740  PLA:PLY:PLX:PLP:PHP:PHX:PHY:PHA
 1750  Jmp ExitReturn
 1760 
 1770.PHEX
 1780  Pha
 1790  Lsr A:Lsr A:Lsr A:Lsr A
 1800  Jsr PN
 1810  Pla
 1820.PN
 1830  And #&0F
 1840  Cmp #10
 1850  Bcc kkk
 1860  Adc #6
 1870.kkk
 1880  Adc #ASC("0")
 1890  Jmp &E7E6
 1900]
 1910=Pass
 1920 
 1930DEFPROCConsts
 1940                                  REM MyXXX's are initialised here for
 1950                                  REM 2-pass assembly in Basic.
 1960                :MyIns  = &8000 : Ins = 21   : InsV = FNVector(Ins)
 1970OsByte = &FFF4  :MyByte = &8000 : Byte = 5   : ByteV = FNVector(Byte)
 1980OsWord = &FFF1
 1990OsCli  = &FFF7
 2000OsRdCh = &FFE0  :MyRdCh = &8000 : RdCh = 8   : RdChV = FNVector(RdCh)
 2010OsRdSc = &FFB9
 2020OsWrCh = &FFEE
 2030OsNewl = &FFE7
 2040OsAscii = &FFE3
 2050OsWrSc = &FFB3
 2060OsFind = &FFCE
 2070OsFile = &FFDD
 2080OsArgs = &FFDA
 2090OsGbPb = &FFD1
 2100OsBPut = &FFD4
 2110OsBGet = &FFD7
 2120OsEvent = &FFBF
 2130GSInit = &FFC2
 2140GSRead = &FFC5
 2150ENDPROC
 2160 
 2170DEFFNVector(N)
 2180 = &200 + 2*N
 2190 
 2200DEFPROCVars
 2210data = FNzp(2)   : REM Points to base of private workspace.
 2220                       REM - set up on zero-page grabbing on each entry
 2230ENDPROC
 2240 
 2250DEFFNzp(N)
 2260LOCAL I
 2270  I = N%
 2280  N% = N% + N
 2290  IF N% > Z% THEN PRINT"ERROR: Using too much zero page.":END
 2300  = I
 2310 
 2320DEFFNRmb(N)
 2330LOCAL I
 2340  I = M%
 2350  M% = M% + N
 2360  = I
 2370 
 2380PRINT "Error in source - dropped into utilities!"
 2390END
