home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / ftp.demon.co.uk-pub-cpm / amstrad / setfontz.arc / SETFONT.Z80 < prev   
Text File  |  1994-05-06  |  60KB  |  2,137 lines

  1. ;SETFONT: A program to alter the character set.
  2. ;
  3. ; Addresses in low memory:
  4. ;
  5. WBOOT   EQU    00000H   ;Warm boot.
  6. JUMP    EQU    00001H   ;Address for start of BIOS
  7. FDOS    EQU    00005H   ;BIOS/BDOS calls come here
  8. FCB     EQU    0005CH   ;Standard file control block
  9. CMDTAIL EQU    00080H   ;The command tail, DMA buffer &c.
  10. ;
  11. ; Character set data
  12. ;
  13. ACHRLEN EQU     00800H  ;Length of the character set (Amstrad PCW/CPC only)
  14. SCHRLEN EQU     01000H  ;Length of the character set (ZX Spectrum only)
  15. SCHRSET EQU     03000H  ;Start of the character set  (ZX Spectrum only)
  16. PCHRSET EQU     0B800H  ;Start of the character set  (Amstrad PCW only)
  17. CCHRSET EQU     08000H  ;Start of the character set  (Amstrad CPC only)
  18. ;
  19. ; Addresses in high memory:
  20. ;
  21. BUFFER  EQU     0C000H  ;Buffer to load to.
  22. SCPROG  EQU     0D001H  ;Relocation address for alteration code
  23. ;
  24. ; BDOS codes:
  25. ;
  26. BDKEY   EQU       01H   ;BDOS code - Await a keypress
  27. BDSCR   EQU       02H   ;BDOS code - Write ASCII
  28. BDMSG   EQU       09H   ;BDOS code - Write a message to the screen
  29. BDLIN   EQU       0AH   ;BDOS code - Read a line from the console
  30. BDVER   EQU       0CH   ;BDOS code - Find the version of CP/M
  31. BDRES   EQU       0DH   ;BDOS code - Reset BDOS
  32. BDSEL   EQU       0EH   ;BDOS code - Select a drive
  33. BDOPN   EQU       0FH   ;BDOS code - Open a file to read.
  34. BDCLO   EQU       10H   ;BDOS code - Close a file
  35. BDSCN   EQU       11H   ;BDOS code - Search for a file on disc
  36. BDERA   EQU       13H   ;BDOS code - Erase a file.
  37. BDRDR   EQU       14H   ;BDOS code - Read a record
  38. BDWRR   EQU       15H   ;BDOS code - Write a record
  39. BDOPW   EQU       16H   ;BDOS code - Open a file to write.
  40. BDDEF   EQU       19H   ;BDOS code - Get current disc drive
  41. BDDMA   EQU       1AH   ;BDOS code - Set the DMA buffer
  42. BDUSR   EQU       20H   ;BDOS code - Set/get user number.
  43. BDRRND  EQU       21H   ;BDOS code - Read random
  44. BDWRND  EQU       22H   ;BDOS code - Write random
  45. BDLEN   EQU       23H   ;BDOS code - Get file length.
  46. BDERR   EQU       2DH   ;BDOS code - Set error mode.
  47. BDSCB   EQU       31H   ;BDOS code - Use CP/M+ SCB
  48. BDCODE  EQU       6CH   ;BDOS code - Send program code
  49. BDPARS  EQU       152   ;BDOS code - Parse a filename
  50. ;
  51. EBVERS  EQU    000E3H   ;Extended BIOS code - Find machine we are using
  52. EBSCRR  EQU    000E9H   ;Extended BIOS code - Run a routine in screen environment
  53. ;
  54. FAILCOD EQU    0FF00H   ;When sent to BDOS, this indicates "program failed."
  55. ;
  56. ; Miscellaneous:
  57. ;
  58. CR      EQU     0DH
  59. LF      EQU     0AH
  60. ESC     EQU     1BH
  61. ;
  62.     .Z80
  63.     CSEG
  64. ;
  65. ;Load or save a set of character data for CP/M:
  66. ;Formats supported are:
  67. ;
  68. ; Amstrad CP/M (10H records)
  69. ; Amstrad CP/M with one-record header (11H records)
  70. ; Spectrum +3 CP/M (20H records)
  71. ; Spectrum +3 CP/M with one-record header (21H records)
  72. ; Spectrum +3 +3DOS with header (7H records - CODE xxxxx,768)
  73. ; PRINTIT double-height (18H records)
  74. ; STOP PRESS (like HITEC-70)
  75. ; MASTERPAINT (like STANDARD)
  76. ;
  77. ; Files saved with a header and a .COM type will self-load.
  78. ; If it is necessary to add a +3 header to a file (only useful under +3DOS) then
  79. ; save without header and use the command :
  80. ;
  81. ; COPY "filename.xyz" TO SPECTRUM FORMAT
  82. ;
  83. ;Version History (in reverse order):
  84. ;
  85. ;v1.02a  Silly mistake fixed; I had got the CPC font address wrong by 200h.
  86. ;        I don't know how I arrived at the wrong figure, but I did.
  87. ;
  88. ;v1.02   Untested additions to allow use on CPC6128.
  89. ;        Bug fix in "Save MasterPaint file". 
  90. ;        Password capabilities extended to all file-handling functions
  91. ;
  92. ;v1.01 - Added capabilities: Save & load Printit fonts. "Small" +3 font can
  93. ;        now be used for all options. /Z option extended to save self-loading
  94. ;        fonts. /F option replaces /P and /X. /F:? (guess) option. /F:E (EMS/EMT)
  95. ;        option. /F:S (Stop Press) option. /F:C (.CAR) option. Spurious errors 
  96. ;        avoided due to improved EOL detection. Multi-command mode. IF 
  97. ;        capability in Multi-command mode. /I (invert font) option. 
  98. ;
  99. ;v1.00 - Works with PCW & Spectrum +3. Load and save PCW fonts, +3DOS fonts.
  100. ;        Spectrum can save +3 CP/M fonts. All fonts other than +3 CP/M use
  101. ;        the large font only. Fonts selected with /P /X options. Users 0-15
  102. ;        and languages 0-7 supported.
  103. ;
  104.     JP      PROGST
  105.     DEFB    CR,'SETFONT v1.02 for Amstrad PCW/CPC and ZX Spectrum +3',CR,LF
  106.     DEFB    'Copyright (c) J. Elliott, 7 May 1994',CR,LF
  107. SGN:    DEFB    'Not tested for use on Amstrad CPC.',cr,lf,26,'$'
  108. PROGST: LD      E,0FFH
  109.     LD      C,BDUSR         ; Store current user no.
  110.     CALL    FDOS             ; in case SETFONT changes it.
  111.     LD      (USER),A
  112.     LD      C,BDERR         ;
  113.     LD      E,0FFH          ; Deactivate the "CP/M Error on X:"
  114.     CALL    FDOS            ; messages and associated warmboots.
  115.     LD      HL,CMDTAIL
  116.     LD      DE,BUF+1        ; Move the command tail up into the
  117.     LD      BC,128          ; internal buffer.
  118.     LDIR
  119.     LD      A,(0053H)       ; Length of first file password
  120.     OR      A               ; No password.
  121.     JR      Z,START
  122.     LD      C,A
  123.     LD      B,0             ; Copy file password to password buffer.
  124.     LD      HL,(0051H)
  125.     LD      DE,PASSWORD
  126.     LDIR
  127. START:  LD      A,(BUF+1)       ; Length of command line.
  128.     LD      E,A
  129.     LD      D,0             ; Add A to HL
  130.     LD      HL,BUF+2
  131.     ADD     HL,DE           ; HL is now pointing to the next space in the
  132.                 ; buffer.
  133.     LD      (HL),0          ; Zero to clear up detection routines.
  134.     CALL    SUBSCAN         ; Find /H switch, act on other switches.
  135.     JP      C,HELP          ; Act on /H switch
  136.     LD      A,(LANGFLG)     ; Language change required?
  137.     OR      A
  138.     JR      Z,START0        ; No.
  139.     LD      DE,MESS22
  140.     CALL    SUBPRINT        ; Change language
  141. START0: LD      A,(FCB+1)
  142.     CP      020H            ; No filename?
  143.     JP      Z,ERR5          ; If so then ask for one.
  144.     CP      '/'
  145.     JP      Z,ERR5          ; Filename starts with /opt or -opt.
  146.     CP      '-'
  147.     JP      Z,ERR5
  148.     LD      C,BDVER         ; Get version number
  149.     CALL    FDOS
  150.     LD      A,H             ; Is the program running under MP/M (unlikely)
  151.     OR      A
  152.     JP      NZ,ERR1         ; MP/M not allowed.
  153.     LD      A,L
  154.     CP      31H
  155.     JP      NZ,ERR1         ; Not CP/M 3
  156.     LD      A,(7)           ; Get the high byte of TPA top.
  157.     CP      0D1H            ; Enough memory?
  158.     JP      C,ERR9          ; No, quit.
  159. ;
  160. ;Machine-specific initialisation. This was originally written on a +3; hence
  161. ;the program self-modifies for the CPC and PCW.
  162. ;
  163.     CALL    SUBUSERF
  164.     DEFW    EBVERS          ;For version. On return:
  165.                 ; A=0 => Amstrad CPC
  166.                 ; A=1 => Amstrad PCW
  167.                 ; A=3 => Spectrum +3
  168.     OR      A
  169.     CALL    Z,SUBCI         ;Is this a CPC?
  170.     CP      01H             ;Or is this a PCW?
  171.     CALL    Z,SUBPI         ;If so, modify program AND set A to 3.
  172.     CP      03H             ;Is the machine suitable?
  173.     JP      NZ,ERR1         ;If not, leave
  174.     LD      A,(EMSFLG)      ;Was /F:E switch encountered?
  175.     OR      A
  176.     JP      NZ,USEMS        ;If yes, use the EMS file handler
  177.     LD      A,(PLUS3)
  178.     OR      A               ;Was /F:+ switch encountered?
  179.     JP      NZ,PL3          ;If yes, use the +3DOS file handler.
  180.     LD      A,(PRINTIT)
  181.     OR      A               ;Was /F:P switch encountered?
  182.     JP      NZ,PTR          ;If yes, use PRINTIT file handler.
  183.     LD      A,(PCW)
  184.     OR      A               ;Was /F:A switch encountered?
  185.     JP      NZ,USEPCW       ;If yes, force 2k font (rather than 4k)
  186.     LD      A,(SPFFLG)
  187.     OR      A               ;Was /F:S switch encountered?
  188.     JP      NZ,USESPF       ;If yes, use Stop Press file handler
  189.     LD      A,(CARFLG)      ;Was /F:C switch encountered?
  190.     OR      A               ;If yes, deal with Masterpaint format.
  191.     JP      NZ,USECAR
  192. ;
  193. ; Default format.
  194. ;
  195.     LD      A,(LOADSAVE)    ;Was /S switch encountered?
  196.     OR      A
  197.     JP      NZ,SAVE         ; If yes, save
  198.     CALL    LOAD            ; Else, perform a standard load.
  199.     JP      LOAD5
  200. ;
  201. USEPCW: CALL    CG0
  202.     LD      A,(LOADSAVE)    ;Load or save?
  203.     OR      A
  204.     JR      NZ,SAVEPCW
  205.     LD      HL,BUFFER       ;Load a PCW font file
  206.     CALL    ASHL            ;Auto Shift HL (allows for /F=)
  207.     LD      (DMAADD),HL
  208.     LD      A,10H           ;File length in records
  209.     LD      (REC),A
  210.     CALL    LOAD            ;Load
  211.     JP      LOAD5           ;Install font
  212. ;
  213. SAVEPCW:
  214.     LD      HL,BUFFER
  215.     CALL    ASHL            ;Set correct address
  216.     LD      (DMAADD),HL
  217.     LD      A,10H           ;File length (records)
  218.     LD      (REC),A
  219.     JP      SAVE
  220. ;
  221. USESPF: LD      A,(LOADSAVE)    ;Load or save?
  222.     OR      A
  223.     JP      NZ,SAVESPF
  224.     CALL    CG0
  225.     LD      HL,4000H        ;Load the Stop Press file at 4000H
  226.     LD      (DMAADD),HL
  227.     LD      A,61H           ;97 records
  228.     LD      (REC),A
  229.     CALL    LOAD
  230.     LD      B,92            ;92 CHARACTERS
  231.     LD      HL,4080H        ;! IN STOP PRESS
  232.     LD      DE,0C108H       ;! IN CP/M FONT.
  233.     CALL    ASDE
  234. USESP0: LD      C,8
  235. USESP1: LD      A,(HL)
  236.     LD      (DE),A
  237.     INC     DE
  238.     INC     HL              ;UNPACK THE CHARACTER SET
  239.     INC     HL
  240.     INC     HL
  241.     INC     HL
  242.     DEC     C
  243.     JR      NZ,USESP1
  244.     PUSH    DE
  245.     LD      DE,60H          ;HL POINTS TO NEXT CHARACTER
  246.     ADD     HL,DE
  247.     POP     DE
  248.     DJNZ    USESP0
  249.     JP      LOAD5           ;FONT LOADED.
  250. ;
  251. SAVESPF:
  252.     CALL    CHARGET         ;GET FONT
  253.     LD      A,61H
  254.     LD      (REC),A         ;FILE LENGTH
  255.     LD      BC,080H
  256.     LD      HL,4000H
  257.     LD      (DMAADD),HL     ;POINT TO START OF FILE
  258.     LD      DE,4001H        ;FILL FIRST RECORD WITH FFs
  259.     LD      (HL),0FFH
  260.     LDIR
  261.     LD      (HL),0
  262.     LD      BC,30FFH
  263.     LDIR                    ;FILL REST WITH BLANKS
  264.     LD      B,92            ;92 CHARACTERS
  265.     LD      DE,4080H        ;! IN STOP PRESS
  266.     LD      HL,0C108H       ;! IN CP/M FONT.
  267.     CALL    ASDE
  268. USESP2: LD      C,8
  269. USESP3: LD      A,(HL)
  270.     LD      (DE),A
  271.     INC     HL
  272.     INC     DE              ;PACK THE CHARACTER
  273.     INC     DE
  274.     INC     DE
  275.     INC     DE
  276.     DEC     C
  277.     JR      NZ,USESP3
  278.     PUSH    HL
  279.     LD      HL,60H          ;DE POINTS TO NEXT CHARACTER
  280.     ADD     HL,DE
  281.     EX      DE,HL
  282.     POP     HL
  283.     DJNZ    USESP2
  284.     JP      SAVE
  285. ;
  286. ;.CAR FILE IS LOADED AT 4000H. LENGTH=60 RECORDS.
  287. ;
  288. USECAR: LD      A,(LOADSAVE)
  289.     OR      A
  290.     JR      NZ,SAVECAR
  291.     CALL    CG0
  292.     LD      HL,4000H        ;LOAD AT 4000H
  293.     LD      (DMAADD),HL
  294.     LD      A,60
  295.     LD      (REC),A         ;60 RECORDS.
  296.     CALL    LOAD
  297.     LD      A,(04000H)      ;Character width (bytes)
  298.     DEC     A
  299.     JP      NZ,ERR11
  300.     LD      A,(04001H)      ;Character height (bytes)
  301.     CP      8
  302.     JP      NZ,ERR11
  303.     LD      HL,04004H
  304.     LD      DE,0C100H
  305.     CALL    ASDE
  306.     LD      C,94
  307. LOADC1: CALL    UPSDOWN         ;UNPACK THE FONT
  308.     INC     HL
  309.     DEC     C
  310.     JR      NZ,LOADC1
  311.     JP      LOAD5
  312. ;
  313. SAVECAR:
  314.     CALL    CHARGET
  315.     LD      HL,4000H        ;LIKE /F:E, NEEDS A FILE TO MODIFY.
  316.     LD      (DMAADD),HL
  317.     LD      A,60
  318.     LD      (REC),A
  319.     CALL    LOAD            ;v1.02 bug fix.
  320.     LD      A,(04000H)      ;Character width (bytes)
  321.     DEC     A
  322.     JP      NZ,ERR11
  323.     LD      A,(04001H)      ;Character height (bytes)
  324.     CP      8
  325.     JP      NZ,ERR11
  326.     LD      DE,04004H
  327.     LD      HL,0C100H
  328.     CALL    ASHL            ;PACK THE CHARACTERS
  329.     LD      C,94
  330. SAVEC1: CALL    UPSDOWN
  331.     INC     DE
  332.     DEC     C
  333.     JR      NZ,SAVEC1
  334.     LD      HL,FCB+12
  335.     LD      DE,FCB+13
  336.     LD      BC,23
  337.     LD      (HL),0
  338.     LDIR
  339.     LD      HL,4000H
  340.     LD      (DMAADD),HL
  341.     LD      A,60
  342.     LD      (REC),A         ;SAVE THE MODIFIED FILE.
  343.     JP      SAVE0
  344. ;
  345. UPSDOWN:
  346.     LD      B,8
  347. UPS0:   INC     DE
  348.     DJNZ    UPS0
  349.     LD      B,8
  350. UPS1:   LD      A,(HL)  ;MOVE CHARACTER AT (HL) TO 
  351.     INC     HL      ;UPSIDE-DOWN CHARACTER AT (DE).
  352.     DEC     DE
  353.     LD      (DE),A
  354.     DJNZ    UPS1
  355.     LD      B,8
  356. UPS2:   INC     DE
  357.     DJNZ    UPS2    ;HL & DE POINT TO JUST OUTSIDE CHAR.
  358.     RET
  359. ;
  360. ; Load a disc file
  361. ;
  362. LOAD:   LD      C,BDSCN         ;Scan for first FCB
  363.     LD      DE,FCB
  364.     CALL    FDOS
  365.     INC     A
  366.     JP      Z,ERR2          ;Is file present?
  367. LOAD8:  CALL    PASSPUT 
  368.     LD      C,BDOPN
  369.     LD      DE,FCB
  370.     CALL    FDOS            ; Was a password required?
  371.     LD      A,H             ; If so, ask for it.
  372.     CP      7               ;
  373.     JP      Z,LOAD9
  374.     LD      C,BDDMA
  375.     LD      DE,(DMAADD)
  376.     CALL    FDOS            ;Open file, set DMA address.
  377.     LD      C,BDRDR
  378.     LD      DE,FCB
  379.     CALL    FDOS            ;Read the first block.
  380.     LD      A,(STRIP)       ;
  381.     OR      A               ; Should the header be stripped?
  382.     JR      Z,LOAD2         ;
  383.     LD      DE,(DMAADD)
  384.     LD      C,BDDMA         ;
  385.     CALL    FDOS            ;Read the next record.
  386.     LD      C,BDRDR
  387.     LD      DE,FCB
  388.     CALL    FDOS
  389. LOAD2:  LD      HL,REC          ;Record number variable.
  390.     DEC     (HL)            ;Fewer records to load.
  391. LOAD3:  LD      DE,080H
  392.     LD      HL,(DMAADD)
  393.     ADD     HL,DE           ;Increase load addr. by 80H
  394.     LD      (DMAADD),HL
  395.     EX      DE,HL
  396.     LD      C,BDDMA         ;Advance the DMA buffer.
  397.     CALL    FDOS
  398. LOAD4:  LD      C,BDRDR         ;Read next data block.
  399.     LD      DE,FCB
  400.     CALL    FDOS            ;End of file?
  401.     CP      01H
  402.     PUSH    AF              ;Save AF in DE
  403.     POP     DE              ;Return addr. must be top of stack
  404.     LD      HL,REC
  405.     DEC     (HL)            ;All records loaded?
  406.     RET     Z               ;Loading finished
  407.     PUSH    DE
  408.     POP     AF
  409.     JP      Z,ERR4          ;End of file met.
  410.     JP      LOAD3
  411. ;
  412. LOAD5:  CALL    CHARPUT
  413.     LD      DE,MESS5        ; Ok message
  414.     CALL    SUBPRINT
  415. WB1:    LD      A,(LANGFLG)
  416.     OR      A
  417.     JR      Z,WB2           ;If no language option active, ignore next bit.
  418.     LD      A,(LANGUAGE)
  419.     LD      (MESS22A),A     ;Select language in A
  420.     CALL    SCR2
  421.     LD      DE,MESS22
  422.     CALL    SUBPRINT
  423.     CALL    SCR1
  424. WB2:    LD      A,(MCM)         ;MULTI-COMMANDS?
  425.     OR      A
  426.     JP      NZ,RESET
  427.     RST     0
  428. ;
  429. LOAD9:  CALL    ERR8            ;Ask for password.
  430.     JP      LOAD8
  431. ;
  432. CHARGET:                        ;Get font from screen bank.
  433.     CALL    CG0
  434.     LD      A,(INVFLG)      ;Invert font?
  435.     OR      A
  436.     LD      HL,0C000H       ;Font at 0C000H
  437.     CALL    NZ,SUBINVFNT
  438.     RET
  439. ;
  440. CG0:    LD      A,0EBH          ;EX DE,HL just before LDIR
  441. CG1:    LD      (SETGET),A
  442.     CALL    SUBMOVEUP       ;Move routine to high memory
  443.     LD      A,(ISCPC)
  444.     OR      A
  445.     JP      NZ,CPCRTN
  446.     LD      BC,SCPROG
  447.     CALL    SUBUSERF
  448.     DEFW    EBSCRR          ;Run it
  449.     RET
  450. ;
  451. CHARPUT:
  452.     LD      DE,08000H
  453.     LD      HL,BUFFER       ;Move font to 8000H
  454.     LD      BC,01000H
  455.     LDIR
  456.     LD      A,(INVFLG)      ;Invert the font?
  457.     OR      A
  458.     LD      HL,08000H
  459.     CALL    NZ,SUBINVFNT
  460. CP1:    CALL    CG0             ;Get current font at C000h
  461.     LD      HL,(DEND)
  462.     LD      DE,(DBEGIN)     ;Move the portion between /B and /E (or all) 
  463.     INC     HL              ;into the current font.
  464.     OR      A
  465.     SBC     HL,DE
  466.     ADD     HL,HL   ;*2
  467.     ADD     HL,HL   ;*4
  468.     ADD     HL,HL   ;*8
  469.     LD      B,H
  470.     LD      C,L     ;BC=LENGTH
  471.     LD      HL,(DBEGIN)
  472.     ADD     HL,HL   ;*2
  473.     ADD     HL,HL   ;*4
  474.     ADD     HL,HL   ;*8
  475.     EX      DE,HL   ;DE=START OFFSET
  476.     LD      IX,08000H
  477.     ADD     IX,DE
  478.     LD      HL,BUFFER
  479.     ADD     HL,DE
  480.     EX      DE,HL   ;DE=DESTINATION ADDR.
  481.     PUSH    IX
  482.     POP     HL      ;HL=SOURCE ADDR.
  483.     LDIR            ;RESTORE COMPOSITE CHARSET.
  484.     XOR     A       ;NOP
  485.     JR      CG1
  486. ;
  487. ; Load a +3DOS font, assumed headed.
  488. ; Or save a +3DOS font, headed.
  489. ;
  490. PL3:    LD      A,(LOADSAVE)    ;LOADING OR SAVING?
  491.     OR      A
  492.     JP      NZ,SAVEP3       ;Saving
  493.     CALL    CG0
  494.     LD      A,06h           ; 6 records
  495.     LD      (REC),A
  496.     LD      HL,0B000H       ; Load temporarily to B000H
  497.     LD      (DMAADD),HL
  498.     LD      A,0FFH          ; Header automatically
  499.     LD      (STRIP),A       ; stripped.
  500.     CALL    LOAD
  501.     LD      HL,0B000H       ;
  502.     LD      DE,0C100H       ; Characters 32-95
  503.     CALL    ASDE
  504.     LD      BC,0200H        ;
  505.     LDIR
  506.     LD      HL,0B200H       ;
  507.     LD      DE,0C518H       ; Pound sign (96)
  508.     CALL    ASDE
  509.     LD      BC,8            ;
  510.     LDIR
  511.     LD      HL,0B208H       ;
  512.     LD      DE,0C308H       ; Characters 97-126
  513.     CALL    ASDE
  514.     LD      BC,0F0H         ;
  515.     LDIR
  516.     LD      HL,0B2F8H       ;
  517.     LD      DE,0C520H       ;
  518.     CALL    ASDE
  519.     LD      BC,8            ; Copyright sign.
  520.     LDIR                    ;
  521.     JP      LOAD5
  522. ;
  523. SAVEP3: LD      A,07H           ; 7 records, including header.
  524.     LD      (REC),A         ;
  525.     CALL    CHARGET
  526.     LD      HL,0C518H        ;
  527.     CALL    ASHL
  528.     LD      DE,0C300H        ; Move pound sign.
  529.     CALL    ASDE
  530.     LD      BC,8             ;
  531.     LDIR
  532.     LD      HL,0C520H        ;
  533.     CALL    ASHL
  534.     LD      DE,0C3F8H        ; Move copyright sign.
  535.     CALL    ASDE
  536.     LD      BC,8             ;
  537.     LDIR
  538.     LD      HL,HEADER        ;
  539.     LD      DE,0C080H        ; Add a +3DOS header.
  540.     CALL    ASDE
  541.     LD      BC,080H          ;
  542.     LDIR
  543.     XOR     A
  544.     LD      (STRIP),A        ; Otherwise program would save with a COM header
  545.     LD      HL,0C080H        ;
  546.     CALL    ASHL
  547.     LD      (DMAADD),HL      ; Save starting at 0C100h/0C900H
  548.     JR      SAVE0            ;
  549. ;
  550. ; Save the current font.
  551. ;
  552. SAVE:   CALL    CHARGET
  553. SAVE0:  LD      C,BDDEF         ;Preserve current disk drive
  554.     CALL    FDOS
  555.     PUSH    AF
  556.     LD      C,BDRES         ;Initialise BDOS
  557.     CALL    FDOS
  558.     POP     AF
  559.     LD      E,A
  560.     LD      C,BDSEL         ;Restore it
  561.     CALL    FDOS
  562.     LD      C,BDSCN         ;Check for file's existence on disc.
  563.     LD      DE,FCB
  564.     CALL    FDOS
  565.     INC     A               ;If A=0FFH, file not found.
  566.     JP      NZ,ERR6
  567. SAVE1:  LD      C,BDOPW         ;If the file is erased, then open to write.
  568.     LD      DE,FCB
  569.     CALL    FDOS
  570.     INC     A               ;If A=0FFH, error.
  571.     JP      Z,ERR7
  572.     LD      A,(STRIP)
  573.     OR      A
  574.     JR      Z,SAVE2
  575.     LD      DE,COMHED
  576.     LD      C,BDDMA         ;Write an extra record: the header
  577.     CALL    FDOS
  578.     LD      DE,FCB
  579.     LD      C,BDWRR
  580.     CALL    FDOS
  581. SAVE2:  LD      HL,(DMAADD) ;Load address
  582.     PUSH    HL           ;Save HL for later.
  583.     EX      DE,HL        ;Move DMA address to DE.
  584.     LD      C,BDDMA      ;Set DMA
  585.     CALL    FDOS
  586.     POP     HL           ;Add 80H to DMA.
  587.     LD      DE,080H
  588.     ADD     HL,DE
  589.     LD      (DMAADD),HL ;Store DMA address.
  590.     LD      C,BDWRR      ;Write to disc.
  591.     LD      DE,FCB
  592.     CALL    FDOS
  593.     OR      A            ;Error if A<>0.
  594.     JP      NZ,ERR7
  595.     LD      A,(REC)      ;Number of records remaining.
  596.     DEC     A            ;Decrease by 1
  597.     JR      Z,SAVE3      ;If file fully written, close it.
  598.     LD      (REC),A
  599.     JP      SAVE2
  600. ;
  601. SAVE3:  LD      DE,FCB
  602.     LD      C,BDCLO      ;Close the file.
  603.     CALL    FDOS
  604.     JP      WB1
  605. ;
  606. SAVE9:  CALL    ERR8
  607.     JP      SAVE0
  608. ;
  609. USEMS:  LD      A,(LOADSAVE)
  610.     OR      A               ;LOAD OR SAVE TO THE EMS FILE?
  611.     JP      NZ,SAVEMS
  612.     CALL    EMSFIND         ;LOAD THE EMS FILE. RETURN ADDRESS OF FONT IN HL
  613.     LD      DE,0C000H
  614. CH2:    LD      BC,1000H
  615.     LD      A,(SIZE)
  616.     OR      A
  617.     JR      Z,USEMS1
  618.     LD      BC,800H
  619. USEMS1: LDIR
  620.     JP      LOAD5           ;MOVE FONT TO PROPER PLACE, INSTALL IT, LEAVE.
  621. ;
  622. SAVEMS: CALL    EMSFIND
  623.     PUSH    HL              ;HL=FONT ADDR.
  624.     CALL    CHARGET
  625.     POP     DE
  626.     LD      BC,800H         ;MOVE FIRST PART OF FONT (ALWAYS COPIED).
  627.     LD      HL,0C000H
  628.     LDIR
  629.     LD      A,(SIZE)
  630.     OR      A               ;Move small characters (optional).
  631.     JR      NZ,SAVEMS1
  632.     LD      BC,800H
  633. CH3:    LDIR                    ;Set to NOP if PCW is used.
  634. SAVEMS1:
  635.     LD      C,BDSCN         ;Check for file's existence on disc.
  636.     LD      DE,FCB
  637.     CALL    FDOS
  638.     INC     A               ;If A=0FFH, file not found. (EMS file needed to save to).
  639.     JP      Z,ERR2
  640.     LD      HL,FCB+12
  641.     LD      DE,FCB+13       ;Blank FCB to avoid corruption.
  642.     LD      BC,22
  643.     LD      (HL),0
  644.     LDIR
  645. XPASS0: CALL    PASSPUT         ;If the file is present, then open to update.
  646.     LD      C,BDOPN         ;Open to update
  647.     LD      DE,FCB
  648.     CALL    FDOS
  649.     LD      A,(FCB+7)       ;If file is R/O due to passwording, ask for
  650.     BIT     7,A             ;password.
  651.     JR      NZ,XPASS0X
  652.     LD      A,(FCB+8)       ;If file is System file in User 0, error.
  653.     BIT     7,A     
  654.     JP      NZ,ERR12
  655.     LD      A,H
  656.     CP      7
  657.     JR      NZ,XPASS1
  658. XPASS0X:
  659.     CALL    ERR8
  660.     JR      XPASS0
  661. ;
  662. XPASS1: INC     A               ;If A=0FFH, error.
  663.     JP      Z,ERR7          ;Write error.
  664.     LD      A,(REC)
  665.     INC     A               ;No. of records.
  666.     LD      B,A
  667.     LD      DE,8000H        ;Prepare to write out to disc.
  668.     LD      HL,(SAVREC)
  669. SRLOOP: PUSH    BC
  670.     PUSH    HL
  671.     CALL    WRRND
  672.     LD      HL,80H          ;Write the record, increase DMA.
  673.     ADD     HL,DE
  674.     EX      DE,HL
  675.     POP     HL
  676.     INC     HL
  677.     POP     BC              ;Next record
  678.     DJNZ    SRLOOP
  679.     JP      SAVE3           ;Close out file.
  680. ;
  681. EMSFIND:
  682.     LD      DE,FCB
  683.     LD      C,BDSCN         ;FILE NOT FOUND?
  684.     CALL    FDOS
  685.     INC     A
  686.     JP      Z,ERR2
  687.     LD      HL,FCB+12
  688.     LD      DE,FCB+13       ;BLANK OUT FCB TO AVOID POSSIBLE CORRUPTION.
  689.     LD      BC,22
  690.     LD      (HL),0
  691.     LDIR
  692. XPASS2: CALL    PASSPUT
  693.     LD      DE,FCB          ;OPEN THE FILE
  694.     LD      C,BDOPN
  695.     CALL    FDOS
  696.     LD      A,H
  697.     OR      A
  698.     CP      7
  699.     JR      NZ,XPASS3
  700.     CALL    ERR8
  701.     JR      XPASS2
  702. ;
  703. XPASS3: INC     A
  704.     JP      Z,ERR4
  705. ;
  706.     LD      HL,0
  707. EMSF0:  CALL    RDRND1
  708.     JP      C,ERR10 ;NO FONT FOUND.
  709.     PUSH    HL
  710.     CALL    CP128   ;CP128 RETURNS IN HL THE ADDRESS IF OK.
  711.     JR      Z,EMSF1
  712.     POP     HL
  713.     INC     HL      ;RECORD NUMBER COUNTER
  714.     JR      EMSF0
  715. ;
  716. EMSF1:  POP     DE      ;DE=RECORD NUMBER HL=ADDRESS OF CHARACTER SET   
  717.     LD      (SAVREC),DE
  718.     LD      (CHRPTR),HL
  719. ;BYTES FOUND.
  720.     LD      A,(REC)         ;NO. OF RECORDS TO LOAD.
  721.     INC     A
  722.     INC     A
  723.     LD      B,A             ;B=NO. OF RECORDS TO LOAD.
  724.     LD      DE,8000H        ;LOAD THE EMS FONT NEAR TO 8000H
  725.     LD      HL,(SAVREC)
  726. EMSF2:  PUSH    BC
  727.     PUSH    HL
  728.     CALL    RDRND           ;READ IN A RECORD
  729.     JP      C,ERR3          ;TOO SHORT.
  730.     LD      HL,0080H
  731.     ADD     HL,DE
  732.     EX      DE,HL           ;INCREASE POINTER
  733.     POP     HL
  734.     INC     HL              ;NEXT RECORD
  735.     POP     BC
  736.     DJNZ    EMSF2           ;UNTIL ALL LOADED.
  737.     LD      HL,(CHRPTR)     ;ADDRESS OF FONT
  738.     RET
  739. ;
  740.     DSEG
  741. PASSWORD:
  742.     DEFB    '        '
  743. SAVREC: DEFW    0
  744. CHRPTR: DEFW    0
  745.     CSEG
  746. ;
  747. CP128:  PUSH    IX              ;Search 128-byte buffer for the right
  748.     LD      IX,8000H        ;character sequence.
  749.     LD      B,128
  750. CP128A: CALL    CPIX
  751.     JR      Z,CP128B        ;It's a lot easier with IX, but be careful.
  752.     INC     IX
  753.     DJNZ    CP128A          
  754.     POP     IX              ;Not found.
  755.     XOR     A
  756.     INC     A
  757.     RET
  758. ;
  759. CP128B: XOR     A
  760.     PUSH    IX              ;Found. Address in HL.
  761.     POP     HL
  762.     POP     IX
  763.     RET
  764. ;
  765. CPIX:   LD      A,(IX+1)        ;The byte at (IX+0) is different on +3s
  766.     OR      A               ;and Amstrads, so it is ignored.
  767.     RET     NZ
  768.     LD      A,(IX+2)
  769.     CP      66H
  770.     RET     NZ
  771.     LD      A,(IX+3)
  772.     CP      0DBH
  773.     RET     NZ
  774.     LD      A,(IX+4)
  775.     CP      0DBH
  776.     RET     
  777. ;
  778. RDRND1: PUSH    HL              ;Read records HL,HL+1 from file at 8000-8100.
  779.     PUSH    DE
  780.     PUSH    HL
  781.     LD      DE,8000H
  782.     CALL    RDRND
  783.     JR      C,EXTR
  784.     POP     HL
  785.     INC     HL
  786.     LD      DE,8080H
  787.     CALL    RDRND
  788.     POP     DE
  789.     POP     HL
  790.     RET
  791. ;
  792. RDRND:  PUSH    HL
  793.     PUSH    DE
  794.     LD      (FCB+21H),HL    ;SET RECORD NUMBER
  795.     XOR     A
  796.     LD      (FCB+23H),A
  797.     LD      C,BDDMA         ;SET LOAD ADDRESS
  798.     CALL    FDOS
  799.     LD      C,BDRRND
  800.     LD      DE,FCB          ;READ RANDOM
  801.     CALL    FDOS
  802.     OR      A
  803.     JP      Z,EXTR
  804.     INC     A
  805.     JP      Z,ERR4
  806.     SCF
  807. EXTR:   POP     DE
  808.     POP     HL
  809.     RET
  810. ;
  811. WRRND:  PUSH    HL
  812.     PUSH    DE
  813.     LD      (FCB+21H),HL    ;SET RECORD NUMBER
  814.     XOR     A
  815.     LD      (FCB+23H),A
  816.     LD      C,BDDMA         ;SET LOAD ADDRESS
  817.     CALL    FDOS
  818.     LD      C,BDWRND
  819.     LD      DE,FCB          ;READ RANDOM
  820.     CALL    FDOS
  821.     OR      A
  822.     JP      NZ,ERR7 ;WRITE ERROR
  823.     POP     DE
  824.     POP     HL
  825.     RET
  826. ;
  827. ; The Subroutines:
  828. ;
  829. ;THIS IS THE SUBROUTINE WHICH IS RELOCATED TO
  830. ;D001H. IT INSTALLS THE CHARACTER SET.
  831. SUBRS:  PUSH    BC              ;Save BC                        ;D001
  832. PCWP1:  LD      BC,SCHRLEN      ;LENGTH OF CHAR. SET            ;D002
  833. PCWP2:  LD      DE,SCHRSET                                      ;D005
  834.     LD      HL,BUFFER       ;SOURCE & DESTINATION           ;D008
  835. SETGET: NOP                     ;IF SAVING, BECOMES EX DE,HL    ;D00B
  836.     LDIR                    ;BLOCK MOVE                     ;D00C
  837.     POP     BC                                              ;D00E
  838.     RET                                                     ;D00F
  839. ;
  840. SUBMOVEUP:
  841.     LD      HL,SUBRS
  842.     LD      DE,SCPROG               ;Destination
  843.     LD      BC,SUBMOVEUP-SUBRS      ;Length of routine
  844.     LDIR
  845.     RET
  846. ;
  847. CPCRTN: CALL    SUBUSERF
  848.     DEFW    0D001H
  849.     RET
  850. ;
  851. SUBINVFNT:
  852.     PUSH    AF
  853.     PUSH    BC
  854.     PUSH    DE
  855.     PUSH    HL
  856.     LD      BC,1000H                ;Invert the font at (HL).
  857. SUBINF1:                                ;Font length=1000h
  858.     LD      A,(HL)
  859.     CPL
  860.     LD      (HL),A                  ;Invert
  861.     INC     HL
  862.     DEC     BC
  863.     LD      A,B                     ;Next byte
  864.     OR      C
  865.     JR      NZ,SUBINF1
  866.     POP     HL
  867.     POP     DE
  868.     POP     BC
  869.     POP     AF
  870.     RET
  871. ;
  872. SUBCI:                          ;SELF-MODIFY FOR AMSTRAD CPC
  873.     LD      DE,SGN
  874.     CALL    SUBPRINT
  875.     XOR     A
  876.     LD      (ISSPEC),A
  877.     DEC     A
  878.     LD      (ISCPC),A
  879.     LD      HL,CCHRSET    ;CPC character set location
  880.     LD      (PCWP2+1),HL
  881.     LD      HL,0
  882.     LD      (PCWP0+1),HL  ;CPC isn't affected by /F=
  883.     LD      (PCWP0A+1),HL
  884.     LD      HL,ACHRLEN    ;Amstrad character set length
  885.     LD      (PCWP1+1),HL
  886.     JR      SUBPI1
  887. ;
  888. SUBPI:                        ;SELF-MODIFY FOR AMSTRAD PCW
  889.     XOR     A               ;Computer type flags
  890.     LD      (ISSPEC),A
  891.     LD      (ISCPC),A
  892.     LD      HL,PCHRSET    ;PCW character set location
  893.     LD      (PCWP2+1),HL
  894.     LD      HL,0
  895.     LD      (PCWP0+1),HL  ;PCW isn't affected by /F=
  896.     LD      (PCWP0A+1),HL
  897.     LD      HL,ACHRLEN    ;Amstrad character set length
  898.     LD      (PCWP1+1),HL
  899. SUBPI1:
  900.     LD      HL,0
  901.     LD      (CH3),HL
  902.     LD      HL,ACHRLEN    ;PCW character set length
  903.     LD      (CH1+1),HL
  904.     LD      (CH2+1),HL
  905.     LD      A,010H        ;PCW file length
  906.     LD      (REC),A
  907.     LD      A,03H         ;03H => Success
  908.     RET
  909. ;
  910. INTHPCW:
  911.     CALL    SUBSTRP1        ;Guess: 2k PCW file with header
  912.     LD      DE,MESS30
  913.     JR      INTPCW0
  914. ;
  915. INTPCW: LD      DE,MESS29       ;Guess: 2k PCW file without header
  916. INTPCW0:
  917.     CALL    SUBPRINT
  918.     POP     HL
  919.     POP     DE
  920.     POP     BC
  921.     POP     AF
  922. SUBPI2:
  923.     PUSH    HL              ; This routine is
  924.     CALL    SUBPI1          ; called to load PCW
  925.     LD      A,0FFH          ; files on a Spectrum.
  926.     LD      (PCW),A         ; It makes all modifications from SUBPI
  927.     POP     HL              ; EXCEPT alteration of the
  928.     JP      SUBSCAN3        ; load address.
  929. ;
  930. SUBEMSFNT:
  931.     LD      A,0FFH          ; Flag that an EMS file is being used.
  932.     LD      (EMSFLG),A
  933.     JP      SUBSCAN3
  934. ;
  935. SUBINPFILE:
  936.     LD      DE,INPPROMPT    ;Prompt: SETFONT>
  937.     CALL    SUBPRINT
  938.     LD      A,0FFH          ; Flag: Multi-command mode running
  939.     LD      (MCM),A
  940.     LD      B,80H           ; Fill the buffer with spaces.
  941.     LD      HL,BUF+1
  942. SUBINP0:
  943.     LD      (HL),' '
  944.     INC     HL
  945.     DJNZ    SUBINP0
  946.     LD      C,BDLIN         ; Read in the command tail.
  947.     LD      DE,BUF
  948.     CALL    FDOS
  949.     LD      DE,CRLF
  950.     CALL    SUBPRINT
  951.     LD      A,(BUF+1)
  952.     OR      A               ;If no characters typed, abandon
  953.     JP      Z,0
  954.     LD      A,(BUF+2)       ;Check for a conditional multi-command
  955.     CP      ';'             ;Or comment.
  956.     JR      Z,SUBINPFILE
  957.     CP      ':'
  958.     JR      NZ,SUBINP0A
  959.     LD      A,(MCFAIL)
  960.     OR      A
  961.     JR      NZ,SUBINPFILE
  962.     LD      DE,BUF+2
  963.     LD      HL,BUF+3        ;Remove colon.
  964.     LD      BC,80H
  965.     LDIR
  966.     LD      A,(BUF+1)       ;Only the :?
  967.     DEC     A
  968.     JP      Z,SUBINPFILE
  969.     LD      (BUF+1),A
  970.     LD      A,(BUF+2)
  971. SUBINP0A:
  972.     CP      '/'
  973.     JR      Z,SUBINP0B      ;ONLY /M OR /H
  974.     CP      '-'
  975.     JR      Z,SUBINP0B
  976.     XOR     A
  977.     LD      (MCFAIL),A
  978. SUBINP0B:
  979.     LD      A,(BUF+1)
  980.     LD      E,A
  981.     LD      D,0
  982.     LD      HL,BUF+2        ;End-of-line marker
  983.     ADD     HL,DE
  984.     XOR     A
  985.     LD      (HL),A
  986.     LD      HL,BUF+2        ; Convert the command line to upper case.
  987. SUBINP1:
  988.     LD      A,(HL)
  989.     OR      A
  990.     JR      Z,SUBINP1A
  991.     CALL    SUBUPCASE ; Convert to upper case.
  992.     LD      (HL),A    ;
  993.     INC     HL
  994.     JR      SUBINP1
  995. ;
  996. SUBINP1A:
  997.     LD      C,BDPARS  ;
  998.     LD      DE,PFCB   ; Parse filename, which
  999.     CALL    FDOS       ; usually happens during program load.
  1000.     LD      A,H
  1001.     CP      0FFH      ; If H=0FFH, Filename is invalid.
  1002.     JP      NZ,START
  1003.     LD      DE,MESS14 ;Let the user know about it.
  1004.     CALL    SUBPRINT
  1005.     JP      SUBINPFILE
  1006. ;
  1007.     DSEG
  1008. BUF:    DEFB    128,0   ; Room for 128 bytes.
  1009.     DEFS    128     ; The 128 bytes.
  1010.     DEFB    0       ; End of buffer
  1011. PFCB:   DEFW    BUF+2   ;Parse the filename at BUF
  1012.     DEFW    FCB     ;and place it at the usual FCB.
  1013.     CSEG
  1014. ;
  1015. SUBUSERF:                 ;FIND USERF AND CALL IT.
  1016.     PUSH    HL
  1017.     PUSH    DE        ;All registers preserved.
  1018.     LD      HL,(JUMP)
  1019.     LD      DE,0057H   ;Offset for func. 30
  1020.     ADD     HL,DE
  1021.     POP     DE
  1022.     EX      (SP),HL
  1023.     RET
  1024. ;
  1025. RESET:  LD      HL,BUFFER       ;RESET ALL VARIABLES
  1026.     LD      (DMAADD),HL
  1027.     LD      A,20H
  1028.     LD      (REC),A
  1029.     LD      HL,PASSUSED
  1030.     LD      DE,PASSUSED+1
  1031.     LD      BC,16
  1032.     LD      (HL),0
  1033.     LDIR
  1034.     LD      A,'0'
  1035.     LD      (LANGUAGE),A
  1036.     LD      (MESS22A),A
  1037.     LD      HL,511
  1038.     LD      (DEND),HL
  1039.     LD      HL,PASSWORD
  1040.     LD      DE,PASSWORD+1
  1041.     LD      BC,7
  1042.     LD      (HL),' '
  1043.     LDIR
  1044.     JP      SUBINPFILE
  1045. ;
  1046. PASSPUT:        
  1047.     LD      HL,PASSWORD
  1048.     LD      A,(HL)
  1049.     CP      ' '
  1050.     RET     Z
  1051.     LD      DE,0080H
  1052.     LD      BC,8
  1053.     LDIR
  1054.     LD      DE,0080H
  1055.     LD      C,BDDMA
  1056.     JP      FDOS
  1057. ;
  1058. SUBPRFCB:                  ;PRINT THE FILENAME IN THE FILE CONTROL BLOCK
  1059.     LD      A,(FCB)
  1060.     OR      A
  1061.     JR      NZ,SUBPRFCB0
  1062.     LD      C,BDDEF
  1063.     CALL    FDOS
  1064.     INC     A
  1065. SUBPRFCB0:
  1066.     ADD     A,'@'
  1067.     LD      (FILDR),A
  1068.     LD      HL,FCB+1
  1069.     LD      DE,FILSP   ;Load in name part
  1070.     LD      BC,08H
  1071.     LDIR
  1072.     LD      HL,FCB+9
  1073.     LD      DE,FILTY   ;Load in type part
  1074.     LD      BC,03H
  1075.     LDIR
  1076.     LD      HL,FILSP   ;
  1077.     LD      B,0CH      ; Print 12 bytes
  1078. SUBPRFCB1:
  1079.     LD      E,(HL)     ;
  1080.     RES     7,E
  1081.     LD      C,BDSCR    ; Print the characters one by one
  1082.     PUSH    HL         ;
  1083.     PUSH    BC
  1084.     CALL    FDOS
  1085.     POP     BC
  1086.     POP     HL
  1087.     INC     HL
  1088.     DJNZ    SUBPRFCB1       ;Until B=0
  1089.     RET
  1090. ;
  1091. SUBPRINT:
  1092.     PUSH    AF
  1093.     PUSH    BC
  1094.     PUSH    DE      ; PRINT A MESSAGE AT (DE)
  1095.     PUSH    HL
  1096.     LD      C,BDMSG ;
  1097.     CALL    FDOS     ; Send the message.
  1098.     POP     HL
  1099.     POP     DE
  1100.     POP     BC
  1101.     POP     AF
  1102.     RET
  1103. ;
  1104. SUBCODE:                      ;INFORM BDOS OF PROGRAM CODE. Restore language.
  1105.     LD      A,(LANGFLG)
  1106.     OR      A
  1107.     PUSH    DE              ;Save error number
  1108.     JR      Z,SUBFAIL1      ;If no language option active, ignore next bit.
  1109.     LD      A,(LANGUAGE)
  1110.     LD      (MESS22A),A     ;Select language in A
  1111.     LD      DE,MESS22
  1112.     CALL    SUBPRINT
  1113. SUBFAIL1:
  1114.     POP     DE
  1115.     LD      D,0FFH          ;Generate a program code.
  1116.     LD      A,E
  1117.     CP      5               ;If E=5, D=0 else D=0FFH (because error 5 is not
  1118.     JR      NZ,SUBFAIL2     ;a fatal error).
  1119.     LD      D,0
  1120. SUBFAIL2:
  1121.     LD      A,D             ;Preserve code for the MCM.
  1122.     LD      (MCFAIL),A
  1123.     LD      C,BDCODE        ;Send code.
  1124.     CALL    FDOS
  1125.     LD      A,(MCM)
  1126.     OR      A
  1127.     JP      NZ,RESET
  1128.     RST     0               ;Leave.
  1129. ;
  1130. SUBSCAN:                        ;SCAN COMMAND TAIL FOR /B,/E,/F,/H,/L,/M,/S,/U,/Z
  1131.                 ;Returns with carry set if /H found.
  1132.                 ;Other switches are dealt with internally.
  1133.     LD      A,(BUF+1)       ;Length of command tail.
  1134.     OR      A
  1135.     RET     Z               ;No command tail?
  1136.     LD      HL,BUF+2        ;Start of command tail.
  1137. SUBSCAN0:
  1138.     LD      A,(HL)          ;Search for switch indicator "/"
  1139.     CP      '/'
  1140.     JR      Z,SUBSCAN1      ;Is there a '/'?
  1141.     CP      '-'
  1142.     JR      Z,SUBSCAN1      ;Is there a '-' (also used as a switch char.)
  1143.     INC     HL
  1144.     OR      A               ;0=EOL marker
  1145.     JR      NZ,SUBSCAN0
  1146.     RET                     ;/H Not found.
  1147. ;
  1148. SUBSCAN1:
  1149.     INC     HL
  1150.     LD      A,(HL)          ;EOL Detection
  1151.     OR      A
  1152.     RET     Z
  1153.     CP      'B'             ; Is switch "B"?
  1154.     JP      Z,SUBBEGIN
  1155.     CP      'E'             ; Is switch "E"?
  1156.     JP      Z,SUBEND
  1157.     CP      'F'             ; Is switch "F"?
  1158.     JP      Z,SUBFORMAT
  1159.     CP      'I'             ; Is switch "I"?
  1160.     JP      Z,SUBSIF
  1161.     CP      'L'             ; Is switch "L"?
  1162.     JP      Z,SUBLANG
  1163.     CP      'M'             ; Is switch "M"?
  1164.     JP      Z,SUBIF
  1165.     CP      'S'             ; Is switch "S"?
  1166.     JP      Z,SUBSELSAVE
  1167.     CP      'U'             ; Is switch "U"?
  1168.     JP      Z,SUBUSER
  1169.     CP      'Z'             ; Is switch "Z"?
  1170.     JP      Z,SUBSTRIP
  1171.     CP      '?'             ; v1.02 - /? now supported as "help" option.
  1172.     JR      Z,FLGHLP
  1173.     CP      'H'             ; Is switch "H"?
  1174.     JR      NZ,SUBSCAN0     ; If not, continue search.
  1175. FLGHLP: SCF
  1176.     RET                     ; Switch found.
  1177. ;
  1178. SUBSCAN3:
  1179.     INC     HL
  1180.     JP      SUBSCAN0
  1181. ;
  1182. SUBFORMAT:
  1183.     LD      A,(FORMDAT)     ;Has there been a /F switch before now?
  1184.     OR      A
  1185.     JR      Z,SUBFORM0
  1186.     PUSH    HL
  1187.     LD      DE,MESS11       ;Can't have two /F switches
  1188.     CALL    SUBPRINT
  1189.     POP     HL
  1190.     JR      SUBSCAN3
  1191. ;
  1192. SUBFORM0:
  1193.     LD      A,0FFH
  1194.     LD      (FORMDAT),A     ;Flag: format already selected
  1195.     INC     HL
  1196.     LD      A,(HL)          ;EOL?
  1197.     OR      A
  1198.     RET     Z
  1199.     CP      '='             ;= is a modifier for extra options on the +3.
  1200.     JR      NZ,SUBFORM1
  1201.     LD      A,0FFH
  1202.     LD      (SIZE),A        ;Flag alternative (usually small) size.
  1203.     JR      SUBFORM2
  1204. ;
  1205. SUBFORM1:
  1206.     CP      ':'
  1207.     JR      Z,SUBFORM2      ; If not /F: or /F=, inform of a syntax error.
  1208.     LD      DE,MESS12
  1209.     CALL    SUBPRINT
  1210.     JR      SUBSCAN3
  1211. ;
  1212. SUBFORM2:
  1213.     INC     HL
  1214.     LD      A,(HL)          ;Get the actual format
  1215.     OR      A
  1216.     RET     Z
  1217.     CP      '+'             ;+3 format
  1218.     JP      Z,SUBPL3
  1219.     CP      'A'             ;Amstrad PCW format
  1220.     JP      Z,SUBPI2
  1221.     CP      'C'             ;MasterPaint .CAR format
  1222.     JP      Z,SUBCARFNT
  1223.     CP      'E'             ;EMS/EMT file format
  1224.     JP      Z,SUBEMSFNT
  1225.     CP      'P'             ;PRINTIT format
  1226.     JP      Z,SUBPRIFNT
  1227.     CP      'S'             ;Stop Press format
  1228.     JP      Z,SUBSPF
  1229.     CP      '?'             ;Unknown format
  1230.     JP      Z,SUBINTFNT
  1231.     LD      DE,MESS13       ;Inavlid /F option.
  1232.     CALL    SUBPRINT
  1233.     JP      SUBSCAN3
  1234. ;
  1235. SUBINTFNT:
  1236.     PUSH    AF              ;INiTialise an unknown font format.
  1237.     PUSH    BC
  1238.     PUSH    DE
  1239.     PUSH    HL
  1240. XPASS4: CALL    PASSPUT
  1241.     LD      DE,FCB
  1242.     LD      C,BDOPN
  1243.     CALL    FDOS            ;Open the file
  1244.     LD      A,H
  1245.     CP      7
  1246.     JR      NZ,XPASS5
  1247.     CALL    ERR8
  1248.     JR      XPASS4
  1249. ;
  1250. XPASS5: INC     A
  1251.     JP      Z,SBINT2
  1252.     LD      DE,FCB          ;Get length
  1253.     LD      C,BDLEN
  1254.     CALL    FDOS
  1255.     LD      HL,FCB+23H
  1256.     LD      A,(HL)          ;Get file length/128. MSB must be 0.
  1257.     OR      A
  1258.     JR      NZ,SUBINT1      ;Middle byte must be 0.
  1259.     DEC     HL
  1260.     LD      A,(HL)          ;LSB=length.
  1261.     OR      A
  1262.     JR      NZ,SUBINT1
  1263.     DEC     HL
  1264.     LD      A,(HL)          ;Guesses by file length
  1265.     CP      7
  1266.     JR      Z,INTPL3        ;+3DOS
  1267.     CP      10H
  1268.     JP      Z,INTPCW        ;PCW
  1269.     CP      11H
  1270.     JP      Z,INTHPCW       ;Headed PCW
  1271.     CP      18H
  1272.     JP      Z,INTPRI        ;PRINTIT
  1273.     CP      19H
  1274.     JP      Z,INTHPRI       ;Headed PRINTIT
  1275.     CP      20H
  1276.     JR      Z,INTBIG        ;4k
  1277.     CP      21H
  1278.     JR      Z,INTHBIG       ;Headed 4k
  1279.     CP      60
  1280.     JP      Z,INTCAR
  1281.     CP      61H
  1282.     JP      Z,INTSPF        ;Stop Press
  1283. SUBINT1:
  1284.     LD      DE,FCB          ;Unknown size
  1285.     LD      C,BDCLO         ;Close the file
  1286.     CALL    FDOS
  1287.     LD      DE,MESS26
  1288.     CALL    SUBPRINT        ;"Sorry, no idea"
  1289. SBINT2: POP     HL
  1290.     POP     DE
  1291.     POP     BC
  1292.     POP     AF              ;Back to scanning the command line
  1293.     JP      SUBSCAN3
  1294. ;
  1295. INTBIG: LD      DE,MESS31       ;Guess: 4k size
  1296.     CALL    SUBPRINT
  1297.     JR      SBINT2
  1298. ;
  1299. INTHBIG:
  1300.     LD      DE,MESS32       ;Guess: 4k size with header
  1301.     CALL    SUBPRINT
  1302.     CALL    SUBSTRP1
  1303.     JR      SBINT2
  1304. ;
  1305. INTPL3: LD      DE,MESS27       ;Guess: +3 file
  1306.     CALL    SUBPRINT
  1307.     POP     HL
  1308.     POP     DE
  1309.     POP     BC
  1310.     POP     AF
  1311. SUBPL3:                         ; SELECT A 768 BYTE +3DOS FILE
  1312.     PUSH    HL              ; Store pointer
  1313.     LD      A,(STRIP)       ;
  1314.     OR      A               ; If /Z switch set, say that it
  1315.     CALL    NZ,SUBPL31      ; isn't needed.
  1316.     LD      A,0FFH
  1317.     LD      (PLUS3),A       ; Set up marker: +3DOS selected.
  1318.     POP     HL
  1319.     JP      SUBSCAN3
  1320. SUBPL31:
  1321.     LD      DE,MESS23       ;Print "/Z switch not needed."
  1322.     JP      SUBPRINT
  1323. ;
  1324. SUBIF:  LD      A,(MCM)
  1325.     OR      A               ;Check; /M option is only valid in
  1326.     JR      Z,SUBIF1        ;Multiple command mode
  1327.     INC     HL
  1328.     LD      A,(HL)
  1329.     OR      A
  1330.     RET     Z
  1331.     CP      ':'             ;Test for /M:x
  1332.     JR      NZ,SUBIF0
  1333.     INC     HL
  1334.     LD      A,(HL)          ;A is the M code
  1335.     OR      A
  1336.     RET     Z
  1337.     CP      'E'             ;ELSE
  1338.     JR      Z,SUBELSE
  1339.     CP      'C'
  1340.     JR      Z,SUBICPC
  1341.     CP      'P'
  1342.     JR      Z,SUBIPCW
  1343.     CP      '+'             ;+3?
  1344.     JR      NZ,SUBIF0
  1345.     LD      A,(ISSPEC)
  1346.     XOR     0FFH            ;0 FOR +3, 0FFH FOR OTHER
  1347. SUBIFX: LD      (MCFAIL),A
  1348.     POP     HL
  1349.     JP      SUBINPFILE      
  1350. ;
  1351. SUBICPC:
  1352.     LD      A,(ISCPC)       ;0 FOR NOT CPC, 0FFH FOR CPC
  1353.     XOR     0FFH            ;SWAP THESE OVER
  1354.     JR      SUBIFX
  1355. ;
  1356. SUBIPCW:
  1357.     LD      A,(ISCPC)
  1358.     LD      B,A
  1359.     LD      A,(ISSPEC)
  1360.     OR      B               ;0 FOR PCW, ELSE 0FFH
  1361.     JR      SUBIFX
  1362. ;
  1363. SUBELSE:
  1364.     LD      A,(MCFAIL)      ;If...Else type command.
  1365.     CPL
  1366.     LD      (MCFAIL),A
  1367.     POP     HL
  1368.     JP      SUBINPFILE
  1369. ;
  1370. SUBIF0: LD      DE,MESS36       ;Bad syntax.
  1371.     CALL    SUBPRINT
  1372.     JP      SUBSCAN3
  1373. ;
  1374. SUBIF1: LD      DE,MESS37       ;Not in multi-command mode.
  1375.     CALL    SUBPRINT
  1376.     JP      SUBSCAN3
  1377. ;
  1378. SUBBEGIN:
  1379.     CALL    SUBPARSEBE      ;GET THE NUMBER IN BC
  1380.     PUSH    HL
  1381.     LD      HL,(DEND)       ;COMPARE WITH "END" VALUE
  1382.     OR      A
  1383.     SBC     HL,BC
  1384.     JR      C,SUBBEG1       ;"START" > "END"
  1385.     LD      (DBEGIN),BC     ;STORE "START" VALUE
  1386.     POP     HL
  1387.     JP      SUBSCAN3
  1388. ;
  1389. SUBBEG1:
  1390.     LD      DE,MESS24       ;Say that Start>End.
  1391.     CALL    SUBPRINT
  1392.     POP     HL
  1393.     JP      SUBSCAN3
  1394. ;
  1395. SUBEND: CALL    SUBPARSEBE      ;GET THE NUMBER IN BC
  1396.     PUSH    HL
  1397.     LD      H,B
  1398.     LD      L,C
  1399.     LD      DE,(DBEGIN)     ;COMPARE WITH "END" VALUE
  1400.     OR      A
  1401.     SBC     HL,DE
  1402.     JR      C,SUBBEG1       ;"START" > "END"
  1403.     LD      (DEND),BC       ;STORE "END" VALUE
  1404.     POP     HL
  1405.     JP      SUBSCAN3
  1406. ;
  1407. SUBPARSEBE:             ;GET A NUMBER (IN BC) FOR THE BEGINNING/END OPTIONS.
  1408.     INC     HL
  1409.     LD      A,(HL)
  1410.     OR      A
  1411.     JR      Z,STKRET
  1412.     LD      BC,0            ;OFFSET FOR CHARACTER SET
  1413.     CP      ':'             ;/B:N - OFFSET IS BC=0
  1414.     JR      Z,SPBE1
  1415.     PUSH    AF              ;/B=N
  1416.     LD      A,(ISSPEC)      ;OFFSET FOR SMALL SET - IGNORED ON PCW.
  1417.     AND     01H
  1418.     LD      B,A             ;OFFSET IS 1 (256 CHARS) ON SPECTRUM AND
  1419.     POP     AF              ;0 ON PCW.
  1420.     CP      '='
  1421.     JR      Z,SPBE1
  1422.     LD      DE,MESS25
  1423.     CALL    SUBPRINT
  1424.     JP      SUBSCAN3
  1425. ;
  1426. STKRET: POP     HL              ;TIDY UP THE STACK
  1427.     RET                     ;LEAVE SCANNER ROUTINE ALTOGETHER
  1428. ;
  1429. SPBE1:  INC     HL
  1430.     LD      A,(HL)
  1431.     OR      A               ;IF (HL)=0, END OF LINE.
  1432.     JR      Z,STKRET
  1433.     PUSH    BC
  1434.     CALL    PARSENUM        ;NUMBER RETURNED IN DE.
  1435.     POP     BC
  1436.     LD      C,E             ;FINAL NUMBER IN BC.
  1437.     RET
  1438. ;
  1439. SUBUSER:                        ;Set the user number, given in decimal.
  1440.     INC     HL
  1441.     LD      A,(HL)
  1442.     OR      A               ;EOL?
  1443.     RET     Z
  1444.     CP      ':'
  1445.     JP      NZ,SUBUSER2     ;If the switch is not /U:nn then report
  1446.     INC     HL              ;a syntax error.
  1447.     LD      A,(HL)          ;EOL?
  1448.     OR      A
  1449.     RET     Z
  1450.     CALL    PARSENUM        ;Parse the number.
  1451.     JP      C,SUBUSER2      ;If main carry flag set, not a number.
  1452.     LD      A,E             ;Only low byte used.
  1453.     AND     0FH             ;Only low Nibble used.
  1454.     LD      E,A
  1455.     LD      D,0
  1456.     CALL    SUBUSER1        ;Set the user.
  1457.     JP      SUBSCAN0
  1458. ;
  1459. SUBUSER1:
  1460.     LD      C,BDUSR         ;Set user number.
  1461.     PUSH    BC              ;Preserve BC & HL.
  1462.     PUSH    HL
  1463.     CALL    FDOS
  1464.     POP     HL
  1465.     POP     BC
  1466.     JP      SUBSCAN3
  1467. ;
  1468. SUBUSER2:
  1469.     LD      DE,MESS15       ;Print "Syntax error.."
  1470.     CALL    SUBPRINT
  1471.     JP      SUBSCAN3
  1472. ;
  1473. SUBLANG:
  1474.     INC     HL
  1475.     LD      A,(HL)
  1476.     OR      A
  1477.     RET     Z
  1478.     CP      '='             ;Check for /L:n or /L=n
  1479.     JR      Z,SETL1
  1480.     CP      ':'
  1481.     JR      Z,SETL2
  1482. BADLS:  LD      DE,MESS21       ;Bad /L syntax
  1483.     CALL    SUBPRINT
  1484.     JP      SUBSCAN3
  1485. ;
  1486. SETL1:  INC     HL
  1487.     LD      A,(HL)
  1488.     OR      A
  1489.     RET     Z
  1490.     CP      '0'
  1491.     JR      C,BADLS
  1492.     CP      '8'
  1493.     JR      NC,BADLS        ;Check: is it 0-7?
  1494.     LD      (MESS22A),A     ;File language
  1495.     LD      A,0FFH
  1496.     LD      (LANGFLG),A     ;Flag that language changes are needed.
  1497.     JP      SUBSCAN3
  1498. ;
  1499. SETL2:  INC     HL
  1500.     LD      A,(HL)
  1501.     OR      A
  1502.     RET     Z
  1503.     CP      '0'
  1504.     JR      C,BADLS
  1505.     CP      '8'
  1506.     JR      NC,BADLS        ;Check: is it 0-7?
  1507.     LD      (LANGUAGE),A    ;Computer language
  1508.     LD      A,0FFH
  1509.     LD      (LANGFLG),A     ;Flag that language changes are needed.
  1510.     JP      SUBSCAN3
  1511. ;
  1512. INTSPF: LD      DE,MESS35       ;Guess: Stop Press format
  1513.     CALL    SUBPRINT
  1514.     POP     HL
  1515.     POP     DE
  1516.     POP     BC
  1517.     POP     AF
  1518. SUBSPF: LD      A,0FFH
  1519.     LD      (SPFFLG),A
  1520.     JP      SUBSCAN3
  1521. ;
  1522. INTHPRI:
  1523.     LD      DE,MESS33       ;Guess: PRINTIT format (headed)
  1524.     JR      INTPRI1
  1525. ;
  1526. INTPRI: LD      DE,MESS28       ;Guess: PRINTIT format (not headed)
  1527. INTPRI1:
  1528.     CALL    SUBPRINT
  1529.     POP     HL
  1530.     POP     DE
  1531.     POP     BC
  1532.     POP     AF
  1533. SUBPRIFNT:
  1534.     LD      A,0FFH
  1535.     LD      (PRINTIT),A
  1536.     JP      SUBSCAN3
  1537. ;
  1538. INTCAR: LD      DE,MESS38
  1539.     CALL    SUBPRINT        ;Guess: .CAR font.
  1540.     POP     HL
  1541.     POP     DE
  1542.     POP     BC
  1543.     POP     AF
  1544. SUBCARFNT:
  1545.     LD      A,0FFH          ;Flag .CAR font.
  1546.     LD      (CARFLG),A
  1547.     JP      SUBSCAN3
  1548. ;
  1549. PARSENUM:
  1550. ;
  1551. ;Inputs: HL points to the start of the number. Lines 0 terminated.
  1552. ;Outputs:
  1553. ;        DE holds the number.
  1554. ;        HL points to the next character.
  1555. ;        Carry set if the first character was not a digit.
  1556. ;        If end-of-line reached, A=0FFH
  1557.  
  1558.     LD      (STARTADD),HL
  1559.     CALL    NUMERIC
  1560.     RET     C
  1561.     LD      DE,0
  1562. NUMLP1: LD      A,(HL)   ;A=DIGIT (ASCII)
  1563.     OR      A
  1564.     JR      Z,NUMLP3 ;EOL
  1565.     CALL    NUMERIC
  1566.     JR      C,NUMLP2 ;NON-NUMERIC => END OF NUMBER
  1567.     SUB     30H      ;A=NUMBER(HEX)
  1568.     CALL    X10      ;MOVE DIGITS IN DE UP.
  1569.     CALL    ADDDE    ;DE=NUMBER(DECIMAL)
  1570.     INC     HL
  1571.     JR      NUMLP1
  1572. ;
  1573. NUMLP2: LD      A,0
  1574.     SCF
  1575.     CCF
  1576.     RET
  1577. ;
  1578. NUMLP3: LD      A,0FFH
  1579.     SCF
  1580.     CCF
  1581.     RET
  1582. ;
  1583. NUMERIC:
  1584. ;CHECK FOR NUMERIC DATA IN A
  1585. ;IF OK, CARRY CLEAR.
  1586.     CP      '0'
  1587.     RET     C       ;NOT OK
  1588.     CP      ':'
  1589.     JR      NC,NUM1
  1590.     OR      A       ;NUMBER OK
  1591.     RET
  1592. ;
  1593. NUM1:   SCF             ;NOT OK
  1594.     RET
  1595. ;
  1596. X10:
  1597. ;MULTIPLY DE BY 10.
  1598. ;RETURN ANSWER IN DE.
  1599.     PUSH    HL
  1600.     EX      DE,HL   ;NUMBER IN HL
  1601.     ADD     HL,HL   ;HL=HL*2
  1602.     PUSH    HL
  1603.     POP     DE      ;DE=HL*2
  1604.     ADD     HL,HL   ;HL=HL*4
  1605.     ADD     HL,HL   ;HL=HL*8
  1606.     ADD     HL,DE   ;HL=HL*10
  1607.     EX      DE,HL   ;DE=DE*10
  1608.     POP     HL
  1609.     RET
  1610. ;
  1611. ADDDE:
  1612. ;ADD A TO DE
  1613. ;
  1614.     PUSH    HL
  1615.     EX      DE,HL   ;ONLY HL CAN BE USED HERE.
  1616.     LD      D,0
  1617.     LD      E,A
  1618.     ADD     HL,DE
  1619.     EX      DE,HL   ;RESULT IN DE
  1620.     POP     HL
  1621.     RET
  1622. ;
  1623.     DSEG
  1624. STARTADD:
  1625.     DEFW    0
  1626. ENDADD: DEFW    0
  1627. DIGITS: DEFB    0
  1628.     CSEG
  1629. ;
  1630. SUBERASE:                       ;ERASE A FILE
  1631.     LD      DE,CRLF
  1632.     CALL    SUBPRINT
  1633. SUBERA0:
  1634.     CALL    PASSPUT
  1635.     LD      DE,FCB
  1636.     LD      C,BDERA         ;Erase file.
  1637.     CALL    FDOS
  1638.     LD      A,H
  1639.     CP      7
  1640.     JR      NZ,SUBERA1
  1641.     CALL    ERR8
  1642.     JR      SUBERA0
  1643. ;
  1644. SUBERA1:                        ;If the file still exists, the ERASE was
  1645.     LD      DE,FCB          ;unsuccessful.
  1646.     LD      C,BDSCN
  1647.     CALL    FDOS
  1648.     CP      0FFH            ;If the file does
  1649.     JP      Z,SAVE1         ;not exist, OK.
  1650.     LD      DE,MESS18
  1651.     CALL    SUBPRINT        ;Otherwise, there has been an error.
  1652.     CALL    SUBPRFCB
  1653.     LD      DE,MESS19
  1654.     CALL    SUBPRINT        ;Print "Can't erase FILENAME.TYP"
  1655.     LD      E,1
  1656.     JP      SUBCODE
  1657. ;
  1658. SUBSELSAVE:
  1659.     PUSH    HL              ;SELECT SAVE RATHER THAN LOAD
  1660.     LD      A,255
  1661.     LD      (LOADSAVE),A    ;Set save flag
  1662.     LD      A,0EBH
  1663.     LD      (SETGET),A      ;Read char. data rather than write.
  1664.     OR      A
  1665.     POP     HL
  1666.     JP      SUBSCAN3
  1667. ;
  1668. SUBUPCASE:              ;CONVERT A CHARACTER TO UPPER CASE
  1669.     CP      061H    ;Below "a"?
  1670.     RET     C
  1671.     CP      07BH    ;Above "z"?
  1672.     RET     NC
  1673.     SUB     020H    ;Otherwise, subtract 20H
  1674.     RET
  1675. ;
  1676. SUBSIF: LD      A,0FFH          ;Set "invert"
  1677.     LD      (INVFLG),A
  1678.     RET
  1679. ;
  1680. SUBSTRIP:
  1681.     CALL    SUBSTRP1        ;Select /Z option
  1682.     JP      SUBSCAN3
  1683. ;
  1684. SUBSTRP1:
  1685.     LD      A,(PLUS3)       ; If +3DOS option
  1686.     OR      A               ; selected, the /Z
  1687.     JR      NZ,SUBSTRP2     ; option is unnecessary.
  1688.     LD      A,255           ; Tell the user so.
  1689.     LD      (STRIP),A
  1690.     RET
  1691. ;
  1692. SUBSTRP2:
  1693.     LD      DE,MESS23       ; Tell the user that you don't
  1694.     CALL    SUBPRINT        ; need /Z with /F:+.
  1695.     RET
  1696. ;
  1697. PTR:    LD      A,(LOADSAVE)    ;LOADING OR SAVING?
  1698.     OR      A
  1699.     JP      NZ,SAVEPTR      ;Saving
  1700.     CALL    CG0
  1701.     LD      A,18h           ; 24 records
  1702.     LD      (REC),A
  1703.     LD      HL,0B000H       ; Load temporarily to B000H
  1704.     LD      (DMAADD),HL
  1705.     CALL    LOAD            ;Load the expanded font.
  1706.     LD      HL,0B000H       ;Chars 32-224
  1707.     LD      DE,0C100H
  1708.     CALL    ASDE
  1709.     LD      BC,00C00H
  1710. PTRL2:  LDI
  1711.     INC     HL
  1712.     LD      A,B
  1713.     OR      C
  1714.     JR      NZ,PTRL2
  1715.     JP      LOAD5
  1716. ;
  1717. SAVEPTR:
  1718.     LD      A,18H           ; 24 records
  1719.     LD      (REC),A         ;
  1720.     CALL    CHARGET
  1721.     LD      DE,0B000H
  1722.     LD      HL,0C100H
  1723.     CALL    ASHL
  1724.     LD      BC,00C00H       ;Create a PRINTIT font at B000H
  1725. SAVPT1: LD      A,(HL)
  1726.     LD      (DE),A
  1727.     INC     DE
  1728.     LDI
  1729.     LD      A,B
  1730.     OR      C
  1731.     JR      NZ,SAVPT1
  1732.     LD      HL,0B000H        ;
  1733.     LD      (DMAADD),HL      ; Save starting at B000H
  1734.     JP      SAVE0            ;
  1735. ;
  1736. ASHL:   PUSH    AF
  1737.     PUSH    DE
  1738.     LD      A,(SIZE)
  1739.     OR      A
  1740.     JR      Z,ASHL2
  1741. PCWP0A: LD      DE,800H
  1742.     ADD     HL,DE
  1743. ASHL2:  POP     DE
  1744.     POP     AF
  1745.     RET
  1746. ;
  1747. ASDE:   PUSH    AF
  1748.     PUSH    HL
  1749.     LD      A,(SIZE)
  1750.     OR      A
  1751.     JR      Z,ASDE2
  1752. PCWP0:  LD      HL,800H
  1753.     ADD     HL,DE
  1754.     EX      DE,HL
  1755. ASDE2:  POP     HL
  1756.     POP     AF
  1757.     RET
  1758. ;
  1759. ; Error handler routines:
  1760. ;
  1761. ERR1:   LD      DE,MESS1   ;Bad environment
  1762.     CALL    SUBPRINT
  1763.     RST     0
  1764. ;
  1765. ERR2:   LD      DE,MESS2   ;File not found
  1766.     CALL    SUBPRINT
  1767.     CALL    SUBPRFCB
  1768.     LD      DE,CRLF
  1769.     CALL    SUBPRINT
  1770.     LD      E,2
  1771.     JP      SUBCODE
  1772. ;
  1773. ERR3:   LD      DE,MESS3   ;End of file met.
  1774.     CALL    SUBPRINT
  1775.     LD      E,3
  1776.     JP      SUBCODE
  1777. ;
  1778. ERR4:   LD      DE,MESS4   ;Read error.
  1779.     CALL    SUBPRINT
  1780.     CALL    SUBPRFCB
  1781.     LD      DE,CRLF
  1782.     CALL    SUBPRINT
  1783.     LD      E,4
  1784.     JP      SUBCODE
  1785. ;
  1786. ERR5:   LD      DE,MESS6   ;No file specified.
  1787.     CALL    SUBPRINT
  1788.     JP      SUBINPFILE
  1789. ;
  1790. ERR6:   LD      A,(CARFLG)      ;The .CAR file is expected to exist already.
  1791.     OR      A
  1792.     JP      NZ,SUBERA0      ;Straight to "erase".
  1793.     LD      DE,MESS8        ;File exists already.
  1794.     CALL    SUBPRINT
  1795.     CALL    SUBPRFCB
  1796.     LD      DE,MESS8A
  1797.     CALL    SUBPRINT
  1798.     LD      C,BDKEY
  1799.     CALL    FDOS            ;Await keypress
  1800.     CP      'Y'
  1801.     JP      Z,SUBERASE
  1802.     CP      'y'
  1803.     JP      Z,SUBERASE
  1804.     LD      DE,CRLF         ;New line
  1805.     CALL    SUBPRINT
  1806.     LD      E,5
  1807.     JP      SUBCODE
  1808. ;
  1809. ERR7:   LD      DE,MESS9        ;Write error
  1810.     CALL    SUBPRINT
  1811.     CALL    SUBPRFCB
  1812.     LD      DE,MESS9A
  1813.     CALL    SUBPRINT
  1814.     LD      E,6
  1815.     JP      SUBCODE
  1816. ;
  1817. ERR8:   LD      A,(PASSUSED) ;GET A PASSWORD.
  1818.     CP      0FFH
  1819.     JP      Z,ERR8A          ;If a password was wrong, leave.
  1820.     CALL    ERR8B
  1821.     LD      DE,MESS16        ;Password needed.
  1822.     CALL    SUBPRINT
  1823.     LD      A,8
  1824.     LD      (CMDTAIL),A     ;Ask for a password,
  1825.     CALL    SCR0
  1826.     LD      C,BDLIN         ;maximum 8 characters.
  1827.     LD      DE,CMDTAIL
  1828.     CALL    FDOS
  1829.     CALL    SCR1
  1830.     LD      A,(0081H)       ;Length of password.
  1831.     OR      A
  1832.     LD      E,7
  1833.     JP      Z,SUBCODE       ;If no password, abort.
  1834.     LD      B,8
  1835.     LD      HL,0082H        ; Convert max. 8
  1836. ERR8C:  LD      A,(HL)          ; bytes of password
  1837.     CALL    SUBUPCASE       ; to uppercase.
  1838.     LD      (HL),A
  1839.     INC     HL              ; Next byte
  1840.     DJNZ    ERR8C
  1841.     LD      DE,PASSWORD     ; Move to permanent home for password
  1842.     LD      HL,0082H        
  1843.     LD      BC,8
  1844.     LDIR
  1845.     LD      A,0FFH          ; Flag that a
  1846.     LD      (PASSUSED),A    ; password has been tried.
  1847.     LD      DE,CRLF
  1848.     JP      SUBPRINT
  1849. ;
  1850.     DSEG
  1851. SCB1:   DEFW    0024H           ;Get CONOUT: redirection
  1852. SCB2:   DEFW    0FE24H          ;Set CONOUT: redirection
  1853. CONVAL: DEFW    0               ;CONOUT: redirection value to set.
  1854. CONVEC: DEFW    0               ;True CONOUT: redirection value
  1855.     CSEG
  1856. ;
  1857. SCR0:   LD      DE,SCB1         ;Disable screen output
  1858.     LD      C,BDSCB
  1859.     CALL    FDOS            ;Get current CONOUT: redirection.
  1860.     LD      (CONVEC),HL
  1861.     LD      C,6DH
  1862.     LD      DE,0FFFFH       ;Disable ^C while input is being made.
  1863.     CALL    FDOS    
  1864.     LD      D,H             ;Get console mode
  1865.     LD      E,L
  1866.     SET     3,E             ;Flag that ^C is disabled
  1867.     LD      C,6DH           ;and set console mode
  1868.     CALL    FDOS
  1869.     LD      HL,0            ;CONOUT:=NUL
  1870. SCR1A:  LD      (CONVAL),HL     ;Set CONOUT: redirection to value in HL.
  1871.     LD      DE,SCB2
  1872.     LD      C,BDSCB
  1873.     JP      FDOS
  1874. ;
  1875. SCR1:   LD      HL,(CONVEC)     ;Restore former CONOUT: redirection
  1876.     JR      SCR1A
  1877. ;
  1878. SCR2:   LD      DE,SCB1         ;Set CONOUT:=CRT, for printing of escape codes.
  1879.     LD      C,BDSCB
  1880.     CALL    FDOS
  1881.     LD      (CONVEC),HL
  1882.     LD      HL,8000H
  1883.     JR      SCR1A
  1884. ;
  1885. ERR8A:  LD      DE,MESS17   ;Password invalid.
  1886.     CALL    SUBPRINT
  1887.     LD      E,7
  1888.     JP      SUBCODE
  1889. ;
  1890. ERR8B:  LD      BC,8            ;Set 8 bytes to 20H
  1891.     LD      HL,0082H        ;Password location
  1892.     LD      DE,0083H        ;Filler destination
  1893.     LD      (HL),020H       ;Filler byte
  1894.     LDIR                    ;Password buffer filled with spaces.
  1895.     RET
  1896. ;
  1897. ERR9:   LD      DE,MESS20       ;Not enough memory.
  1898.     CALL    SUBPRINT
  1899.     LD      E,8
  1900.     JP      SUBCODE
  1901. ;
  1902. ERR10:  LD      DE,MESS34       ;No font in EMS file
  1903.     CALL    SUBPRINT
  1904.     LD      E,9
  1905.     JP      SUBCODE
  1906. ;
  1907. ERR11:  LD      DE,MESS39       ;Invalid font size in .CAR file.
  1908.     CALL    SUBPRINT
  1909.     LD      E,10
  1910.     JP      SUBCODE
  1911. ;
  1912. ERR12:  LD      DE,MESS8        ;Attempt to write to a System file in user 0.
  1913.     CALL    SUBPRINT
  1914.     CALL    SUBPRFCB
  1915.     LD      DE,MESS40
  1916.     CALL    SUBPRINT
  1917.     LD      E,11
  1918.     JP      SUBCODE
  1919. ;
  1920. HELP:   LD      DE,MESS7        ;Print the helpscreen
  1921.     CALL    SUBPRINT        ;(Part 1)
  1922.     LD      C,BDKEY         ;Await a keypress
  1923.     CALL    FDOS
  1924.     CP      3               ;^C to abandon helpscreen
  1925.     JP      Z,WB1
  1926.     LD      DE,MESS7A       ;Print part 2
  1927.     CALL    SUBPRINT
  1928.     LD      C,BDKEY         ;keypress
  1929.     CALL    FDOS
  1930.     CP      3               ;^C again.
  1931.     JP      Z,WB1
  1932.     LD      DE,MESS7B
  1933.     CALL    SUBPRINT        ;Last bit of HELP message
  1934.     JP      WB1
  1935. ;
  1936. ; Program messages
  1937. ;
  1938.     DSEG
  1939. MESS1:  DEFB    'This program requires Amstrad PCW/CPC or Spectrum +3.',CR,LF,'$'
  1940. MESS2:  DEFB    'Input file not found: $'
  1941. FILDR:  DEFB    ' :'
  1942. FILSP:  DEFB    '        .'
  1943. FILTY:  DEFB    '   ',CR,LF,'$'
  1944. MESS3:  DEFB    'End of file met.',CR,LF,'$'
  1945. MESS4:  DEFB    'Disc read error: $'
  1946. MESS5:  DEFB    'Character set loaded.',CR,LF,'$'
  1947. MESS6:  DEFB    'SETFONT v1.02a Multiple Command Mode',cr,lf
  1948.     DEFB    'For help type /H. To leave press RETURN.',CR,LF,lf,'$'
  1949. MESS7:  DEFB    'SETFONT v1.02a',CR,LF,LF
  1950.     DEFB    'Syntax:',CR,LF,'   SETFONT {d:filename.ext} {/option /option...}'
  1951.     DEFB    CR,LF,LF
  1952.     DEFB    'Options are /B /E /F /H /I /L /M /S /U /Z',cr,lf
  1953.         ;1...5...10...15...20...25...30...35...40...45...50...55...60...65...70...75...80
  1954.     DEFB    '/B and /E limit the loading of the font; only that part which lies between the',cr,lf
  1955.     DEFB    '   /B(egin) number and the /E(nd) number is used. Syntax is /B:n /B=n /E:n /E=n',cr,lf
  1956.     DEFB    '   On the Spectrum +3, if an equals sign is used, the number refers to the small',cr,lf
  1957.     DEFB    '   font.',cr,lf
  1958.     DEFB    '/F selects the font format:',cr,lf
  1959.     DEFB    '     F:+ - Spectrum +3DOS type. +3DOS fonts are saved or loaded with the correct',cr,lf
  1960.     DEFB    '           +3DOS header. The pound and copyright signs are loaded correctly.',cr,lf
  1961.     DEFB    '     F:A - Amstrad PCW/CPC type. Only useful on a Spectrum; others use this',cr,lf
  1962.     DEFB    '           format anyway.',cr,lf
  1963.     DEFB    '     F:C - MasterPaint .CAR font. When saving, modifies a file already present.',cr,lf
  1964.     DEFB    '           (Similar in size to STANDARD.CAR).',cr,lf
  1965.     DEFB    '     F:E - Contained in an EMS/EMT file. LocoScript 2 EMS files are not suitable',cr,lf
  1966.     DEFB    '           When saving, this modifies an EMS file already present.',cr,lf
  1967.     DEFB    '[More]',cr,'$'
  1968. MESS7A: DEFB    '     F=E - On a Spectrum +3, restricts the /F:E action to the large font.',cr,lf
  1969.     DEFB    '     F:P - PRINTIT double-height font.',cr,lf
  1970.     DEFB    '     F:S - Stop Press font (similar in size to HITEC-70)',CR,LF
  1971.     DEFB    '     F:? - If you don`t know what it is',21h,' SETFONT will try to guess the',cr,lf
  1972.     DEFB    '           type (only useful when loading)',cr,lf
  1973.     DEFB    '  On the Spectrum +3, if you use an = sign instead of the colon (eg /F=P) then',cr,lf
  1974.     DEFB    'the small font will be used (Except /F=E above).',cr,lf
  1975.     DEFB    '/H brings up this screen.',CR,LF
  1976.     DEFB    '/I inverts the font being loaded or saved.',cr,lf
  1977.     DEFB    '/L:n and /L=n select the CP/M language to use, as follows:',CR,LF
  1978.     DEFB    '     /L:n specifies which language the computer is in at the moment.',cr,lf
  1979.     DEFB    '     /L=n specifies which language the file should be in.',cr,lf
  1980.     DEFB    '     If only one of these is present, the other is assumed to be 0.',cr,lf
  1981.     DEFB    '/M:x Multi-command mode options. x can be +, C, E or P (see documentation)',cr,lf
  1982.     DEFB    '/S will make the program save instead of loading.',CR,LF
  1983.     DEFB    '/U needs a colon and then a user number from 0 to 15. It selects that area to',cr,lf
  1984.     DEFB    '   load or save with.',CR,LF
  1985.     DEFB    '[More]',cr,'$'
  1986. MESS7B: DEFB    '/Z indicates that there is a "header" record on the file. If saving, the',cr,lf
  1987.     DEFB    '   "header record" contains machine code which makes the character set self-',cr,lf
  1988.     DEFB    '   loading. eg:',cr,lf,lf
  1989.     DEFB    '      SETFONT MYFONT.COM /Z /S ',cr,lf,lf
  1990.     DEFB    '   then typing MYFONT will load the font. The use when loading is to remove',cr,lf
  1991.     DEFB    '   +3DOS header information.',CR,LF
  1992.     DEFB    '  SETFONT with no filename or options enters the multiple command mode (like',cr,lf
  1993.     DEFB    'PIP).',cr,lf
  1994.     DEFB    '  The program will work with Amstrad PCW 8000 and 9000 series, CPC 6128s and',cr,lf
  1995.     DEFB    'ZX Spectrum +3 with CP/M. It uses a character set file. For information about',cr,lf
  1996.     DEFB    'the format of the character set, see the documentation.',CR,LF,LF,'$'
  1997. MESS8:  DEFB    'File $'
  1998. MESS8A: DEFB    ' exists, delete (Y/N) ?$'
  1999. MESS9:  DEFB    'Write error on file: $'
  2000. MESS9A: DEFB    CR,LF,'The disc or directory may be full.',CR,LF,'$'
  2001. MESS10: DEFB    'This option is not valid: $'
  2002. MESS11: DEFB    'You can only have one /F switch in a command. Using first /F',cr,lf,'$'
  2003. MESS12: DEFB    'Syntax for /F switch is /F:f or /F=f',cr,lf,'$'
  2004. MESS13: DEFB    'Valid formats are +,?,A,C,E,P,S only.',cr,lf,'$'
  2005. MESS14: DEFB    'That filename is not valid.',cr,lf,'$'
  2006. INPPROMPT:
  2007.     DEFB    'SETFONT>$'
  2008. CRLF:   DEFB     CR,LF,'$'     ;
  2009. MESS15: DEFB    'The /U option must be followed by a colon. Only users 0-15 allowed.',CR,LF,'$'
  2010. MESS16: DEFB    'This file is password protected.',CR,LF,'Please enter password:$'
  2011. MESS17: DEFB    'Password was wrong.',CR,LF,'$'
  2012. MESS18: DEFB    'Can`t delete file: $'
  2013. MESS19: DEFB CR,LF,'The file may be read only.',CR,LF,'$'
  2014. MESS20: DEFB    'Not enough memory. Please remove RSXs etc.',cr,lf,'$'
  2015. MESS21: DEFB    'Syntax for /L option is /L:n or /L=n where n is a one-digit number.',cr,lf,'$'
  2016. MESS22: DEFB    ESC,'2'
  2017. MESS22A: DEFB   '0$'
  2018. MESS23: DEFB    'The /Z is unnecessary in +3DOS format.',cr,lf,'$'
  2019. MESS24: DEFB    'The "begin" number must be less than the "end" number.',cr,lf,'$'
  2020. MESS25: DEFB    'The "begin" and "end" options must be formed /B:n /B=n /E:n or /E=n',cr,lf,'$'
  2021. MESS26: DEFB    'File type unknown. Attempting to load as full font.',cr,lf,'$'
  2022. MESS27: DEFB    'Guess: Spectrum +3DOS type.',cr,lf,'$'
  2023. MESS28: DEFB    'Guess: PRINTIT type.',cr,lf,'$'
  2024. MESS29: DEFB    'Guess: Amstrad standard.',cr,lf,'$'
  2025. MESS30: DEFB    'Guess: Amstrad standard with header.',cr,lf,'$'
  2026. MESS31: DEFB    'Guess: Spectrum +3 CP/M.',cr,lf,'$'
  2027. MESS32: DEFB    'Guess: Spectrum +3 CP/M with header.',cr,lf,'$'
  2028. MESS33: DEFB    'Guess: PRINTIT type with header.',cr,lf,'$'
  2029. MESS35: DEFB    'Guess: Stop Press font.',cr,lf,'$'
  2030. MESS38: DEFB    'Guess: MasterPaint .CAR format font.',cr,lf,'$'
  2031. MESS34: DEFB    'This file contains no suitable font.',cr,lf,'$'
  2032. MESS36: DEFB    '/M option must be formed /M:x where x is +,C,E or P',cr,lf,'$'
  2033. MESS37: DEFB    'Not in multiple command mode - /M option ignored.',cr,lf,'$'
  2034. MESS39: DEFB    'The font does not have 8x8 character size.',cr,lf,'$'
  2035. MESS40: DEFB    ' is a System file in User 0 - Cannot write to it from here.',cr,lf,'$'
  2036. ;
  2037. ; Program data
  2038. ;
  2039. DMAADD: DEFW    BUFFER
  2040. REC:    DEFB    020H
  2041. PASSUSED: DEFB  0       ;Was a password used?
  2042. USER:   DEFB    0       ;Startup user number.
  2043. FORMDAT: DEFB   0       ;was there a /F switch?
  2044. PLUS3:  DEFB    0       ;/F:+ switch?
  2045. PCW:    DEFB    0       ;/F:A switch?
  2046. EMSFLG: DEFB    0       ;/F:E switch?
  2047. PRINTIT: DEFB   0       ;/F:P switch?
  2048. SPFFLG: DEFB    0       ;/F:S switch?
  2049. CARFLG: DEFB    0       ;/F:C switch?
  2050. SIZE:   DEFB    0       ;/F=  switch?
  2051. INVFLG: DEFB    0       ;/I switch?
  2052. LANGUAGE: DEFB  0       ;/L: switch?
  2053. LANGFLG:  DEFB  0       ;/L switch?
  2054. LOADSAVE: DEFB  0       ;/S switch?
  2055. STRIP:  DEFB    0       ;/Z switch?
  2056. DBEGIN: DEFW    0
  2057. DEND:   DEFW    511
  2058. ISSPEC: DEFB    0FFH    ;SPECTRUM OR AMSTRAD?
  2059. ISCPC:  DEFB    0       ;PCW OR CPC?
  2060. MCM:    DEFB    0       ;MULTI-COMMAND MODE?
  2061. MCFAIL: DEFB    0       ;MULTI-COMMAND MODE FAILURE FLAG
  2062. PASS1:  DEFB    '        '
  2063. ;
  2064. ; There now follows the +3DOS header for a character set file:
  2065. ;
  2066. HEADER: DEFB      'PLUS3DOS',01AH ; +3DOS signature
  2067.     DEFB      1,0             ; Version 1.0
  2068.     DEFW      0380H,0         ; Length=768+Header
  2069. ;Now follows +3BASIC information
  2070.     DEFB    3               ; +3DOS CODE type file.
  2071.     DEFW    768             ; 768 bytes
  2072.     DEFW    0               ; Load address not specified.
  2073.     DEFB    0,0,0           ; Unused bytes.
  2074. ; The next 104 bytes are reserved.
  2075.     DEFS    104
  2076. ;
  2077.     DEFB      01            ; Header checksum
  2078.     CSEG
  2079. ;
  2080. COMHED:
  2081. ;
  2082. ; This section will be loaded 0100h relative.
  2083. CH1:
  2084.     .phase  0100h
  2085.     LD      BC,01000H
  2086.     LD      HL,0180H
  2087.     LD      DE,0C080H
  2088.     LDIR                    ;MOVE FONT UP TO 0C000H
  2089.     LD      BC,007FH
  2090.     LD      HL,CHHHH
  2091.     LD      DE,0C000H
  2092.     LDIR
  2093.     LD      HL,(0101H)
  2094.     LD      (0C001H),HL
  2095.     CALL    CHUSF
  2096.     DEFW    00E3H
  2097.     CP      01H
  2098.     JR      Z,CHPCW
  2099.     OR      A
  2100.     JP      Z,CHCPC
  2101.     LD      HL,SCHRSET
  2102.     LD      (CHRTX+1),HL
  2103. CHRUN:  LD      BC,CHRTN
  2104.     CALL    CHUSF
  2105.     DEFW    00E9H
  2106.     RST     0
  2107. ;
  2108. CHPCW:  LD      HL,0800H
  2109.     LD      (CHRTN+1),HL
  2110.     LD      HL,PCHRSET
  2111.     LD      (CHRTX+1),HL
  2112.     JR      CHRUN
  2113. ;
  2114. CHCPC:  LD      HL,0800H
  2115.     LD      (CHRTN+1),HL
  2116.     CALL    CHUSF
  2117.     DEFW    0C000H
  2118.     RST     0
  2119. ;
  2120. CHUSF:  LD      HL,(1)
  2121.     LD      DE,0057H
  2122.     ADD     HL,DE
  2123.     JP      (HL)
  2124. ;
  2125. CHHHH:  .DEPHASE
  2126.     .PHASE  0C000H
  2127. CHRTN:  LD      BC,01000H       ;C000
  2128. CHRTX:  LD      DE,CCHRSET      ;C003
  2129.     LD      HL,0C080H
  2130.     LDIR
  2131.     RET
  2132. ;
  2133.     .DEPHASE
  2134.     DEFB    13,27,'MCharacter set',13,10,26
  2135. ;
  2136.     END
  2137.