home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / dskutl / zap35.ark / ZAP35.Z80 < prev   
Encoding:
Text File  |  1986-09-19  |  101.4 KB  |  5,003 lines

  1.     .xlist        ;Moved here to keep .PRN file short for Z8E
  2.     .Z80
  3.     TITLE    SPZ - CP/M DISK UTILITY
  4. ;------------------------------------------------------------------------------
  5. ;
  6. ;    SUPERZAP - A screen-oriented disk editor for CP/M-80
  7. ;
  8. ;    Versions prior to 3.x by Davidson and Sheldrake
  9. ;
  10. ;    Upgraded to CP/M+ operation by:
  11. ;        John Hastwell-Batten,
  12. ;        SYSOP, Tesseract RCPM+,
  13. ;        P.O. Box 242,
  14. ;        Dural, NSW 2158,
  15. ;        AUSTRALIA.
  16. ;
  17. ;    Hopefully, what we have now is a "universal" version that will run
  18. ;    without change under CP/M 2.2 and CP/M 3.1 but since I do not have
  19. ;    a CP/M 2.2 system there is the chance that I have screwed it up.
  20. ;
  21. ;    All of Willie Davidson's code is in upper case.  My changes are easy
  22. ;    to identify because they are in lower case.  JHB.
  23. ;       (.. I changed MOST OF THEM TO UPPER -- TO DISTINGUISH
  24. ;          RECENT ONES I MADE...... PGM.
  25. ;------------------------------------------------------------------------------
  26. ;
  27. ; Update list (most recent first)
  28. ;
  29. ;  3.5    15 Sep 86    John T. Coburn
  30. ;
  31. ;    Fixed 2 bugs in the cursor addressing routines when using ANSI 
  32. ;    terminal addressing. Insured that Row1st byte is a zero or one. 
  33. ;    Setup source to default to ANSI terminal cursor addressing. Set 
  34. ;    Peter's additions to the default case. Setup to be assembled by
  35. ;    most assemblers - the ENTRY pseudoop is conditionalized.
  36. ;
  37. ;
  38. ;  3.4    11-24 Jul 86      Peter G. Martin
  39. ;
  40. ;    Added hex & ascii searches in Edit mode,
  41. ;    random sector/page/line access in Type mode,(rough)
  42. ;    Alternative line-end interpretation for Type
  43. ;    for word-processed ('document') files 
  44. ;
  45. ;
  46. ; 3.3    20 Mar 86    Willie Davidson (mods done by John Hastwell-Batten)
  47. ;
  48. ; -    Incorporated Willie Davidson's updates to the CP/M 2.2 version into
  49. ;    this universal version.
  50. ;
  51. ; 3.2    24 Feb 86    John Hastwell-Batten
  52. ;
  53. ; -    Removed CP/M 3 configuration/implementation dependencies.
  54. ;    SUPERZAP should now run on any CP/M 3 or 2.2 system with a Z80.
  55. ;
  56. ; 3.1    11 Jan 86    John Hastwell-Batten
  57. ;
  58. ; -    Added ability to select user number (very crude).
  59. ; -    Changed default track number to directory track
  60. ; -    Made terminal functions more general and object-patchable.
  61. ;
  62. ; 3.0    9 Jan 86    John Hastwell-Batten
  63. ;
  64. ; -    ASEG and ORG directives added, .LIST and .XLIST directives moved
  65. ;    to simplify use with Z8E debugger.
  66. ; -    Upgraded to be compatible with CP/M 3.1
  67. ; -    Introduced inverse video display of characters with high bit set
  68. ;    to make display of directory sectors more readable
  69. ;
  70. ; 2.1    Willie Davidson and H Sheldrake
  71. ;
  72. ;    Original (as distributed by SIG/M)
  73. ;
  74. ;------------------------------------------------------------------------------
  75.  
  76.     ASEG            ;For Z8E debugger symbol table alignment
  77.     ORG    100H        ;(Just makes it a little easier)
  78.  
  79. ;---------------- Entry point to program -----------------
  80.  
  81.     JP    INIT        ;Now we have to do this ourselves
  82.  
  83. $VER    DEFL    '3'            ;VERSION NUMBER
  84. $MOD    DEFL    '5'            ;MODIFICATION LEVEL  
  85.  
  86.     DB    ' SUPERZAP 3  '        ;DELETED A FEW "BLANK" LINES.
  87.     DB    '  for CP/M 2.2  '    ;SCREEN CONTROLS NOW AT 150H
  88.     DB    '  and CP/M 3.1  '    ;INSTEAD OF 180H -- JHB
  89.     DB    '  W.M.Davidson  '
  90.     DB    '  H.J.Sheldrake '
  91. ;    DB    '18 DEAN PARK CR.'
  92. ;    DB    ' EDINBURGH      '
  93. ;    DB    '        EH4 1PH '
  94. ;    DB    '  SCOTLAND      '
  95.  
  96. ;    CURSOR CHARACTER EQUATES (MUST BE 01H TO 01FH)
  97.  
  98. $LEFT    EQU    013H        ;CURSOR LEFT  IS ^S  
  99. $RIGHT    EQU    004H        ;CURSOR RIGHT IS ^D  
  100. $UP    EQU    005H        ;CURSOR UP    IS ^E  
  101. $DOWN    EQU    018H        ;CURSOR DOWN  IS ^X  
  102. $TAB    EQU    009H        ;CURSOR TAB   IS ^I
  103. $ESC    EQU    01BH        ;ESCAPE          IS ESC
  104. $INSRT    EQU    'V'-040H    ;INSERT          IS ^V
  105. $DELETE EQU    'G'-040H    ;DELETE          IS ^G
  106. $QUIT    EQU    'Q'-040H    ;QUIT EDIT    IS ^Q
  107. $END    EQU    'K'-040H    ;END EDIT     IS ^K  
  108.  
  109. ; SCREEN CONTROL (for ANSI terminals)
  110.  
  111. CLSSTR:    DB    6,1bh,5Bh,48h,1Bh,5Bh,4Ah,0,0    ;CLEAR SCREEN
  112. CLLSTR:    DB    3,1Bh,5Bh,4BH,0,0,0,0,0        ;CLEAR LINE
  113. vInv:    db    4,1Bh,5Bh,37h,6Dh,0,0,0        ;Inverse video
  114. vNorm:    db    3,1Bh,5Bh,6Dh,0,0,0,0        ;Normal video
  115. cpPref:    DB    2,1Bh,5Bh,0,0,0,0,0        ;CURSOR POSITION PREFIX
  116. cpMid:    db    1,3Bh,0,0,0,0,0,0        ;Cursor position infix
  117. cpEnd:    db    1,48h,0,0,0,0,0,0        ;Cursor position suffix
  118. row1st:    db    1            ;1=row first, 0=column first
  119. rowOff:    db    1            ;Offset for row
  120. colOff:    db    1            ;Offset for column
  121. cpBin:    db    0            ;0 for decimal cursor coordinates,
  122.                     ;Non-0 for binary.
  123. maxASC: db    7Eh            ;set to 7dh for stupid hazeltines
  124.  
  125. ;  --- WARNING WARNING WARNING WARNING ---
  126. ; the value of row1st is set to 0 or 1 ( Odd numbers are 1 )
  127.  
  128. FLAGCH: DB    ' '        ;FLAG CHARACTER IN LIST MODE
  129.  
  130. ;  NEW: word processor newline characters for typing of files 
  131. ;   Standard which should be harmless is to have all 'line end' chars
  132. ;   set to 0DH, which is normally handled by the 'hard-wired' code...
  133. ;   This means, you may insert UP TO 2 'soft' codes for those line-ends 
  134. ;   used by your word-processor files which ARE NOT NORMALLY FOLLOWED BY
  135. ;   a LF and 2 'hard' codes for CRs normally followed by LFs such as
  136. ;   Wordstar's 8D 0A combination.
  137. ;                    PGM   24 July 86
  138. ;   DEFAULT FOR ALL FOUR ENTRIES IS 0DH -- SELECT FOR WORD-PROCESSOR YOU USE
  139. ;    OR LEAVE HARMLESS AS 0DH
  140.  
  141. soft1:    db    0dh    ; CHANGE AS YOU WOULD OR LEAVE AS 0DH
  142. soft2:    db    0dh    ; for the default - No Action case
  143. hard1:    db    0dh    ; 
  144. hard2:    db    0dh    ; 
  145.  
  146. SLR_Z80    equ    1    ; Ignore the ENTRY pseudo op
  147.  
  148. ;---------------- MACRO DEFINITIONS
  149. ; NB: macro variables prefix of '#' are preferred for Z80MR macro assembler
  150. ;        --- PGM.
  151.  
  152. ; $RTN - STANDARD ROUTINE ENTRY
  153.  
  154. $RTN    MACRO    $RTNN
  155.     IfNDef    SLR_Z80        ; Z80ASM doesn't allow in Absolute Mode
  156.     ENTRY    $RTNN
  157.     EndIf
  158. $RTNN:    DS    0
  159.     ENDM
  160.  
  161. ; $PANEL - LOAD HL AND DISPLAY PANEL
  162.  
  163. $PANEL    MACRO    $PNLNM
  164.     LD    HL,$PNLNM    ;POINT TO PANEL
  165.     CALL    DPNL        ;DISPLAY IT
  166.     ENDM
  167.  
  168. ; $FLD - LOAD HL AND DISPLAY FIELD
  169.  
  170. $FLD    MACRO    $FLDNM
  171.     LD    HL,$FLDNM
  172.     CALL    DFLD
  173.     ENDM
  174.  
  175. ; $NPANEL - CLEAR SCREEN AND DISPLAY PANEL
  176.  
  177. $NPANEL MACRO    $PNLNM
  178.     CALL    DHDR
  179.     $PANEL    $PNLNM
  180.     ENDM
  181.  
  182. ; $STRO - PRINT STRING AT (HL)
  183.  
  184. $STRO    MACRO    $STRNM
  185.     LD    HL,$STRNM
  186.     CALL    STRO
  187.     ENDM
  188.  
  189. ; $STRL - PRINT STRING AT (HL) WHERE FIRST BYTE IS LENGTH
  190.  
  191. $STRL    MACRO    $STRNM
  192.     LD    HL,$STRNM
  193.     CALL    STRL
  194.     ENDM
  195.  
  196. ; $IFLD - LOAD HL, DISPLAY FIELD, GET AND FOLD INPUT
  197.  
  198. $IFLD    MACRO    $FLDNM
  199.     LD    HL,$FLDNM        ;POINT TO FIELD
  200.     CALL    DFLD            ;DISPLAY IT
  201.     CALL    CHRF            ;GET INPUT
  202.     ENDM
  203.  
  204. ; $MTCH - CALL BYTE MATCHER
  205.  
  206. $MTCH    MACRO    $LST
  207.     LD    HL,$LST
  208.     CALL    MTCH
  209.     ENDM
  210.  
  211. ; $EXVA - EXECUTE VECTORED ACTION
  212.  
  213. $EXVA    MACRO    $LST
  214.     LD    DE,$LST
  215.     CALL    EXVA
  216.     ENDM
  217.  
  218. ; $HEXW - DISPLAY HEX WORD
  219.  
  220. $HEXW    MACRO    $WORD
  221.     LD    HL,($WORD)
  222.     CALL    HEXW
  223.     ENDM
  224.  
  225. ;---------------- GLOBAL EQUATES ----------------
  226.  
  227. CR    EQU    0DH
  228. LF    EQU    0AH
  229. FALSE    EQU    000H
  230. TRUE    EQU    0FFH
  231. CMD    EQU    80H
  232.  
  233. FBUFF    EQU    80H
  234.  
  235. ;Note:    The CP/M2.2-specific version of this program used the default
  236. ;    file I/O buffer at 80H for all disk operations, i.e. for file-
  237. ;    oriented AND physical I/O.  Under CP/M 3.1 this is not tenable
  238. ;    because the BIOS deals with physical sectors rather than 128-
  239. ;    byte "logical" sectors and physical sectors can be much larger
  240. ;    than 128 bytes.
  241. ;
  242. ;    Physical disk I/O for CP/M 3.x now uses an area set aside at
  243. ;    the end of this program, before the scratchpad.     2048 bytes has
  244. ;    been reserved.    That should be enough; I don't know of any
  245. ;    system which supports physical sectors longer than 1024 bytes
  246. ;    but the notes on the WD1797 FDC suggest that 2048 is possible.
  247. ;
  248. ;    JHB    January 1986
  249. ;
  250. ;---------------- CPM SYSTEM CALL CODES
  251.  
  252. CPM    EQU    05H        ;CPM CALL ADDRESS
  253. CONIO    EQU    06H        ;DIRECT CONSOLE I/O
  254. GETVSN    EQU    0Ch        ;Get CP/M version number
  255. RESET    EQU    0DH        ;RESET DISK SYSTEM
  256. SETDEF    EQU    0EH        ;SET DEFAULT DRIVE
  257. OPEN    EQU    0FH        ;OPEN FILE
  258. CLOSE    EQU    10H        ;CLOSE FILE
  259. FNDFST    EQU    11H        ;FIND FIRST DIRECTORY MATCH
  260. FNDNXT    EQU    12H        ;FIND NEXT DIRECTORY MATCH
  261. GETDEF    EQU    19H        ;GET CURRENT DRIVE ID
  262. SDMA    EQU    1Ah        ;Set DMA address (Req'd for CP/M 3.1)
  263. USERNO    EQU    20h        ;GET/SET USER NUMBER
  264. READRN    EQU    21H        ;READ RANDOM RECORD
  265. WRITRN    EQU    22H        ;WRITE RANDOM RECORD
  266. FILESZ    EQU    23H        ;COMPUTE FILE SIZE
  267. SETRN    EQU    24H        ;SET RANDOM RECORD
  268.  
  269. ;---------------- DEFAULT FCB IMAGE
  270.  
  271. WRKFCB    EQU    5CH        ;DEFAULT FCB ADDRESS
  272. WRKDR    EQU    WRKFCB+0    ;DRIVE
  273. WRKFN    EQU    WRKDR+1        ;FILE NAME BODY
  274. WRKFT    EQU    WRKFN+8        ;FILE NAME EXTENSION
  275. WRKEX    EQU    WRKFT+3        ;EXTENT NUMBER
  276. WRKS1    EQU    WRKEX+1        ;CPM RESERVED
  277. WRKS2    EQU    WRKS1+1        ;CPM RESERVED
  278. WRKRC    EQU    WRKS2+1        ;RECORD COUNT THIS EXTENT
  279. WRKMP    EQU    WRKRC+1        ;ALLOCATION MAP FOR EXTENT
  280. WRKNR    EQU    WRKMP+16    ;NEXT SEQUENTIAL RECORD
  281. WRKRR    EQU    WRKNR+1        ;2 BYTE RANDOM RECORD NUMBER
  282. WRKOV    EQU    WRKRR+2        ;RANDOM OVERFLOW FLAG
  283.  
  284. FREESP: DW    ENDCDE        ;ALLOW USER CODE INSERTION
  285.  
  286.  
  287. ;---------------- MESSAGES
  288.  
  289. HLAREA    EQU    0109H        ;HELP    IN LINES 01-10 (01 FOR 09)
  290. DRAREA    EQU    0E08H        ;DIRECTORY LINES 14-21 (14 FOR 08)
  291.  
  292. HDRMSG: DB    0,21,'SUPERZAP version ',$VER,'.',$MOD,0
  293.  
  294. ;---------------- GLOBAL WORK AREAS
  295.  
  296. MEMRY:    DS    2        ;FREE MEMORY SPACE
  297. CPM3:    DS    1        ;CP/M 3 flag
  298. READST: DB    0FFH        ;RETURN CODE FROM READ OPERATIONS
  299. INCH:    DB    0        ;INPUT CHARACTER
  300. TYCURC: DB    0        ;CURRENT CHARACTER FOR TYPE
  301. RELREC: DW    0        ;CURRENT RECORD NUMBER
  302. BUFPOS: DS    1
  303. linesc: ds    2        ; line count for type display
  304. BASEAD: DS    3
  305. SAVREC: DW    0        ;SAVE RECORD DURING SET
  306. SAVFSC: DW    0        ;RECORD TO BE READ
  307. RO:    DB    0        ;READ ONLY FILE FILE
  308. NEWDE@: DS    2        ;ADDRESS OF ENTRY JUST FOUND
  309. NXTDE@: DS    2        ;NEXT POSITION IN TABLE
  310. TOPDE@: DW    0        ;TOP OF DIRECTORY TABLE
  311. FSTDE@: DW    0        ;BOTTOM OF DIRECTORY TABLE
  312. DECNT:    DB    0        ;NUMBER OF ENTRIES READ
  313. PRTCNT: DB    0        ;NUMBER OF ENTRIES DISPLAYED
  314. PRTENT: DB    0        ;ENTRY NUMBER TO BE PRINTED
  315. SELDE:    DS    1        ;SELECTED DIRECTORY ENTRY
  316. DIROFF: DB    0        ;DIRECTORY DISPLAY OFFSET
  317. DEFDRV: DS    1        ;CURRENT DRIVE ID
  318. REQDRV: DS    1        ;REQUIRED DRIVE ID
  319. CURAN:    DS    1        ;CURRENT ABSOLUTE DRIVE NUMBER
  320. ERRFLD: DW    0        ;ERROR FIELD ON SCREEN
  321.     DB    0        ;END OF FIELD MARK
  322. ERRTXT: DW    0        ;ADDRESS EOF ERROR TEXT
  323. PRVERR: DW    0        ;ADDRESS OF PREVIOUS TEXT
  324. WTG:    DB    0        ;NEXT PROCESS MODE
  325. AFNSTR: DB    '???????????'
  326. DSKCMD: DB    'DSK:'
  327. PGEPTR: DS    2        ;ADDRESS OF PAGE POINTER LIST
  328. CURPG@: DS    2        ;ADDRESS OF CURRENT PAGE ENTRY
  329. MAXPG@: DS    2        ;ADDRESS OF LAST PAGE ENTRY
  330. RPANEL: DS    1        ;DISPLAY PANEL REQUEST
  331.  
  332. ; SCRATCHPAD DATA
  333.  
  334. SPADDR: DS    2        ;SCRATCHPAD BUFFER ADDRESS
  335. SPTYPE: DS    1        ;NONE/PHYSICAL/RELATIVE
  336. SPSECT: DS    2        ;SECTOR NUMBER
  337. SPDRIV: DS    1        ;ABSOLUTE DRIVE NUMBER
  338. SPNAME: DS    12        ;UFN OR TRACK NUMBER
  339.     DB    0        ;END OF FIELD MARK
  340. SPDMSG: DB    'Drive ',0
  341. SPTMSG: DB    ' Track ',0
  342. SPSMSG: DB    ' Sector ',0
  343. SPEMTY: DB    'Empty',0
  344.  
  345. ;---------------- LIST MODE FCB
  346.  
  347. LMDFCB    EQU    $
  348.  
  349. LMDDR:    DB    0        ;DRIVE
  350. LMDFN:    DS    8        ;FILE NAME
  351. LMDFT:    DS    3        ;FILE TYPE
  352. LMDEX:    DB    0        ;EXTENT NUMBER
  353. LMDS1:    DB    0
  354. LMDS2:    DB    0
  355. LMDRC:    DB    0        ;RECORD COUNT
  356. LMDD0:    DS    16        ;CLUSTER ALLOC MAP
  357. LMDCR:    DB    0        ;CURRENT RECORD
  358.  
  359. ; LOCAL BIOS COPY - USED TO SIMPLIFY DIRECT BIOS CALLS
  360.  
  361. LBIOS    EQU    $        ;START OF LOCAL BIOS
  362.  
  363. WBOOT:    CALL    BIOS3        ;For CP/M3 we make all of these
  364. CONST:    CALL    BIOS3        ;branch to the same place.  From
  365. CONIN:    CALL    BIOS3        ;there we will do a "Come From"
  366. CONOUT: CALL    BIOS3        ;statement to figure out which
  367. LIST:    CALL    BIOS3        ;routine was called.
  368. PUNCH:    CALL    BIOS3
  369. READER: CALL    BIOS3        ;For CP/M 2.2 these CALLs will
  370. HOME:    CALL    BIOS3        ;be overlaid with a copy of the
  371. SELDSK: CALL    BIOS3        ;JP table at the beginning of
  372. SETTRK: CALL    BIOS3        ;the BIOS.
  373. SETSEC: CALL    BIOS3
  374. SETDMA: CALL    BIOS3        ;JHB - January 1986
  375. READ:    CALL    BIOS3
  376. WRITE:    CALL    BIOS3
  377. LISTST: CALL    BIOS3
  378. SECTRN: CALL    BIOS3
  379.  
  380. ; Note that the entire CP/M 3.x BIOS table is not represented here.
  381.  
  382. ELBIOS    EQU    $        ;END OF LOCAL BIOS
  383.  
  384. ; INIT - SPZ INITIALISATION
  385.  
  386.     $RTN    INIT
  387.     LD    HL,(6)
  388.     LD    L,0        ;Don't interfere with any RSXs
  389.     LD    SP,HL        ;SET STACK TO BASE OF BDOS
  390.  
  391.     ld    a,(row1st)    ; Insure that Row1st 
  392.     and    1        ;  is a 1 or 0
  393.     ld    (row1st),a
  394.  
  395.     LD    C,GETVSN    ;Test CP/M version.  Set
  396.     CALL    CPM        ;'cpm3' to zero if 2.x
  397.     LD    A,2FH        ;or to 1 if 3.x
  398.     SUB    L
  399.     LD    A,H        ;Pull in MP/M flag too
  400.     JR    NC,NOTPLUS
  401.     INC    A
  402. NOTPLUS:
  403.     LD    (CPM3),A    ;Zero if CP/M 2.x, Non-zero if MP/M or CP/M 3.x
  404.     OR    A        ;Only copy BIOS vector if CP/M 2.x
  405.     JR    NZ,NOLOCAL
  406.     LD    HL,(1)        ;LOAD BIOS VECTOR ADDRESS
  407.     LD    DE,LBIOS
  408.     LD    BC,ELBIOS-LBIOS
  409.     LDIR            ;SET UP LOCAL BIOS VECTOR
  410. NOLOCAL:
  411.     LD    HL,AFNSTR
  412.     CALL    LSEL        ;SET LIST SELECTION TO ALL
  413.     LD    HL,(FREESP)    ;FIND TOP OF PROG
  414.     LD    (SPADDR),HL    ;SET SCRATCHPAD ADDRESS
  415.     LD    DE,080H
  416.     ADD    HL,DE        
  417.     LD    (MEMRY),HL    ;PUT WORK AREA ABOVE SCRATCHPAD
  418.     XOR    A
  419.     LD    (SPTYPE),A    ;SET SCRATCHPAD EMPTY
  420.     LD    HL,0
  421.     LD    (ERRTXT),HL    ;CLEAR ERROR MESSAGE FIELD
  422.     LD    (PRVERR),HL    ;AND PREVIOUS ERROR
  423.     LD    C,GETDEF
  424.     CALL    CPM        ;GET DEFAULT DRIVE NUMBER
  425.     LD    (DEFDRV),A    ;SAVE IT
  426.     LD    (CURAN),A    ;SET CURRENT ABSOLUTE DISK NUMBER
  427.     LD    A,(WRKDR)
  428.     OR    A
  429.     JR    Z,INIT01    ;IF DRIVE ID IN COMMAND
  430.     DEC    A
  431.     LD    (CURAN),A    ;USE THAT AS CURRENT
  432. INIT01    EQU    $        ;ENDIF
  433.     LD    HL,CMD        ;POINT TO COMMAND AREA
  434. INIT02    EQU    $        ;LOOP
  435.     INC    HL
  436.     LD    A,(HL)
  437.     OR    A
  438.     JR    Z,INIT05    ;QUIT IF END OF COMMAND
  439.     CP    ' '
  440.     JR    Z,INIT02    ;IGNORE SPACES
  441.     INC    HL
  442.     LD    A,(HL)
  443.     CP    ':'        
  444.     JR    NZ,INIT03    ;IF CMD IS DRIVE ID
  445.     INC    HL        ;SKIP PAST IT
  446.     JR    INIT04
  447. INIT03    EQU    $        ;ELSE
  448.     DEC    HL        ;POINT TO FIRST CHARACTER
  449. INIT04    EQU    $        ;ENDIF
  450.     LD    DE,DSKCMD
  451.     LD    BC,4
  452.     CALL    CPST
  453.     JR    NZ,INIT05    ;IF DISK OPTION
  454.     CALL    SETP        ;SET DISK MODE
  455.     JR    INIT06
  456. INIT05    EQU    $        ;ELSE
  457.     CALL    SETD        ;ASSUME DIRECTORY MODE
  458.     LD    HL,WRKFN
  459.     LD    A,(HL)
  460.     CP    ' '
  461.     JR    Z,INIT08    ;IF NOT NULL OPTION
  462.     LD    B,11
  463. INIT09    EQU    $        ;LOOP
  464.     LD    A,(HL)
  465.     CP    '?'
  466.     JR    Z,INIT10    ;EXIT IF AFN INDICATED
  467.     INC    HL
  468.     DJNZ    INIT09        ;TILL FN AND FT SCANNED
  469.     CALL    SETF        ;MUST BE UFN
  470.     JR    INIT12
  471. INIT10    EQU    $        ;ON '?' FOUND
  472.     LD    HL,WRKFN
  473.     CALL    LSEL        ;SET LIST SELECTION TO AFN GIVEN
  474. INIT12    EQU    $        ;ENDIF
  475. INIT08    EQU    $        ;ENDIF
  476. INIT06    EQU    $        ;ENDIF
  477.     LD    A,(CURAN)    
  478.     CALL    CHDR        ;INITIALISE DISK CONTROL BLOCKS
  479.     JR    NZ,INIT13    ;IF ILLEGAL DISK
  480.     LD    A,(DEFDRV)
  481.     CALL    CHDR        ;USE DEFAULT DISK
  482.     LD    HL,ILDMSG
  483.     LD    (ERRTXT),HL    ;SET ERROR MESSAGE
  484. INIT13    EQU    $
  485.  
  486. ; MAIN - SPZ MAINLINE
  487.  
  488.     $RTN    MAIN
  489. MAIN01    EQU    $        ;LOOP
  490.     LD    A,(WTG)
  491.     $MTCH    MAINLS        ;TEST CODE
  492.     JR    NZ,MAIN02    ;IF INVALID ACTION EXIT
  493.     $EXVA    MAINVC        ;EXEC ACTION
  494.     JR    MAIN01
  495. MAIN02    EQU    $        ;ENDLOOP
  496.     CALL    CLRS
  497.     LD    A,(DEFDRV)
  498.     LD    E,A
  499.     LD    C,SETDEF
  500.     CALL    CPM        ;RESTORE ORIGINAL DEFAULT
  501.     LD    C,RESET        ;Reset disk system
  502.     CALL    CPM
  503.     JP    0        ;EXIT TO SYSTEM
  504.  
  505. ILDMSG: DB    '** Invalid Disk Specified',0
  506.  
  507. ; MAINLINE ACTION VECTOR
  508.  
  509. MAINLS: DB    4,'XFDP'
  510. MAINVC    EQU    $
  511.     DW    ENDR        ;END RUN
  512.     DW    FDMD        ;FILE DISPLAY MODE
  513.     DW    DRMD        ;DIRECTORY MODE
  514.     DW    PSMD        ;PHYSICAL SECTOR MODE
  515.  
  516.  
  517. ; ENDR - END SPZ RUN
  518.  
  519.     $RTN    ENDR
  520.     XOR    A
  521.     LD    (WTG),A
  522.     RET
  523.  
  524.  
  525. ; FDMD - FILE DISPLAY MODE
  526.  
  527.     $RTN    FDMD
  528.     LD    HL,(FDMDER)
  529.     LD    (ERRFLD),HL    ;SET ERROR FIELD POINTER
  530.     LD    A,0FFH
  531.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  532.     LD    (RPANEL),A    ;REQUEST PANEL DISPLAY
  533.     CALL    TFLE
  534.     LD    A,(FLERR)
  535.     OR    A
  536.     JR    Z,FDMD03    ;IF FILE ERROR
  537.     CALL    SETD        ;SET DIRECTORY MODE
  538.     JP    FDMD04
  539. FDMD03    EQU    $        ;ELSE
  540. FDMD05    EQU    $        ;LOOP
  541.     LD    A,(RPANEL)
  542.     OR    A
  543.     JR    Z,FDMD11    ;IF PANEL REQUIRED
  544.     XOR    A
  545.     LD    (RPANEL),A    ;RESET REQUEST
  546.     $NPANEL FDMDPN        ;DISPLAY FILE MODE PANEL
  547.     LD    HL,FILEMS    ;POINT TO FILE MESSAGE
  548.     LD    A,(COMFLG)
  549.     OR    A
  550.     JR    Z,FDMD09    ;IF .COM FILE
  551.     LD    HL,LOADMS    ;POINT TO LOAD MESSAGE
  552. FDMD09    EQU    $        ;ENDIF
  553.     CALL    DFLD
  554.     $FLD    FSPMSG
  555.     CALL    DSPI        ;DISPLAY SCRATCHPAD INFO
  556.     ld    a,8        ; new display clear -- pgm 
  557.     call    CLRL        ;  "     "
  558. FDMD11    EQU    $        ;ENDIF
  559.     CALL    ERRP        ;PROCESS ERRORS
  560.     LD    A,(FDMDSI)
  561.     OR    A
  562.     JR    Z,FDMD10    ;IF SI DISPLAY REQUIRED
  563.     CALL    DFSI        ;DISPLAY FILE SECTOR INFO
  564.     LD    HL,FBUFF
  565.     CALL    WRBF        ;DISPLAY BUFFER CONTENTS
  566.     XOR    A
  567.     LD    (FDMDSI),A    ;RESET REQUEST
  568. FDMD10    EQU    $        ;ENDIF
  569. FDMD07    EQU    $        ;LOOP
  570.     $IFLD    SELMSG        ;PROMPT SELMSG AND GET COMMAND
  571.     $MTCH    FDMDLS
  572.     JR    Z,FDMD06    ;EXITIF VALID
  573.     CALL    ALRM        ;SOUND THE ALARM
  574.     JR    FDMD07
  575. FDMD06    EQU    $        ;ENDLOOP
  576.     $EXVA    FDMDVC
  577.     LD    A,(WTG)
  578.     CP    'F'
  579.     JR    NZ,FDMD08    ;EXIT IF MODE NO LONGER F
  580.     JP    FDMD05
  581. FDMD08    EQU    $        ;ENDLOOP
  582.     LD    C,CLOSE
  583.     LD    DE,WRKFCB
  584.     CALL    CPM
  585. FDMD04    EQU    $        ;ENDIF
  586.     RET
  587.  
  588. COMSTR: DB    'COM'        ;.COM FILE TYPE
  589.  
  590.  
  591. ; FILE DISPLAY MODE MESSAGES, PANEL AND ACTION VECTOR
  592. ;     -- under mod 4, july 86, new options added... PGM.
  593.  
  594. SELMSG: DB    9,10,'Select Function ===> ',00
  595. SETMSG: DB    11,36,'Enter Hex Sector',0    ;OVERLAID BY CURMSG
  596. FDMDER: DB    7,0                ;ERROR POSITION
  597. FILEMS: DB    11,53,'File Offset ',0
  598. LOADMS: DB    11,53,'Load Address',0
  599.  
  600. FDMDPN: db    16                ;field count
  601.     DB    02,00,'N  Next sector',0
  602.     DB    03,00,'P  Previous sector',0
  603.     DB    02,22,'T  Top of file',0
  604.     DB    03,22,'E  Last sector of file',0
  605.     DB    02,54,'Z  Exit from Superzap',0
  606.     DB    03,54,'L  Exit to file list',0
  607.     DB    04,00,'C  Change Sector',0
  608.     DB    04,22,'S  Select Sector',0
  609.     DB    04,54,'X  Scratchpad operations',0
  610.     db    05,00,'A  Find ASCII string',0    ; new one
  611.     db    05,22,'H  Find HEX sequence',0    ; new one
  612.     DB    11,04,'File-Name',0
  613.     DB    11,16,'Access',0
  614. CURMSG: DB    11,36,'Current-Sector  ',0    ;OVERLAID BY SETMSG
  615. FILE:    DB    12,00
  616. DRIVNM: DB    'd:'
  617. FILENM: DB    'filename.typ',0
  618.     DB    12,17,'R/'
  619. FDMDRS: DB    's ',0                ;ACCESS INDICATOR
  620. FSPMSG: DB    06,00,'Scratchpad :- ',0
  621.  
  622.  
  623. fndpmt: db    08,00,'Find :',$TAB,0      ; new 
  624. strpos: db    08,08              ; new
  625. notfnd: db    08,00,'NOT FOUND - HIT <T> FOR START ',0  ; new
  626. fndcon: db    13,64,'NEXT (Y/N) ? ',0      ; new
  627.  
  628. ; FILE STATISTICS FIELDS
  629.  
  630. WRSNFL: DB    12,41,0
  631. WRFOFL: DB    12,55,0
  632. SFSNIP: DB    12,45,0
  633.  
  634. FDMDLS: db    11,'NPTEZLCSXAH'    ; new extra options added ...PGM.
  635. FDMDVC    EQU    $
  636.     dw    NXFS        ;NEXT FILE SECTOR
  637.     dw    PRFS        ;PREVIOUS FILE SECTOR
  638.     dw    FRFS        ;POSITION TO FIRST FILE SECTOR
  639.     dw    LSFS        ;POSITION TO LAST FILE SECTOR
  640.     dw    SETX        ;SET EXIT MODE
  641.     dw    SETD        ;SELECT DIRECTORY MODE
  642.     dw    FSCH        ;FILE SECTOR CHANGE
  643.     dw    SFSN        ;SET FILE SECTOR NUMBER
  644.     dw    FSPM        ;SCRATCHPAD MANAGER
  645.     dw    fasc        ; find ascii string  ; new
  646.     dw    fhex        ; find hex sequence  ; new
  647.  
  648. FDMDSI: DS    1        ;SI REQUEST FLAG
  649.  
  650. ; NXFS - READ NEXT FILE SECTOR
  651.  
  652. ; Maybe it's just my caution or lack of complete comprehension
  653. ;  of all of the code, but I DO think we could do with a deal
  654. ;  more of register-preservation in many routines....pgm.
  655.  
  656.     $RTN    NXFS
  657.     push    de        ; new -- save some registers
  658.     LD    HL,(RELREC)
  659.     INC    HL
  660.     LD    (RELREC),HL    ;INCREMENT RECORD NUMBER
  661.     CALL    RDFS        ;ATTEMPT TO READ RECORD
  662.     push    af        ; <= save file status (new)
  663.     JR    NZ,NXFS02    ;IF GOOD READ
  664.     LD    A,TRUE
  665.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  666.     JR    NXFS01
  667. NXFS02    EQU    $        ;ELSE
  668.     CALL    ALRM        ;SOUND ALARM
  669. NXFS01    EQU    $        ;ENDIF
  670.     pop    af        ; new -- return file status in A
  671.     pop    de        ; new
  672.     RET
  673.  
  674.  
  675. ; PRFS - READ PREVIOUS FILE SECTOR
  676.  
  677.     $RTN    PRFS
  678.     LD    HL,(RELREC)
  679.     LD    A,H
  680.     OR    L
  681.     JR    NZ,PRFS01    ;IF RECORD ZERO
  682.     CALL    ALRM        ;SOUND ALARM
  683.     JR    PRFS02
  684. PRFS01    EQU    $
  685.     DEC    HL
  686.     LD    (RELREC),HL    ;DECREMENT RECORD POINTER
  687.     CALL    RDFS        ;ATTEMPT TO READ IT
  688.     JR    NZ,PRFS03    ;IF GOOD READ
  689.     LD    A,TRUE
  690.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  691.     JP    PRFS04
  692. PRFS03    EQU    $        ;ELSE
  693.     CALL    ALRM        ;SOUND ALARM
  694. PRFS04    EQU    $        ;ENDIF
  695. PRFS02    EQU    $        ;ENDIF
  696.     RET
  697.  
  698.  
  699. ; FSCH - FILE SECTOR CHANGE
  700.  
  701.     $RTN    FSCH
  702.     LD    A,(RO)
  703.     OR    A
  704.     JR    Z,FSCH01    ;IF READ ONLY FILE
  705.     CALL    ALRM        ;SOUND THE ALARM
  706.     JR    FSCH02
  707. FSCH01    EQU    $        ;ELSE
  708.     CALL    SCCH        ;GO INTO SECTOR CHANGE MODE
  709.     LD    A,(SCCHWR)
  710.     OR    A
  711.     JR    Z,FSCH03    ;IF WRITE REQUIRED
  712.     CALL    WRFS        ;WRITE OUT SECTOR
  713.     JR    FSCH04
  714. FSCH03    EQU    $        ;ELSE
  715.     CALL    RDFS        ;READ SECTOR
  716. FSCH04    EQU    $        ;ENDIF
  717.     LD    A,TRUE
  718.     LD    (RPANEL),A    ;REDISPLAY FILE MODE PANEL
  719.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  720. FSCH02    EQU    $        ;ENDIF
  721.     RET            
  722.  
  723. ; FRFS - POSITION TO FIRST FILE SECTOR
  724.  
  725.     $RTN    FRFS
  726.     LD    HL,0
  727.     LD    (RELREC),HL
  728.     CALL    RDFS        ;READ THE SECTOR
  729.     LD    A,TRUE
  730.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  731.     RET
  732.  
  733. ; LSFS - POSITION TO LAST FILE SECTOR
  734.  
  735.     $RTN    LSFS
  736.     LD    DE,WRKFCB
  737.     LD    C,FILESZ    ;COMPUTE FILE SIZE
  738.     CALL    CPM
  739.     LD    HL,(WRKRR)
  740.     DEC    HL
  741.     LD    (RELREC),HL    ;SET UP RECORD TO READ
  742.     CALL    RDFS        ;READ THE RECORD
  743.     LD    A,TRUE
  744.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  745.     RET
  746.  
  747. ; SFSN - SET FILE SECTOR NUMBER
  748.  
  749.     $RTN    SFSN
  750.     LD    HL,SELMSG
  751.     CALL    CFLD        ;CLEAR FUNCTION PROMPT
  752.     LD    HL,(RELREC)
  753.     LD    (SAVREC),HL    ;SAVE RECORD NUMBER
  754.     $FLD    SETMSG        ;DISPLAY SET MESSAGE
  755.     LD    HL,0
  756.     LD    (RELREC),HL    ;ZERO RECORD NUMBER
  757. SFSN01    EQU    $
  758.     CALL    DFSI        ;DISPLAY FILE SECTOR INFO
  759.     $IFLD    SFSNIP        ;POSITION AND GET INPUT
  760.     $MTCH    HEXCHR
  761.     JR    NZ,SFSN02    ;IF VALID
  762.     EX    DE,HL        ;DIGIT TO DE
  763.     LD    HL,(RELREC)
  764.     CALL    H16D        ;HL=HL*16+DIGIT
  765.     LD    (RELREC),HL    ;SAVE NEW RECORD NUMBER
  766.     JR    SFSN03
  767. SFSN02    EQU    $
  768.     CP    $ESC
  769.     JR    NZ,SFSN04    ;ELSE IF ESC
  770.     LD    HL,(SAVREC)
  771.     LD    (RELREC),HL    ;RESTORE SECTOR NUMBER
  772.     JR    SFSN03
  773. SFSN04    EQU    $
  774.     CP    $LEFT
  775.     JR    NZ,SFSN06    ;ELSE IF BACKSPACE
  776.     LD    HL,RELREC+1
  777.     XOR    A
  778.     RRD
  779.     DEC    HL
  780.     RRD            ;RELREC=RELREC/16
  781.     JR    SFSN03
  782. SFSN06    EQU    $
  783.     CP    CR
  784.     JR    NZ,SFSN07    ;ELSE IF C/R
  785.     CALL    RDFS        ;READ SECTOR
  786.     JR    Z,SFSN08    ;IF BAD READ
  787.     CALL    ALRM        ;SOUND THE ALARM
  788.     XOR    A
  789.     LD    (INCH),A    ;DONT EXIT
  790. SFSN08    EQU    $        ;ENDIF
  791.     JR    SFSN03
  792. SFSN07    EQU    $        ;ELSE 
  793.     CALL    ALRM        ;ERROR
  794. SFSN03    EQU    $
  795.     LD    A,(INCH)
  796.     CP    CR
  797.     JR    Z,SFSN99    ;EXITIF C/R
  798.     CP    $ESC
  799.     JR    Z,SFSN99    ;OR ESC
  800.     JP    SFSN01
  801. SFSN99    EQU    $        ;ENDLOOP
  802.     $FLD    CURMSG        ;REDISPLAY CURRENT SECTOR MESSAGE
  803.     LD    A,TRUE
  804.     LD    (FDMDSI),A    ;REQUEST DISPLAY
  805.     RET
  806.  
  807. ; FSPM - FILE SCRATCHPAD MODE
  808.  
  809.     $RTN    FSPM
  810.     $NPANEL PSPMPN        ;DISPLAY PANEL
  811.     $FLD    PSPCUR        ;POSITION FOR CURRENT INFO
  812.     LD    A,(CURAN)
  813.     ADD    A,41H
  814.     CALL    CHRO        ;DISPLAY DRIVE
  815.     LD    A,':'
  816.     CALL    CHRO
  817.     $STRO    FILENM
  818.     $STRO    SPSMSG
  819.     $HEXW    RELREC        ;SECTOR
  820.     $FLD    PSPSPD        ;POSITION FOR S/P DATA
  821.     CALL    DSPD        ;DISPLAY SCRATCHPAD DATA
  822.     CALL    SPCI        ;GET COMMAND
  823.     $EXVA    FSPMV        ;PROCESS COMMAND
  824.     LD    A,0FFH
  825.     LD    (RPANEL),A    ;REQUEST PANEL
  826.     LD    (FDMDSI),A    ;REQUEST SECTOR INFO
  827.     RET
  828.  
  829. FSPMV:    DW    FSPX
  830.     DW    FLSP
  831.     DW    FXSP
  832.  
  833.     $RTN    FSPX
  834.     RET
  835.  
  836. ; SPCI - GET SCRATCHPAD COMMAND
  837.  
  838.     $RTN    SPCI
  839. SPCI01    EQU    $        ;LOOP
  840.     $IFLD    SELMSG        ;GET COMMAND
  841.     $MTCH    PSPML
  842.     JR    Z,SPCI02    ;EXIT IF VALID
  843.     CALL    ALRM        ;SOUND ALARM
  844.     JR    SPCI01
  845. SPCI02    EQU    $        ;ENDLOOP
  846.     RET
  847.  
  848. ; DSPI - DISPLAY S/P INFO
  849.  
  850.     $RTN    DSPI
  851.     LD    A,(SPTYPE)
  852.     OR    A
  853.     JR    NZ,DSPI01    ;IF EMPTY
  854.     $STRO    SPEMTY
  855.     JR    DSPI02
  856. DSPI01    EQU    $
  857.     DEC    A
  858.     JR    NZ,DSPI03    ;ELSE IF PHYSICAL
  859.     $STRO    SPDMSG
  860.     LD    A,(SPDRIV)
  861.     ADD    A,41H
  862.     CALL    CHRO        ;DISPLAY DRIVE
  863.     $STRO    SPTMSG
  864.     $HEXW    SPNAME        ;TRACK
  865.     $STRO    SPSMSG
  866.     $HEXW    SPSECT        ;SECTOR
  867.     JR    DSPI02
  868. DSPI03    EQU    $        ;ELSE FILE RELATIVE
  869.     LD    A,(SPDRIV)
  870.     ADD    A,041H
  871.     CALL    CHRO
  872.     LD    A,':'
  873.     CALL    CHRO
  874.     $STRO    SPNAME        ;DISPLAY FILE NAME
  875.     $STRO    SPSMSG
  876.     $HEXW    SPSECT        ;AND SECTOR
  877. DSPI02    EQU    $        ;ENDIF
  878.     RET
  879.  
  880.  
  881. ; FXSP - EXCHANGE WITH SCRATCHPAD
  882.  
  883.     $RTN    FXSP
  884.     LD    A,(SPTYPE)
  885.     OR    A
  886.     JR    NZ,FXSP01    ;IF PAD EMPTY
  887.     CALL    ALRM        ;RING BELL
  888.     JR    FXSP02
  889. FXSP01    EQU    $        ;ELSE
  890.     LD    A,(RO)
  891.     OR    A
  892.     JR    Z,FXSP03    ;IF READ ONLY
  893.     CALL    ALRM        ;ERROR
  894.     JR    FXSP04        ;ELSE
  895. FXSP03    EQU    $
  896.     LD    BC,(SPADDR)
  897.     CALL    DMASET        ;SET CPM BUFFER
  898.     CALL    WRFS        ;WRITE BUFFER
  899.     LD    BC,FBUFF
  900.     CALL    DMASET        ;RESTORE DMA
  901.     CALL    FLSP        ;COPY OLD BUFFER
  902.     CALL    RDFS        ;RE READ SECTOR
  903. FXSP04    EQU    $        ;ENDIF
  904. FXSP02    EQU    $        ;ENDIF
  905.     RET
  906.  
  907. ; FLSP - LOAD SCRATCHPAD (LOGICAL)
  908.  
  909.     $RTN    FLSP
  910.     LD    HL,FBUFF
  911.     LD    DE,(SPADDR)
  912.     LD    BC,128
  913.     LDIR            ;COPY THE BUFFER
  914.     LD    A,(CURAN)
  915.     LD    (SPDRIV),A    ;SET DRIV
  916.     LD    HL,FILENM
  917.     LD    DE,SPNAME
  918.     LD    BC,12
  919.     LDIR            ;COPY FILE NAME
  920.     LD    HL,(RELREC)
  921.     LD    (SPSECT),HL
  922.     LD    A,2
  923.     LD    (SPTYPE),A    ;SET THE TYPE
  924.     RET
  925.  
  926. ; DFSI - DISPLAY FILE SECTOR INFORMATION
  927.  
  928.     $RTN    DFSI
  929.     $FLD    WRSNFL        ;POSITION FOR SECTOR NUMBER
  930.     $HEXW    RELREC        ;DISPLAY RECORD NUMBER
  931.     $FLD    WRFOFL        ;POSITION FOR FILE OFFSET
  932.     LD    HL,(RELREC)    ;GET REC NO
  933.     XOR    A
  934.     SRL    H
  935.     RR    L
  936.     RRA
  937.     LD    (BASEAD+2),A
  938.     LD    A,(COMFLG)
  939.     OR    A
  940.     JR    Z,DFSI01    ;IF .COM FLAG
  941.     INC    HL
  942. DFSI01    EQU    $        ;ENDIF
  943.     LD    (BASEAD),HL    ;SAVE REC/2
  944.     CALL    PRTADR        ;PRINT 3 BYTE ADDRESS
  945.     RET
  946.  
  947. COMFLG: DS    1        
  948.  
  949. ;    New Section
  950. ;
  951. pattrn: ds    21    ; 20 bytes ought to be enough ?
  952. lasthl: ds    2    ; pointers for last 'lead' byte found
  953. lastbc: ds    2    ;
  954. prevhl: ds    2    ; pointers to find in earlier sector
  955. prevbc: ds    2    ;
  956. oerlap: db    0    ; pattrn overlaps buffers flag
  957. curch:    ds    1    ; byte storage
  958. lsflg:    ds    1
  959. curct:    ds    1
  960. cuhx:    ds    1
  961. nib:    ds    1
  962. fndmk:    db    2,'->'
  963.  
  964. ; FASC    -- GET ASCII PATTERN FOR SEARCH, FIND AND DISPLAY IT.
  965.  
  966.     $RTN    fasc
  967.     ld    a,0ffh
  968.     ld    (ascii),a
  969.     call    asin    ; < = prompt, get and check ascii pattrn
  970.             ; and leave it in pattrn, null terminated.
  971.     call    find    ;  go find it, display it etc.
  972.     ret
  973.  
  974. ; FIND -- search for and display with pointers all instances of hex
  975. ;   or ascii patterns in object file.  Prompts for continuation, and
  976. ;   continues if requested to end of file. Ends on display of end of 
  977. ;   file, last sector accessed, or top of file
  978.  
  979.  
  980.     $RTN    find
  981.     ld    a,(afncnt)
  982.     or    a
  983.     jp    z,cpout
  984. top    equ    $
  985.     xor    a        ; clear indicator of sector overlap
  986.     ld    (oerlap),a
  987.     ld    hl,fbuff
  988.     ld    bc,0080h
  989.     ld    (lasthl),hl
  990.     ld    (lastbc),bc
  991.     ld    (prevhl),hl    ; storage for when we cross
  992.     ld    (prevhl),bc    ; sector boundaries
  993. topres    equ    $
  994.     ld    a,0ffh        ; signal not lone last byte
  995.     ld    (lsflg),a
  996.     ld    hl,(lasthl)
  997.     ld    bc,(lastbc)
  998. topccp    equ    $
  999.     ld    a,(afncnt)
  1000.     ld    (curct),a
  1001.     ld    de,pattrn    ; get and look for 1st byte
  1002.     ld    a,(de)
  1003.     cpir
  1004.     jp    po,cplast    ; if not overrun 
  1005.     ld    (lasthl),hl    ; save pointers
  1006.     ld    (lastbc),bc
  1007.  
  1008. cprest    equ    $        ; check tail
  1009.     call    DCCT        ; next byte -- end of search pattern ?
  1010.     jr    z,cpfnd        ; yes -- go display find.
  1011.     dec    c        ;  else are we at buffer end 
  1012.     jp    m,nbbitf    ; yes 
  1013.     cp    (hl)        ; no -- continue checking pattrn
  1014.     jr    nz,topres    ; failed -- restart search
  1015.     inc    hl        ; otherwise --    next buffer byte
  1016.     jr    cprest        ; and loop
  1017.  
  1018. cplast    equ    $        ; was it a find on last byte
  1019.     jr    z,cplfnd    ; if not found on last byte
  1020.     call    nxfs        ;     get another sector
  1021.     jp    nz,cp99        ;    aborting if none available
  1022.     jp    top        ;    or looping if one is
  1023.  
  1024. cplfnd    equ    $        ; else 
  1025.     ld    (lasthl),hl    ; save these for screen
  1026.     ld    (lastbc),bc
  1027.     call    DCCT        ;  reached end ?
  1028.     jp    nz,nbbitf    ; if only byte in pattern
  1029.     ld    a,c        ;  and it's at end of buffer
  1030.     ld    (lsflg),a    ; signal with c=0=lsflg and show it
  1031.     jp    cpfnd        ; endif
  1032.  
  1033. nbbitf    equ    $        ; We found a bit, but reached end of sector
  1034.     ld    (curch),a    ; save current byte
  1035.     ld    a,c        ; use BC value as flag to show
  1036.     ld    (lsflg),a    ; whether found pattrn at very end
  1037.     ld    hl,(lasthl)
  1038.     ld    (prevhl),hl
  1039.     ld    bc,(lastbc)
  1040.     ld    (prevbc),bc    ; save pointers for progress point
  1041.     ld    a,0ffh
  1042.     ld    (oerlap),a    ; flagging that we have overlapped
  1043. nbbit0    equ    $
  1044.     call    nxfs        ; get/check next sector
  1045.     jp    nz,cp99        ; reached eof -- exit 
  1046.     ld    hl,fbuff    ; point to start of next sector
  1047.     ld    bc,80h
  1048.     ld    a,(curch)      ; restore byte
  1049. nbbit1    equ    $
  1050.     cp    (hl)
  1051.     jr    nz,nbunf    ; if found,
  1052.     call    DCCT        ;   keep checking
  1053.     jr    z,cpfnd
  1054.     inc    hl
  1055.     jr    nbbit1
  1056.  
  1057. nbunf    equ    $        ; tried the overlap, but no match..
  1058.     ld    a,(lsflg)    ; was it on last byte anyway ?
  1059.     or    a        ; if so, loop
  1060.     jp    z,top        ; if not last byte
  1061.     call    prfs        ;    go back a sector
  1062.     xor    a        ;    establish we're back
  1063.     ld    (oerlap),a
  1064.     ld    hl,(prevhl)    ; restore the sector's pointers
  1065.     ld    bc,(prevbc)
  1066.     jp    topccp        ; and continue search on 1st sector
  1067.  
  1068. cpfnd    equ    $        ; we found something
  1069.     ld    bc,(lastbc)    ; well get a pointer anyway
  1070.     ld    a,(lsflg)
  1071.     or    a
  1072.     jr    nz,cpfnd0    ; if last char
  1073.     ld    hl,fbuff    ;   reinitialise ptrs for new buffer
  1074.     ld    (lasthl),hl
  1075.     ld    bc,80h
  1076.     ld    (lastbc),bc    ; endif
  1077.  
  1078. cpfnd0    equ    $
  1079.     ld    a,(oerlap)    ; was find in overlap?
  1080.     or    a
  1081.     jr    z,cpfnd2    ; if overlap
  1082.     ld    bc,(prevbc)    ; replace ptr with earlier one
  1083. cpfnd1    equ    $
  1084.     call    prfs        ; and go back to start of find
  1085.     xor    a        ; remembering to flag that's done
  1086.     ld    (oerlap),a
  1087. cpfnd2    equ    $
  1088.     push    bc        ; are registers saved ? save bc anyway
  1089.     call    DFSI        ; show things
  1090.     ld    hl,FBUFF
  1091.     call    WRBF
  1092.     pop    bc        ; get back byte ptr
  1093.     ld    hl,80h        ; calculate equivalent
  1094.     or    a        ; of bufpos for display
  1095.     sbc    hl,bc
  1096.     ld    a,l
  1097.     or    a
  1098.     jr    nz,cpfnd3    ; if zero, it's last byte
  1099.     ld    a,80h        ;   so set up to char in front
  1100. cpfnd3    equ    $
  1101.     dec    a
  1102.     ld    (bufpos),a    ; use that
  1103.     call    slcp        ; to update cursor and
  1104.     ld    hl,(lpos)    ;  then fiddle
  1105.     dec    h        ;   to go back a bit more
  1106.     dec    h        ;   to allow room for visual ptr
  1107.     ld    (lpos),hl    
  1108.     call    udcp        ; point to that position
  1109.     call    vmInv
  1110.     ld    hl,fndmk    ; and point to the find
  1111.     call    strl
  1112.     call    vmNorm
  1113.     $fld    fndcon        ; ask if we want next
  1114.     call    chrf        ; get answer to next query
  1115.     cp    'Y'
  1116.     push    af        ; save response
  1117.     call    slcp        ; reposition on display
  1118.     ld    hl,(lpos)
  1119.     dec    h        ; back again
  1120.     dec    h
  1121.     ld    (lpos),hl
  1122.     call    udcp        ; for cursor update and
  1123.     call    spco        ; clear fndmk
  1124.     call    spco
  1125.     pop    af        ; now check query answer
  1126.     jp    nz,cpout    ; if next wanted, do it
  1127.     jr    nz,cp99
  1128.     ld    a,(lsflg)    ; but check first
  1129.     or    a        ; if on last byte in buffer
  1130.     jp    nz,topres    ;   not ? then loop
  1131.     call    nxfs        ; last byte? get new sector
  1132.     jp    z,topres    ; if its there, loop
  1133.                 ; else
  1134. cp99    equ    $        ; clear pattrn input line
  1135.     ld    hl,fndcon
  1136.     call    cfld
  1137.     ld    a,8
  1138.     call    CLRL
  1139.     $fld    notfnd        ; say eof and not found
  1140.     call    chrf        ; wait, displaying, for any input
  1141.     cp    'T'
  1142.     jr    nz,cpout
  1143.     call    frfs
  1144. cpout    equ    $
  1145.     ld    a,0ffh
  1146.     ld    (rpanel),a
  1147. cpout1    equ    $
  1148.     ld    (fdmdsi),a
  1149.     ret
  1150.  
  1151. ; DDCT    - GET NEXT PATTERN BYTE AND CHECK COUNT OF BYTES
  1152.  
  1153.     $RTN    DCCT        ; get next byte
  1154.     inc    de
  1155.     ld    a,(de)
  1156.     push    hl        ; and decrement count
  1157.     ld    hl,curct
  1158.     dec    (hl)        ; did we get to end ?
  1159.     pop    hl
  1160.     ret
  1161.  
  1162.  
  1163. ; ASIN -- GETTING ASCII PATTERN INPUT FOR SEARCH
  1164.  
  1165.     $RTN    asin
  1166.     call    sstr
  1167. asin01    equ    $
  1168.     call    afnc        ; position cursor
  1169.     call    chri        ; get a char (unfolded)
  1170.     cp    CR
  1171.     JR    Z,asin99
  1172.     cp    $ESC
  1173.     jr    NZ,asin02
  1174.     xor    a
  1175.     ld    (pattrn),a
  1176.     jp    asin99
  1177.  
  1178. asin02    equ    $
  1179.     $MTCH    asincd        ; if scrn char control key
  1180.     jr    nz,asin03
  1181.     $EXVA    asinvc        ; do action required
  1182.     JR    asin01        ; endif
  1183.  
  1184. asin03    equ    $
  1185.     cp    $TAB
  1186.     jr    z,asin04
  1187.     cp    20h        ; else if not other ctrl key
  1188.     jr    nc,asin04
  1189.     call    alrm
  1190.     jr    asin01
  1191.  
  1192. asin04    equ    $
  1193.     call    pastr        ; output progress
  1194.     ld    a,(afnmax)
  1195.     ld    hl,afncnt
  1196.     inc    (hl)
  1197.     cp    (hl)
  1198.     jp    nz,asin01
  1199.     call    alrm
  1200.  
  1201. asin99    equ    $
  1202.     ret
  1203.  
  1204. asincd: db    3,$LEFT,$RIGHT,$DELETE
  1205.  
  1206. asinvc: dw    afnl
  1207.     dw    afnr
  1208.     dw    afnd
  1209.  
  1210.     
  1211. ; PASTR -- STORING BYTES OF PATTERN FOR SEARCH
  1212.  
  1213.     $RTN    pastr
  1214.     push    af
  1215.     ld    hl,(afnchp)
  1216.     ld    a,(afncnt)
  1217.     call    aahl
  1218.     pop    af
  1219.     ld    (hl),a
  1220.     push    af
  1221.     ld    a,(ascii)
  1222.     or    a
  1223.     jr    z,pastr1
  1224.     pop    af
  1225.     call    chro
  1226.     jr    pastr2
  1227. pastr1    equ    $
  1228.     pop    af
  1229.     call    hexo
  1230. pastr2    equ    $
  1231.     ret
  1232.  
  1233. ; FHEX -- INPUT HEX SEQUENCE AND SEARCH FOR IT.
  1234.     $RTN    fhex
  1235.     xor    a
  1236.     ld    (ascii),a
  1237.     call    hxin
  1238.     call    find
  1239.     ret
  1240. ;
  1241.  
  1242. ;  SSTR -- INITIALISING PATTERN FOR SEARCH AND PROMPTING
  1243.  
  1244.     $RTN    sstr        ; initialise variables
  1245.     xor    a        ; and prompt for find input
  1246.     ld    (afncnt),a
  1247.     ld    (pattrn),a
  1248.     $fld    fndpmt
  1249.     ld    hl,(strpos)
  1250.     ld    (afncur),hl
  1251.     ld    a,20
  1252.     ld    (afnmax),a
  1253.     ld    hl,pattrn
  1254.     ld    (afnchp),hl
  1255.     ret
  1256.  
  1257. ; HXIN -- GETTING INPUT OF HEX BYTE SEQUENCE FOR SEARCH
  1258.  
  1259.  
  1260.     $RTN    hxin
  1261.     call    sstr        ; initialise
  1262. hxnib1    equ    $
  1263.     xor    a        ; clear temporary byte hold
  1264.     ld    (cuhx),a
  1265.     call    hxsc        ; position on screen
  1266.     $strl    cllstr        ; clear line beyond that
  1267.     call    hxsc        ; reposition
  1268.     call    chrf        ; get a nibble in
  1269.     $MTCH    HEXCHR
  1270.     jr    nz,hxino1
  1271.     ld    a,(cuhx)
  1272.     call    hxad
  1273.     ld    (cuhx),a
  1274.     call    pastr        ; now save byte and display 
  1275.     ld    hl,afncnt    ; incrementing byte count
  1276.     inc    (hl)
  1277.  
  1278. hxnib2    equ    $
  1279.     call    chrf
  1280.     $MTCH    HEXCHR
  1281.     jr    nz,hxino2
  1282.     ld    a,(cuhx)
  1283.     call    hxad
  1284.     ld    (cuhx),a
  1285.     ld    hl,afncnt    ; going back in byte count
  1286.     dec    (hl)
  1287.     call    hxsc        ; to ensure save and screen right
  1288.     call    pastr
  1289.     ld    a,(afnmax)    ; IF after 2 nibbles in,
  1290.     ld    hl,afncnt    ;  we are at maximum byte count
  1291.     cp    (hl)        ;  exit
  1292.     jp    z,hxin99    ; ENDIF
  1293.     inc    (hl)        ; IF NOT
  1294.     jp    hxnib1        ;  loop for another byte
  1295.                 ; ENDIF
  1296. hxino1    equ    $        ; IF NON-HEX CHARS ON 1st nibble,
  1297.     ld    a,(inch)    ; SWITCH CASE 
  1298.     cp    CR        ; CASE cr input,
  1299.     jr    z,hxin99    ; we're done
  1300.     cp    $ESC        ; CASE esc 
  1301.     jp    z,hxinX        ; exit signalling no valid input
  1302.     cp    $LEFT        ; CASE left
  1303.     jr    nz,hxinw1
  1304.     ld    a,(afncnt)    ;   IF still the 1st byte of input
  1305.     or    a        ;     just restart //ENDIF
  1306.     jp    z,hxnib1    ;   ENDIF 
  1307.     dec    a        ;   IF not 1st byte,decrement count
  1308.     ld    (afncnt),a    ;      and restart
  1309.     jp    hxnib1        ;    ENDIF
  1310.  
  1311. hxinw1    equ    $        ; DEFAULT:
  1312.     call    alrm        ;   ring bell
  1313.     jp    hxnib1        ;   and try agin
  1314.  
  1315.  
  1316. hxino2    equ    $        ; NON-HEX INPUT 2nd nibble
  1317.     ld    a,(inch)
  1318.     cp    CR
  1319.     jr    nz,hxino3
  1320.     ld    hl,afncnt    ; decrement count 
  1321.     dec    (hl)        ; before exit, but ...
  1322.     jr    nz,hxin99    ; IF it's single 1st nibble
  1323.     inc    (hl)        ;    don't signal no input
  1324.     jr    hxin99        ; ENDIF
  1325. hxino3    equ    $
  1326.     cp    $ESC
  1327.     jr    z,hxinX
  1328.     cp    $LEFT
  1329.     jr    nz,hxinw2
  1330.     xor    a
  1331.     ld    hl,cuhx        ; rotate byte back
  1332.     rrd
  1333.     ld    a,(hl)
  1334.     or    a        ; IF still known relevant data
  1335.     jp    nz,hxnib2    ;   loop for 2nd nibble
  1336.     ld    hl,afncnt    ; ELSE reposition
  1337.     dec    (hl)        ;   and loop for whole new byte
  1338.     jp    hxnib1        ; ENDIF
  1339.  
  1340. hxinw2    equ    $        ; wrong input
  1341.     call    alrm        ;  ring and loop
  1342.     jp    hxnib2
  1343.  
  1344. hxinX    equ    $        ; exit -- cancel search
  1345.     xor    a
  1346.     ld    (afncnt),a
  1347. hxin99    equ    $        ; just exit
  1348.     ret
  1349.  
  1350.  
  1351. ; HXSC -- POSITION CURSOR FOR HEX SCREEN INPUT -- EACH BYTE 
  1352. ; SEPARATED WITH SPACES 
  1353.  
  1354.  
  1355.     $RTN    hxsc
  1356.     push    bc
  1357.     push    af
  1358.     ld    hl,(afncur)
  1359.     ld    a,(afncnt)
  1360.     ld    b,a
  1361.     add    a,a
  1362.     add    a,b
  1363.     add    a,h
  1364.     ld    h,a
  1365.     call    curs
  1366.     pop    af
  1367.     pop    bc
  1368.     ret
  1369.  
  1370. ; HXAD
  1371.  
  1372.     $RTN    hxad
  1373.     ex    de,hl    ; move value into de
  1374.     ld    l,a    ; and current byte into L 
  1375.     ld    h,0    ; rotating and adding
  1376.     call    h16d
  1377.     ld    a,l    ; and getting result in af
  1378.     ret
  1379.  
  1380. ;    End of New Section     v.3 mod 4    pgm
  1381.  
  1382. ; DRMD - DIRECTORY MODE
  1383.  
  1384.     $RTN    DRMD
  1385.     LD    HL,(DRMDEF)
  1386.     LD    (ERRFLD),HL    ;SET PANEL ERROR FIELD
  1387.     LD    A,TRUE
  1388.     LD    (DRMDLD),A    ;REQUEST LIST
  1389. DRMD01    EQU    $        ;LOOP
  1390.     LD    A,(DRMDLD)
  1391.     OR    A
  1392.     JR    Z,DRMD02    ;IF LIST REQUIRED
  1393.     $NPANEL DRMDPN        ;DISPLAY DIRECTORY LIST PANEL
  1394.     CALL    DLST        ;DO DIRECTORY LIST
  1395.     XOR    A
  1396.     LD    (DRMDLD),A    ;RESET LIST REQUEST
  1397. DRMD02    EQU    $        ;ENDIF
  1398. DRMD06    EQU    $        ;LOOP
  1399.     CALL    ERRP        ;PROCESS ERRORS
  1400.     LD    A,(SELDE)
  1401.     CALL    DIRPOS        ;POSITION OVER CURRENT ENTRY
  1402.     CALL    CHRF
  1403.     $MTCH    DRMDLS
  1404.     JR    Z,DRMD05    ;EXITIF VALID
  1405.     CALL    ALRM        ;SOUND ALARM
  1406.     JR    DRMD06
  1407. DRMD05    EQU    $        ;ENDLOOP
  1408.     $EXVA    DRMDVC        ;PERFORM ACTION
  1409.     LD    A,(WTG)
  1410.     CP    'D'    
  1411.     JR    NZ,DRMD07    ;EXIT IF MODE NO LONGER D
  1412.     JP    DRMD01
  1413. DRMD07    EQU    $        ;ENDLOOP
  1414.     RET
  1415.  
  1416.  
  1417. ; DIRECTORY MODE PANEL AND VECTOR
  1418. ;
  1419. ; Updated Jan 86 by JHB to include user number selection
  1420.  
  1421. DRMDPN: DB    13    ;(Was 12)
  1422.     DB    02,00,'^',$LEFT+040H,'  Cursor left',0
  1423.     DB    03,00,'^',$RIGHT+040H,'  Cursor right',0
  1424.     DB    04,00,'^',$UP+040H,'  Cursor up',0
  1425.     DB    05,00,'^',$DOWN+040H,'  Cursor down',0
  1426.     DB    02,22,'P  Previous directory page',0
  1427.     DB    03,22,'N  Next directory page',0
  1428.     db    04,22,'U  Change user number',0
  1429.     DB    02,54,'Z  Exit from Superzap',0
  1430.     DB    03,54,'C  Change disk',0
  1431.     DB    04,54,'S  Select track/sector',0
  1432.     DB    05,54,'M  Set directory selection',0
  1433.  
  1434.     DB    07,00,'E  Edit file',0
  1435.     DB    07,22,'T  Type file',0
  1436.  
  1437. DRMDLS: DB    15,$LEFT,$RIGHT,$UP,$DOWN,CR,'EZCSMPNTU',$TAB
  1438.  
  1439. DRMDVC: DW    FBS
  1440.     DW    FFS
  1441.     DW    FUP
  1442.     DW    FDN
  1443.     DW    FNL
  1444.     DW    STFL
  1445.     DW    SETX
  1446.     DW    CHDD
  1447.     DW    SETP
  1448.     DW    SAFN
  1449.     DW    DIRP
  1450.     DW    DIRN
  1451.     DW    TYPE
  1452.     DW    CHUN
  1453.     DW    FFS
  1454.  
  1455. DRMDEF: DB    9,0
  1456. NRFMSG: DB    '** No records in file',0
  1457. FNFMSG: DB    '** File not found',0
  1458.  
  1459. DRMDLD: DS    1        ;LIST DIRECTORY REQUEST FLAG
  1460.  
  1461.  
  1462. ; DIRP - PAGE UP DIRECTORY
  1463.  
  1464.     $RTN    DIRP
  1465.     LD    A,(DIROFF)
  1466.     OR    A
  1467.     JR    Z,DIRP01    ;IF NOT PAGE 0
  1468.     SUB    32
  1469.     LD    (DIROFF),A    ;SET PREV PAGE
  1470.     XOR    A
  1471.     LD    (SELDE),A    ;FIRST ENTRY ON PAGE
  1472.     CALL    ERRP
  1473.     LD    HL,DRAREA
  1474.     CALL    CLRA        ;CLEAR AREA
  1475.     CALL    DLST        ;DISPLAY PAGE
  1476.     JR    DIRP02
  1477. DIRP01    EQU    $        ;ELSE
  1478.     CALL    ALRM        ;RING BELL
  1479. DIRP02    EQU    $        ;ENDIF
  1480.     RET
  1481.  
  1482. ; DIRN - PAGE DOWN DIRECTORY
  1483.  
  1484.     $RTN    DIRN
  1485.     LD    A,(DIROFF)
  1486.     ADD    A,32        ;POINT TO NEXT PAGE
  1487.     LD    HL,DECNT
  1488.     CP    (HL)
  1489.     JR    NC,DIRN01    ;IF AVAILABLE
  1490.     LD    (DIROFF),A    ;SAVE NEW POINTER
  1491.     XOR    A
  1492.     LD    (SELDE),A    ;SET FIRST ENTRY ON PAGE
  1493.     CALL    ERRP
  1494.     LD    HL,DRAREA
  1495.     CALL    CLRA        ;CLEAR DIRECTORY AREA
  1496.     CALL    DLST        ;DISPLAY DIRECTORY
  1497.     JR    DIRN02
  1498. DIRN01    EQU    $        ;ELSE
  1499.     CALL    ALRM        ;ALARM
  1500. DIRN02    EQU    $        ;ENDIF
  1501.     RET
  1502.  
  1503.  
  1504. ; FBS - BACKSPACE IN DIRECTORY
  1505.  
  1506.     $RTN    FBS
  1507.     LD    A,(DIROFF)
  1508.     LD    B,A
  1509.     LD    HL,DECNT
  1510. FBS01    EQU    $        ;REPEAT
  1511.     LD    A,(SELDE)
  1512.     DEC    A
  1513.     AND    31
  1514.     LD    (SELDE),A    ;SELECT PREVIOUS
  1515.     JR    Z,FBS02        ;EXIT IF FIRST POSN
  1516.     ADD    A,B
  1517.     CP    (HL)
  1518.     JR    NC,FBS01    ;UNTIL NEW<=MAX
  1519. FBS02    EQU    $
  1520.     RET
  1521.  
  1522. ; FUP - CURSOR UP IN DIRECTORY
  1523.  
  1524.     $RTN    FUP
  1525.     LD    A,(DIROFF)
  1526.     LD    B,A
  1527.     LD    HL,DECNT
  1528. FUP01    EQU    $        ;REPEAT
  1529.     LD    A,(SELDE)
  1530.     SUB    4
  1531.     AND    31
  1532.     LD    (SELDE),A    ;1 LINE UP
  1533.     JR    Z,FUP02        ;EXIT IF FIRST POSN
  1534.     ADD    A,B
  1535.     CP    (HL)
  1536.     JR    NC,FUP01    ;UNTIL NEW<=MAX
  1537. FUP02    EQU    $
  1538.     RET
  1539.  
  1540. ; FDN - CURSOR DOWN IN DIRECTORY
  1541.  
  1542.     $RTN    FDN
  1543.     LD    A,(DIROFF)
  1544.     LD    B,A
  1545.     LD    HL,DECNT
  1546. FDN01    EQU    $        ;REPEAT
  1547.     LD    A,(SELDE)
  1548.     ADD    A,4
  1549.     AND    31
  1550.     LD    (SELDE),A    ;1 LINE DOWN
  1551.     JR    Z,FDN02
  1552.     ADD    A,B
  1553.     CP    (HL)
  1554.     JR    NC,FDN01    ;UNTIL NEW<=MAX
  1555. FDN02    EQU    $
  1556.     RET
  1557.  
  1558. ; FNL - C/R IN DIRECTORY
  1559.  
  1560.     $RTN    FNL
  1561.     LD    A,(DIROFF)
  1562.     LD    B,A
  1563.     LD    HL,DECNT
  1564. FNL01    EQU    $        ;REPEAT
  1565.     LD    A,(SELDE)    ;PICK UP CURRENT
  1566.     ADD    A,4        ;MOVE TO NEXT LINE
  1567.     AND    01CH
  1568.     LD    (SELDE),A    ;START OF NEXT LINE
  1569.     JR    Z,FNL02
  1570.     ADD    A,B
  1571.     LD    HL,DECNT
  1572.     CP    (HL)
  1573.     JR    NC,FNL01    ;UNTIL NEW<=MAX
  1574. FNL02    EQU    $
  1575.     RET
  1576.  
  1577. ; FFS - CURSOR FORWARD IN DIRECTORY
  1578.  
  1579.     $RTN    FFS
  1580.     LD    A,(DIROFF)
  1581.     LD    B,A        ;GET START OF DISPLAY
  1582.     LD    HL,DECNT
  1583. FFS01    EQU    $        ;REPEAT
  1584.     LD    A,(SELDE)
  1585.     INC    A
  1586.     AND    31
  1587.     LD    (SELDE),A    ;NEXT ENTRY
  1588.     JR    Z,FFS02
  1589.     ADD    A,B
  1590.     CP    (HL)
  1591.     JR    NC,FFS01    ;UNTIL NEW<=MAX
  1592. FFS02    EQU    $
  1593.     RET
  1594.  
  1595. ; DIRPOS - POSITION TO PRINT DIRECTORY ENTRY
  1596.  
  1597. DIRPOS    EQU    $
  1598.     LD    (DIRNUM),A    ;SAVE ENTRY POSITION
  1599.     LD    HL,LPTAB
  1600.     RRCA
  1601.     RRCA            ;DIVIDE COUNT BY 4
  1602.     AND    0FH        ;MAKE IT LINE COUNT
  1603.     CALL    AAHL
  1604.     LD    B,(HL)        ;PICK UP LINE POSN
  1605.     LD    HL,DCTAB
  1606.     LD    A,(DIRNUM)    ;PICK UP ENTRY AGAIN
  1607.     AND    03        ;MAKE COUNT INTO COLUM NUMBER
  1608.     CALL    AAHL
  1609.     LD    H,(HL)        ;GET COLUMN POSITION
  1610.     LD    L,B        ;AND LINE NUMBER
  1611.     CALL    CURS        ;POSITION CURSOR
  1612.     RET
  1613. DIRNUM: DS    1
  1614.  
  1615.  
  1616. ; STFL - SELECT FILE
  1617.  
  1618.     $RTN    STFL
  1619.     CALL    CFCB        ;COPY FCB FROM DIR LIST
  1620.     CALL    SETF        ;SET FILE MODE
  1621.     RET
  1622.  
  1623. ; CFCB - COPY FCB FROM DIRECTORY LIST
  1624.  
  1625.     $RTN    CFCB
  1626.     LD    A,(DECNT)
  1627.     OR    A
  1628.     JR    NZ,CFCB01    ;IF NO FILES
  1629.     CALL    ALRM        ;SOUND ALARM
  1630.     LD    HL,FNFMSG
  1631.     LD    (ERRTXT),HL    ;SET FILE NOT FOUND ERROR
  1632.     JR    CFCB02
  1633. CFCB01    EQU    $        ;ELSE
  1634.     LD    A,(SELDE)    ;GET SELECTED ENTRY NUMBER
  1635.     LD    B,A
  1636.     LD    A,(DIROFF)
  1637.     ADD    A,B        ;ADD DISPLAY START
  1638.     LD    H,0
  1639.     LD    L,A
  1640.     LD    DE,(MEMRY)    ;BASE OF TABLE
  1641.     CALL    H16D        ;HL=HL*16+DE
  1642.     LD    DE,WRKFN    ;START OF FILE NAME
  1643.     LD    BC,11
  1644.     LDIR            ;MOVE DE OVER TO FCB
  1645.     XOR    A
  1646.     LD    (WRKEX),A
  1647. CFCB02    EQU    $        ;ENDIF
  1648.     RET
  1649.  
  1650. ;  Second new section    --main routine has bits and pieces added...PGM.
  1651. ; TYPE - TYPE SELECTED FILE
  1652.  
  1653.     $RTN    TYPE
  1654.     CALL    CFCB        ;SET UP FCB
  1655.     CALL    TFLE        ;TEST FILE
  1656.     LD    A,(FLERR)
  1657.     OR    A
  1658.     JP    NZ,TYPE01    ;IF FILE FOUND
  1659.     XOR    A
  1660.     LD    (BUFPOS),A    ;BUFFER OFFSET 0
  1661.     LD    (BASEAD+1),A
  1662.     ld    (tqued),a    ; New -- reset already queued flag
  1663.     ld    (linesc+1),a    ;     and line count
  1664.     ld    (tsect),a    ;     and specific sector flag
  1665.     ld    (tline),a    ;     and specific line flag
  1666.     INC    A
  1667.     LD    (BASEAD),A    ;INITIALISE PAGE NUMBER 1
  1668.     ld    (linesc),a    ;  new -- line number 1
  1669.     CALL    TGET        ;PRIME FIRST CHARACTER
  1670.     LD    HL,(PGEPTR)
  1671.     LD    (CURPG@),HL    ;SET CURRENT PAGE ENTRY TO FIRST
  1672.     LD    (MAXPG@),HL    ;AND LAST
  1673.     LD    A,0FFH
  1674.     LD    (TYPEX),A    ;SET NO EXIT
  1675.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1676. TYPE03    EQU    $        ;LOOP
  1677.     LD    A,(TYDSP)
  1678.     OR    A
  1679.     JR    Z,TYPE09    ;IF DISPLAY REQUIRED
  1680.     XOR    A
  1681.     LD    (TYDSP),A    ;RESET REQUEST
  1682.     $NPANEL TYPEPN        ;DISPLAY PANEL
  1683.     $FLD    TYPEFN
  1684.     $STRO    DRIVNM        ; new filename display
  1685.     $fld    mxsnum        ;     and data on max sector
  1686.     $hexw    maxrec
  1687.     $FLD    PGENUM
  1688.     $HEXW    BASEAD        ;DISPLAY PAGE NUMBER
  1689.     $FLD    RECNUM
  1690.     $HEXW    RELREC        ;DISPLAY RECORD NUMBER
  1691.     $fld    linnum        ; new line number display
  1692.     $hexw    linesc
  1693.     CALL    TYPG        ;DISPLAY PAGE
  1694.     ld    a,(tqued)    ; new -- is data queued?
  1695.     or    a        ;  (this probably should go elsewhere)
  1696.     call    z,TYPQ        ; if not, queue it
  1697.     xor    a        ; reinitialise flags
  1698.     ld    (tsect),a
  1699.     ld    (tline),a
  1700.     $fld    recnm2        ; and then end of ranges
  1701.     $hexw    relrec        ; display range
  1702.     $fld    linnm2
  1703.     $hexw    lastln
  1704. TYPE09    EQU    $        ;ENDIF
  1705. TYPE06    EQU    $        ;LOOP
  1706.     $IFLD    TYPIP        ;GET COMMAND
  1707.     $MTCH    TYPLST
  1708.     JR    Z,TYPE05    ;EXITIF VALID
  1709.     CALL    ALRM        ;SOUND ALARM
  1710.     JR    TYPE06
  1711. TYPE05    EQU    $        ;ENDLOOP
  1712.     $EXVA    TYPVEC        ;EXEC COMMAND
  1713.     LD    A,(TYPEX)
  1714.     OR    A
  1715.     JR    Z,TYPE04    ;EXITIF FLAG SET
  1716.     JP    TYPE03        ; not relative any more
  1717. TYPE04    EQU    $        ;ENDLOOP
  1718. TYPE01    EQU    $        ;ENDIF
  1719.     LD    A,TRUE
  1720.     LD    (DRMDLD),A    ;REQUEST DIRECTORY LIST
  1721.     RET
  1722.  
  1723. TYPEPN: DB    11        ; new display and extra options
  1724.     DB    01,00,'N  Next page',0
  1725.     DB    01,22,'R  Return after Paging',0
  1726.     DB    01,50,'L  Exit to file list',0
  1727.     DB    02,00,'P  Previous page',0
  1728.     DB    02,22,'T  Top of file',0
  1729.     DB    02,50,'Z  Exit from Superzap',0
  1730.     db    03,00,'S  Sector to type',0
  1731.     db    03,22,'G  Goto Page No.',0
  1732.     db    03,50,'W  Select line',0
  1733.     db    04,00,'Enter Selection ==>',0
  1734.  
  1735. mxsnum: db    05,50,'Max. Sector ',0
  1736. mxout:    db    05,62,0            ; posn for max sector
  1737. PGENUM: DB    6,0,'Page ',0        ; moved down & across
  1738. RECNUM: DB    6,32,'Sectors ',0
  1739. recnm2: db    6,44,'-',0
  1740. tyfofl: db    6,44,0            ; input position for 1st sector
  1741. linnum: db    6,60,'Lines ',0
  1742. linnm2: db    6,71,'-',0
  1743. loadin: db    4,22,'** LOADING FILE DATA **',0
  1744. TYPEFN: DB    5,22,'File : ',0    ; on diff line
  1745. TYPIP:    DB    4,19,0            ;new input position
  1746. TYPFL:    DB    8,0,0            ;FIRST CHR POSITION
  1747. tcsend: db    6,44,'       ',0
  1748. tclend    db    6,71,'        ',0
  1749.  
  1750. decs    db    10,'0123456789'        ; new data for decimal input
  1751.  
  1752. TYPLST: db    9,'NRLPTZSGW'
  1753. TYPVEC: DW    TYPF
  1754.     DW    TYPR
  1755.     DW    TYPL
  1756.     DW    TYPB
  1757.     DW    TYPT
  1758.     DW    TYPZ
  1759.     dw    typs            ; new options
  1760.     dw    typp
  1761.     dw    tpln
  1762.  
  1763. TYPEX:    DS    1        ;EXIT FLAG
  1764. TYDSP:    DS    1        ;DISPLAY REQUEST
  1765. TYPEOP: DS    1        ;END OF PAGE
  1766. target: DS    2        ; sector requested
  1767. tqued:    ds    1        ; queued flag
  1768. tsect:    ds    1        ; flag showing typs called
  1769. tline:    ds    1        ; flag showing tpln called
  1770. maxrec: ds    2        ; last sector read
  1771. savba:    ds    2        ; temp storage, basead
  1772. lastln: ds    2
  1773.  
  1774. ; TYPF - FORWARD PAGE
  1775.  
  1776.     $RTN    TYPF
  1777.     LD    A,(READST)
  1778.     OR    A
  1779.     JR    Z,TYPF01    ;IF EOF
  1780.     CALL    ALRM
  1781.     JR    TYPF02
  1782. TYPF01    EQU    $        ;ELSE
  1783.     LD    HL,(CURPG@)
  1784.     LD    DE,8
  1785.     ADD    HL,DE
  1786.     LD    (CURPG@),HL    ;UPDATE CURRENT POINTER
  1787.     LD    A,0FFH
  1788.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1789. TYPF02    EQU    $
  1790.     RET
  1791.  
  1792. ; TYPR - RETURN AFTER PAGING
  1793.  
  1794.     $RTN    TYPR
  1795.     LD    HL,(CURPG@)
  1796.     LD    DE,(MAXPG@)
  1797.     XOR    A
  1798.     SBC    HL,DE
  1799.     JR    Z,TYPR01    ;IF NOT END OF FILE
  1800.     EX    DE,HL        ;RESTORE TOP OF QUEUE
  1801.     LD    DE,8
  1802.     XOR    A
  1803.     SBC    HL,DE
  1804.     CALL    LPGE        ;LOAD LAST PAGE
  1805.     LD    A,0FFH
  1806.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1807. TYPR01    EQU    $        ;ENDIF
  1808.     RET
  1809.  
  1810. ; TYPL - EXIT TYPE TO DIR LIST
  1811.  
  1812.     $RTN    TYPL
  1813.     XOR    A
  1814.     LD    (TYPEX),A    ;REQUEST EXIT
  1815.     RET
  1816.  
  1817. ; TYPB - PAGE BACKWARD
  1818.  
  1819.     $RTN    TYPB
  1820.     LD    DE,(CURPG@)
  1821.     LD    HL,(PGEPTR)
  1822.     XOR    A
  1823.     SBC    HL,DE
  1824.     JR    Z,TYPB01    ;IF NOT TOP OF FILE
  1825.     EX    DE,HL
  1826.     LD    DE,8
  1827.     XOR    A
  1828.     SBC    HL,DE
  1829.     CALL    LPGE        ;LOAD PAGE DATA
  1830.     LD    A,0FFH
  1831.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1832. TYPB01    EQU    $        ;ENDIF
  1833.     RET
  1834.  
  1835. ; TYPT - PAGE TO TOP OF FILE
  1836.  
  1837.     $RTN    TYPT
  1838.     LD    HL,(PGEPTR)
  1839.     CALL    LPGE        ;LOAD FIRST PAGE
  1840.     LD    A,0FFH
  1841.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1842.     RET
  1843.  
  1844. ; TYPZ - EXIT TYPE TO CP/M
  1845.  
  1846.     $RTN    TYPZ
  1847.     CALL    SETX        ;EXIT SUPERZAP
  1848.     XOR    A
  1849.     LD    (TYPEX),A    ;REQUEST EXIT
  1850.     RET
  1851.  
  1852. ; TYPG - TYPE PAGE
  1853. ;    alterations include renumbering of labels -- pgm.
  1854.     $RTN    typg
  1855.     CALL    QPGE        ;PUT PAGE ON QUEUE
  1856.     $FLD    TYPFL        ;POSITION FOR FIRST CHAR
  1857. ;    $STRO    TYNPRF        ;LEFT  MARGIN -- omitted
  1858.     XOR    A
  1859.     LD    (TYPEOP),A    ;RESET END OF PAGE
  1860.     LD    (PGECOL),A
  1861.     LD    (PGELNE),A    ;LINE 0 COL 0
  1862. typg01    EQU    $        ;LOOP
  1863.     LD    A,(TYPEOP)
  1864.     OR    A
  1865.     jp    NZ,typg99    ; exit if eop (non-rel jump)
  1866.     LD    A,(COMFLG)
  1867.     OR    A
  1868.     LD    A,(TYCURC)
  1869.     JR    Z,typg02    ;IF COM FILE
  1870.     push    af
  1871.     xor    a
  1872.     ld    (tsect),a    ; not whole sector 
  1873.     pop    af
  1874.     CALL    TPUT        ;OUTPUT CHARACTER
  1875.     LD    A,(READST)
  1876.     OR    A
  1877.     jp    NZ,typg99    ; exit if end of file (non-rel now)
  1878.     LD    A,(TYPEOP)
  1879.     OR    A
  1880.     jp    NZ,typg99    ; or end of page
  1881.     CALL    TGET        ;GET NEXT CHARACTER
  1882.     jp    typg12
  1883. typg02    EQU    $        ;ELSE (NOT A COM FILE)
  1884.     push    af
  1885.     ld    a,(tsect)
  1886.     or    a
  1887.     jr    z,typg03
  1888.     ld    hl,(WRKRR)
  1889.     call    tinv
  1890.     jr    typg04
  1891. typg03    EQU    $
  1892.     ld    hl,(LINESC)
  1893.     ld    a,(tline)
  1894.     or    a
  1895.     call    nz,tinv
  1896. typg04    EQU    $
  1897.     pop    af
  1898.     CP    009H
  1899.     JR    NZ,typg06    ;IF TAB
  1900. typg05    EQU    $        ;REPEAT
  1901.     LD    A,' '
  1902.     CALL    TPUT        ;PUT SPACE
  1903.     LD    A,(PGECOL)
  1904.     AND    7
  1905.     JR    NZ,typg05    ;UNTIL TAB STOP
  1906.     jp    typg11
  1907. typg06    EQU    $
  1908.     CP    CR        ; ELSE IF C/R 
  1909.     JR    Z,typg07    ; GO CHECK FOR TRAILING L/F
  1910.     ld    hl,HARD1
  1911.     cp    (hl)        ; do same for 'hard's
  1912.     jr    z,typg07
  1913.     ld    hl,HARD2
  1914.     cp    (hl)
  1915.     jr    z,typg07    ;     (just do newline)
  1916.     ld    hl,SOFT1    ; now process 'softs'
  1917.     cp    (hl)
  1918.     jr    z,typg09
  1919.     ld    hl,SOFT2
  1920.     cp    (hl)
  1921.     jr    z,typg09
  1922.     jr    typg10
  1923. typg07    EQU    $
  1924.     LD    A,(READST)
  1925.     OR    A
  1926.     JR    NZ,typg08    ;IF EOF
  1927.     LD    A,(BUFPOS)
  1928.     LD    HL,FBUFF
  1929.     CALL    AAHL
  1930.     LD    A,(HL)
  1931.     CP    00AH
  1932.     push    AF        ; save result
  1933.     call    TYNL        ; but do newline anyway
  1934.     pop    AF
  1935.     call    z,TGET        ; and swallow char if L/F there
  1936.     JR    typg11
  1937. typg08    EQU    $        ; eof cr only
  1938.     LD    A,CR
  1939.     CALL    TPUT        ;PUT CHAR
  1940.     JR    typg11
  1941. typg09    EQU    $        ;ELSE
  1942.     CALL    TYNL        ; newline for softs
  1943.     JR    typg11            ;ENDIF
  1944. typg10    EQU    $        ;ELSE
  1945.     CALL    TPUT        ; just do a NORMAL char output
  1946. typg11    EQU    $        ;ENDIF
  1947.     LD    A,(READST)
  1948.     OR    A
  1949.     JR    NZ,typg99    ;EXIT IF EOF
  1950.     CALL    TGET        ;GET NEXT CHR
  1951. typg12    EQU    $
  1952.     jp    typg01        ; non-relative jmp, now
  1953. typg99    EQU    $        ;ENDLOOP
  1954.     call    vmNorm        ; ensure enhancement off eof
  1955.     LD    HL,(BASEAD)
  1956.     call    BCDU        ; do bcd incrementing
  1957.     LD    (BASEAD),HL    ;INC PAGE NUMBER
  1958.     RET            ;ENDIF
  1959.  
  1960. PGECOL: DS    1
  1961. PGELNE: DS    1
  1962. TUNPUT: db    0        ; flag for dummy paging ops
  1963. ; TYNPRF: DB      ' ',0       ; <= omitted left margin
  1964.  
  1965. ; QPGE - PUT PAGE DATA ON QUEUE
  1966.  
  1967.     $RTN    QPGE
  1968.     LD    HL,(MAXPG@)
  1969.     LD    DE,(CURPG@)
  1970.     XOR    A
  1971.     SBC    HL,DE
  1972.     JR    NZ,QPGE01    ;IF AT END OF Q
  1973.     LD    HL,TYCURC
  1974.     LD    DE,(MAXPG@)
  1975.     LD    BC,8
  1976.     LDIR            ;COPY PAGE DATA
  1977.     LD    (MAXPG@),DE    ;UPDATE MAX PTR
  1978. QPGE01    EQU    $        ;ENDIF
  1979.     RET
  1980.  
  1981.  
  1982. ; LPGE - LOAD PAGE DATA FROM QUEUE AT (HL)
  1983.  
  1984.     $RTN    LPGE
  1985.     LD    (CURPG@),HL    ;SET CURRENT POINTER
  1986.     LD    DE,TYCURC
  1987.     LD    BC,8
  1988.     LDIR            ;COPY PAGE DATA
  1989.     CALL    RDFS        ;READ FIRST SECTOR OF PAGE
  1990.     RET
  1991.  
  1992.  
  1993. ; TGET - GET CHARACTER FOR TYPE
  1994.  
  1995.     $RTN    TGET
  1996.     LD    A,(READST)
  1997.     OR    A
  1998.     JR    NZ,TGET02    ;IF NOT EOF
  1999.     LD    HL,BUFPOS
  2000.     LD    A,(HL)        ;GET CURRENT OFFSET
  2001.     INC    (HL)        ;INC FOR NEXT GET
  2002.     LD    HL,FBUFF
  2003.     CALL    AAHL        ;POINT TO CURRENT CHARACTER
  2004.     LD    A,(HL)
  2005.     LD    (TYCURC),A    ;GET CHARACTER
  2006.     LD    A,(BUFPOS)
  2007.     CP    080H
  2008.     JR    NZ,TGET01    ;IF BUFPOS=80
  2009.     LD    HL,(RELREC)
  2010.     ld    a,(tqued)    ; new -- check if queued
  2011.     or    a
  2012.     jr    nz,tget04    ; if not queued
  2013.     ld    (maxrec),hl    ;   save last sector
  2014. tget04    equ    $        ; endif
  2015.     call    tinv        ; switch for enhanced display on/off
  2016.     INC    HL
  2017.     LD    (RELREC),HL    ;SET NEXT SECTOR
  2018.     call    tinv        ; switch again
  2019.     XOR    A
  2020. tget03    equ    $
  2021.     LD    (BUFPOS),A    ;BUFFER OFFSET=0
  2022.     CALL    RDFS        ;READ SECTOR
  2023. TGET01    EQU    $        ;ENDIF
  2024. TGET02    EQU    $        ;ENDIF
  2025.     LD    A,(TYCURC)    ;RETURN CHARACTER
  2026.     RET
  2027.  
  2028.  
  2029. ; TINV    -- ENHANCE SECTOR  switch routine -- checks if needed.
  2030.  
  2031.     $RTN    tinv
  2032.     ld    a,(tsect)
  2033.     or    a
  2034.     jr    nz,tinv1
  2035.     ld    a,(tline)
  2036.     or    a
  2037.     jr    z,tinv4
  2038. tinv1    equ    $
  2039.     push    hl
  2040.     push    de        ; preserve -- in case
  2041.     ld    de,(TARGET)
  2042.     sbc    hl,de
  2043.     jr    NZ,tinv2
  2044.     call    vmInv
  2045.     jr    tinv3
  2046. tinv2    equ    $
  2047.     call    vmNorm
  2048. tinv3    equ    $
  2049.     pop    de        ; and restore
  2050.     pop    hl
  2051. tinv4    equ    $
  2052.     ret
  2053.  
  2054.  
  2055. ; TPUT - TYPE A CHARACTER
  2056.  
  2057.     $RTN    TPUT
  2058.     LD    B,A
  2059.     LD    A,(PGECOL)
  2060.     CP    79        ; changed for 80 cols -- no left margin
  2061.     JR    NZ,TPUT01    ; if COL=79
  2062.     CALL    TYNL        ; TAKE NEW LINE
  2063. TPUT01    EQU    $        ; endif
  2064.     LD    A,(TYPEOP)
  2065.     OR    A
  2066.     JR    NZ,TPUT02    ;IF NOT EOP
  2067.     ld    a,(TUNPUT)    ; if unput flagged
  2068.     or    a        ;   then skip screen output
  2069.     jr    nz,TPUT03    ;   and just count lines
  2070.     LD    A,B        ; else
  2071.     CALL    ASCO        ;OUTPUT CHARACTER
  2072. TPUT03    EQU    $        ; endif
  2073.     LD    HL,PGECOL
  2074.     INC    (HL)        ;INC COL COUNT
  2075. TPUT02    EQU    $        ;ENDIF
  2076.     RET
  2077.  
  2078.  
  2079. ; TYNL - TYPE NEW LINE
  2080.  
  2081.     $RTN    TYNL
  2082.     XOR    A
  2083.     LD    (PGECOL),A    ;SET COL 0
  2084.     ld    hl,(LINESC)    ; get file line count
  2085.     ld    (LASTLN),hl
  2086.     call    BCDU        ; incremented
  2087.     ld    (LINESC),hl
  2088.     call    tinv        ; switch if we've got to specified line
  2089.     LD    HL,PGELNE
  2090.     INC    (HL)        ;NOW PAGE LINE COUNT UP
  2091.     LD    A,16
  2092.     CP    (HL)
  2093.     JR    NZ,TYNL01    ;if page line = 16
  2094.     ld    a,(tsect)    ;  check if page specified and done 
  2095.     or    a
  2096.     call    nz,vmNorm    ;  switch enhanced off if it is
  2097.     LD    A,0FFH
  2098.     LD    (TYPEOP),A    ;SET END OF PAGE
  2099.     JR    TYNL02
  2100. TYNL01    EQU    $        ;ELSE
  2101.     ld    a,(TUNPUT)    ;  check if just counting lines
  2102.     or    a
  2103.     jr    nz,TYNL02
  2104.     LD    A,00DH        ; if not, output newline
  2105.     CALL    CHRO
  2106.     LD    A,00AH
  2107.     CALL    CHRO        ;OUTPUT CRLF
  2108. ;    $STRO    TYNPRF        ; <= omitted left margin again
  2109. TYNL02    EQU    $        ;ENDIF
  2110.     RET
  2111.  
  2112. ; all new option
  2113. ; TYPS -- selecting sector for typing
  2114.  
  2115.     $RTN    typs
  2116.     ld    a,0ffh
  2117.     ld    (tsect),a    ; flag specific sector function
  2118.     ld    hl,(RELREC)    ; save current
  2119.     ld    (SAVFSC),hl
  2120.     ld    hl,0        ; set to start
  2121.     ld    (RELREC),hl
  2122. typs00    equ    $
  2123.     $fld    tcsend        ; clear end of range bit
  2124.     $fld    recnum        ; redisplay sector
  2125.     $hexw    relrec
  2126.     call    CHRF        ; get folded input
  2127.     $MTCH    HEXCHR
  2128.     jr    nz,typs01
  2129.     ex    de,hl
  2130.     ld    hl,(RELREC)
  2131.     call    H16D
  2132.     ld    (RELREC),hl
  2133.     jr    typs05
  2134. typs01    equ    $
  2135.     cp    $ESC
  2136.     jr    nz,typs02
  2137.     ld    hl,(SAVFSC)
  2138.     ld    (RELREC),hl
  2139.     jr    typs05
  2140. typs02    equ    $
  2141.     cp    $LEFT
  2142.     jr    nz,typs03
  2143.     ld    hl,RELREC+1
  2144.     xor    a
  2145.     rrd
  2146.     dec    hl
  2147.     rrd
  2148.     jr    typs05
  2149. typs03    equ    $
  2150.     cp    CR
  2151.     jr    nz,typs04
  2152.     ld    hl,(RELREC)    ; get sector target
  2153.     ld    (TARGET),hl    ; and save it for later
  2154.     ld    hl,(PGEPTR)
  2155.     ld    de,1        ; offset to 1st relrec instance
  2156.     call    tloc        ; look for and load data 
  2157.     jr    z,typs99    ; if actual read error
  2158.     xor    a
  2159.     ld    (INCH),a    ; fall thru to alrm
  2160. typs04    equ    $
  2161.     call    ALRM        ; endif
  2162. typs05    equ    $
  2163.     ld    a,(INCH)
  2164.     cp    CR
  2165.     jr    z,typs99
  2166.     cp    $ESC
  2167.     jr    NZ,typs00    ; loop bottom
  2168.  
  2169. typs99    equ    $
  2170.     ld    a,0ffh
  2171.     ld    (TYDSP),a
  2172.     ret
  2173.  
  2174. ; New
  2175. ; TYPQ -- COMPILE QUEUE OF DATA FOR WHOLE FILE
  2176. typq    equ    $
  2177.     ld    a,0ffh
  2178.     ld    (TUNPUT),a    ; set unput flag
  2179.     ld    hl,(SAVFSC)    ; go back to where we were
  2180.     ld    (RELREC),hl
  2181.     call    TYPT        ; start at top,
  2182. typq01    equ    $
  2183.     call    vmInv
  2184.     $FLD    LOADIN
  2185.     call    vmNorm
  2186.     call    TYPG        ; using dummy paging process
  2187.     $fld    mxout
  2188.     $hexw    maxrec
  2189.     call    TYPF        ; getting next page
  2190.     ld    hl,loadin    ;  and flashing signal
  2191.     call    cfld
  2192.     ld    a,(READST)
  2193.     or    a
  2194.     jr    z,typq01    ; until eof
  2195.     ld    hl,(CURPG@)    ; insert null terminators
  2196.     ld    de,8
  2197.     add    hl,de
  2198.     xor    a
  2199.     ld    b,e
  2200. typq02    equ    $
  2201.     ld    (hl),a
  2202.     inc    hl
  2203.     djnz    typq02
  2204. typq03    equ    $
  2205.     ld    (tunput),a    ; reset dummy run flag
  2206.     dec    a        ; set queued-already flag, 
  2207.     ld    (tqued),a
  2208.     call    TYPT        ; and call redisplay of 1st sector
  2209.     ret
  2210.  
  2211. ; new option 
  2212. ; TYPP -- Select and find screen page within file to display 
  2213.  
  2214.     $RTN    typp        ; select page number to type
  2215.     ld    hl,(RELREC)
  2216.     ld    (SAVFSC),hl
  2217.     ld    hl,(BASEAD)
  2218.     ld    (SAVBA),hl
  2219.     ld    hl,0
  2220.     ld    (BASEAD),hl
  2221. typp00    equ    $
  2222.     $fld    PGENUM
  2223.     $hexw    BASEAD
  2224.     call    CHRF
  2225.     $MTCH    DECS
  2226.     jr    nz,typp01
  2227.     ld    a,l
  2228.     ld    hl,(BASEAD)
  2229.     add    hl,hl
  2230.     add    hl,hl
  2231.     add    hl,hl
  2232.     add    hl,hl
  2233.     add    a,l
  2234.     daa
  2235.     ld    l,a
  2236.     ld    a,h
  2237.     ld    h,0
  2238.     adc    a,h
  2239.     daa
  2240.     ld    h,a
  2241.     ld    (BASEAD),hl
  2242.     jr    typp00
  2243.  
  2244. typp01    equ    $
  2245.     cp    $ESC
  2246.     jr    nz,typp02
  2247.     ld    hl,(SAVFSC)
  2248.     ld    (RELREC),hl
  2249.     ld    hl,(SAVBA)
  2250.     ld    (BASEAD),hl
  2251.     jp    typp06
  2252.  
  2253. typp02    equ    $
  2254.     cp    $LEFT
  2255.     jr    nz,typp03
  2256.     ld    hl,BASEAD+1
  2257.     xor    a
  2258.     rrd
  2259.     dec    hl
  2260.     rrd
  2261.     jr    typp06
  2262.  
  2263. typp03    equ    $
  2264.     cp    CR
  2265.     jr    nz,typp05
  2266.     ld    hl,(BASEAD)
  2267.     ld    a,l
  2268.     or    h
  2269.     jr    nz,typp04    ; if zero page
  2270.     inc    a        ;   make it page 1
  2271.     ld    (BASEAD),a    ; endif
  2272. typp04    equ    $
  2273.     ld    hl,(BASEAD)
  2274.     ld    (TARGET),hl
  2275.     ld    hl,(PGEPTR)
  2276.     ld    de,6        ; offset to basead posn
  2277.     call    tloc        ; call routine to find target
  2278.                 ; and test it for range
  2279.     jr    z,typp99    ; if read error 
  2280.     xor    a        ;    signal
  2281.     ld    (INCH),a    ;  and fall thru alarm
  2282.  
  2283. typp05    equ    $
  2284.     call    ALRM
  2285.                 ; endif
  2286. typp06    equ    $
  2287.     ld    a,(INCH)
  2288.     cp    CR
  2289.     jr    z,typp99
  2290.     cp    $ESC
  2291.     jp    nz,typp00    ; loop 
  2292.     xor    a 
  2293.     ld    (TYDSP),a
  2294.  
  2295. typp99    equ    $
  2296.     ld    a,0ffh
  2297.     ld    (TYDSP),a
  2298.     ret
  2299.  
  2300. ; 3rd new option under TYPE
  2301.  
  2302. ; TPNL -- Select and display specified line within file
  2303.  
  2304.  
  2305.     $RTN    tpln
  2306.     ld    a,0ffh
  2307.     ld    (tline),a
  2308.     ld    hl,(RELREC)
  2309.     ld    (SAVFSC),hl
  2310.     ld    hl,(LINESC)
  2311.     ld    (SAVBA),hl
  2312.     ld    hl,0
  2313.     ld    (LINESC),hl
  2314. tpln00    equ    $
  2315.     $fld    tclend
  2316.     $fld    linnum
  2317.     $hexw    linesc
  2318.     call    CHRF
  2319.     $MTCH    DECS
  2320.     jr    nz,tpln01
  2321.     ld    a,l
  2322.     ld    hl,(LINESC)
  2323.     add    hl,hl
  2324.     add    hl,hl
  2325.     add    hl,hl
  2326.     add    hl,hl
  2327.     add    a,l
  2328.     daa
  2329.     ld    l,a
  2330.     ld    a,h
  2331.     ld    h,0
  2332.     adc    a,h
  2333.     daa
  2334.     ld    h,a
  2335.     ld    (LINESC),hl
  2336.     jr    tpln00
  2337.  
  2338. tpln01    equ    $
  2339.     cp    $ESC
  2340.     jr    nz,tpln02
  2341.     ld    hl,(SAVFSC)
  2342.     ld    (RELREC),hl
  2343.     ld    hl,(SAVBA)
  2344.     ld    (LINESC),hl
  2345.     jp    tpln06
  2346.  
  2347. tpln02    equ    $
  2348.     cp    $LEFT
  2349.     jr    nz,tpln03
  2350.     ld    hl,LINESC+1
  2351.     xor    a
  2352.     rrd
  2353.     dec    hl
  2354.     rrd
  2355.     jp    tpln06
  2356.  
  2357. tpln03    equ    $
  2358.     cp    CR
  2359.     jr    nz,tpln05
  2360.     ld    hl,(LINESC)
  2361.     ld    a,l        ; minimum line is 0001
  2362.     or    h
  2363.     jr    nz,tpln04
  2364.     inc    a
  2365.     ld    (LINESC),a
  2366. tpln04    equ    $
  2367.     ld    hl,(LINESC)
  2368.     ld    (TARGET),hl
  2369.     ld    hl,(PGEPTR)
  2370.     ld    de,4        ; offset to linesc posn
  2371.     call    tloc        ; call routine to find target
  2372.                 ; and test it for range
  2373.     jr    z,tpln99    ; if read error 
  2374.     xor    a        ;    signal
  2375.     ld    (INCH),a    ;  and fall thru alarm
  2376.                 ; to loop for other input
  2377. tpln05    equ    $
  2378.     call    ALRM
  2379.                 ; endif
  2380. tpln06    equ    $
  2381.     ld    a,(INCH)
  2382.     cp    CR
  2383.     jr    z,tpln99
  2384.     cp    $ESC
  2385.     jp    nz,tpln00
  2386.  
  2387. tpln99    equ    $
  2388.     ld    a,0ffh
  2389.     ld    (TYDSP),A
  2390.     ret
  2391.  
  2392. ; Routine to support new options -- sequential search thru queued data
  2393.  
  2394. ;   TLOC -- find place in queue for match  
  2395. ;  This REALLY should be a binary search, based on the assumption we
  2396. ;   save the address of the last queued entry, while pgeptr already should
  2397. ;   hold address of first.   
  2398.  
  2399.  
  2400.     $RTN    tloc        ; sequential search in queue
  2401.     push    de        ; preserve offset to tycurc posn
  2402.     add    hl,de        ; point to field we want
  2403.     ld    bc,8        ;  sizeof the queue structure
  2404. tloc00    equ    $
  2405.     ld    de,(TARGET)    ;  get in what we're looking for
  2406.     push    hl        ; record where we're at
  2407.     call    LDHL        ; get the current field
  2408.     xor    a
  2409.     sbc    hl,de        ; check against 'target'
  2410.     jr    nc,tloc02    ; if not found yet
  2411.     pop    hl        ;  get back where we're at
  2412.     pop    de        ; and offset to tycurc
  2413.     push    de        ; --- saving it again
  2414.     add    hl,bc        ;  move to next queue item
  2415.     push    hl        ; save its address
  2416.     or    a
  2417.     sbc    hl,de
  2418.     ld    de,06        ; now check its BASEAD value
  2419.     add    hl,de        ; (we're really hacking here )
  2420.     call    LDHL        ; (binary srch WOULD be better)
  2421.     ld    a,l        ; ANYWAY... BECAUSE THIS IS AN UNTIL,
  2422.     or    h        ; zero BASEAD means endofq
  2423.     pop    hl        ; fall thru
  2424.     jr    nz,tloc00    ; or loop if more
  2425.  
  2426. tloc01    equ    $        ; search failed
  2427.     pop    de
  2428.     push    af        ; preserve z flag set
  2429.     call    typr        ; set up end of file parameters
  2430.     call    alrm        ; say it didn't really work
  2431.     pop    af
  2432.     jr    tloc99        ; but signal z set -- ok 
  2433.  
  2434. tloc02    equ    $
  2435.     pop    hl
  2436.     jr    z,tloc03    ; if past it,
  2437.     or    a        ;   go back one
  2438.     sbc    hl,bc        ; endif
  2439. tloc03    equ    $
  2440.     pop    de
  2441.     or    a
  2442.     sbc    hl,de        ; restore offset to top of entry
  2443.     call    LPGE        ; signals nz on bad read, z if found
  2444. tloc99    equ    $        ; endif
  2445.     ret
  2446.  
  2447.  
  2448. ; routine separated -- increments packed BCD data in HL by one
  2449.  
  2450.     $RTN    BCDU
  2451.     LD    A,1
  2452.     ADD    A,L
  2453.     DAA
  2454.     LD    L,A
  2455.     LD    A,0
  2456.     ADC    A,H
  2457.     DAA
  2458.     LD    H,A
  2459.     ret
  2460.  
  2461. ;  End of second new section v3 mod 4 -PGM. 
  2462.  
  2463. ; CHUN - CHANGE USER NUMBER    (CODE MOSTLY COPIED FROM CHDD)
  2464.  
  2465.     $RTN    CHUN
  2466.     LD    HL,UNMSG
  2467.     CALL    CFLD
  2468.     LD    A,TRUE
  2469.     LD    (DRMDLD),A
  2470.     $IFLD    UNMSG
  2471.     CP    $ESC
  2472.     RET    Z
  2473.     SUB    30H        ;Make user number 0-9
  2474.     JR    C,CHUN04    ;If illegal user number
  2475.     CP    10        ;Check for A..F
  2476.     JR    C,CHUN05
  2477.     SUB    7
  2478. CHUN02: CP    16
  2479.     JR    C,CHUN05
  2480. CHUN04: CALL    ALRM
  2481.     RET
  2482. CHUN05: LD    E,A
  2483.     LD    C,USERNO
  2484.     CALL    CPM
  2485.     LD    C,GETDEF
  2486.     CALL    CPM
  2487.     CALL    CHDR
  2488.     XOR    A
  2489.     LD    (SELDE),A
  2490.     RET
  2491.  
  2492. UNMSG:    DEFB    12,20,'Enter user number or press ESC ===>',0
  2493.  
  2494. ; CHDD - CHANGE DIRECTORY DRIVE
  2495.  
  2496.     $RTN    CHDD
  2497.     LD    HL,DSKMSG
  2498.     CALL    CFLD        ;CLEAR PROMPT FIELD
  2499.     LD    A,TRUE
  2500.     LD    (DRMDLD),A    ;REQUEST LIST ON RETURN
  2501.     $IFLD    DSKMSG        ;PROMPT FOR DRIVE
  2502.     CP    $ESC
  2503.     JR    Z,CHDD03    ;IF NOT ESC
  2504.     SUB    041H        ;MAKE DRIVE ID
  2505.     CALL    CHDR        ;CHANGE DISK
  2506.     JR    NZ,CHDD04    ;IF ILLEGAL DISK
  2507.     CALL    ALRM        ;SOUND ALARM
  2508.     JR    CHDD05
  2509. CHDD04    EQU    $        ;ELSE
  2510.     XOR    A
  2511.     LD    (SELDE),A    ;SELECT FIRST ENTRY
  2512. CHDD05    EQU    $        ;ENDIF
  2513. CHDD03    EQU    $        ;ENDIF
  2514.     RET
  2515.  
  2516. DSKMSG: DB    12,20,'Enter Drive Name or press ESC ===>',0
  2517. NFDMSG: DB    '** No Files on Drive',0
  2518.  
  2519.  
  2520. ; SAFN - SET DIRECTORY LIST AFN
  2521.  
  2522.     $RTN    SAFN
  2523.     $NPANEL AFNPNL        ;DISPLAY SET AFN PANEL
  2524.     LD    A,TRUE
  2525.     LD    (DRMDLD),A    ;REQUEST DIRECTORY LIST
  2526.     LD    HL,LMDFCB+1
  2527.     LD    DE,CPYAFN
  2528.     LD    BC,11
  2529.     LDIR            ;TAKE LOCAL COPY OF DIR SEARCH NAME
  2530.     CALL    DAFN        ;DISPLAY CURRENT MASK
  2531.     XOR    A
  2532.     LD    (IMODE),A    ;RESET INSERT MODE
  2533.     LD    (NMODE),A    ;SET FOR NAME PART
  2534.     LD    (AFNCNT),A    ;SET COUNT=0
  2535.     LD    HL,(AFNPNM)
  2536.     LD    (AFNCUR),HL    ;SET START ADDRESS ON SCREEN
  2537.     LD    A,8
  2538.     LD    (AFNMAX),A    ;SET LENGTH OF FIELD
  2539.     LD    HL,CPYAFN
  2540.     LD    (AFNCHP),HL    ;SAVE START ADDRESS IN MEMORY
  2541. SAFN01    EQU    $        ;LOOP
  2542.     CALL    AFNC        ;POSITION CURSOR
  2543.     CALL    CHRF        ;GET A CHARACTER
  2544.     CP    CR
  2545.     JR    Z,SAFN02    ;EXITIF C/R
  2546.     CP    $ESC
  2547.     JR    Z,SAFN02    ;OR ESCAPE
  2548.     $MTCH    AFNACD
  2549.     JR    NZ,SAFN03    ;IF VALID CONTROL
  2550.     $EXVA    AFNAVC        ;PERFORM ACTION
  2551.     JR    SAFN04
  2552. SAFN03    EQU    $        ;ELSE
  2553.     $MTCH    AFNINV
  2554.     JR    Z,SAFN05    ;IF NOT IN ILLEGAL CHARACTER SET
  2555.     CP    020H
  2556.     JP    C,SAFN05    ;AND NOT CONTROL CHARACTER
  2557.     CALL    PAFN        ;PUT CHARACTER IN STRING
  2558.     JR    SAFN06
  2559. SAFN05    EQU    $        ;ELSE
  2560.     CALL    ALRM        ;RING BELL
  2561. SAFN06    EQU    $        ;ENDIF
  2562. SAFN04    EQU    $        ;ENDIF
  2563.     JR    SAFN01
  2564. SAFN02    EQU    $        ;ENDLOOP
  2565.     CP    $ESC
  2566.     JR    Z,SAFN99    ;IF EXIT BY C/R
  2567.     LD    HL,CPYAFN
  2568.     CALL    LSEL        ;COPY NEW NAME TO FCB
  2569.     CALL    RDIR        ;READ DIRECTORY
  2570.     XOR    A
  2571.     LD    (SELDE),A    ;RESET CURRENT SELECTION
  2572. SAFN99    EQU    $        ;ENDIF
  2573.     RET
  2574.  
  2575. AFNINV: DB    7,07FH,':;<>[]' ;INVALID FILENAME CHARACTERS
  2576. IMODE:    DS    1        ;INSERT ON/OFF
  2577. NMODE:    DS    1        ;IN NAME/EXT PART
  2578. AFNCNT: DS    1        ;CURENT POSITION IN NAME
  2579. AFNCUR: DS    2        ;CURSOR POSITION OF CURRENT FIELD
  2580. AFNCHP: DS    2        ;ADDRESS OF CURRENT FIELD
  2581. AFNMAX: DS    1        ;LENGTH OF CURRENT PART
  2582. CPYAFN: DS    11
  2583.  
  2584. AFNPNL    EQU    $
  2585.     DB    10        ;FIELD COUNT
  2586.     DB    02,00,'^',$LEFT+040H,'  Cursor Left',0
  2587.     DB    02,27,'^',$RIGHT+040H,'  Cursor Right',0
  2588.     DB    03,00,'^',$DELETE+040H,'  Delete Character',0
  2589.     DB    03,27,'^',$INSRT+040H,'  Insert On/Off',0  
  2590.     DB    02,54,'^',$TAB+040H,'  Edit Name/Type',0
  2591.     DB    03,54,'ESC Use Current Selection',0
  2592. AFNMSG: DB    7,08,'Edit File Name ===>',0
  2593.     DB    7,37,'<=',0            ;FILENAME END MARKER
  2594.     DB    9,13,'File Type ===>',0
  2595.     DB    9,32,'<=',0            ;FILE TYPE END MARKER
  2596. AFNPNM: DB    7,28,0                ;POSITION OF FILE NAME
  2597. AFNPEX: DB    9,28,0                ;POSITION OF FILE TYPE
  2598.  
  2599. INSMSG: DB    05,29,'Insert',0
  2600.  
  2601. AFNACD: DB    8,$LEFT,$RIGHT,$DELETE,$INSRT,$TAB,' .*'
  2602.  
  2603. AFNAVC: DW    AFNL        ;CURSOR LEFT
  2604.     DW    AFNR        ;CURSOR RIGHT
  2605.     DW    AFND        ;DELETE CHAR
  2606.     DW    AFNI        ;TOGGLE INSERT MODE
  2607.     DW    AFNT        ;TOGGLE NAME MODE
  2608.     DW    AFNS        ;SPACE FILL FIELD
  2609.     DW    AFNP        ;PERIOD
  2610.     DW    AFNQ        ; "?" FILL (USED BY "*")
  2611.  
  2612. ; AFNP - PERIOD IN AFN
  2613.  
  2614.     $RTN    AFNP
  2615.     LD    A,(NMODE)
  2616.     OR    A
  2617.     JR    NZ,AFNP01    ;IF IN NAME
  2618.     CALL    AFNS        ;SPACE FILL
  2619. AFNP01    EQU    $        ;ENDIF
  2620.     RET
  2621.  
  2622. ; AFND - DELETE CHARACTER IN AFN
  2623.  
  2624.     $RTN    AFND
  2625.     LD    HL,(AFNCHP)    ;ADDRESS OF CURRENT FIELD
  2626.     LD    A,(AFNCNT)
  2627.     LD    C,A        ;SAVE COUNT
  2628.     CALL    AAHL        ;ADDRESS OF CURRENT CHARACTER
  2629.     LD    D,H
  2630.     LD    E,L        ;DEST IN DE
  2631.     INC    HL        ;SOURCE IN HL
  2632.     LD    A,(AFNMAX)    ;LENGTH OF FIELD
  2633.     SUB    C        ;LENGTH REMAINING
  2634.     DEC    A        ;LENGTH TO MOVE
  2635.     JR    Z,AFND01    ;IF SOMETHING TO MOVE
  2636.     LD    B,0
  2637.     LD    C,A        ;SET UP COUNT
  2638.     LDIR            ;MOVE FIELD LEFT
  2639. AFND01    EQU    $        ;ENDIF
  2640.     LD    A,' '
  2641.     LD    (DE),A        ;BLANK LAST CHARACTER
  2642.     CALL    DAFN        ;DISPLAY NEW AFN
  2643.     RET
  2644.  
  2645. ; AFNS - SPACE FILL AFN
  2646.  
  2647.     $RTN    AFNS
  2648.     LD    A,' '
  2649.     LD    (FILLCH),A
  2650.     CALL    AFNF
  2651.     RET
  2652.  
  2653. ; AFNQ - "?" FILL AFN
  2654.  
  2655.     $RTN    AFNQ
  2656.     LD    A,'?'
  2657.     LD    (FILLCH),A
  2658.     CALL    AFNF
  2659.     RET
  2660.  
  2661. FILLCH: DS    1        ;CHARACTER TO FILL AFN
  2662.  
  2663.  
  2664. ; AFNF - FILL AFN FIELD
  2665.  
  2666.     $RTN    AFNF
  2667.     LD    HL,(AFNCHP)
  2668.     LD    A,(AFNCNT)
  2669.     LD    B,A        ;SAVE COUNT
  2670.     CALL    AAHL        ;POSITION IN FIELD
  2671.     LD    A,(AFNMAX)
  2672.     SUB    B
  2673.     LD    B,A        ;SAVE COUNT
  2674.     LD    A,(FILLCH)
  2675. AFNF01    EQU    $        ;REPEAT
  2676.     LD    (HL),A        ;INSERT SPACE
  2677.     INC    HL        ;POINT NEXT CHARACTER
  2678.     DJNZ    AFNF01        ;UNTIL END OF FIELD
  2679.     CALL    DAFN        ;DISPLAY FIELD
  2680.     CALL    AFNT        ;POSITION IN OTHER HALF
  2681.     RET
  2682.  
  2683.  
  2684. ; DAFN - DISPLAY DIRECTORY SEARCH NAME
  2685.  
  2686.     $RTN    DAFN
  2687.     $FLD    AFNPNM        ;POSITION FOR NAME
  2688.     LD    B,8
  2689.     LD    HL,CPYAFN
  2690. DAFN01    EQU    $        ;LOOP
  2691.     LD    A,(HL)
  2692.     CALL    CHRO        ;PRINT A CHARCTER
  2693.     INC    HL        ;POINT TO NEXT
  2694.     DJNZ    DAFN01        ;UNTIL END OF FIELD
  2695.     $FLD    AFNPEX        ;POSITION FOR TYPE
  2696.     LD    HL,CPYAFN+8
  2697.     LD    B,3
  2698. DAFN02    EQU    $        ;REPEAT
  2699.     LD    A,(HL)
  2700.     CALL    CHRO        ;PRINT CHAR
  2701.     INC    HL        ;POINT TO NEXT
  2702.     DJNZ    DAFN02        ;UNTIL END OF FIELD
  2703.     RET
  2704.  
  2705.  
  2706. ; PAFN - PUT CHARACTER IN STRING
  2707.  
  2708.     $RTN    PAFN
  2709.     PUSH    AF        ;SAVE CHARACTER
  2710.     LD    A,(IMODE)
  2711.     OR    A    
  2712.     JR    Z,PAFN01    ;IF INSERT ON
  2713.     CALL    AFNM        ;MAKE SPACE
  2714. PAFN01    EQU    $        ;ENDIF
  2715.     LD    HL,(AFNCHP)    ;GET CHARACTER POSITION
  2716.     LD    A,(AFNCNT)
  2717.     CALL    AAHL        ;ADD COUNT TO HL
  2718.     POP    AF        ;RESTORE CHARACTER
  2719.     LD    (HL),A        ;PUT IT IN STRING
  2720.     CALL    CHRO        ;DISPLAY CHARACTER
  2721.     LD    A,(IMODE)
  2722.     OR    A
  2723.     JR    Z,PAFN02    ;IF INSERT ON
  2724.     CALL    DAFN        ;DISPLAY FULL NAME
  2725. PAFN02    EQU    $        ;ENDIF
  2726.     CALL    AFNR        ;MOVE CURSOR
  2727.     RET
  2728.  
  2729. ; AFNM - MAKE SPACE FOR INSERT
  2730.  
  2731.     $RTN    AFNM
  2732.     LD    HL,(AFNCHP)    ;ADDRESS OF CURRENT FIELD
  2733.     LD    A,(AFNMAX)
  2734.     DEC    A        ;ADJUST COUNT TO OFFSET
  2735.     CALL    AAHL        ;ADDRESS OF LAST CHARACTER
  2736.     LD    D,H
  2737.     LD    E,L        ;DEST IN DE
  2738.     DEC    HL        ;SOURCE IN HL
  2739.     LD    A,(AFNCNT)    ;CURRENT OFFSET
  2740.     LD    C,A
  2741.     LD    A,(AFNMAX)
  2742.     SUB    C        ;LENGTH REMAINING
  2743.     DEC    A        ;LENGTH TO MOVE
  2744.     JR    Z,AFNM01    ;IF SOMETHING TO MOVE
  2745.     LD    B,0
  2746.     LD    C,A        ;SET UP COUNT
  2747.     LDDR            ;MOVE FIELD RIGHT
  2748. AFNM01    EQU    $        ;ENDIF
  2749.     RET
  2750.  
  2751. ; AFNL - CURSOR LEFT IN AFN
  2752.  
  2753.     $RTN    AFNL
  2754.     LD    A,(AFNCNT)
  2755.     OR    A
  2756.     JR    Z,AFNL01    ;IF NOT START OF FIELD
  2757.     DEC    A        ;POSITION TO PREVIOUS
  2758.     JR    AFNL02
  2759. AFNL01    EQU    $        ;ELSE
  2760.     CALL    AFNT        ;TOGGLE MODE
  2761.     LD    A,(AFNMAX)    ;GET END OF FIELD COUNT
  2762.     DEC    A        ;POINT TO LAST CHAR IN FIELD
  2763.     LD    B,A        ;SET COUNT
  2764.     DEC    A        ;POINT TO PREVIOUS
  2765.     LD    HL,(AFNCHP)
  2766.     CALL    AAHL
  2767.     LD    A,' '
  2768. AFNL03    EQU    $        ;REPEAT
  2769.     CP    (HL)
  2770.     JR    NZ,AFNL04    ;EXITIF PREVIOUS NOT SPACE
  2771.     DEC    HL
  2772.     DJNZ    AFNL03        ;UNTIL END OF FIELD
  2773. AFNL04    EQU    $        ;ENDLOOP
  2774.     LD    A,B        ;RESTORE COUNT
  2775. AFNL02    EQU    $        ;ENDIF
  2776.     LD    (AFNCNT),A    ;BACKSPACE POSITION
  2777.     RET
  2778.  
  2779.  
  2780. ; AFNR - CURSOR RIGHT IN AFN
  2781.  
  2782.     $RTN    AFNR
  2783.     LD    HL,(AFNCHP)
  2784.     LD    A,(AFNCNT)
  2785.     CALL    AAHL        ;POINT TO CURRENT CHARACTER
  2786.     LD    A,(HL)
  2787.     CP    ' '
  2788.     JR    NZ,AFNR02    ;IF SPACE
  2789.     CALL    AFNT        ;CHANGE MODE
  2790.     JR    AFNR03
  2791. AFNR02    EQU    $        ;ELSE
  2792.     LD    A,(AFNMAX)    ;GET FIELD MAX
  2793.     LD    HL,AFNCNT
  2794.     INC    (HL)        ;INC POSITION
  2795.     CP    (HL)
  2796.     JP    NZ,AFNR01    ;IF OUT OF RANGE
  2797.     CALL    AFNT        ;TOGGLE MODE
  2798. AFNR01    EQU    $        ;ENDIF
  2799. AFNR03    EQU    $        ;ENDIF
  2800.     RET
  2801.  
  2802. ; AFNI - TOGGLE AFN INSERT MODE
  2803.  
  2804.     $RTN    AFNI
  2805.     LD    A,(IMODE)
  2806.     CPL
  2807.     LD    (IMODE),A    ;TOGGLE MODE FLAG
  2808.     LD    HL,INSMSG    ;POINT TO INSERT MESSAGE
  2809.     OR    A
  2810.     JR    Z,AFNI01    ;IF NOW INSERT MODE
  2811.     CALL    DFLD        ;DISPLAY IT
  2812.     JR    AFNI02
  2813. AFNI01    EQU    $        ;ELSE
  2814.     CALL    CFLD        ;CLEAR IT
  2815. AFNI02    EQU    $        ;ENDIF
  2816.     RET
  2817.  
  2818.  
  2819. ; AFNT - TOGGLE AFN MODE
  2820.  
  2821.     $RTN    AFNT
  2822.     XOR    A
  2823.     LD    (AFNCNT),A    ;RESET COUNT
  2824.     LD    A,(NMODE)
  2825.     CPL
  2826.     LD    (NMODE),A    ;TOGLE MODE FLAG
  2827.     OR    A
  2828.     JR    NZ,AFNT01    ;IF NOW NAME MODE
  2829.     LD    A,8        ;GET MAX LENGTH
  2830.     LD    HL,(AFNPNM)    ;GET START POSITION
  2831.     LD    DE,CPYAFN
  2832.     JR    AFNT02        
  2833. AFNT01    EQU    $        ;ELSE
  2834.     LD    A,3        ;GET MAX FOR EXTENSION
  2835.     LD    HL,(AFNPEX)    ;GET POSITION FOR EXTENSION
  2836.     LD    DE,CPYAFN+8
  2837. AFNT02    EQU    $        ;ENDIF
  2838.     LD    (AFNMAX),A    ;SET MAX
  2839.     LD    (AFNCUR),HL    ;SET START POSITION
  2840.     LD    (AFNCHP),DE    ;SET START ADDRESS
  2841.     RET
  2842.  
  2843.  
  2844. ; AFNC - POSITION CURSOR IN AFN
  2845.  
  2846.     $RTN    AFNC
  2847.     LD    HL,(AFNCUR)    ;GET START OF FIELD
  2848.     LD    A,(AFNCNT)    ;GET OFFSET
  2849.     ADD    A,H
  2850.     LD    H,A        ;OFFSET CURSOR
  2851.     CALL    CURS        ;POSITION CURSOR
  2852.     RET
  2853.  
  2854.  
  2855. ; TFLE - TEST FILE
  2856.  
  2857.     $RTN    TFLE
  2858.     XOR    A
  2859.     LD    (FLERR),A    ;RESET ERROR FLAG
  2860.     LD    DE,WRKFCB    ;POINT TO WORK FCB
  2861.     LD    C,OPEN
  2862.     CALL    CPM        ;ATTEMPT TO OPEN FILE
  2863.     INC    A
  2864.     JR    NZ,TFLE01    ;IF OPEN ERROR
  2865.     LD    HL,FNFMSG
  2866.     LD    (ERRTXT),HL    ;SET FILE NOT FOUND ERROR
  2867.     LD    A,0FFH
  2868.     LD    (FLERR),A    ;SET ERROR FLAG
  2869.     JP    TFLE02
  2870. TFLE01    EQU    $        ;ELSE
  2871.     LD    HL,0
  2872.     LD    (RELREC),HL    ;INITIALISE RECORD COUNTER
  2873.     LD    (SAVFSC),HL
  2874.     LD    DE,WRKFN
  2875.     CALL    FMTN
  2876.     LD    A,(WRKDR)
  2877.     ADD    A,040H
  2878.     LD    (DRIVNM),A    ;FORMAT NAME AND DRIVE
  2879.     CALL    RDFS        ;READ SECTOR
  2880.     JR    Z,TFLE03    ;IF READ BAD
  2881.     LD    HL,NRFMSG
  2882.     LD    (ERRTXT),HL    ;SET NO RECORDS ON FILE ERROR
  2883.     LD    A,0FFH
  2884.     LD    (FLERR),A    ;SET ERROR FLAG
  2885. TFLE03    EQU    $        ;ENDIF
  2886. TFLE02    EQU    $        ;ENDIF
  2887.     RET
  2888. FLERR:    DS    1
  2889.  
  2890.  
  2891. ; PSMD - PHYSICAL SECTOR MODE
  2892.  
  2893.     $RTN    PSMD
  2894.     LD    HL,(PSMDER)
  2895.     LD    (ERRFLD),HL    ;SET ERROR FIELD POINTER
  2896.     LD    A,0FFH
  2897.     LD    (PMNEWD),A    ;FLAG NEW DISK
  2898.     LD    (RPANEL),A    ;REQUEST PANEL
  2899. PSMD05    EQU    $        ;LOOP 
  2900.     CALL    ZBSA        ;CLEAR ADDRESS COUNTER
  2901.     LD    A,(PMNEWD)
  2902.     OR    A
  2903.     JP    Z,PSMD01    ;IF NEW DISK
  2904.     XOR    A
  2905.     LD    (PMNEWD),A    ;RESET FLAG
  2906.     LD    A,(CURAN)
  2907.     LD    C,A
  2908.     CALL    SELDSK        ;SELECT PHYSICAL DISK
  2909.     CALL    HOME        ;HOME THE DISK
  2910.     LD    HL,0
  2911.     LD    (PSMDSC),HL    ;SET SECTOR TO 0
  2912. ;    LD    (PSMDTR),HL    ;SET TRACK TO 0
  2913. ; The above used to set the track to 0 but I found that is not very useful so
  2914. ; I changed it to point to the beginning of the directory (JHB)
  2915.     LD    HL,(DPBOFF)
  2916.     LD    (PSMDTR),HL
  2917. PSMD01    EQU    $        ;ENDIF
  2918.     LD    A,(RPANEL)
  2919.     OR    A
  2920.     JR    Z,PSMD06    ;IF PANEL REQUIRED
  2921.     XOR    A
  2922.     LD    (RPANEL),A    ;RESET FLAG
  2923.     $NPANEL PSMDPN        ;DISPLAY PHYSICAL MODE PANEL
  2924.     $FLD    PSPMSG
  2925.     CALL    DSPI        ;DISPLAY SCRATCHPAD DATA
  2926. PSMD06    EQU    $
  2927.     CALL    PRDD        ;READ AND DISPLAY SECTOR
  2928.     CALL    ERRP        ;PROCESS ERROR MESSAGES
  2929. PSMD03    EQU    $        ;LOOP
  2930.     $IFLD    SELMSG        ;ISSUE SELMSG, GET COMMAND
  2931.     $MTCH    PSMDLS
  2932.     JR    Z,PSMD02    ;EXITIF VALID
  2933.     CALL    ALRM        ;SOUND THE ALARM
  2934.     JR    PSMD03
  2935. PSMD02    EQU    $        ;ENDLOOP
  2936.     $EXVA    PSMDVC        ;EXEC ACTION
  2937.     LD    A,(WTG)
  2938.     CP    'P'
  2939.     JR    NZ,PSMD04    ;EXIT IF NEXT MODE <> P
  2940.     JP    PSMD05
  2941. PSMD04    EQU    $        ;ENDLOOP
  2942.     RET
  2943. PMNEWD: DS    1        ;NEW DISK FLAG
  2944.  
  2945. BIOS3:                ;General BIOS entry for CP/M 3.1
  2946.     LD    (HLVAL),HL    ;Save caller's register values
  2947.     LD    (DEVAL),DE    ; in BIOS parameter block
  2948.     LD    (BCVAL),BC    ;
  2949.     LD    (AVAL),A    ;
  2950.     POP    HL        ;Get return address for figuring which
  2951.                 ; routine was called.  (Also leaves proper
  2952.                 ; return address on stack!)
  2953.     LD    DE,LBIOS-3    ;Base of jump table
  2954.     XOR    A        ;Clear carry flag
  2955.     SBC    HL,DE        ;(BIOS function) * 3 now in HL
  2956.     LD    B,A
  2957.     LD    A,L
  2958. FNCALC:
  2959.     SUB    3        ;Figure out which BIOS function was called
  2960.     JR    Z,GOTFN
  2961.     INC    B
  2962.     JR    FNCALC
  2963. GOTFN:
  2964.     LD    A,B        ;Stash it in the BIOS parameter block
  2965.     LD    DE,BIOSFN
  2966.     LD    (DE),A
  2967.     LD    C,50        ;CP/M Plus direct BIOS call
  2968.     CALL    CPM
  2969.     RET
  2970.  
  2971. BIOSFN: DEFS    1        ;CP/M Plus BIOS parameter block
  2972. AVAL:    DEFS    1
  2973. BCVAL:    DEFS    2
  2974. DEVAL:    DEFS    2
  2975. HLVAL:    DEFS    2
  2976.  
  2977. ; LOCAL DISK PARAMETER HEADER
  2978. ;
  2979. ; It seems that the DPH layouts for CP/M 2.x and CP/M 3.x are different.
  2980. ; In particular, there are 10 bytes between DPHXLT and DPHDPB instead
  2981. ; of the 8 shown here.    We will correct for this when we are making a
  2982. ; local copy of the DPB.
  2983. ;
  2984. ; Note that the labels DPHDIR, DPHCSV and DPHALV are not used anywhere.
  2985. ;            --- (JHB)
  2986. DPHLCL    EQU    $
  2987. DPHXLT: DS    2
  2988.     DS    6        ;FILLER
  2989. DPHDIR: DS    2
  2990. DPHDPB: DS    2
  2991. DPHCSV: DS    2
  2992. DPHALV: DS    2
  2993.  
  2994. DPHDP3    EQU    DPHDPB+2    ;Equivalence for CP/M 3.x
  2995.  
  2996. ; LOCAL DISK PARAMETER BLOCK
  2997.  
  2998. DPBLCL    EQU    $
  2999. DPBSPT: DS    2        ;CP/M LOGICAL SECTORS PER TRACK
  3000. DPBBSH: DS    1
  3001. DPBBLM: DS    1        ;LOGICAL SECTORS PER BLOCK - 1
  3002. DPBEXM: DS    1
  3003. DPBDSM: DS    2        ;FILE BLOCKS PER DISK
  3004. DPBDRM: DS    2
  3005. DPBAL0: DS    1
  3006. DPBAL1: DS    1
  3007. DPBCKS: DS    2
  3008. DPBOFF: DS    2
  3009. DPBPSH: DS    1        ;CP/M 3 only
  3010. DPBPSM: DS    1        ;CP/M 3 only
  3011.  
  3012. ; LOCAL DISK PARAMETER EXTENSIONS
  3013.  
  3014. DPETPD: DS    2        ;TRACKS PER DISK
  3015. DPESPB: DS    2        ;SECTORS PER BLOCK
  3016. DPERSC: DS    2        ;RESERVED SECTORS
  3017.  
  3018.  
  3019. PSMDTR: DS    2
  3020. PSMDSC: DS    2
  3021. PSMDBL: DS    2
  3022.  
  3023. PHYSEC: DS    2
  3024.  
  3025. ; PHYSICAL DISK MODE MESSAGES, PANEL AND ACTION VECTOR
  3026.  
  3027. TRKMSG: DB    11,04,'Enter Hex Track',0    ;OVERLAID BY CTRMSG
  3028. SECMSG: DB    11,23,'Enter Hex Sector',0    ;OVERLAID BY CSCMSG
  3029. BLKMSG: DB    11,42,'Enter Hex Block',0    ;OVERLAID BY CBLMSG
  3030. DIDMSG: DB    11,61,'Enter Drive ID',0    ;OVERLAID BY CDKMSG
  3031.  
  3032. PSMDPN: DB    16                ;FIELD COUNT
  3033.     DB    02,00,'N  Next sector',0
  3034.     DB    03,00,'P  Previous sector',0
  3035.     DB    04,00,'I  Next track',0
  3036.     DB    05,00,'O  Previous track',0
  3037.     DB    02,27,'T  Select track',0
  3038.     DB    03,27,'S  Select sector',0
  3039.     DB    04,27,'B  Select block',0
  3040.     DB    05,27,'D  Select drive',0
  3041.     DB    02,54,'Z  Exit from Superzap',0
  3042.     DB    03,54,'L  Exit to file list',0
  3043.     DB    04,54,'X  Scratchpad operations',0
  3044.     DB    05,54,'C  Change sector',0
  3045.  
  3046. CTRMSG: DB    11,04,'Current-Track  ',0    ;OVERLAID BY TRKMSG
  3047. CSCMSG: DB    11,23,'Current-Sector  ',0    ;OVERLAID BY SECMSG
  3048. CBLMSG: DB    11,42,'Current-Block  ',0    ;OVERLAID BY BLKMSG
  3049. CDKMSG: DB    11,61,'Current-Drive ',0    ;OVERLAID BY DIDMSG
  3050.  
  3051. PSMDER: DB    8,0        ;ERROR FIELD
  3052. PSPMSG: DB    07,00,'Scratchpad :- ',0
  3053.  
  3054. ; FILE STATISTICS FIELDS
  3055.  
  3056. PSTRFL: DB    12,11,0
  3057. PSTRIP: DB    12,15,0
  3058. PSSCFL: DB    12,28,0
  3059. PSSCIP: DB    12,32,0 
  3060. PSBLFL: DB    12,47,0
  3061. PSBLIP: DB    12,51,0
  3062. PSDKFL: DB    12,67,0
  3063.  
  3064. PSMDLS: DB    12,'NCPSITOZLBDX'
  3065. PSMDVC    EQU    $
  3066.     DW    NXPS        ;NEXT PHYSICAL SECTOR
  3067.     DW    PSCH        ;PHYSICAL SECTOR CHANGE MODE
  3068.     DW    PRPS        ;PREVIOUS PHYSICAL SECTOR
  3069.     DW    SPSN        ;SET PHYSICAL SECTOR
  3070.     DW    FRTR        ;FORWARD TRACK
  3071.     DW    SPTN        ;SET PHYSICAL TRACK
  3072.     DW    BWTR        ;BACKWARD TRACK
  3073.     DW    SETX        ;SET EXIT MODE
  3074.     DW    PTOD        ;CHANGE TO DIRECTORY MODE
  3075.     DW    SPBL        ;SET PHYSICAL BLOCK
  3076.     DW    CHPD        ;CHANGE PHYSICAL DISK
  3077.     DW    PSPM        ;PHYSICAL S/P MANAGER
  3078.  
  3079. ; PTOD - CHANGE TO DIRECTORY
  3080.  
  3081.     $RTN    PTOD
  3082.     LD    A,(CURAN)
  3083.     CALL    CHDR        ;RESET DISKS
  3084.     CALL    SETD        ;SET D MODE
  3085.     RET
  3086.  
  3087. ; CHPD - CHANGE PHYSICAL DISK
  3088.  
  3089.     $RTN    CHPD
  3090.     $FLD    DIDMSG        ;DISPLAY PROMP
  3091. CHPD01    EQU    $        ;LOOP
  3092.     $FLD    PSDKFL        ;POSITION FOR DISK ID
  3093.     LD    A,(CURAN)    ;GET ABSOLUTE DRIVE NUMBER
  3094.     ADD    A,041H        ;MAKE IT ALPHA
  3095.     CALL    CHRO        ;DISPLAY DRIVE ID
  3096.     CALL    CHRF
  3097.     CP    $ESC
  3098.     JR    Z,CHPD02    ;EXIT IF ESCAPE
  3099.     CP    CR
  3100.     JR    Z,CHPD02    ;OR CR
  3101.     SUB    041H        ;MAKE IT DISK NUMBER
  3102.     CALL    CHDR        ;CHANGE DRIVE
  3103.     JR    NZ,CHPD02    ;EXITIF NON ZERO DPH
  3104.     CALL    ALRM        ;RING BELL
  3105.     JR    CHPD01
  3106. CHPD02    EQU    $        ;ENDLOOP
  3107.     CP    $ESC
  3108.     JR    Z,CHPD03    ;IF NOT ESC
  3109.     LD    A,0FFH
  3110.     LD    (PMNEWD),A    ;FLAG NEW DISK
  3111. CHPD03    EQU    $
  3112.     $FLD    CDKMSG        ;REDISPLAY CURRENT
  3113.     RET
  3114.  
  3115.  
  3116. ; PRDD - READ AND DISPLAY PHYSICAL SECTOR
  3117.  
  3118.     $RTN    PRDD
  3119.     CALL    PSRD        ;READ PHYSICAL SECTOR
  3120.     LD    HL,FBUFF
  3121.     CALL    WRBF        ;DISPLAY BUFFER CONTENTS
  3122.     CALL    UBLK        ;UPDATE BLOCK
  3123.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  3124.     RET
  3125.  
  3126. ; DPSI - DISPLAY SECTOR INFORMATION
  3127.  
  3128.     $RTN    DPSI
  3129.     $FLD    PSTRFL        ;POSITION CURSOR FOR TRACK NUMBER
  3130.     $HEXW    PSMDTR        ;DISPLAY TRACK
  3131.     $FLD    PSSCFL        ;POSITION FOR SECTOR NUMBER
  3132.     $HEXW    PSMDSC        ;DISPLAY SECTOR
  3133.     $FLD    PSBLFL        ;POSITION FOR BLOCK NUMBER
  3134.     $HEXW    PSMDBL        ;DISPLAY BLOCK
  3135.     $FLD    PSDKFL        ;POSITION FOR DISK ID
  3136.     LD    A,(CURAN)    ;GET ABSOLUTE DRIVE NUMBER
  3137.     ADD    A,041H        ;MAKE IT ALPHA
  3138.     CALL    CHRO        ;DISPLAY DRIVE ID
  3139.     RET
  3140.  
  3141.  
  3142. ; UBLK - UPDATE BLOCK NUMBER
  3143.  
  3144.     $RTN    UBLK
  3145.     LD    DE,(PSMDTR)
  3146.     LD    BC,(DPBSPT)
  3147.     CALL    MULT
  3148.     LD    DE,(PSMDSC)
  3149.     ADD    HL,DE        ;CALCULATE ABSOLUTE SECTOR
  3150.     LD    DE,(DPERSC)
  3151.     OR    A
  3152.     SBC    HL,DE
  3153.     JR    NC,UBLK01    ;IF WITHIN SYSTEM AREA
  3154.     LD    DE,0        ;SET BLOCK ZERO
  3155.     JR    UBLK02
  3156. UBLK01    EQU    $        ;ELSE
  3157.     EX    DE,HL
  3158.     LD    BC,(DPESPB)
  3159.     CALL    DIVD        ;CALCULATE BLOCK NUMBER
  3160.     LD    HL,(DPBDSM)
  3161.     OR    A
  3162.     SBC    HL,DE
  3163.     JR    NC,UBLK04    ;IF BLOCK NOT IN RANGE
  3164.     LD    DE,0        ;SET BLOCK ZERO
  3165. UBLK04    EQU    $        ;ENDIF
  3166. UBLK02    EQU    $        ;ENDIF
  3167.     LD    (PSMDBL),DE    ;SET NEW BLOCK NUMBER
  3168.     RET
  3169.  
  3170.  
  3171. ; NXPS - NEXT PHYSICAL SECTOR
  3172.  
  3173.     $RTN    NXPS
  3174.     LD    HL,(PSMDSC)
  3175.     INC    HL
  3176.     LD    (PSMDSC),HL    ;INCREMENT PHYSICAL SECTOR
  3177.     LD    DE,(DPBSPT)
  3178.     OR    A
  3179.     SBC    HL,DE
  3180.     JR    C,NXPS01    ;IF TRACK OVERFLOW
  3181.     LD    HL,0
  3182.     LD    (PSMDSC),HL    ;SET TO FIRST SECTOR
  3183.     CALL    FRTR        ;ADVANCE TRACK
  3184. NXPS01    EQU    $        ;ENDIF
  3185.     RET
  3186.  
  3187.  
  3188. ; PRPS - PREVIOUS PHSICAL SECTOR
  3189.  
  3190.     $RTN    PRPS
  3191.     LD    HL,(PSMDSC)
  3192.     LD    A,H
  3193.     OR    L
  3194.     JR    NZ,PRPS01    ;IF SECTOR IS ZERO
  3195.     CALL    BWTR        ;GO BACK A TRACK
  3196.     LD    HL,(DPBSPT)    ;SET UP FOR DECREMENT
  3197. PRPS01    EQU    $        ;ENDIF
  3198.     DEC    HL
  3199.     LD    (PSMDSC),HL    ;DECREMENT TO PREVIOUS SECTOR
  3200.     RET
  3201.  
  3202.  
  3203. ; SPSN - SET PHYSICAL SECTOR NUMBER
  3204.  
  3205.     $RTN    SPSN
  3206.     LD    HL,SELMSG
  3207.     CALL    CFLD
  3208.     LD    HL,(PSMDSC)
  3209.     LD    (SAVPSC),HL    ;SAVE RECORD NUMBER
  3210.     $FLD    SECMSG        ;DISPLAY SET SECTOR
  3211.     LD    HL,0
  3212.     LD    (PSMDSC),HL    ;ZERO RECORD NUMBER
  3213. SPSN01    EQU    $
  3214.     CALL    UBLK
  3215.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  3216.     $IFLD    PSSCIP        ;POSITION AND GET INPUT
  3217.     $MTCH    HEXCHR
  3218.     JR    NZ,SPSN02    ;IF VALID HEX
  3219.     EX    DE,HL
  3220.     LD    HL,(PSMDSC)
  3221.     CALL    H16D        ;HL=HL*16+DIGIT
  3222.     LD    (PSMDSC),HL    ;SAVE NEW SECTOR NUMBER
  3223.     JR    SPSN03
  3224. SPSN02    EQU    $
  3225.     CP    $ESC
  3226.     JR    NZ,SPSN04    ;ELSEIF ESCAPE
  3227.     LD    HL,(SAVPSC)
  3228.     LD    (PSMDSC),HL    ;RESTORE SECTOR NUMBER
  3229.     JR    SPSN03
  3230. SPSN04    EQU    $
  3231.     CP    $LEFT
  3232.     JR    NZ,SPSN05    ;ELSEIF BACKSPACE
  3233.     LD    HL,PSMDSC+1
  3234.     XOR    A
  3235.     RRD
  3236.     DEC    HL
  3237.     RRD            ;SECTOR=SECTOR/16
  3238.     JR    SPSN03
  3239. SPSN05    EQU    $
  3240.     CP    CR
  3241.     JR    NZ,SPSN06    ;ELSEIF CR
  3242.     OR    A
  3243.     LD    HL,(PSMDSC)
  3244.     LD    DE,(DPBSPT)
  3245.     SBC    HL,DE
  3246.     JR    C,SPSN07    ;IF SECTOR OUT OF RANGE
  3247.     CALL    ALRM        ;SIGNAL ERROR
  3248.     LD    HL,(SAVPSC)
  3249.     LD    (PSMDSC),HL    ;RESTORE TO ORIGINAL
  3250.     XOR    A
  3251.     LD    (INCH),A    ;DONT EXIT
  3252. SPSN07    EQU    $
  3253.     JR    SPSN03
  3254. SPSN06    EQU    $        ;ELSE
  3255.     CALL    ALRM        ;ERROR
  3256. SPSN03    EQU    $        ;ENDIF
  3257.     LD    A,(INCH)
  3258.     CP    CR
  3259.     JR    Z,SPSN08    ;EXIT IF CR
  3260.     CP    $ESC
  3261.     JR    Z,SPSN08    ;EXIT IF ESC
  3262.     JP    SPSN01
  3263. SPSN08    EQU    $        ;ENDLOOP
  3264.     $FLD    CSCMSG        ;DISPLAY CURRENT SECTOR MESSAGE
  3265.     RET
  3266.  
  3267. SAVPSC: DS    2
  3268.  
  3269.  
  3270. ; FRTR - FORWARD TRACK
  3271.  
  3272.     $RTN    FRTR
  3273.     LD    HL,(PSMDTR)
  3274.     INC    HL
  3275.     LD    (PSMDTR),HL
  3276.     LD    DE,(DPETPD)
  3277.     OR    A
  3278.     SBC    HL,DE
  3279.     JR    C,FRTR01    ;IF DISK OVERFLOW
  3280.     LD    HL,0
  3281.     LD    (PSMDTR),HL    ;SET TO FIRST TRACK
  3282. FRTR01    EQU    $
  3283.     RET
  3284.  
  3285.  
  3286. ; SPTN - SET PHYSICAL TRACK NUMBER
  3287.  
  3288.     $RTN    SPTN
  3289.     LD    HL,SELMSG
  3290.     CALL    CFLD
  3291.     LD    HL,(PSMDTR)
  3292.     LD    (SAVPTR),HL    ;SAVE TRACK NUMBER
  3293.     $FLD    TRKMSG        ;DISPLAY TRKMSG
  3294.     LD    HL,0
  3295.     LD    (PSMDTR),HL    ;ZERO TRACK NUMBER
  3296. SPTN01    EQU    $
  3297.     CALL    UBLK
  3298.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  3299.     $IFLD    PSTRIP        ;POSITION AND GET INPUT
  3300.     $MTCH    HEXCHR
  3301.     JR    NZ,SPTN02    ;IF VALID HEX
  3302.     EX    DE,HL
  3303.     LD    HL,(PSMDTR)
  3304.     CALL    H16D        ;HL=HL*16+DIGIT
  3305.     LD    (PSMDTR),HL    ;SAVE NEW TRACK NUMBER
  3306.     JR    SPTN03
  3307. SPTN02    EQU    $
  3308.     CP    $ESC
  3309.     JR    NZ,SPTN04    ;ELSEIF ESCAPE
  3310.     LD    HL,(SAVPTR)
  3311.     LD    (PSMDTR),HL    ;RESTORE TRACK NUMBER
  3312.     JR    SPTN03
  3313. SPTN04    EQU    $
  3314.     CP    $LEFT
  3315.     JR    NZ,SPTN05    ;ELSEIF BACKSPACE
  3316.     LD    HL,PSMDTR+1
  3317.     XOR    A
  3318.     RRD
  3319.     DEC    HL
  3320.     RRD            ;TRACK=TRACK/16
  3321.     JR    SPTN03
  3322. SPTN05    EQU    $
  3323.     CP    CR
  3324.     JR    NZ,SPTN06    ;ELSEIF CR
  3325.     OR    A
  3326.     LD    HL,(PSMDTR)
  3327.     LD    DE,(DPETPD)
  3328.     SBC    HL,DE
  3329.     JR    C,SPTN07    ;IF TRACK OUT OF RANGE
  3330.     CALL    ALRM        ;SIGNAL ERROR
  3331.     LD    HL,(SAVPTR)
  3332.     LD    (PSMDTR),HL    ;RESTORE TO ORIGINAL
  3333.     XOR    A
  3334.     LD    (INCH),A    ;DONT EXIT
  3335. SPTN07    EQU    $        ;ENDIF
  3336.     JR    SPTN03
  3337. SPTN06    EQU    $        ;ELSE
  3338.     CALL    ALRM        ;ERROR
  3339. SPTN03    EQU    $        ;ENDIF
  3340.     LD    A,(INCH)
  3341.     CP    CR
  3342.     JR    Z,SPTN08    ;EXIT IF CR
  3343.     CP    $ESC
  3344.     JR    Z,SPTN08    ;EXIT IF ESC
  3345.     JP    SPTN01
  3346. SPTN08    EQU    $        ;ENDLOOP
  3347.     $FLD    CTRMSG        ;REDISPLY TRACK MESSAGE
  3348.     RET
  3349.  
  3350. SAVPTR: DS    2
  3351.  
  3352.  
  3353. ; BWTR - BACKWARD TRACK
  3354.  
  3355.     $RTN    BWTR
  3356.     LD    HL,(PSMDTR)
  3357.     LD    A,H
  3358.     OR    L
  3359.     JR    NZ,BWTR01    ;IF TRACK IS ZERO
  3360.     LD    HL,(DPETPD)    ;SET UP FOR DECREMENT
  3361. BWTR01    EQU    $        ;ENDIF
  3362.     DEC    HL
  3363.     LD    (PSMDTR),HL    ;DECREMENT TO PREVIOUS TRACK
  3364.     RET
  3365.  
  3366.  
  3367. ; SPBL - SET PHYSICAL BLOCK
  3368.  
  3369.     $RTN    SPBL
  3370.     LD    HL,SELMSG
  3371.     CALL    CFLD
  3372.     LD    HL,(PSMDBL)
  3373.     LD    (SAVPBL),HL    ;SAVE BLOCK NUMBER
  3374.     $FLD    BLKMSG        ;DISPLAY BLKMSG
  3375.     LD    HL,0
  3376.     LD    (PSMDBL),HL    ;ZERO BLOCK NUMBER
  3377. SPBL01    EQU    $
  3378.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  3379.     $IFLD    PSBLIP        ;POSITION AND GET INPUT
  3380.     $MTCH    HEXCHR
  3381.     JR    NZ,SPBL02    ;IF VALID HEX
  3382.     EX    DE,HL
  3383.     LD    HL,(PSMDBL)
  3384.     CALL    H16D        ;BLOCK=BLOCK*16+DIGIT
  3385.     LD    (PSMDBL),HL    ;SAVE NEW BLOCK NUMBER
  3386.     JR    SPBL03
  3387. SPBL02    EQU    $
  3388.     CP    $ESC
  3389.     JR    NZ,SPBL04    ;ELSEIF ESCAPE
  3390.     LD    HL,(SAVPBL)
  3391.     LD    (PSMDBL),HL    ;RESTORE BLOCK NUMBER
  3392.     JR    SPBL03
  3393. SPBL04    EQU    $
  3394.     CP    $LEFT
  3395.     JR    NZ,SPBL05    ;ELSEIF BACKSPACE
  3396.     LD    HL,PSMDBL+1
  3397.     XOR    A
  3398.     RRD
  3399.     DEC    HL
  3400.     RRD            ;BLOCK=BLOCK/16
  3401.     JR    SPBL03
  3402. SPBL05    EQU    $
  3403.     CP    CR
  3404.     JR    NZ,SPBL06    ;ELSEIF CR
  3405.     OR    A
  3406.     LD    DE,(PSMDBL)
  3407.     LD    HL,(DPBDSM)
  3408.     SBC    HL,DE
  3409.     JP    P,SPBL07    ;IF BLOCK OUT OF RANGE
  3410.     CALL    ALRM        ;SIGNAL ERROR
  3411.     LD    HL,(SAVPBL)
  3412.     LD    (PSMDBL),HL    ;RESTORE TO ORIGINAL
  3413.     XOR    A
  3414.     LD    (INCH),A    ;DONT EXIT
  3415.     JR    SPBL08
  3416. SPBL07    EQU    $        ;ELSE
  3417.     LD    DE,(PSMDBL)
  3418.     LD    BC,(DPESPB)
  3419.     CALL    MULT
  3420.     LD    DE,(DPERSC)
  3421.     ADD    HL,DE        ;CALCULATE ABSOLUTE SECTOR
  3422.     EX    DE,HL
  3423.     LD    BC,(DPBSPT)
  3424.     CALL    DIVD
  3425.     LD    (PSMDTR),DE    ;SET TRACK
  3426.     LD    (PSMDSC),HL    ;SET SECTOR
  3427. SPBL08    EQU    $        ;ENDIF
  3428.     JR    SPBL03
  3429. SPBL06    EQU    $        ;ELSE
  3430.     CALL    ALRM        ;ERROR
  3431. SPBL03    EQU    $        ;ENDIF
  3432.     LD    A,(INCH)
  3433.     CP    CR
  3434.     JR    Z,SPBL09    ;EXIT IF CR
  3435.     CP    $ESC
  3436.     JR    Z,SPBL09    ;EXIT IF ESC
  3437.     JP    SPBL01
  3438. SPBL09    EQU    $        ;ENDLOOP
  3439.     $FLD    CBLMSG        ;REDISPLAY CURRENT BLOCK MESSAGE
  3440.     RET
  3441.  
  3442. SAVPBL: DS    2
  3443.  
  3444.  
  3445. ; PSPM - PHYSICAL SCRATCHPAD MODE
  3446.  
  3447.     $RTN    PSPM
  3448.     $NPANEL PSPMPN        ;DISPLAY PANEL
  3449.     $FLD    PSPCUR        ;POSITION FOR CURRENT INFO
  3450.     $STRO    SPDMSG
  3451.     LD    A,(CURAN)
  3452.     ADD    A,41H
  3453.     CALL    CHRO        ;DISPLAY DRIVE
  3454.     $STRO    SPTMSG
  3455.     $HEXW    PSMDTR        ;TRACK
  3456.     $STRO    SPSMSG
  3457.     $HEXW    PSMDSC        ;SECTOR
  3458.     $FLD    PSPSPD        ;POSITION FOR S/P DATA
  3459.     CALL    DSPD
  3460.     CALL    SPCI        ;GET COMMAND
  3461.     $EXVA    PSPMV        ;PROCESS COMMAND
  3462.     LD    A,0FFH
  3463.     LD    (RPANEL),A    ;REQUEST PANEL
  3464.     RET
  3465.  
  3466. PSPMPN: DB    3
  3467.     DB    2,0,'ESC Return to sector display',0
  3468.     DB    3,0,'C   Copy current sector to scratchpad',0
  3469.     DB    4,0,'E   Exchange current sector with scratchpad',0
  3470.  
  3471. PSPCUR: DB    11,0,'Current    :- ',0
  3472. PSPSPD: DB    12,0,'Scratchpad :- ',0
  3473.  
  3474. PSPML:    DB    3,$ESC,'CE'
  3475. PSPMV:    DW    PSPX
  3476.     DW    PLSP
  3477.     DW    PXSP
  3478.  
  3479.     $RTN    PSPX
  3480.     RET
  3481.  
  3482.  
  3483. ; PXSP - EXCHANGE WITH SCRATCHPAD
  3484.  
  3485.     $RTN    PXSP
  3486.     LD    A,(SPTYPE)
  3487.     OR    A
  3488.     JR    NZ,PXSP01    ;IF PAD EMPTY
  3489.     CALL    ALRM        ;RING BELL
  3490.     JR    PXSP02
  3491. PXSP01    EQU    $        ;ELSE
  3492.     LD    BC,(SPADDR)
  3493.     CALL    dmaSet        ;SET CPM BUFFER
  3494.     CALL    PSWR        ;WRITE BUFFER
  3495.     LD    BC,FBUFF
  3496.     CALL    DMASET        ;RESTORE DMA
  3497.     CALL    PLSP        ;COPY OLD BUFFER
  3498. PXSP02    EQU    $        ;ENDIF
  3499.     RET
  3500.  
  3501. ; PLSP - LOAD SCRATCHPAD (PHYSICAL)
  3502.  
  3503.     $RTN    PLSP
  3504.     LD    HL,FBUFF
  3505.     LD    DE,(SPADDR)
  3506.     LD    BC,128
  3507.     LDIR            ;COPY THE BUFFER
  3508.     LD    A,(CURAN)
  3509.     LD    (SPDRIV),A    ;SET DRIV
  3510.     LD    HL,(PSMDTR)
  3511.     LD    (SPNAME),HL    ;SET TRACK
  3512.     LD    HL,(PSMDSC)
  3513.     LD    (SPSECT),HL    ;SET SECTOR
  3514.     LD    A,1
  3515.     LD    (SPTYPE),A    ;SET THE TYPE
  3516.     RET
  3517.  
  3518.  
  3519. ; DSPD DISPLAY S/P DATA
  3520.  
  3521.     $RTN    DSPD
  3522.     CALL    DSPI        ;DISPLAY SP INFO
  3523.     LD    A,(SPTYPE)
  3524.     OR    A
  3525.     JR    Z,DSPD01    ;IF SP NOT EMPTY
  3526.     CALL    ZBSA        ;CLEAR ADDRESS COUNTER
  3527.     LD    HL,(SPADDR)
  3528.     CALL    WRBF        ;DISPLAY IT
  3529. DSPD01    EQU    $        ;ENDIF
  3530.     RET
  3531.  
  3532.  
  3533. ; LSEL - LIST FILE SELECTION STUB MASK POINTED TO BY HL
  3534.  
  3535.     $RTN    LSEL
  3536.     LD    DE,LMDFN
  3537.     LD    BC,11
  3538.     LDIR
  3539.     RET
  3540.  
  3541. ; PSCH - PHYSICAL SECTOR CHANGE
  3542.  
  3543.     $RTN    PSCH
  3544.     CALL    SCCH        ;GO INTO SECTOR CHANGE MODE
  3545.     LD    A,(SCCHWR)
  3546.     OR    A
  3547.     JR    Z,PSCH03    ;IF WRITE REQUIRED
  3548.     CALL    PSWR        ;WRITE OUT SECTOR
  3549. PSCH03    EQU    $        ;ENDIF
  3550.     LD    A,0FFH
  3551.     LD    (RPANEL),A    ;REQUEST PANEL
  3552.     RET            
  3553.  
  3554.  
  3555. ; SCCH - SECTOR CHANGE MODE
  3556.  
  3557.     $RTN    SCCH
  3558.     LD    HL,HLAREA
  3559.     CALL    CLRA        ;CLEAR THE HELP AREA
  3560.     $PANEL    SCCHPN        ;DISPLAY SECTOR CHANGE PANEL
  3561.     LD    A,FALSE
  3562.     LD    (SCCHWR),A    ;WRITE FLAG FALSE
  3563.     LD    (ASCII),A    ;ASCII FALSE
  3564.     LD    (SCCHEX),A    ;EXIT FALSE
  3565.     LD    (LOORD),A    ;START WITH HO HEX DIGIT
  3566.     XOR    A
  3567.     LD    (BUFPOS),A    ;BUFFER POSITION 0
  3568. SCCH03    EQU    $        ;LOOP
  3569.     CALL    SLCP
  3570.     CALL    UDCP        ;POSITION CURSOR
  3571.     CALL    CHRI
  3572.     CP    020H
  3573.     JP    NC,SCCH04    ;IF CONTROL CODE
  3574.     $MTCH    SCCHLS
  3575.     JR    Z,SCCH05    ;IF NOT VALID
  3576.     CALL    ALRM        ;SOUND THE ALARM
  3577.     JR    SCCH06
  3578. SCCH05    EQU    $        ;ELSE
  3579.     $EXVA    SCCHVC        ;ACTION CONTROL CODE
  3580. SCCH06    EQU    $        ;ENDIF
  3581.     JR    SCCH08
  3582. SCCH04    EQU    $        ;ELSE
  3583.     LD    A,(ASCII)
  3584.     OR    A
  3585.     JR    Z,SCCH09    ;IF ASCII MODE
  3586.     CALL    MACH        ;MAKE ASCII CHANGE
  3587.     JR    SCCH10
  3588. SCCH09    EQU    $        ;ELSE
  3589.     CALL    MHCH        ;MAKE HEX CHANGE
  3590. SCCH10    EQU    $        ;ENDIF
  3591. SCCH08    EQU    $        ;ENDIF
  3592.     LD    A,(SCCHEX)
  3593.     OR    A
  3594.     JR    NZ,SCCH11    ;EXIT IF END OF UPDATES
  3595.     JR    SCCH03
  3596. SCCH11    EQU    $        ;ENDLOOP
  3597.     RET
  3598.  
  3599. SCCHEX: DB    0
  3600. SCCHWR: DB    0
  3601.  
  3602.  
  3603. ; SECTOR CHANGE MODE PANEL AND ACTION VECTOR
  3604.  
  3605. SCCHPN: DB    8
  3606.     DB    2,0,'^',$LEFT+040H,'  Cursor left',0
  3607.     DB    2,40,'^',$RIGHT+040H,'  Cursor right',0
  3608.     DB    3,0,'^',$UP+040H,'  Cursor up',0
  3609.     DB    3,40,'^',$DOWN+040H,'  Cursor down',0
  3610.     DB    4,0,'^',$TAB+040H,'  Change Side',0
  3611.     DB    4,40,'CR  New Line',0
  3612.     DB    5,0,'^',$QUIT+040H,'  Cancel changes',0
  3613.     DB    5,40,'^',$END+040H,'  Save Changes',0
  3614.  
  3615. SCCHLS: DB    8,$LEFT,$TAB,$DOWN,$UP,$RIGHT,CR,$END,$QUIT
  3616.  
  3617. SCCHVC    EQU    $
  3618.     DW    LEFT
  3619.     DW    TOGL
  3620.     DW    DOWN
  3621.     DW    UPWD
  3622.     DW    RGHT
  3623.     DW    NWLN
  3624.     DW    CHND
  3625.     DW    QUIT
  3626.  
  3627.  
  3628. ; LEFT - MOVE CURSOR LEFT
  3629.  
  3630.     $RTN    LEFT
  3631.     LD    A,(LOORD)
  3632.     OR    A
  3633.     JR    NZ,LEFT01    ;IF HIGH OR ASCII
  3634.     LD    A,(BUFPOS)
  3635.     DEC    A
  3636.     AND    07FH
  3637.     LD    (BUFPOS),A    ;DECREMENT POSITION
  3638. LEFT01    EQU    $
  3639.     LD    A,(ASCII)
  3640.     OR    A
  3641.     JR    NZ,LEFT02    ;IF HEX MODE
  3642.     LD    A,(LOORD)
  3643.     CPL
  3644.     LD    (LOORD),A    ;TOGGLE DIGIT
  3645. LEFT02    EQU    $
  3646.     RET
  3647.  
  3648.  
  3649. ; TOGL - TOGGLE BETWEEN HEX AND ASCII
  3650.  
  3651.     $RTN    TOGL
  3652.     LD    A,(ASCII)
  3653.     CPL
  3654.     LD    (ASCII),A    ;TOGGLE MODE FLAG
  3655.     LD    A,FALSE
  3656.     LD    (LOORD),A    ;INDICATE HO DIGIT
  3657.     RET
  3658.  
  3659.  
  3660. ; DOWN - MOVE CURSOR DOWN ONE LINE
  3661.  
  3662.     $RTN    DOWN
  3663.     LD    A,(BUFPOS)
  3664.     ADD    A,16
  3665.     AND    07FH
  3666.     LD    (BUFPOS),A
  3667.     RET
  3668.  
  3669.  
  3670. ; UPWD - MOVE CURSOR UP ONE LINE
  3671.  
  3672.     $RTN    UPWD
  3673.     LD    A,(BUFPOS)
  3674.     SUB    16
  3675.     AND    07FH        ;MODULO 128
  3676.     LD    (BUFPOS),A
  3677.     RET
  3678.  
  3679.  
  3680. ; RGHT - MOVE CURSOR RIGHT
  3681.  
  3682.     $RTN    RGHT
  3683.     LD    A,(ASCII)
  3684.     OR    A
  3685.     JR    NZ,RGHT01    ;IF HEX MODE
  3686.     LD    A,(LOORD)
  3687.     CPL            ;TOGGLE HEX DIGIT
  3688.     LD    (LOORD),A
  3689. RGHT01    EQU    $        ;ENDIF
  3690.     LD    A,(LOORD)
  3691.     OR    A
  3692.     JR    NZ,RIGH02    ;IF HIGH ORD OR ASCII
  3693.     LD    A,(BUFPOS)
  3694.     INC    A
  3695.     AND    07FH
  3696.     LD    (BUFPOS),A    ;INCREMENT POSITION
  3697. RIGH02    EQU    $        ;ENDIF
  3698.     RET
  3699.  
  3700.  
  3701. ; NWLN - MOV CURSOR TO START OF NEW LINE
  3702.  
  3703.     $RTN    NWLN
  3704.     LD    A,FALSE
  3705.     LD    (LOORD),A    ;INDICATE HO HEX DIGIT
  3706.     LD    A,(BUFPOS)
  3707.     ADD    A,16
  3708.     AND    070H
  3709.     LD    (BUFPOS),A    ;NEW BUFFER ADDR
  3710.     RET
  3711.  
  3712.  
  3713. ; CHND - CHANGE END AND WRITE
  3714.  
  3715.     $RTN    CHND
  3716.     LD    A,TRUE
  3717.     LD    (SCCHEX),A    ;SIGNAL EXIT
  3718.     LD    (SCCHWR),A    ;SIGNAL WRITE
  3719.     RET
  3720.  
  3721.  
  3722. ; QUIT - END WITHOUT SAVING UPDATES
  3723.  
  3724.     $RTN    QUIT
  3725.     LD    A,TRUE
  3726.     LD    (SCCHEX),A    ;SIGNAL EXIT
  3727.     RET
  3728.  
  3729.  
  3730. ; WRBF - DISPLAY FILE DATA IN SECTOR BUFFER
  3731.  
  3732.     $RTN    WRBF
  3733.     EX    DE,HL
  3734.     XOR    A
  3735.     LD    (BUFPOS),A    ;SET OFFSET TO 0
  3736. WRBF01    EQU    $        ;LOOP (HEX AND ASCII LINE)
  3737.     PUSH    DE        ;SAVE BUFFER POINTER
  3738.     PUSH    DE        ;AND FOR ASCII
  3739.     XOR    A
  3740.     LD    (CPOS),A    ;POSITION 1
  3741.     CALL    STLP        ;SET LINE CURSOR POSITION
  3742.     CALL    UDCP        ;UPDATE CURSOR
  3743.     CALL    PRTADR        ;DISPLAY ADDRESS
  3744.     LD    A,(BASEAD+2)
  3745.     ADD    A,010H
  3746.     LD    (BASEAD+2),A    ;INC ADDR FOR NEXT LINE
  3747.     CALL    SHCP        ;SET UP CURSOR POSN IN HEX AREA
  3748.     CALL    UDCP        ;UPDATE CURSOR
  3749.     POP    DE        ;GET CURRENT ADDRESS
  3750. WRBF03    EQU    $        ;LOOP (BYTES IN HEX)
  3751.     LD    A,(DE)        ;GET CHARACTER THERE
  3752.     INC    DE        ;INCREMENT BUFF POINTER
  3753.     CALL    HEXO        ;PRINT BYTE
  3754.     CALL    SPCO        ;PRINT SPACE
  3755.     LD    HL,BUFPOS
  3756.     INC    (HL)        ;INC TO NEXT COL
  3757.     LD    A,3
  3758.     AND    (HL)
  3759.     JR    NZ,WRBF04    ;IF END OF GROUP
  3760.     CALL    SPCO        ;PRINT SPACE
  3761. WRBF04    EQU    $        ;ENDIF
  3762.     LD    A,0FH
  3763.     AND    (HL)
  3764.     JR    NZ,WRBF03    ;UNTIL 16 BYTES DISPLAYED
  3765.  
  3766.     LD    A,(HL)
  3767.     SUB    16
  3768.     LD    (HL),A        ;RESET BUFFER OFFSET
  3769.     CALL    SACP        ;POSITION FOR ASCII
  3770.     LD    HL,CPOS
  3771.     DEC    (HL)        ;BACK OFF 1 FOR MARGIN
  3772.     CALL    UDCP        ;POSITION CURSOR
  3773.     LD    A,'|'
  3774.     CALL    CHRO        ;PRINT MARGIN
  3775.     POP    DE        ;RESTORE CHAR POINTER
  3776. WRBF02    EQU    $        ;LOOP (BYTES IN ASCII)
  3777.     LD    A,(DE)        ;GET CURRENT CHARACTER
  3778.     INC    DE        ;INCREMENT POINTER
  3779.     CALL    ASCO        ;PRINT CHAR
  3780.     LD    HL,BUFPOS
  3781.     INC    (HL)        ;INCREMENT BUFFER OFFSET
  3782.     LD    A,0FH
  3783.     AND    (HL)
  3784.     JR    NZ,WRBF02    ;UNTIL 16 BYTES DISPLAYED
  3785.     LD    A,'|'
  3786.     CALL    CHRO        ;PRINT MARGIN
  3787.  
  3788.     LD    A,(HL)
  3789.     AND    07FH
  3790.     JP    NZ,WRBF01    ;UNTIL 128 BYTES DISPLAYED
  3791.     RET
  3792.  
  3793.  
  3794. ; CURSOR POSITON TABLES FOR HEX AND ASCII DISPLAY
  3795.  
  3796. LPTAB:    DB    14,15,16,17,18,19,20,21
  3797.  
  3798. HCTAB:    DB     9,12,15,18,22,25,28,31,35,38,41,44,48,51,54,57
  3799. ACTAB:    DB    63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78
  3800.  
  3801. DCTAB:    DB    00,20,40,60 
  3802.  
  3803.  
  3804. ; ZBSA - ZERO BASE ADDRESS
  3805.  
  3806.     $RTN    ZBSA
  3807.     XOR    A
  3808.     LD    (BASEAD),A
  3809.     LD    (BASEAD+1),A
  3810.     LD    (BASEAD+2),A
  3811.     RET
  3812.  
  3813.  
  3814. ; PRTADR - PRINT FILE ADDRESS
  3815.  
  3816.     $RTN    PRTADR
  3817.     $HEXW    BASEAD        ;DISPLAY 2 BYTES
  3818.     LD    A,(BASEAD+2)
  3819.     CALL    HEXO
  3820.     RET
  3821.  
  3822.  
  3823. ; SLCP - SET CURSOR TO CURRENT LINE AND COLUMN POSITION IN BUFFER
  3824.  
  3825.     $RTN    SLCP
  3826.     CALL    STLP
  3827.     CALL    STCP
  3828.     RET
  3829.  
  3830.  
  3831. ; STLP - SET UP LINE POSITION
  3832.  
  3833.     $RTN    STLP
  3834.     LD    HL,LPTAB    ;GET BASE OF LINE TABLE
  3835.     LD    A,(BUFPOS)
  3836.     RRA
  3837.     RRA
  3838.     RRA
  3839.     RRA
  3840.     AND    0FH        ;MOV TO LOW ORDER
  3841.     CALL    AAHL
  3842.     LD    A,(HL)        ;GET VALUE
  3843.     LD    (LPOS),A    ;SET UP FOR UDCP
  3844.     RET
  3845.  
  3846. ; STCP - SET UP COLUMN POSITION IN BUFFER
  3847.  
  3848.     $RTN    STCP
  3849.     LD    A,(ASCII)
  3850.     OR    A
  3851.     JR    Z,STCP01    ;IF IN ASCII DISPLAY MODE
  3852.     CALL    SACP        ;SET UP ASCII DISPLAY
  3853.     JR    STCP02
  3854. STCP01    EQU    $        ;ELSE
  3855.     CALL    SHCP        ;SET UP FOR HEX DISPLAY
  3856.     LD    A,(LOORD)
  3857.     OR    A
  3858.     JR    Z,STCP03    ;IF LOW ORDER DIGIT
  3859.     LD    HL,CPOS
  3860.     INC    (HL)        ;INCREMENT COLUMN POS
  3861. STCP03    EQU    $        ;ENDIF
  3862. STCP02    EQU    $        ;ENDIF
  3863.     RET
  3864.  
  3865. ASCII:    DB    0
  3866. LOORD:    DB    0
  3867.  
  3868.  
  3869. ; SHCP - SET CURSOR ADDRESS FOR HEX DISPLAY
  3870.  
  3871.     $RTN    SHCP
  3872.     LD    HL,HCTAB
  3873.     LD    A,(BUFPOS)
  3874.     AND    0FH
  3875.     CALL    AAHL
  3876.     LD    A,(HL)        ;PICK UP VALUE
  3877.     LD    (CPOS),A    ;SET POSITION
  3878.     RET
  3879.  
  3880.  
  3881. ; SACP - SET CURSOR ADDRESS FOR ASCII DISPLAY
  3882.  
  3883.     $RTN    SACP
  3884.     LD    HL,ACTAB
  3885.     LD    A,(BUFPOS)
  3886.     AND    0FH
  3887.     CALL    AAHL
  3888.     LD    A,(HL)
  3889.     LD    (CPOS),A
  3890.     RET
  3891.  
  3892.  
  3893. ; MACH - UPDATE BUFFER IN ASCII FORMAT
  3894.  
  3895.     $RTN    MACH
  3896.     LD    A,(INCH)
  3897.     CP    020H
  3898.     JR    C,MACH01
  3899.     CP    080H
  3900.     JR    C,MACH02    ;IF CHARACTER OUT OF RANGE
  3901. MACH01    EQU    $
  3902.     CALL    ALRM        ;SOUND THE ALARM
  3903.     JR    MACH03
  3904. MACH02    EQU    $        ;ELSE
  3905.     PUSH    AF
  3906.     PUSH    AF        ;SAVE CHAR
  3907.     LD    A,(BUFPOS)    ;GET BUFFER OFFSET
  3908.     LD    HL,FBUFF
  3909.     CALL    AAHL        ;POINT TO CHARACTER
  3910.     POP    AF        ;RESTORE CHAR
  3911.     LD    (HL),A        ;CHARACTER TO BUFFER
  3912.     CALL    ASCO        ;ECHO IT
  3913.     CALL    SHCP        
  3914.     CALL    UDCP        ;POSITION IN HEX AREA
  3915.     POP    AF        ;RESTORE CHAR
  3916.     CALL    HEXO
  3917.     CALL    RGHT        ;MOVE CURSOR FOR NEXT
  3918. MACH03    EQU    $        ;ENDIF
  3919.     RET
  3920.  
  3921.  
  3922. ; MHCH - UPDATE BUFFER CONTENTS IN HEX
  3923.  
  3924.     $RTN    MHCH
  3925.     LD    A,(INCH)    ;GET INPUT CHARACTER
  3926.     CALL    FOLD
  3927.     LD    (INCH),A    ;SAVE FOLDED VERSION
  3928.     $MTCH    HEXCHR
  3929.     JR    Z,MHCH02    ;IF NOT VALID HEX
  3930.     CALL    ALRM        ;SOUND THE ALARM
  3931.     JR    MHCH03
  3932. MHCH02    EQU    $
  3933.     LD    C,L        ;SET HEX VALUE OF NIBBLE IN C
  3934.     LD    A,(INCH)
  3935.     CALL    ASCO        ;ECHO IT
  3936.     LD    A,(BUFPOS)    ;GET OFFSET
  3937.     LD    HL,FBUFF    ;BASE OF BUFFET
  3938.     CALL    AAHL        ;HL=A(CURRENT CHAR)
  3939.     LD    B,(HL)        ;B = CURRENT CHARACTER
  3940.     LD    A,(LOORD)
  3941.     OR    A
  3942.     JR    Z,MHCH04    ;IF LO ORDER NIBBLE
  3943.     LD    A,0F0H        ;SET MASK
  3944.     JR    MHCH05
  3945. MHCH04    EQU    $        ;ELSE
  3946.     LD    A,C        ;CHAR TO A REG
  3947.     RLCA
  3948.     RLCA
  3949.     RLCA
  3950.     RLCA            ;HEX=HEX*16
  3951.     AND    0F0H        ;CLEAR ANY MINCE LEFT
  3952.     LD    C,A        ;BACK TO C REG
  3953.     LD    A,00FH        ;SET MASK
  3954. MHCH05    EQU    $        ;ENDIF
  3955.     AND    B        ;MASK NIBBLE
  3956.     OR    C        ;INSERT NEW VALUE
  3957.     LD    (HL),A        ;REPLACE IN BUFFER
  3958.     PUSH    AF        ;SAVE IT FOR ASCII
  3959.     CALL    SACP
  3960.     CALL    UDCP        ;TOGGLE TO ASCII DISP
  3961.     POP    AF        ;PICK UP NEW CHAR
  3962.     CALL    ASCO        ;DISPLAY IT
  3963.     CALL    RGHT        ;ADVANCE CURSOR
  3964. MHCH03    EQU    $        ;ENDIF
  3965.     RET
  3966.  
  3967. HEXCHR: DB    16,'0123456789ABCDEF'    ;VALID HEX CHARACTERS
  3968.  
  3969.  
  3970. ; CHDR - CHANGE TO DRIVE IN A
  3971.  
  3972.     $RTN    CHDR
  3973.     LD    (SAVDRV),A    ;SAVE REQUESTED DRIVE
  3974.     LD    C,A
  3975.     CALL    SELDSK        ;LOCATE DPH
  3976.     LD    A,H
  3977.     OR    L
  3978.     JR    NZ,CHDR01    ;IF INVALID DISK
  3979.     LD    A,(CURAN)    ;GET CURRENT ID
  3980.     LD    C,A
  3981.     CALL    SELDSK        ;RE-SELECT IT
  3982.     XOR    A
  3983.     JP    CHDR02
  3984. CHDR01    EQU    $        ;ELSE
  3985.     PUSH    HL        ;SAVE DPH
  3986.     LD    C,RESET
  3987.     CALL    CPM        ;RESET DISKS
  3988.     LD    HL,-1        ;Clear prvTrk and prvSec to force
  3989.     LD    (PRVTRK),HL    ; physical I/O on next access
  3990.     LD    (PRVSEC),HL
  3991.  
  3992. ;        <<< INITIALISE PHYSICAL CONTROL BLOCKS >>>
  3993. ; If CP/M 3.1 then the DPH is not necessarily in the same memory bank as
  3994. ; this program but the banked BDOS does us the favour of making a local
  3995. ; copy in common memory.
  3996.  
  3997.     POP    HL        ;RESTORE DPH
  3998.     LD    DE,DPHLCL
  3999.     LD    BC,16
  4000.     LDIR            ;TAKE LOCAL COPY OF DPH
  4001.     LD    HL,(DPHDPB)    ;DPB pointer for CP/M 2.x
  4002.     LD    A,(CPM3)    ;Check which version of CP/M so we get
  4003.     OR    A        ; the DPB pointer right
  4004.     JR    Z,COPYDPB    ;Skip reload if 2.2
  4005.     LD    HL,(DPHDP3)    ;Get CP/M 3 DPB pointer
  4006. COPYDPB:
  4007.     LD    DE,DPBLCL
  4008.     LD    BC,17        ;Increased from 15 for CP/M+
  4009.     LDIR            ;TAKE LOCAL COPY OF DPB
  4010.     LD    DE,(DPBSPT)
  4011.     LD    BC,(DPBOFF)
  4012.     CALL    MULT        ;HL RETURNS NUMBER OF SYSTEM SECTORS
  4013.     PUSH    HL
  4014.     LD    (DPERSC),HL    ;SAVE RESERVED SECTORS
  4015.     LD    A,(DPBBLM)
  4016.     LD    D,0
  4017.     LD    E,A
  4018.     INC    DE
  4019.     LD    (DPESPB),DE    ;SAVE SECTORS PER BLOCK
  4020.     LD    BC,(DPBDSM)
  4021.     CALL    MULT        ;HL RETURNS NUMBER OF FILE SECTORS
  4022.     POP    DE
  4023.     ADD    HL,DE        ;HL CONTAINS SECTORS PER DISK
  4024.     LD    DE,(DPBSPT)
  4025.     DEC    DE
  4026.     ADD    HL,DE        ;READY TO ROUND UP
  4027.     EX    DE,HL
  4028.     LD    BC,(DPBSPT)
  4029.     CALL    DIVD        ;DE RETURNS TRACKS PER DISK
  4030.     LD    (DPETPD),DE    ;SAVE TRACKS PER DISK
  4031.                 ;INITIALISE FILE CONTROL BLOCKS
  4032.     LD    A,(SAVDRV)    ;RESTORE REQUESTED DRIVE
  4033.     LD    (CURAN),A    ;SAVE AS ABSOLUTE DISK NUMBER
  4034.     INC    A    
  4035.     LD    (WRKDR),A    ;PUT IT IN WORK FCB
  4036.     LD    (LMDDR),A    ;AND DIRECTORY FCB
  4037.     CALL    RDIR        ;READ DIRECTORY
  4038.     LD    A,0FFH
  4039.     OR    A        ;SET NON-ZERO FLAGS
  4040. CHDR02    EQU    $        ;ENDIF
  4041.     RET
  4042.  
  4043. SAVDRV: DS    1
  4044.  
  4045.  
  4046. ; DLST - DIRECTORY LISTING
  4047.  
  4048.     $RTN    DLST
  4049.     $FLD    DDLMSG
  4050.     LD    A,(CURAN)    ;GET DISK ID
  4051.     ADD    A,41H        ;CONVERT TO ASCII LETTER
  4052.     LD    (DRIVNM),A    ;PUT DRIVE NAME IN MESSAGE
  4053.     LD    DE,LMDFN
  4054.     CALL    FMTN
  4055.     $STRO    DRIVNM
  4056.     LD    DE,(FSTDE@)
  4057.     LD    A,(DIROFF)    ;GET STARTING ENTRY
  4058.     LD    H,0
  4059.     LD    L,A
  4060.     CALL    H16D        ;HL=COUNT*LENGTH+FIRST
  4061.     LD    (NXTDE@),HL    ;POINT TO FIRST DISPLAY
  4062.     XOR    A
  4063.     LD    (PRTCNT),A
  4064. DLST02    EQU    $        ;LOOP
  4065.     LD    A,(DIROFF)
  4066.     LD    B,A
  4067.     LD    A,(DECNT)
  4068.     SUB    B
  4069.     LD    HL,PRTCNT
  4070.     CP    (HL)
  4071.     JR    Z,DLST03    ;EXIT IF ALL ENTRIES PROCESSED
  4072.     LD    A,(HL)        ;GET DISPLAY COUNTER
  4073.     CALL    DIRPOS        ;POSITION TO DISPLAY
  4074.     LD    A,(FLAGCH)    ;LOAD FLAG CHARACTER
  4075.     CALL    CHRO        ;PRINT IT
  4076.     CALL    SPCO        ;AND SPACE
  4077.     LD    DE,(NXTDE@)    ;POINT ENTRY TO PRINT
  4078.     CALL    FMTN        ;FORMAT FILE NAME
  4079.     $STRO    FILENM        ;PRINT NAME
  4080.     LD    HL,(NXTDE@)
  4081.     LD    DE,16
  4082.     ADD    HL,DE
  4083.     LD    (NXTDE@),HL    ;UPDATE TABLE POINTER
  4084.     LD    HL,PRTCNT
  4085.     INC    (HL)        ;INCREMENT DISPLAY COUNTER
  4086.     LD    A,32
  4087.     CP    (HL)
  4088.     JR    Z,DLST03    ;EXIT DISPLAY FULL
  4089.     JR    DLST02
  4090. DLST03    EQU    $        ;ENDLOOP
  4091.     RET
  4092.  
  4093. DDLMSG: DB    12,20,'Directory list - ',0
  4094.  
  4095.  
  4096. ; RDIR - READ DIRECTORY
  4097.  
  4098.     $RTN    RDIR
  4099.     XOR    A
  4100.     LD    (DECNT),A    ;NO ENTRIES IN TABLE
  4101.     LD    (SELDE),A    ;SELECT LIST ENTRY 0
  4102.     LD    (DIROFF),A    ;DISPLAY STARTS AT 0
  4103.     LD    HL,(MEMRY)
  4104.     LD    (NXTDE@),HL    ;WHERE TO INSERT POINTER
  4105.     LD    (FSTDE@),HL    ;START OF TABLE POINTER
  4106.     DEC    HL
  4107.     LD    (TOPDE@),HL    ;TOP OF TABLE
  4108.     LD    DE,LMDFCB
  4109.     LD    C,FNDFST
  4110.     CALL    CPM        ;GET FIRST DIRECTORY ENTRY
  4111.     CP    0FFH
  4112.     JR    Z,RDIR01    ;QUIT IF NO FILE MATCHED
  4113.     RRCA
  4114.     RRCA
  4115.     RRCA            ;MULTIPY BY 32
  4116.     LD    HL,FBUFF    ;POINT TO RECORD
  4117.     CALL    AAHL        ;ADDRESS OF CURRENT ENTRY
  4118.     LD    (NEWDE@),HL    ;SAVE IT
  4119.     CALL    INSRT        ;PUT MATCHED ENTRY IN TABLE
  4120.     LD    HL,(TOPDE@)
  4121.     LD    DE,16
  4122.     ADD    HL,DE
  4123.     LD    (TOPDE@),HL    ;MARK TOP OF TABLE
  4124. RDIR02    EQU    $        ;LOOP
  4125.     LD    DE,LMDFCB
  4126.     LD    C,FNDNXT
  4127.     CALL    CPM        ;FIND NEXT MATCH
  4128.     CP    0FFH
  4129.     JR    Z,RDIR03    ;EXITIF NO MORE
  4130.     RRCA
  4131.     RRCA
  4132.     RRCA            ;MULTIPLY DIR CODE BY 32
  4133.     LD    HL,FBUFF    ;POINT TO RECORD
  4134.     CALL    AAHL
  4135.     LD    (NEWDE@),HL    ;SAVE IT
  4136.     CALL    ORDER        ;FIND OUT WHERE TO PUT IT
  4137.     CALL    INSRT        ;PUT ENTRY IN TABLE
  4138.     JR    RDIR02
  4139. RDIR03    EQU    $        ;ENDLOOP
  4140. RDIR01    EQU    $        ;ENDIF
  4141.     LD    HL,(TOPDE@)
  4142.     INC    HL
  4143.     LD    (PGEPTR),HL    ;MARK START OF PAGING POINTERS
  4144.     RET
  4145.  
  4146. ; INSRT - PUT DIRECTORY ENTRY IN TABLE
  4147.  
  4148. INSRT    EQU    $
  4149.     LD    DE,(NXTDE@)    ;GET TABLE POINTER
  4150.     LD    HL,(NEWDE@)    ;GET ADDRESS OF NEW ENTRY
  4151.     INC    HL        ;DONT COPY DRIVE BYTE
  4152.     LD    BC,16        ;LENGTH OF ENTRY
  4153.     LDIR            ;SAVE ENTRY
  4154.     LD    HL,DECNT
  4155.     INC    (HL)        ;ADD ONE TO ENTRY COUNT
  4156.     RET
  4157.  
  4158. ; ORDER - UPDATE THE DIRECTORY TABLE
  4159.  
  4160. ORDER    EQU    $
  4161.     LD    HL,(FSTDE@)
  4162. ORDER1    EQU    $        ;LOOP
  4163.     LD    DE,(TOPDE@)
  4164.     EX    DE,HL
  4165.     OR    A
  4166.     SBC    HL,DE
  4167.     JP    M,ORDER2    ;EXIT IF END OF TABLE
  4168.     PUSH    DE        ;SAVE CURRENT POINTER
  4169.     LD    HL,(NEWDE@)    ;POINT TO NEW ENTRY
  4170.     INC    HL        ;IGNORE DRIVE ID FIELD
  4171.     LD    BC,11        ;LENGTH OF FILE NAME
  4172.     CALL    CPST        ;COMPARE FILENAME
  4173.     POP    DE        ;RESTORE CURRENT POINTER
  4174.     JP    M,ORDER2    ;EXIT IF CURRENT>NEW
  4175.     LD    HL,16
  4176.     ADD    HL,DE        ;POINT TO NEXT ENTRY
  4177.     JP    ORDER1
  4178. ORDER2    EQU    $        ;ENDLOOP
  4179.     LD    (NXTDE@),DE    ;SAVE INSERT ADDRESS
  4180.     LD    HL,(TOPDE@)
  4181.     INC    HL
  4182.     OR    A
  4183.     SBC    HL,DE
  4184.     LD    B,H
  4185.     LD    C,L        ;LENGTH TO MOVE
  4186.     LD    HL,(TOPDE@)    ;CURRENT TOP OF TABLE
  4187.     PUSH    HL        ;SAVE CURRENT TOP
  4188.     LD    DE,16
  4189.     ADD    HL,DE        ;NEW TOP OF TABLE
  4190.     LD    (TOPDE@),HL    ;SAVE NEW TOP
  4191.     POP    DE        ;RESTORE OLD TOP
  4192.     LD    A,B
  4193.     OR    C
  4194.     JP    Z,ORDER3    ;QUIT IF NOTHING TO MOVE
  4195.     EX    DE,HL        ;DEST=NEW,SRC=OLD TOP ADDRESS
  4196.     LDDR            ;MOVE TABLE UP 16 BYTES
  4197. ORDER3    EQU    $        ;ENDIF
  4198.     RET
  4199.  
  4200.  
  4201. ; CPST - COMPARE STRING (HL)0:6 WITH (DE)0:6 LENGTH (BC) 
  4202.  
  4203.     $RTN    CPST
  4204.     XOR    A
  4205.     LD    (CPSTCN),A    ;COMPARE CONDITION IS =
  4206. CPST01    EQU    $        ;LOOP
  4207.     LD    A,C
  4208.     OR    B
  4209.     JR    Z,CPST02    ;EXITIF DONE
  4210.     PUSH    BC        ;SAVE COUNTER
  4211.     LD    A,(DE)        ;GET 2ND STR CHAR
  4212.     AND    07FH        ;IGNORE HIGH BIT
  4213.     LD    B,A        ;SAVE IT
  4214.     LD    A,(HL)        ;GET 1ST STR CHAR
  4215.     AND    07FH        ;IGNORE HI BIT
  4216.     SUB    B        ;COMPARE CURRENT CHARS
  4217.     LD    (CPSTCN),A    ;SAVE RESULT
  4218.     POP    BC        ;RETRIEVE COUNTER
  4219.     JR    NZ,CPST02    ;EXITIF NOT EQUAL
  4220.     INC    HL
  4221.     INC    DE
  4222.     DEC    BC        ;POINT TO NEXT CHARS
  4223.     JR    CPST01
  4224. CPST02    EQU    $        ;ENDLOOP
  4225.     LD    A,(CPSTCN)    ;PICK UP CONDITIONS
  4226.     OR    A        ;SET CPU FLAGS
  4227.     RET
  4228.  
  4229. CPSTCN: DS    1        ;COMPARE CONDITION
  4230.  
  4231. ; CLRA - CLEAR AREA FROM LINE H FOR L
  4232.  
  4233.     $RTN    CLRA
  4234.     LD    A,H
  4235.     LD    B,L
  4236. CLRA01    EQU    $
  4237.     CALL    CLRL
  4238.     INC    A
  4239.     DJNZ    CLRA01
  4240.     LD    HL,0
  4241.     LD    (PRVERR),HL    ;NO ERROR NOW DISPLAYED
  4242.     RET
  4243.  
  4244. ; FMTN - FORMAT FILE NAME FROM FCB POINTED TO BY DE INTO FILENM
  4245.  
  4246.     $RTN    FMTN
  4247.     LD    HL,FILENM
  4248.     LD    B,8        ;LENGTH 8
  4249. FMTN01    EQU    $        ;LOOP
  4250.     LD    A,(DE)
  4251.     AND    07FH        ;STRIP OFF HIGH BIT
  4252.     LD    (HL),A        ;COPY CHARACTER
  4253.     INC    HL
  4254.     INC    DE
  4255.     DJNZ    FMTN01        ;UNTIL NAME DONE
  4256.     LD    (HL),'.'    ;INSERT SEPERATOR
  4257.     INC    HL
  4258.     LD    A,(DE)
  4259.     AND    80H
  4260.     LD    (RO),A        ;SET RO FLAG
  4261.     LD    B,3        ;LENGTH 3
  4262. FMTN02    EQU    $        ;REPEAT
  4263.     LD    A,(DE)
  4264.     AND    07FH        ;STRIP OFF HIGH BIT
  4265.     LD    (HL),A        ;COPY CHARACTER
  4266.     INC    HL
  4267.     INC    DE        ;POINT TO NEXT
  4268.     DJNZ    FMTN02        ;UNTIL TYPE DONE
  4269.     LD    A,(RO)
  4270.     OR    A        ;TEST RO FLAG
  4271.     LD    A,'W'        ;ASSUME R/W MODE
  4272.     JR    Z,FMTN03    ;IF READ ONLY
  4273.     LD    A,'O'        ;SELECT R/O MODE
  4274. FMTN03    EQU    $        ;ELSE 
  4275.     LD    (FDMDRS),A    ;SET MODE
  4276.     XOR    A
  4277.     LD    (COMFLG),A    ;CLEAR .COM FLAG
  4278.     LD    HL,COMSTR
  4279.     LD    DE,FILENM+9    ;POINT TO TYPE
  4280.     LD    BC,3
  4281.     CALL    CPST
  4282.     JR    NZ,FMTN04    ;IF .COM FILE
  4283.     LD    A,0FFH
  4284.     LD    (COMFLG),A    ;SET FLAG
  4285. FMTN04    EQU    $        ;ENDIF
  4286.     RET
  4287.  
  4288.  
  4289. ; UDCP - UPDATE CURSOR POSITION TO LPOS/CPOS
  4290.  
  4291. UDCP    EQU    $
  4292.     PUSH    HL
  4293.     PUSH    AF
  4294.     LD    A,(LPOS)    ;GET LINE NUMBER
  4295.     LD    L,A
  4296.     LD    A,(CPOS)    ;GET COLUM POSITION
  4297.     LD    H,A
  4298.     CALL    CURS        ;PUT CURSOR THERE
  4299.     POP    AF
  4300.     POP    HL
  4301.     RET
  4302.  
  4303. LPOS:    DB    0
  4304. CPOS:    DB    0
  4305.  
  4306. ;---------------
  4307. ; FILE I/O ROUTINES
  4308. ;---------------
  4309.  
  4310. ; IOADDR - Set the data transfer address for disk operations
  4311.  
  4312.     $RTN    IOADDR
  4313.     LD    DE,(DMA)
  4314.     LD    C,SDMA
  4315.     CALL    CPM        ;Could just JP CPM but this is
  4316.     RET            ;easier when using Z8E debugger
  4317.  
  4318. ; DMASET - Record the data transfer address for disk operations
  4319.  
  4320.     $RTN    DMASET
  4321.     LD    (DMA),BC
  4322.     RET
  4323.  
  4324. DMA:    DEFW    80h        ;(Default at entry to this program)
  4325.  
  4326. ; RDFS - READ FILE RELATIVE SECTOR
  4327.  
  4328.     $RTN    RDFS
  4329.     push    bc
  4330.     XOR    A
  4331.     LD    (WRKOV),A
  4332.     LD    HL,(WRKRR)
  4333.     LD    (SAVFSC),HL    ;SAVE CURRENT RECORD
  4334.     LD    HL,(RELREC)
  4335.     LD    (WRKRR),HL    ;SET RECORD NUMBER
  4336.     CALL    IOADDR        ;Set data pointer
  4337.     LD    DE,WRKFCB    ;POINT TOFCB
  4338.     LD    C,READRN
  4339.     CALL    CPM        ;READ THE RECORD
  4340.     LD    (READST),A    ;SAVE STATUS
  4341.     OR    A
  4342.     JR    Z,RDFS01    ;IF BAD READ
  4343.     LD    HL,(SAVFSC)
  4344.     LD    (RELREC),HL    ;RESTORE RECORD NUMBER
  4345.     LD    (WRKRR),HL
  4346. RDFS01    EQU    $
  4347.     pop    bc
  4348.     RET      
  4349.  
  4350. ; WRFS - WRITE FILE RELATIVE SECTOR BACK TO DISK
  4351.  
  4352.  
  4353.     $RTN    WRFS
  4354.     CALL    IOADDR        ;Set data pointer
  4355.     LD    DE,WRKFCB    ;POINT TO FCB
  4356.     LD    C,WRITRN    ;RANDOM WRITE
  4357.     CALL    CPM        ;GO DO IT
  4358.     RET
  4359.  
  4360. ; PHYS3 - Test if CP/M Plus and if so then change sector number to
  4361. ;      conform to physical sector size.
  4362.  
  4363.     $RTN    PHYS3
  4364.     LD    A,(CPM3)
  4365.     OR    A
  4366.     PUSH    AF        ;Save result for caller
  4367.     JR    Z,PEXIT        ;No transformation needed for 2.x
  4368.     LD    A,(DPBPSH)    ;Pick up physical sector size from DPH
  4369.     INC    A        ;Pre-increment for shift loop
  4370. PSHIFT:
  4371.     DEC    A        ;Count down the number of shifts
  4372.     JR    Z,PEXIT        ;Exit when done
  4373.     SRL    B        ;BC := BC/2
  4374.     SRA    C
  4375.     JR    PSHIFT        ;Around again
  4376. PEXIT:
  4377.     POP    AF
  4378.     RET
  4379.  
  4380. ; SECPNT    Build address of 128-byte "logical" sector within psBuff
  4381. ;        On exit, HL holds required address and BC contains the
  4382. ;        value 128 (ready for an LDIR instruction)
  4383.  
  4384.     $RTN    SECPNT
  4385.     LD    HL,(PSMDSC)    ;Get sector number
  4386.     LD    A,(DPBPSM)    ;Get physical sector mask
  4387.     AND    L        ;Calculate which 128-byte chunk
  4388.     LD    HL,PSBUFF
  4389.     LD    BC,128        ;Chunk size
  4390. POFF:    RET    Z        ;Exit now if address calculated
  4391.     ADD    HL,BC        ;Otherwise increment pointer
  4392.     DEC    A
  4393.     JR    POFF
  4394.  
  4395. ; PSRD - READ PHYSICAL SECTOR
  4396.  
  4397.     $RTN    PSRD
  4398.     CALL    IOADDR        ;We'll override this later if CP/M 3.x
  4399.     LD    BC,(PSMDTR)
  4400.     CALL    SETTRK        ;SELECT TRACK
  4401.     LD    BC,(PSMDSC)
  4402.     CALL    PHYS3        ;If CP/M 3.x then change to physical
  4403.     PUSH    BC        ;Save sector number during tests
  4404.     JR    Z,PREAD        ;If CP/M 2.x then do the read
  4405.     LD    HL,(PRVSEC)    ;See if same physical sector as last time
  4406.     SBC    HL,BC        ;(Carry flag is already clear)
  4407.     JR    NZ,PREAD    ;Do read if different
  4408.     LD    BC,(PRVTRK)    ;Check track
  4409.     LD    HL,(PSMDTR)
  4410.     SBC    HL,BC
  4411.     JR    NZ,PREAD    ;Do read if different
  4412.  
  4413. ;If we get here then we are running under CP/M+ and we already have the
  4414. ;correct physical sector in memory.  All we have to do is deliver the
  4415. ;appropriate logical sector to the rest of the program.
  4416.  
  4417.     POP    BC        ;Align stack
  4418.     CALL    SECPNT        ;Build pointer into psBuff
  4419.     LD    DE,(DMA)    ;Where to put the data
  4420.     LDIR            ;Move 128 bytes
  4421.     RET
  4422. PREAD:
  4423.     POP    BC
  4424.     LD    (PRVSEC),BC    ;Record sector ..
  4425.     LD    HL,(PSMDTR)
  4426.     LD    (PRVTRK),HL    ;.. and track
  4427. ;    LD    DE,(DPBOFF)
  4428. ;    OR    A
  4429. ;    SBC    HL,DE
  4430. ;    JR    C,STSA01    ;IF NOT SYSTEM TRACK
  4431.     LD    DE,(DPHXLT)
  4432.     CALL    SECTRN        ;DO SECTOR TRANSLATION
  4433.     LD    B,H
  4434.     LD    C,L
  4435. STSA01    EQU    $
  4436.     CALL    SETSEC
  4437.     LD    A,(CPM3)    ;If CP/M 3 then ..
  4438.     OR    A
  4439.     JR    Z,DOREAD
  4440.     LD    BC,PSBUFF    ;.. use physical sector buffer
  4441.     CALL    SETDMA
  4442. DOREAD: CALL    READ        ;READ SECTOR
  4443.     PUSH    AF        ;Preserve result
  4444.     LD    A,(CPM3)
  4445.     OR    A
  4446.     JR    Z,PSRDX        ;Exit if CP/M 2.2
  4447.     CALL    IOADDR        ;Restore DMA
  4448.     CALL    SECPNT        ;Calculate address in psBuff
  4449.     LD    DE,(DMA)    ;Where to put the data
  4450.     LDIR            ;Copy it
  4451. PSRDX:    POP    AF
  4452.     RET
  4453.  
  4454.  
  4455. ; PSWR - WRITE PHYSICAL SECTOR
  4456.  
  4457.     $RTN    PSWR
  4458.     LD    A,(CPM3)    ;Decide which method to use
  4459.     OR    A
  4460.     JR    Z,PSWR2
  4461.     CALL    SECPNT        ;Calculate address within psBuff
  4462.     EX    DE,HL        ;Put destination address into DE
  4463.     LD    HL,(DMA)    ;Where to put the data
  4464.     LDIR            ;Move the data
  4465.     LD    BC,PSBUFF    ;Set address for data transfer
  4466.     CALL    SETDMA
  4467. PSWR2:
  4468.     LD    C,WRDIR        ;USE WRITE DIRECTORY TO FORCE WRITE
  4469.     CALL    WRITE        ;WRITE SECTOR
  4470.     PUSH    AF        ;Save result
  4471.     CALL    IOADDR        ;Restore data address
  4472.     POP    AF
  4473.     RET
  4474.  
  4475. WRDIR    EQU    1        ;BIOS DIRECTORY WRITE CODE
  4476.  
  4477. PRVSEC: DEFW    -1
  4478. PRVTRK: DEFW    -1
  4479.  
  4480. ;----------------
  4481. ; UTILITY ROUTINES
  4482. ;----------------
  4483.  
  4484. ; H16D - HL * 16 + DE
  4485.  
  4486.     $RTN    H16D
  4487.     ADD    HL,HL
  4488.     ADD    HL,HL
  4489.     ADD    HL,HL
  4490.     ADD    HL,HL        ;HL=HL*16
  4491.     ADD    HL,DE        ; + DE
  4492.     RET
  4493.  
  4494. ; ERRP - PROCESS ERROR DISPLAYS
  4495.  
  4496.     $RTN    ERRP
  4497.     LD    HL,(PRVERR)
  4498.     LD    A,H
  4499.     OR    L
  4500.     JR    Z,ERRP01    ;IF PREVIOS ERROR
  4501.     PUSH    HL        ;SAVE TEXT ADDRESS
  4502.     $FLD    ERRFLD        ;POSITION CURSOR
  4503.     POP    HL
  4504.     CALL    CSTR        ;CLEAR STRING
  4505.     LD    HL,0
  4506.     LD    (PRVERR),HL    ;CLEAR POINTER
  4507. ERRP01    EQU    $        ;ENDIF
  4508.     LD    HL,(ERRTXT)
  4509.     LD    A,H
  4510.     OR    L
  4511.     JR    Z,ERRP02    ;IF ERROR SET
  4512.     PUSH    HL        ;SAVE TEXT POINTER
  4513.     $FLD    ERRFLD        ;POSITION CURSOR
  4514.     POP    HL
  4515.     LD    (PRVERR),HL    ;SAVE TEXT ADDRESS
  4516.     CALL    STRO        ;OUTPUT TEXT
  4517.     CALL    ALRM        ;SOUND ALARM
  4518.     LD    HL,0
  4519.     LD    (ERRTXT),HL    ;CLEAR TEXT POINTER
  4520. ERRP02    EQU    $        ;ENDIF
  4521.     RET
  4522.  
  4523. ; MTCH - BYTE LIST MATCHER
  4524.  
  4525.     $RTN    MTCH
  4526.     PUSH    BC        ;SAVE BC
  4527.     LD    B,0
  4528.     LD    C,(HL)        ;BC=LENGTH
  4529.     INC    HL        ;POINT TO START OF LIST
  4530.     PUSH    BC        ;SAVE LENGTH
  4531.     CPIR            ;SCAN LIST
  4532.     POP    HL        ;RESTORE LENGTH TO HL
  4533.     JR    NZ,MTCH01    ;IF FOUND
  4534.     OR    A
  4535.     SBC    HL,BC        ;SUBTRACT RESIDUE TO GIVE OFFSET+1
  4536.     DEC    HL        ;HL IS OFFSET
  4537.     CP    A        ;SET Z FLAG
  4538. MTCH01    EQU    $
  4539.     POP    BC        ;RESTORE BC
  4540.     RET
  4541.  
  4542.  
  4543. ; EXVA - JUMP TO ROUTINE AT OFFSET 2*HL FROM DE
  4544.  
  4545.     $RTN    EXVA
  4546.     ADD    HL,HL
  4547.     ADD    HL,DE        ;DERIVE ACTION ADDR
  4548.     CALL    LDHL
  4549.     JP    (HL)
  4550.  
  4551.  
  4552. ; LDHL - LOAD HL WITH (HL)
  4553.  
  4554.     $RTN    LDHL
  4555.     PUSH    AF
  4556.     LD    A,(HL)
  4557.     INC    HL
  4558.     LD    H,(HL)
  4559.     LD    L,A        ;HL = (HL)
  4560.     POP    AF
  4561.     RET
  4562.  
  4563.  
  4564. ; AAHL - ADD A TO HL
  4565.  
  4566.     $RTN    AAHL
  4567.     PUSH    DE        ;SAVE DE
  4568.     LD    E,A
  4569.     LD    D,0
  4570.     ADD    HL,DE
  4571.     POP    DE        ;RESTORE DE
  4572.     RET
  4573.  
  4574. ; MULT - MULTIPLY DE BY BC TO GIVE RESULT IN HL AND OVERFLOW IN DE
  4575.  
  4576.     $RTN    MULT
  4577.     LD    A,16        ;SET A TO LOOP COUNT
  4578.     LD    HL,0        ;ZERO RESULT
  4579.     OR    A        ;CLEAR CARRY
  4580. MULT01    EQU    $        ;LOOP
  4581.     EX    DE,HL
  4582.     ADC    HL,HL        ;SHIFT DE LEFT 1 (AND INTO CARRY)
  4583.     EX    DE,HL
  4584.     JP    NC,MULT02    ;IF BIT SHIFTED OUT OF DE IS SET
  4585.     ADD    HL,BC        ;ADD MULTIPLICAND TO RESULT
  4586.     JP    NC,MULT03    ;IF RESULT OVERFLOWED
  4587.     INC    DE        ;PROPAGATE INTO DE
  4588. MULT03    EQU    $        ;ENDIF
  4589. MULT02    EQU    $        ;ENDIF
  4590.     DEC    A        ;DECREMENT LOOP COUNT
  4591.     JP    Z,MULT04    ;IF LOOP COUNT IS ZERO EXIT
  4592.     ADD    HL,HL        ;SHIFT LEFT 1 (OVERFLOW ADDED BY ADC)
  4593.     JP    MULT01
  4594. MULT04    EQU    $        ;ENDLOOP
  4595.     RET
  4596.  
  4597. ; DIVD - DIVIDE DE BY BC TO GIVE REMAINDER IN HL AND QUOTIENT IN DE
  4598.  
  4599.     $RTN    DIVD
  4600.     LD    A,16        ;SET A TO LOOP COUNT
  4601.     LD    HL,0        ;ZERO REMAINDER
  4602. DIVD01    EQU    $        ;LOOP
  4603.     ADD    HL,HL        ;SHIFT REMAINDER LEFT 1
  4604.     EX    DE,HL
  4605.     ADD    HL,HL        ;SHIFT DIVISOR LEFT 1
  4606.     EX    DE,HL
  4607.     JP    NC,DIVD02    ;IF CARRY SET
  4608.     INC    HL        ;INCREMENT RESULT
  4609. DIVD02    EQU    $        ;ENDIF
  4610.     OR    A        ;RESET CARRY FLAG
  4611.     SBC    HL,BC        ;SUBTRACT DIVISOR
  4612.     INC    DE        ;INCREMENT QUOTIENT
  4613.     JP    P,DIVD03    ;IF RESULT IS NEGATIVE
  4614.     ADD    HL,BC        ;BACK OFF SUBTRACT
  4615.     DEC    DE        ;DECREMENT QUOTIENT
  4616. DIVD03    EQU    $        ;ENDIF
  4617.     DEC    A        ;DECREMENT LOOP COUNT
  4618.     JP    Z,DIVD04    ;IF LOOP COUNT ZERO EXIT
  4619.     JP    DIVD01
  4620. DIVD04    EQU    $        ;ENDLOOP
  4621.     RET
  4622.  
  4623.  
  4624. ; SETD - SET DIRECTORY MODE
  4625.  
  4626.     $RTN    SETD
  4627.     LD    A,'D'
  4628.     LD    (WTG),A        ;NEXT MODE IS DIRECTORY
  4629.     RET
  4630.  
  4631.  
  4632. ; SETF - SET FILE MODE
  4633.  
  4634.     $RTN    SETF
  4635.     LD    A,'F'
  4636.     LD    (WTG),A        ;NEXT MODE IS FILE
  4637.     RET
  4638.  
  4639.  
  4640. ; SETP - SET PHYSICAL SECTOR MODE
  4641.  
  4642.     $RTN    SETP
  4643.     LD    A,'P'
  4644.     LD    (WTG),A        ;NEXT MODE IS PHYSICAL SECTOR
  4645.     RET
  4646.  
  4647.  
  4648. ; SETX - SET EXIT MODE
  4649.  
  4650.     $RTN    SETX
  4651.     LD    A,'X'
  4652.     LD    (WTG),A        ;NEXT MODE IS EXIT
  4653.     RET
  4654.  
  4655. ;----------------
  4656. ; SCREEN I/O ROUTINES
  4657. ;----------------
  4658.  
  4659. ; CHRI - INPUT CHARACTER
  4660. ;     USE BIOS CALL TO SUPPORT SYSTEMS WITH SOFTWARE CURSOR
  4661.  
  4662.     $RTN    CHRI
  4663.     PUSH    HL
  4664.     PUSH    DE
  4665.     PUSH    BC
  4666.     CALL    CONIN
  4667.     LD    (INCH),A
  4668.     POP    BC
  4669.     POP    DE
  4670.     POP    HL
  4671.     RET
  4672.  
  4673.  
  4674. ; FOLD - FOLD CHARACTER IN A TO UPPER CASE IF REQUIRED
  4675.  
  4676.     $RTN    FOLD
  4677.     CP    'a'
  4678.     JR    C,FOLD01
  4679.     CP    'z'+1
  4680.     JR    NC,FOLD01    ;IF NOT UPPER CASE
  4681.     AND    05FH        ;FOLD CHARACTER
  4682. FOLD01    EQU    $        ;ENDIF
  4683.     RET
  4684.  
  4685.  
  4686. ; CHRF - GET FOLDED CHARACTER
  4687.  
  4688.     $RTN    CHRF
  4689.     CALL    CHRI
  4690.     CALL    FOLD
  4691.     RET
  4692.  
  4693. ; CHRO - OUTPUT CHARACTER IN A 
  4694.  
  4695.     $RTN    CHRO
  4696.     PUSH    BC
  4697.     PUSH    DE
  4698.     PUSH    HL
  4699.     PUSH    AF
  4700.     LD    E,A        ;INPUT TO PARM REG
  4701.     LD    C,CONIO        ;DIRECT OUTPUT
  4702.     CALL    CPM        ;CALL CPM 
  4703.     POP    AF
  4704.     POP    HL
  4705.     POP    DE
  4706.     POP    BC
  4707.     RET
  4708.  
  4709.  
  4710. ; ALRM - SOUND THE CONSOLE BELL
  4711.  
  4712.     $RTN    ALRM
  4713.     PUSH    AF
  4714.     LD    A,07H
  4715.     CALL    CHRO
  4716.     POP    AF
  4717.     RET
  4718.  
  4719.  
  4720. ; SPCO - OUTPUT SPACE TO SCREEN
  4721.  
  4722.     $RTN    SPCO
  4723.     PUSH    AF
  4724.     LD    A,' '
  4725.     CALL    CHRO
  4726.     POP    AF
  4727.     RET
  4728.  
  4729.  
  4730. ; CLRS - CLEAR SCREEN AND HOME CURSOR
  4731.  
  4732.     $RTN    CLRS
  4733.     PUSH    AF
  4734.     PUSH    HL
  4735.     $STRL    CLSSTR        ;PRINT CLEAR SCREEN STRING
  4736.     LD    HL,0
  4737.     LD    (PRVERR),HL    ;CLEAR PREV ERROR
  4738.     POP    HL
  4739.     POP    AF
  4740.     RET
  4741.  
  4742.  
  4743. ; DHDR - CLEAR SCREEN AND DISPLAY HEADER
  4744.  
  4745.     $RTN    DHDR
  4746.     CALL    CLRS
  4747.     $FLD    HDRMSG
  4748.     RET
  4749.  
  4750. ; CLRL - CLEAR LINE CONTAINED IN A
  4751.  
  4752.     $RTN    CLRL
  4753.     PUSH    AF
  4754.     PUSH    HL
  4755.     LD    H,0        ;COLUMN ZERO
  4756.     LD    L,A        ;LINE (A)
  4757.     CALL    CURS        ;POSITION TO LINE
  4758.     $STRL    CLLSTR        ;PRINT CLEAR LINE STRING
  4759.     POP    HL
  4760.     POP    AF
  4761.     RET
  4762.  
  4763.  
  4764. ; CURS - SET CURSOR POSITION TO LINE L COLUMN H
  4765.  
  4766.     $RTN    CURS
  4767.     PUSH    AF
  4768.     PUSH    HL
  4769.     $STRL    CPPREF        ;OUTPUT CURSOR POSITION PREFIX
  4770.     POP    HL
  4771.     PUSH    HL
  4772.     LD    A,(ROW1ST)    ;Row or column?
  4773.     OR    A
  4774.     PUSH    AF        ;Save row/column flag
  4775.     CALL    COORD
  4776.     $STRL    CPMID        ;Output cursor position infix
  4777.     POP    AF        ;Recover row/column flag
  4778.     DEC    A        ;Toggle it for 2nd coordinate
  4779.     POP    HL
  4780.     CALL    COORD
  4781.     $STRL    CPEND
  4782.     POP    AF
  4783.     RET
  4784.  
  4785. ; COORD - outputs a cursor-position coordinate.
  4786. ;      H contains horizontal position
  4787. ;      L contains line number
  4788. ;      Z flag is set if H coord required, reset if L
  4789.  
  4790.     $RTN    COORD
  4791.     JR    Z,DOHOR
  4792.     LD    A,(ROWOFF)
  4793.     ADD    A,L
  4794.     JR    EITHER
  4795. DOHOR:    LD    A,(COLOFF)
  4796.     ADD    A,H
  4797. EITHER: LD    E,A
  4798.     ld    d,0        ; JTC be sure no extra values in D
  4799.     LD    A,(CPBIN)
  4800.     OR    A
  4801.     JR    NZ,COBIN
  4802.     CALL    DECOUT
  4803.     RET
  4804. COBIN:    LD    A,E
  4805.     CALL    CHRO
  4806.     RET
  4807.  
  4808. ; DECOUT - Convert 16-bit number in DE to decimal and output to the screen
  4809. ;       Leading zeros are suppressed.  Number is treated as unsigned.
  4810.  
  4811.     $RTN    DECOUT
  4812.     PUSH    HL
  4813.     PUSH    DE
  4814.     PUSH    BC
  4815.     EX    DE,HL
  4816.     LD    BC,-10        ;Radix
  4817.     LD    DE,-1        ;Initialise quotient
  4818. DVLP:    ADD    HL,BC        ;Subtract radix
  4819.     INC    DE        ;Increment quotient
  4820.     JR    C,DVLP        ;(Slow way to divide)
  4821.     SBC    HL,BC        ;Correct for extra subtract
  4822. ;JTC    EX    DE,HL
  4823.     ld    a,d        ; JTC
  4824.     or    e        ;Test for zero
  4825.     CALL    NZ,DECOUT    ;Recursive call
  4826.     LD    A,'0'        ;Convert digit for display
  4827.     add    a,l        ; JTC
  4828.     CALL    CHRO        ;Write to screen
  4829.     POP    BC        ;Restore stack
  4830.     POP    DE
  4831.     POP    HL
  4832.     RET
  4833.  
  4834. ; DPNL - DISPLAY PANEL
  4835.  
  4836.     $RTN    DPNL
  4837.     LD    B,(HL)
  4838.     INC    HL
  4839. DPNL01    EQU    $
  4840.     PUSH    BC
  4841.     CALL    DFLD        ;DISPLAY FIELD
  4842.     POP    BC
  4843.     DJNZ    DPNL01
  4844.     RET
  4845.  
  4846.  
  4847. ; DFLD - DISPLAY FIELD
  4848.  
  4849.     $RTN    DFLD
  4850.     PUSH    HL
  4851.     CALL    LDHL
  4852.     CALL    CURS        ;SET CURSOR POSITION
  4853.     POP    HL
  4854.     INC    HL
  4855.     INC    HL
  4856.     CALL    STRO        ;OUPUT STRING
  4857.     RET
  4858.  
  4859. ; CFLD - CLEAR FIELD
  4860.  
  4861.     $RTN    CFLD
  4862.     PUSH    HL
  4863.     CALL    LDHL
  4864.     CALL    CURS        ;SET CURSOR POSITION
  4865.     POP    HL
  4866.     INC    HL
  4867.     INC    HL
  4868.     CALL    CSTR        ;CLEAR STRING
  4869.     RET
  4870.  
  4871. ; CSTR - CLEAR STRING POINTED TO BY HL
  4872.  
  4873.     $RTN    CSTR
  4874. CSTR01    EQU    $        ;LOOP
  4875.     LD    A,(HL)        ;PICK UP FIELD CHARACTER
  4876.     OR    A
  4877.     JR    Z,CSTR02    ;EXIT IF NULL
  4878.     CALL    SPCO        ;OUTPUT BLANK
  4879.     INC    HL        ;POINT TO NEXT CHARACTER
  4880.     JR    CSTR01
  4881. CSTR02    EQU    $        ;ENDLOOP
  4882.     INC    HL
  4883.     RET
  4884.  
  4885. ; STRO - OUTPUT STRING POINTED TO BY HL AND DELIMITED BY A NULL
  4886.  
  4887.     $RTN    STRO
  4888. STRO01    EQU    $
  4889.     LD    A,(HL)
  4890.     OR    A
  4891.     JR    Z,STRO02
  4892.     CALL    CHRO
  4893.     INC    HL
  4894.     JR    STRO01
  4895. STRO02    EQU    $
  4896.     INC    HL
  4897.     RET
  4898.  
  4899. ; STRL - Output length-prefixed string pointed to by HL
  4900.  
  4901.     $RTN    STRL
  4902.     PUSH    BC
  4903.     LD    B,(HL)
  4904.     INC    B
  4905. STRLLP: INC    HL
  4906.     DEC    B
  4907.     JR    Z,STRLXT
  4908.     LD    A,(HL)
  4909.     PUSH    HL
  4910.     CALL    CHRO
  4911.     POP    HL
  4912.     JR    STRLLP
  4913. STRLXT: POP    BC
  4914.     RET
  4915.  
  4916. ; ASCO - OUTPUT ASCII CHARACTER OR '.' TO SCREEN
  4917. ;
  4918. ;    Modified Jan 86 by JHB to display ASCII chars with high bit
  4919. ;    set in reverse video.  The idea is to make displays of file
  4920. ;    names in directory sectors more readable.
  4921.  
  4922.     $RTN    ASCO
  4923.     PUSH    HL
  4924.     PUSH    AF
  4925.     BIT    7,A        ;Check high bit
  4926.     PUSH    AF        ;Save high bit flag
  4927.     PUSH    AF        ;Save character during video mode change
  4928.     CALL    NZ,VMINV    ;Turn on highlight
  4929.     POP    AF        ;Recover character for display
  4930.     AND    7FH        ;Mask off high bit
  4931.     LD    HL,MAXASC    ;Check for graphic
  4932.     CP    (HL)
  4933.     JR    NC,ASCO01
  4934.     CP    20H
  4935.     JR    NC,ASCO02
  4936. ASCO01    EQU    $
  4937.     LD    A,'.'
  4938. ASCO02    EQU    $
  4939.     CALL    CHRO
  4940.     POP    AF        ;Did we highlight?
  4941.     CALL    NZ,VMNORM    ;If so then return to normal video
  4942.     POP    AF
  4943.     POP    HL
  4944.     RET
  4945.  
  4946.  
  4947. ; HEXO - OUTPUT BYTE IN A IN HEX TO SCREEN
  4948.  
  4949.     $RTN    HEXO
  4950.     PUSH    AF
  4951.     RRA
  4952.     RRA
  4953.     RRA
  4954.     RRA            ;REVERSE NIBBLES
  4955.     CALL    HEXC        ;PRINT HO NIBBLE
  4956.     POP    AF
  4957.     CALL    HEXC        ;PRINT LO NIBBLE
  4958.     RET
  4959.  
  4960. ;
  4961. ; HEXW - OUTPUT WORD IN HL TO SCREEN
  4962. ;
  4963.     $RTN    HEXW
  4964.     PUSH    AF
  4965.     LD    A,H
  4966.     CALL    HEXO
  4967.     LD    A,L
  4968.     CALL    HEXO
  4969.     POP    AF
  4970.     RET
  4971.  
  4972.  
  4973. ; HEXC - OUTPUT LO NIBBLE IN A IN HEX TO SCREEN
  4974.  
  4975.     $RTN    HEXC
  4976.     AND    0FH        ;LOSE HO NIBBLE
  4977.     ADD    A,90H
  4978.     DAA
  4979.     ADC    A,40H
  4980.     DAA
  4981.     CALL    CHRO        ;OUTPUT HEX CHARACTER
  4982.     RET
  4983.  
  4984. ; VIDEO FUNCTIONS
  4985.  
  4986.     $RTN    VMINV        ;Inverse video
  4987.     LD    HL,VINV
  4988.     JR    VMSET
  4989.  
  4990.     $RTN    VMNORM        ;Normal video
  4991.     LD    HL,VNORM
  4992. VMSET:    CALL    STRL
  4993.     RET
  4994.  
  4995. ;    END OF CODE
  4996.  
  4997. PSBUFF    EQU    $        ;Physical sector I/O buffer
  4998. ENDCDE    EQU    $+2048
  4999.     .list
  5000. ; Enable symbols for Z8E
  5001.     END    INIT
  5002. D    7FH        ;Mask off high bit
  5003.     LD    HL,MAXASC    ;Check for grap