   10REM SAVE"$.Arabic.Source.Help"
   20DIM O% &BFFF-P%
   30Q%=O%:R%=P%
   40table=&A8  : REM zp for *command decoding.
   50user=&F2
   60text_terminator=&00:REM to be compatible with ROM header
   70com_count_brief = 1 : REM Number of major entries returned by *HELP
   80com_count = 11 : REM Number of entries searched through by *HELP
   90OsWrch=&FFEE
  100title_string=&8009
  110FOR Pass=4 TO 6+L% STEP 2+L%
  120O%=Q%:P%=R%
  130[OPT Pass
  140\
  150\*******************************************************************
  160\*
  170\*   HELP handler for Arabic
  180\*
  190\*   Table driven information system
  200\*
  210\*   On entry (user),Y points to the user input following
  220\*   the *HELP command
  230\*   This routine gets each word and compares it with a table of
  240\*   keywords. If a match is found, a page of information is displayed.
  250\*   If a word doesn't match, it is ignored.
  260\*   Note that abbreviations (.) are recognised.
  270\*   If there is nothing following the *HELP command, the table of
  280\*   keywords is listed with a title, in keeping with other ROMs
  290\*
  300\*   On exit, X and Y are preserved
  310\*
  320\*******************************************************************
  330\
  340.osnewl
  350  Pha:Lda #13:Jsr oswrch
  360  Lda #10:Jsr oswrch
  370  Pla
  380  Rts
  390.oswrch  \ Zero-page corrupted by MOS during (possibly intercepted) OSWrch
  391Jmp &E7E6
  400  Phy
  410  Ldy user:Phy
  420  Ldy user+1:Phy
  430  Ldy table:Phy
  440  Ldy table+1:Phy
  450  Jsr OsWrch
  460  Ply:Sty table+1
  470  Ply:Sty table
  480  Ply:Ldy user+1
  490  Ply:Ldy user
  500  Ply
  510  Rts
  520.HelpHandler
  530   Phy                     \ preserve Y for benefit of other ROMs
  550   Phx                     \ preserve X
  555   Pha                     \ preserve A
  570\
  571  Lda table:Pha
  572  Lda table+1:Pha
  580\
  590   Lda user                 \ preserve parameter pointer
  600   Pha                      \ for other roms.
  610   Lda user+1
  620   Pha
  630   Jsr add_offset          \ synchronise pointers for string comparisons
  640\
  650.help_skip_spaces
  660   Ldy #0
  670   Lda (user),Y            \ skip leading spaces
  680   Cmp #&0D                \ check for OSCLI string terminator
  690   Beq help_summary        \ if no more chars. or all spaces give summary
  700   Cmp #ASC(" ")
  710   Bne help_compare        \ if have non-space char, compare strings
  720   Inc user
  730   Bne help_skip_spaces
  740   Inc user+1
  750   Bne help_skip_spaces    \ always true
  760\
  770.help_compare
  780   Jsr compare_str         \ compare next word in user stream with keywords
  790   Bcs help_find_terminator \ carry set = no match
  800   Jsr disp_text            \ display help page;pointer set by compare_str
  810   Ldy #0
  820.help_find_terminator
  830   Lda (user),Y            \ current char. in user stream
  840   Cmp #&0D                \ end of user stream?
  850   Beq help_exit           \ yes.
  860   Cmp #ASC(" ")           \ no. find terminator for this word
  870   Beq help_synchronise
  880   Cmp #ASC(".")           \ check for abbrev.
  890   Beq help_synchronise
  900   Iny                     \ advance window
  910   Jmp help_find_terminator
  920\
  930.help_synchronise
  940   Iny                     \ advance window beyond terminator
  950   Jsr add_offset          \ synchronise pointers and
  960   Jmp help_compare        \ try next word in user stream
  970\
  980\
  990.help_summary
 1000   Jsr osnewl
 1010   Lda #title_string MOD &100
 1020   Sta table               \ set pointer to start of title string
 1030   Lda #title_string DIV &100
 1040   Sta table+1
 1050   Jsr disp_text           \ display title string
 1060   Lda #ASC(" ")
 1070   Jsr oswrch
 1080   Iny                     \ advance to version string
 1090   Jsr disp_text           \ display the version string
 1100   Jsr osnewl
 1110   Lda #help_subheadings MOD &100
 1120   Sta table               \ point to start of keyword table
 1130   Lda #help_subheadings DIV &100
 1140   Sta table+1
 1150   Ldy #0
 1160   Jsr disp_text           \ display first subheading
 1170   Ldx #1                  \ count table entries
 1180.help_list
 1190   Cpx #com_count_brief    \ end of table list?
 1200   Bcs help_lf             \ yes. tidy up
 1210   Lda #&0A                \ line feed
 1220   Jsr oswrch
 1230   Lda #ASC(" ")
 1240   Jsr oswrch
 1250   Jsr oswrch
 1260   Iny                     \ advance beyond terminator
 1270   Iny                     \ advance beyond data pointer bytes
 1280   Iny
 1290   Jsr disp_text           \ display next keyword
 1300   Inx
 1310   Jmp help_list           \ list rest
 1320\
 1330.help_lf
 1340   Lda #&0A
 1350   Jsr oswrch
 1360\
 1370.help_exit
 1380\
 1390   Pla                     \ restore parameter pointer
 1400   Sta user+1
 1410   Pla
 1420   Sta user
 1421\
 1422  Pla:Sta table+1
 1423  Pla:Sta table
 1430\
 1431  Pla                      \ restore A
 1440   Plx                     \ restore value of X on entry
 1460   Ply                     \ restore Y
 1480   Rts
 1490\
 1500\
 1510\****************************
 1520\*
 1530\*  add_offset
 1540\*
 1550\*  adds Y to user,user+1
 1560\*  to slide the user stream
 1570\*  under the window (Y)
 1580\*
 1590\****************************
 1600\
 1610.add_offset
 1620   Tya
 1630   Clc
 1640   Adc user               \ add Y to base value to give indexing with Y=0
 1650   Sta user                \ Y then has a common starting point for
 1660   Bcc add_exit              \ string comparison
 1670   Inc user+1
 1680.add_exit
 1690   Rts
 1700\
 1710\
 1720\*********************************
 1730\*
 1740\*   compare_str
 1750\*
 1760\*   compares a word in the user
 1770\*   stream with keyword table
 1780\*   stream
 1790\*
 1800\*   On entry, the streams are
 1810\*   synchronised. i.e. Y=0
 1820\*   windows the first char. in
 1830\*   each
 1840\*   Abbreviations are recognised.
 1850\*   On exit,
 1860\*     Carry clear  = match
 1870\*     Carry set    = no match
 1880\*     user,user+1 point to last
 1890\*     char. in word and Y=0
 1900\*
 1910\*********************************
 1920\
 1930.compare_str
 1940   Lda #help_table MOD &100
 1950   Sta table              \ pointer to keyword table
 1960   Lda #help_table DIV &100
 1970   Sta table+1
 1980   Ldx #1                 \ count table entries
 1990\
 2000.compare_loop
 2010   Ldy #&FF               \ initialise window to strings
 2020.compare_chars
 2030   Iny                    \ window next pair of chars. - Y always < 255
 2040   Lda (user),Y           \ get next char. in user stream
 2050   Cmp #ASC(".")          \ abbreviation match?
 2060   Beq compare_skip       \ yes. get pointer to display page
 2070   Cmp (table),Y          \ no. compare with table stream
 2080   Beq compare_end
 2090   Sec                    \ no match. lower case?
 2100   Sbc #&20               \ lower to upper case displacement
 2110   Cmp (table),Y          \ try again
 2120   Beq compare_end
 2130   Cmp #ASC(" ")-&20      \ char mismatch. space vs. return?
 2140   Bne compare_table      \ no. strings don't match
 2150   Lda (table),Y          \ yes. see if table stream is <return>
 2160   Cmp #&0D
 2170   Beq compare_skip       \ exact match
 2180\
 2190.compare_table            \ no match
 2200   Cpx #com_count         \ more table entries to try?
 2210   Bcs compare_synchronise \ no.
 2220   Inx                    \ yes. get next entry
 2230   Lda #12                \ advance pointer to next table entry
 2240   Jsr advance_pointer
 2250   Jmp compare_loop
 2260\
 2270.compare_end
 2280   Cmp #&0D               \ end of both strings?
 2290   Bne compare_chars      \ no. keep comparing streams
 2300.compare_skip             \ match
 2310   Jsr add_offset         \ point to terminator or dot in user stream
 2320   Lda #10                \ point to display data pointer
 2330   Jsr advance_pointer
 2340   Ldy #0                 \ reset window
 2350   Lda (table),Y          \ low byte of data pointer
 2360   Pha
 2370   Iny
 2380   Lda (table),Y          \ high byte
 2390   Sta table+1
 2400   Pla
 2410   Sta table
 2420   Clc                    \ indicate string match
 2430   Bcc compare_exit       \ exit with carry flag and pointer
 2440\
 2450.compare_synchronise
 2460   Jsr add_offset         \ point to terminator
 2470   Sec                    \ indicate no match
 2480\
 2490.compare_exit
 2500   Ldy #0                 \ exit pointing to current char. in user stream
 2510   Rts                    \ and with carry flag (clear=match)
 2520\
 2530\
 2540\******************************
 2550\*
 2560\*   advance_pointer
 2570\*
 2580\*   add A to table,table+1
 2590\*   to get table entries etc.
 2600\*
 2610\******************************
 2620\
 2630.advance_pointer
 2640   Clc
 2650   Adc table
 2660   Sta table
 2670   Bcc advance_exit
 2680   Inc table+1
 2690.advance_exit
 2700   Rts
 2710\
 2720\
 2730\**********************************
 2740\*
 2750\*   disp_text
 2760\*
 2770\*   displays the text pointed to
 2780\*   by (table),Y until terminator
 2790\*
 2800\**********************************
 2810\
 2820.disp_text
 2830   Lda (table),Y           \ pick up char byte
 2840   Cmp #text_terminator    \ end of display text?
 2850   Beq disp_exit
 2860   Jsr oswrch
 2870   Iny                     \ rollover?
 2880   Bne disp_text           \ no.
 2890   Inc table+1
 2900   Bne disp_text
 2910\
 2920.disp_exit
 2930   Rts
 2940\
 2950\
 2960\  -----  KEYWORD TABLE AND DISPLAY DATA
 2970\
 2980.help_subheadings
 2990   EQUS "  "             \ embedded spaces for summary display
 3000.help_table
 3010   EQUS "ARABIAN":EQUB &0D
 3020   EQUB &0D
 3030   EQUB text_terminator \ final terminator for disp_text
 3040   EQUW help_arabian
 3050  EQUS "COUNTRY":EQUB &0D
 3060  EQUB &0D
 3070  EQUB text_terminator
 3080  EQUW help_country
 3090  EQUS "ALPHABET"
 3100  EQUB &0D
 3110  EQUB text_terminator
 3120  EQUW help_alphabet
 3130  EQUS "KEYBOARD"
 3140  EQUB &0D
 3150  EQUB text_terminator
 3160  EQUW help_keyboard
 3170  EQUS "CONFIG":EQUW &0D0D
 3180  EQUB &0D
 3190  EQUB text_terminator
 3200  EQUW help_configure
 3210  EQUS "STATUS":EQUB &0D:EQUB &0D
 3220  EQUB &0D
 3230  EQUB text_terminator
 3240  EQUW help_status
 3250  EQUS "ARABIC":EQUW &0D0D
 3260  EQUB &0D
 3270  EQUB text_terminator
 3280  EQUW help_arabic
 3290  EQUS "SCRNFLIP"
 3300  EQUB &0D
 3310  EQUB text_terminator
 3320  EQUW help_screenflip
 3330  EQUS "TEXTFLIP"
 3340  EQUB &0D
 3350  EQUB text_terminator
 3360  EQUW help_textflip
 3370  EQUS "FONTFLIP"
 3380  EQUB &0D
 3390  EQUB text_terminator
 3400  EQUW help_fontflip
 3410  EQUS "PRINTER":EQUB &0D
 3420  EQUB &0D
 3430  EQUB text_terminator
 3440  EQUW help_printer
 3450\ REMEMBER to set com_count to number of main help entries...
 3460\
 3470.help_arabian
 3480  EQUW &0A0D
 3490  EQUS "Arabian Rom"
 3500  EQUW &0A0D
 3510  EQUS "  Detailed information can be had by asking for Help on any or all of these:"
 3520  EQUW &0A0D
 3530  EQUS "  *Help COUNTRY ALPHABET KEYBOARD CONFIG.  STATUS"
 3540  EQUW &0A0D
 3550  EQUS "  *Help ARABIC  SCRNFLIP TEXTFLIP FONTFLIP"
 3560  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 3570.help_arabic
 3580  EQUW &0A0D
 3590  EQUS "*Arabic controls context analysis and number reversal, and"
 3600  EQUW &0A0D
 3610  EQUS "whether or not a local Arabic printer emulation is installed."
 3620  EQUW &0A0D
 3630  EQUS "See also *HELP Arabic printer."
 3640  EQUW &0A0D
 3650  EQUS "Syntax: *Arabic <Text | Numerals> <On | Off>"
 3660  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 3670.help_alphabet
 3680  EQUW &0A0D
 3690  EQUS "*Alphabet sets the font for a particular country."
 3700  EQUW &0A0D
 3710  EQUS "Syntax: *Alphabet [<country name> | <alphabet name>]"
 3720  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 3730.help_country
 3740  EQUW &0A0D
 3750  EQUS "*Country selects both the Alphabet (qv) and Keyboard (qv) for the named"
 3760  EQUW &0A0D
 3770  EQUS "country.  *Country Arabic enables Arabic context-sensitivity and the <FLIP> key"
 3780  EQUW &0A0D
 3790  EQUS "Syntax: *Country [<country name>]"
 3800  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 3810.help_keyboard
 3820  EQUW &0A0D
 3830  EQUS "*Keyboard sets the keyboard driver for a particular country."
 3840  EQUW &0A0D
 3850  EQUS "Syntax: *Keyboard [<country name>]"
 3860  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 3870.help_configure
 3880  EQUW &0A0D
 3890  EQUS "*Configure Country will assign the country active on power-on."
 3900  EQUW &0A0D
 3910  EQUS "Syntax: *Configure [<configure parameter>]"
 3920  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 3930.help_status
 3940  EQUW &0A0D
 3950  EQUS "*Status Country will display the country active on power-on."
 3960  EQUW &0A0D
 3970  EQUS "Syntax: *Status [<configure parameter>]"
 3980  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 3990.help_screenflip
 4000  EQUW &0A0D
 4010  EQUS "*Scrnflip reverses the text on the screen, and the direction in which text is"
 4020  EQUW &0A0D
 4030  EQUS "written.  *Scrnflip with a parameter will force text to go left or right."
 4040  EQUW &0A0D
 4050  EQUS "Syntax: *Scrnflip [UK | Arabic]"
 4060  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 4070.help_textflip
 4080  EQUW &0A0D
 4090  EQUS "*Textflip with no parameter reverses the direction that text is written, and"
 4100  EQUW &0A0D
 4110  EQUS "*Textflip with a parameter forces the direction to be left or right."
 4120  EQUW &0A0D
 4130  EQUS "Syntax: *Textflip [UK | Arabic]"
 4140  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 4150.help_fontflip
 4160  EQUW &0A0D
 4170  EQUS "*Fontflip mirrors all the character definitions, and *Fontflip with a"
 4180  EQUW &0A0D
 4190  EQUS "country parameter forces the characters to be correct for that country."
 4200  EQUW &0A0D
 4210  EQUS "Syntax: *Fontflip [UK | Arabic]"
 4220  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 4230.help_printer
 4240  EQUW &0A0D
 4250  EQUS "*Arabic Printer installs a local emulation of an ISO Arabic printer."
 4260  EQUW &0A0D
 4270  EQUS "There is an optional parameter which is the width of the printer paper in use."
 4280  EQUW &0A0D
 4290  EQUS "Syntax: *Arabic printer [on | off | normal | wide]"
 4300  EQUW &0A0D:EQUB &0A:EQUB text_terminator
 4310 
 4320 
 4330 
 4340 
 4350 
 4360]
 4370NEXT Pass
 4380OSCLI("SAVE $.Arabic.Object.HelpObj "+STR$~(Q%)+" "+STR$~(O%)+" "+STR$~(R%-&8000+&3000)+" "+STR$~(R%-&8000+&3000))
 4390A%=HelpHandler
 4400CHAIN"$.Arabic.Source.Flip"
