home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / SPZAP128.LZH / SUPERZAP.MAC < prev   
Text File  |  1987-11-07  |  83KB  |  4,067 lines

  1.     .xlist        ;Moved here to keep .PRN file short for Z8E
  2.     .Z80
  3.     TITLE    SUPERZAP - CP/M DISK UTILITY
  4. ;    (SUPERZAP v.3.3 PRECONFIGURED AND CORRECTED FOR C128)
  5. ;------------------------------------------------------------------------------
  6. ;
  7. ;    SUPERZAP - A screen-oriented disk editor for CP/M-80
  8. ;
  9. ;    Versions prior to 3.x by Davidson and Sheldrake
  10. ;
  11. ;    Upgraded to CP/M+ operation by:
  12. ;        John Hastwell-Batten,
  13. ;        SYSOP, Tesseract RCPM+,
  14. ;        P.O. Box 242,
  15. ;        Dural, NSW 2158,
  16. ;        AUSTRALIA.
  17. ;
  18. ;    Hopefully, what we have now is a "universal" version that will run
  19. ;    without change under CP/M 2.2 and CP/M 3.1 but since I do not have
  20. ;    a CP/M 2.2 system there is the chance that I have screwed it up.
  21. ;
  22. ;    All of Willie Davidson's code is in upper case.  My changes are easy
  23. ;    to identify because they are in lower case.  JHB.
  24. ;
  25. ;------------------------------------------------------------------------------
  26. ;
  27. ; Update list (most recent first)
  28. ;
  29. ;    7 Nov 87 CONFIGURED FOR C128 BY M.D. GIRARDEAU
  30. ;    *********THIS VERSION ONLY FOR THE C128*********
  31. ;
  32. ; 3.3    20 Mar 86    Willie Davidson (mods done by John Hastwell-Batten)
  33. ;
  34. ; -    Incorporated Willie Davidson's updates to the CP/M 2.2 version into
  35. ;    this universal version.
  36. ;
  37. ; 3.2    24 Feb 86    John Hastwell-Batten
  38. ;
  39. ; -    Removed CP/M 3 configuration/implementation dependencies.
  40. ;    SUPERZAP should now run on any CP/M 3 or 2.2 system with a Z80.
  41. ;
  42. ; 3.1    11 Jan 86    John Hastwell-Batten
  43. ;
  44. ; -    Added ability to select user number (very crude).
  45. ; -    Changed default track number to directory track
  46. ; -    Made terminal functions more general and object-patchable.
  47. ;
  48. ; 3.0    9 Jan 86    John Hastwell-Batten
  49. ;
  50. ; -    ASEG and ORG directives added, .LIST and .XLIST directives moved
  51. ;    to simplify use with Z8E debugger.
  52. ; -    Upgraded to be compatible with CP/M 3.1
  53. ; -    Introduced inverse video display of characters with high bit set
  54. ;    to make display of directory sectors more readable
  55. ;
  56. ; 2.1    Willie Davidson and H Sheldrake
  57. ;
  58. ;    Original (as distributed by SIG/M)
  59. ;
  60. ;------------------------------------------------------------------------------
  61.  
  62.     aseg            ;For Z8E debugger symbol table alignment
  63.     org    100h        ;(Just makes it a little easier)
  64.  
  65. ;---------------- Entry point to program -----------------
  66.  
  67.     jp    init        ;Now we have to do this ourselves
  68.  
  69. $VER    DEFL    '3'            ;VERSION NUMBER
  70. $MOD    DEFL    '3'            ;MODIFICATION LEVEL
  71.  
  72.     DB    ' SUPERZAP 3  '        ;Deleted a few "blank" lines.
  73.     DB    '  for CP/M 2.2  '    ;Screen controls now at 150h
  74.     DB    '  and CP/M 3.1  '    ;instead of 180h
  75.     DB    '  W.M.Davidson  '
  76.     DB    '  H.J.Sheldrake '
  77. ;    DB    '18 DEAN PARK CR.'
  78. ;    DB    ' EDINBURGH      '
  79. ;    DB      '        EH4 1PH '
  80. ;    DB    '  SCOTLAND      '
  81.  
  82. ;    CURSOR CHARACTER EQUATES (MUST BE 01H TO 01FH)
  83.  
  84. $LEFT    EQU    013H        ;CURSOR LEFT  IS ^S
  85. $RIGHT    EQU    004H        ;CURSOR RIGHT IS ^D
  86. $UP    EQU    005H        ;CURSOR UP    IS ^E
  87. $DOWN    EQU    018H        ;CURSOR DOWN  IS ^X
  88. $TAB    EQU    009H        ;CURSOR TAB   IS ^I
  89. $ESC    EQU    01BH        ;ESCAPE       IS ESC
  90. $INSRT    EQU    'V'-040H    ;INSERT       IS ^V
  91. $DELETE    EQU    'G'-040H    ;DELETE       IS ^G
  92. $QUIT    EQU    'Q'-040H    ;QUIT EDIT    IS ^Q
  93. $END    EQU    'K'-040H    ;END EDIT     IS ^K
  94.  
  95. ; SCREEN CONTROL (for Commodore 128)
  96.  
  97. CLSSTR:    DB    1,1Ah,0,0,0,0,0,0    ;CLEAR SCREEN
  98. CLLSTR:    DB    2,1Bh,54h,0,0,0,0,0    ;CLEAR LINE
  99. vInv:    db    3,1Bh,47h,34h,0,0,0,0    ;Inverse video
  100. vNorm:    db    3,1Bh,47h,30h,0,0,0,0    ;Normal video
  101. cpPref:    DB    2,1Bh,3Dh,0,0,0,0,0    ;CURSOR POSITION PREFIX
  102. cpMid:    db    0,0,0,0,0,0,0,0        ;Cursor position infix
  103. cpEnd:    db    0,0,0,0,0,0,0,0        ;Cursor position suffix
  104. row1st:    db    1            ;1=row first, 0=column first. SEE NOTE!
  105. rowOff:    db    20h            ;Offset for row
  106. colOff:    db    20h            ;Offset for column
  107. cpBin:    db    1            ;0 for decimal cursor coordinates,
  108.                     ;Non-0 for binary.
  109. maxASC:    db    7Eh            ;Set to 7Dh for stupid Hazeltines
  110.  
  111. ; --- WARNING WARNING WARNING WARNING ---
  112. ; The value of row1st must not be set to any value other than 0 or 1.
  113.  
  114. FLAGCH:    DB    ' '        ;FLAG CHARACTER IN LIST MODE
  115.  
  116. ;---------------- MACRO DEFINITIONS
  117.  
  118.  
  119. ; $RTN - STANDARD ROUTINE ENTRY
  120.  
  121. $RTN    MACRO    $RTNN
  122.     ENTRY    $RTNN
  123. $RTNN:    DS    0
  124.     ENDM
  125.  
  126. ; $PANEL - LOAD HL AND DISPLAY PANEL
  127.  
  128. $PANEL    MACRO    $PNLNM
  129.     LD    HL,$PNLNM    ;POINT TO PANEL
  130.     CALL    DPNL        ;DISPLAY IT
  131.     ENDM
  132.  
  133. ; $FLD - LOAD HL AND DISPLAY FIELD
  134.  
  135. $FLD    MACRO    $FLDNM
  136.     LD    HL,$FLDNM
  137.     CALL    DFLD
  138.     ENDM
  139.  
  140. ; $NPANEL - CLEAR SCREEN AND DISPLAY PANEL
  141.  
  142. $NPANEL    MACRO    $PNLNM
  143.     CALL    DHDR
  144.     $PANEL    $PNLNM
  145.     ENDM
  146.  
  147. ; $STRO - PRINT STRING AT (HL)
  148.  
  149. $STRO    MACRO    $STRNM
  150.     LD    HL,$STRNM
  151.     CALL    STRO
  152.     ENDM
  153.  
  154. ; $strl - print string at (HL) where first byte is length
  155.  
  156. $strl    macro    $strnm
  157.     ld    hl,$strnm
  158.     call    strl
  159.     endm
  160.  
  161. ; $IFLD - LOAD HL, DISPLAY FIELD, GET AND FOLD INPUT
  162.  
  163. $IFLD    MACRO    $FLDNM
  164.     LD    HL,$FLDNM        ;POINT TO FIELD
  165.     CALL    DFLD            ;DISPLAY IT
  166.     CALL    CHRF            ;GET INPUT
  167.     ENDM
  168.  
  169. ; $MTCH - CALL BYTE MATCHER
  170.  
  171. $MTCH    MACRO    $LST
  172.     LD    HL,$LST
  173.     CALL    MTCH
  174.     ENDM
  175.  
  176. ; $EXVA - EXECUTE VECTORED ACTION
  177.  
  178. $EXVA    MACRO    $LST
  179.     LD    DE,$LST
  180.     CALL    EXVA
  181.     ENDM
  182.  
  183. ; $HEXW - DISPLAY HEX WORD
  184.  
  185. $HEXW    MACRO    $WORD
  186.     LD    HL,($WORD)
  187.     CALL    HEXW
  188.     ENDM
  189.  
  190. ;---------------- GLOBAL EQUATES ----------------
  191.  
  192. CR    EQU    0DH
  193. LF    EQU    0AH
  194. FALSE    EQU    000H
  195. TRUE    EQU    0FFH
  196. CMD    EQU    80H
  197.  
  198. FBUFF    EQU    80H
  199.  
  200. ;Note:    The CP/M2.2-specific version of this program used the default
  201. ;    file I/O buffer at 80H for all disk operations, i.e. for file-
  202. ;    oriented AND physical I/O.  Under CP/M 3.1 this is not tenable
  203. ;    because the BIOS deals with physical sectors rather than 128-
  204. ;    byte "logical" sectors and physical sectors can be much larger
  205. ;    than 128 bytes.
  206. ;
  207. ;    Physical disk I/O for CP/M 3.x now uses an area set aside at
  208. ;    the end of this program, before the scratchpad.  2048 bytes has
  209. ;    been reserved.  That should be enough; I don't know of any
  210. ;    system which supports physical sectors longer than 1024 bytes
  211. ;    but the notes on the WD1797 FDC suggest that 2048 is possible.
  212. ;
  213. ;    JHB    January 1986
  214. ;
  215. ;---------------- CPM SYSTEM CALL CODES
  216.  
  217. CPM    EQU    05H        ;CPM CALL ADDRESS
  218. CONIO    EQU    06H        ;DIRECT CONSOLE I/O
  219. getVsn    EQU    0Ch        ;Get CP/M version number
  220. RESET    EQU    0DH        ;RESET DISK SYSTEM
  221. SETDEF    EQU    0EH        ;SET DEFAULT DRIVE
  222. OPEN    EQU    0FH        ;OPEN FILE
  223. CLOSE    EQU    10H        ;CLOSE FILE
  224. FNDFST    EQU    11H        ;FIND FIRST DIRECTORY MATCH
  225. FNDNXT    EQU    12H        ;FIND NEXT DIRECTORY MATCH
  226. GETDEF    EQU    19H        ;GET CURRENT DRIVE ID
  227. sDMA    equ    1Ah        ;Set DMA address (Req'd for CP/M 3.1)
  228. userNo    equ    20h        ;Get/Set user number
  229. READRN    EQU    21H        ;READ RANDOM RECORD
  230. WRITRN    EQU    22H        ;WRITE RANDOM RECORD
  231. FILESZ    EQU    23H        ;COMPUTE FILE SIZE
  232. SETRN    EQU    24H        ;SET RANDOM RECORD
  233.  
  234. ;---------------- DEFAULT FCB IMAGE
  235.  
  236. WRKFCB    EQU    5CH        ;DEFAULT FCB ADDRESS
  237. WRKDR    EQU    WRKFCB+0    ;DRIVE
  238. WRKFN    EQU    WRKDR+1        ;FILE NAME BODY
  239. WRKFT    EQU    WRKFN+8        ;FILE NAME EXTENSION
  240. WRKEX    EQU    WRKFT+3        ;EXTENT NUMBER
  241. WRKS1    EQU    WRKEX+1        ;CPM RESERVED
  242. WRKS2    EQU    WRKS1+1        ;CPM RESERVED
  243. WRKRC    EQU    WRKS2+1        ;RECORD COUNT THIS EXTENT
  244. WRKMP    EQU    WRKRC+1        ;ALLOCATION MAP FOR EXTENT
  245. WRKNR    EQU    WRKMP+16    ;NEXT SEQUENTIAL RECORD
  246. WRKRR    EQU    WRKNR+1        ;2 BYTE RANDOM RECORD NUMBER
  247. WRKOV    EQU    WRKRR+2        ;RANDOM OVERFLOW FLAG
  248.  
  249. FREESP:    DW    ENDCDE        ;ALLOW USER CODE INSERTION
  250.  
  251.  
  252. ;---------------- MESSAGES
  253.  
  254. HLAREA    EQU    0109H        ;HELP   IN LINES 01-10 (01 FOR 09)
  255. DRAREA    EQU    0E08H        ;DIRECTORY LINES 14-21 (14 FOR 08)
  256.  
  257. HDRMSG:    DB    0,21,'SUPERZAP version ',$VER,'.',$MOD,0
  258.  
  259. ;---------------- GLOBAL WORK AREAS
  260.  
  261. MEMRY:    DS    2        ;FREE MEMORY SPACE
  262. CPM3:    DS    1        ;CP/M 3 flag
  263. READST:    DB    0FFH        ;RETURN CODE FROM READ OPERATIONS
  264. INCH:    DB    0        ;INPUT CHARACTER
  265. TYCURC:    DB    0        ;CURRENT CHARACTER FOR TYPE
  266. RELREC:    DW    0        ;CURRENT RECORD NUMBER
  267. BUFPOS:    DS    1
  268. BASEAD:    DS    3
  269. SAVREC:    DW    0        ;SAVE RECORD DURING SET
  270. SAVFSC:    DW    0        ;RECORD TO BE READ
  271. RO:    DB    0        ;READ ONLY FILE FILE
  272. NEWDE@:    DS    2        ;ADDRESS OF ENTRY JUST FOUND
  273. NXTDE@:    DS    2        ;NEXT POSITION IN TABLE
  274. TOPDE@:    DW    0        ;TOP OF DIRECTORY TABLE
  275. FSTDE@:    DW    0        ;BOTTOM OF DIRECTORY TABLE
  276. DECNT:    DB    0        ;NUMBER OF ENTRIES READ
  277. PRTCNT:    DB    0        ;NUMBER OF ENTRIES DISPLAYED
  278. PRTENT:    DB    0        ;ENTRY NUMBER TO BE PRINTED
  279. SELDE:    DS    1        ;SELECTED DIRECTORY ENTRY
  280. DIROFF:    DB    0        ;DIRECTORY DISPLAY OFFSET
  281. DEFDRV:    DS    1        ;CURRENT DRIVE ID
  282. REQDRV:    DS    1        ;REQUIRED DRIVE ID
  283. CURAN:    DS    1        ;CURRENT ABSOLUTE DRIVE NUMBER
  284. ERRFLD:    DW    0        ;ERROR FIELD ON SCREEN
  285.     DB    0        ;END OF FIELD MARK
  286. ERRTXT:    DW    0        ;ADDRESS EOF ERROR TEXT
  287. PRVERR:    DW    0        ;ADDRESS OF PREVIOUS TEXT
  288. WTG:    DB    0        ;NEXT PROCESS MODE
  289. AFNSTR:    DB    '???????????'
  290. DSKCMD:    DB    'DSK:'
  291. PGEPTR:    DS    2        ;ADDRESS OF PAGE POINTER LIST
  292. CURPG@:    DS    2        ;ADDRESS OF CURRENT PAGE ENTRY
  293. MAXPG@:    DS    2        ;ADDRESS OF LAST PAGE ENTRY
  294. RPANEL:    DS    1        ;DISPLAY PANEL REQUEST
  295.  
  296. ; SCRATCHPAD DATA
  297.  
  298. SPADDR:    DS    2        ;SCRATCHPAD BUFFER ADDRESS
  299. SPTYPE:    DS    1        ;NONE/PHYSICAL/RELATIVE
  300. SPSECT:    DS    2        ;SECTOR NUMBER
  301. SPDRIV:    DS    1        ;ABSOLUTE DRIVE NUMBER
  302. SPNAME:    DS    12        ;UFN OR TRACK NUMBER
  303.     DB    0        ;END OF FIELD MARK
  304. SPDMSG:    DB    'Drive ',0
  305. SPTMSG: DB    ' Track ',0
  306. SPSMSG:    DB    ' Sector ',0
  307. SPEMTY:    DB    'Empty',0
  308.  
  309. ;---------------- LIST MODE FCB
  310.  
  311. LMDFCB    EQU    $
  312.  
  313. LMDDR:    DB    0        ;DRIVE
  314. LMDFN:    DS    8        ;FILE NAME
  315. LMDFT:    DS    3        ;FILE TYPE
  316. LMDEX:    DB    0        ;EXTENT NUMBER
  317. LMDS1:    DB    0
  318. LMDS2:    DB    0
  319. LMDRC:    DB    0        ;RECORD COUNT
  320. LMDD0:    DS    16        ;CLUSTER ALLOC MAP
  321. LMDCR:    DB    0        ;CURRENT RECORD
  322.  
  323. ; LOCAL BIOS COPY - USED TO SIMPLIFY DIRECT BIOS CALLS
  324.  
  325. LBIOS     EQU    $        ;START OF LOCAL BIOS
  326.  
  327. WBOOT:    CALL    BIOS3        ;For CP/M3 we make all of these
  328. CONST:    CALL    BIOS3        ;branch to the same place.  From
  329. CONIN:    CALL    BIOS3        ;there we will do a "Come From"
  330. CONOUT:    CALL    BIOS3        ;statement to figure out which
  331. LIST:    CALL    BIOS3        ;routine was called.
  332. PUNCH:    CALL    BIOS3
  333. READER:    CALL    BIOS3        ;For CP/M 2.2 these CALLs will
  334. HOME:    CALL    BIOS3        ;be overlaid with a copy of the
  335. SELDSK:    CALL    BIOS3        ;JP table at the beginning of
  336. SETTRK:    CALL    BIOS3        ;the BIOS.
  337. SETSEC:    CALL    BIOS3
  338. SETDMA:    CALL    BIOS3        ;JHB - January 1986
  339. READ:    CALL    BIOS3
  340. WRITE:    CALL    BIOS3
  341. LISTST:    CALL    BIOS3
  342. SECTRN:    CALL    BIOS3
  343.  
  344. ; Note that the entire CP/M 3.x BIOS table is not represented here.
  345.  
  346. ELBIOS    EQU    $        ;END OF LOCAL BIOS
  347.  
  348. ; INIT - SPZ INITIALISATION
  349.  
  350.     $RTN    INIT
  351.     LD    HL,(6)
  352.     ld    l,0        ;Don't interfere with any RSXs
  353.     LD    SP,HL        ;SET STACK TO BASE OF BDOS
  354.  
  355.     ld    c,getVsn    ;Test CP/M version.  Set
  356.     call    cpm        ;'cpm3' to zero if 2.x
  357.     ld    a,2Fh        ;or to 1 if 3.x
  358.     sub    l
  359.     ld    a,h        ;Pull in MP/M flag too
  360.     jr    nc,notPlus
  361.     inc    a
  362. notPlus:
  363.     ld    (cpm3),a    ;Zero if CP/M 2.x, Non-zero if MP/M or CP/M 3.x
  364.     or    a        ;Only copy BIOS vector if CP/M 2.x
  365.     jr    nz,noLocal
  366.     LD    HL,(1)        ;LOAD BIOS VECTOR ADDRESS
  367.     LD    DE,LBIOS
  368.     LD    BC,ELBIOS-LBIOS
  369.     LDIR            ;SET UP LOCAL BIOS VECTOR
  370. noLocal:
  371.     LD    HL,AFNSTR
  372.     CALL    LSEL        ;SET LIST SELECTION TO ALL
  373.     LD    HL,(FREESP)    ;FIND TOP OF PROG
  374.     LD    (SPADDR),HL    ;SET SCRATCHPAD ADDRESS
  375.     LD    DE,080H
  376.     ADD    HL,DE        
  377.     LD    (MEMRY),HL    ;PUT WORK AREA ABOVE SCRATCHPAD
  378.     XOR    A
  379.     LD    (SPTYPE),A    ;SET SCRATCHPAD EMPTY
  380.     LD    HL,0
  381.     LD    (ERRTXT),HL    ;CLEAR ERROR MESSAGE FIELD
  382.     LD    (PRVERR),HL    ;AND PREVIOUS ERROR
  383.     LD    C,GETDEF
  384.     CALL    CPM        ;GET DEFAULT DRIVE NUMBER
  385.     LD    (DEFDRV),A    ;SAVE IT
  386.     LD    (CURAN),A    ;SET CURRENT ABSOLUTE DISK NUMBER
  387.     LD    A,(WRKDR)
  388.     OR    A
  389.     JR    Z,INIT01    ;IF DRIVE ID IN COMMAND
  390.     DEC    A
  391.     LD    (CURAN),A    ;USE THAT AS CURRENT
  392. INIT01    EQU    $        ;ENDIF
  393.     LD    HL,CMD        ;POINT TO COMMAND AREA
  394. INIT02    EQU    $        ;LOOP
  395.     INC    HL
  396.     LD    A,(HL)
  397.     OR    A
  398.     JR    Z,INIT05    ;QUIT IF END OF COMMAND
  399.     CP    ' '
  400.     JR    Z,INIT02    ;IGNORE SPACES
  401.     INC    HL
  402.     LD    A,(HL)
  403.     CP    ':'        
  404.     JR    NZ,INIT03    ;IF CMD IS DRIVE ID
  405.     INC    HL        ;SKIP PAST IT
  406.     JR    INIT04
  407. INIT03    EQU    $        ;ELSE
  408.     DEC    HL        ;POINT TO FIRST CHARACTER
  409. INIT04    EQU    $        ;ENDIF
  410.     LD    DE,DSKCMD
  411.     LD    BC,4
  412.     CALL    CPST
  413.     JR    NZ,INIT05    ;IF DISK OPTION
  414.     CALL    SETP        ;SET DISK MODE
  415.     JR    INIT06
  416. INIT05    EQU    $        ;ELSE
  417.     CALL    SETD        ;ASSUME DIRECTORY MODE
  418.     LD    HL,WRKFN
  419.     LD    A,(HL)
  420.     CP    ' '
  421.     JR    Z,INIT08    ;IF NOT NULL OPTION
  422.     LD    B,11
  423. INIT09    EQU    $        ;LOOP
  424.     LD    A,(HL)
  425.     CP    '?'
  426.     JR    Z,INIT10    ;EXIT IF AFN INDICATED
  427.     INC    HL
  428.     DJNZ    INIT09        ;TILL FN AND FT SCANNED
  429.     CALL    SETF        ;MUST BE UFN
  430.     JR    INIT12
  431. INIT10    EQU    $        ;ON '?' FOUND
  432.     LD    HL,WRKFN
  433.     CALL    LSEL        ;SET LIST SELECTION TO AFN GIVEN
  434. INIT12    EQU    $        ;ENDIF
  435. INIT08    EQU    $        ;ENDIF
  436. INIT06    EQU    $        ;ENDIF
  437.     LD    A,(CURAN)    
  438.     CALL    CHDR        ;INITIALISE DISK CONTROL BLOCKS
  439.     JR    NZ,INIT13    ;IF ILLEGAL DISK
  440.     LD    A,(DEFDRV)
  441.     CALL    CHDR        ;USE DEFAULT DISK
  442.     LD    HL,ILDMSG
  443.     LD    (ERRTXT),HL    ;SET ERROR MESSAGE
  444. INIT13    EQU    $
  445.  
  446. ; MAIN - SPZ MAINLINE
  447.  
  448.     $RTN    MAIN
  449. MAIN01    EQU    $        ;LOOP
  450.     LD    A,(WTG)
  451.     $MTCH    MAINLS        ;TEST CODE
  452.     JR    NZ,MAIN02    ;IF INVALID ACTION EXIT
  453.     $EXVA    MAINVC        ;EXEC ACTION
  454.     JR    MAIN01
  455. MAIN02    EQU    $        ;ENDLOOP
  456.     CALL    CLRS
  457.     LD    A,(DEFDRV)
  458.     LD    E,A
  459.     LD    C,SETDEF
  460.     CALL    CPM        ;RESTORE ORIGINAL DEFAULT
  461.     ld    c,reset        ;Reset disk system
  462.     call    cpm
  463.     JP    0        ;EXIT TO SYSTEM
  464.  
  465. ILDMSG:    DB    '** Invalid Disk Specified',0
  466.  
  467. ; MAINLINE ACTION VECTOR
  468.  
  469. MAINLS:    DB    4,'XFDP'
  470. MAINVC    EQU    $
  471.     DW    ENDR        ;END RUN
  472.     DW    FDMD        ;FILE DISPLAY MODE
  473.     DW    DRMD        ;DIRECTORY MODE
  474.     DW    PSMD        ;PHYSICAL SECTOR MODE
  475.  
  476.  
  477. ; ENDR - END SPZ RUN
  478.  
  479.     $RTN    ENDR
  480.     XOR    A
  481.     LD    (WTG),A
  482.     RET
  483.  
  484.  
  485. ; FDMD - FILE DISPLAY MODE
  486.  
  487.     $RTN    FDMD
  488.     LD    HL,(FDMDER)
  489.     LD    (ERRFLD),HL    ;SET ERROR FIELD POINTER
  490.     LD    A,0FFH
  491.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  492.     LD    (RPANEL),A    ;REQUEST PANEL DISPLAY
  493.     CALL    TFLE
  494.     LD    A,(FLERR)
  495.     OR    A
  496.     JR    Z,FDMD03    ;IF FILE ERROR
  497.     CALL    SETD        ;SET DIRECTORY MODE
  498.     JP    FDMD04
  499. FDMD03    EQU    $        ;ELSE
  500. FDMD05    EQU    $        ;LOOP
  501.     LD    A,(RPANEL)
  502.     OR    A
  503.     JR    Z,FDMD11    ;IF PANEL REQUIRED
  504.     XOR    A
  505.     LD    (RPANEL),A    ;RESET REQUEST
  506.     $NPANEL    FDMDPN        ;DISPLAY FILE MODE PANEL
  507.     LD    HL,FILEMS    ;POINT TO FILE MESSAGE
  508.     LD    A,(COMFLG)
  509.     OR    A
  510.     JR    Z,FDMD09    ;IF .COM FILE
  511.     LD    HL,LOADMS    ;POINT TO LOAD MESSAGE
  512. FDMD09    EQU    $        ;ENDIF
  513.     CALL    DFLD
  514.     $FLD    FSPMSG
  515.     CALL    DSPI        ;DISPLAY SCRATCHPAD INFO
  516. FDMD11    EQU    $        ;ENDIF
  517.     CALL    ERRP        ;PROCESS ERRORS
  518.     LD    A,(FDMDSI)
  519.     OR    A
  520.     JR    Z,FDMD10    ;IF SI DISPLAY REQUIRED
  521.     CALL    DFSI        ;DISPLAY FILE SECTOR INFO
  522.     LD    HL,FBUFF
  523.     CALL    WRBF        ;DISPLAY BUFFER CONTENTS
  524.     XOR    A
  525.     LD    (FDMDSI),A    ;RESET REQUEST
  526. FDMD10    EQU    $        ;ENDIF
  527. FDMD07    EQU    $        ;LOOP
  528.     $IFLD    SELMSG        ;PROMPT SELMSG AND GET COMMAND
  529.     $MTCH    FDMDLS
  530.     JR    Z,FDMD06    ;EXITIF VALID
  531.     CALL    ALRM        ;SOUND THE ALARM
  532.     JR    FDMD07
  533. FDMD06    EQU    $        ;ENDLOOP
  534.     $EXVA    FDMDVC
  535.     LD    A,(WTG)
  536.     CP    'F'
  537.     JR    NZ,FDMD08    ;EXIT IF MODE NO LONGER F
  538.     JP    FDMD05
  539. FDMD08    EQU    $        ;ENDLOOP
  540.     LD    C,CLOSE
  541.     LD    DE,WRKFCB
  542.     CALL    CPM
  543. FDMD04    EQU    $        ;ENDIF
  544.     RET
  545.  
  546. COMSTR:    DB    'COM'        ;.COM FILE TYPE
  547.  
  548.  
  549. ; FILE DISPLAY MODE MESSAGES, PANEL AND ACTION VECTOR
  550.  
  551. SELMSG:    DB    9,10,'Select Function ===> ',00
  552. SETMSG:    DB    11,36,'Enter Hex Sector',0    ;OVERLAID BY CURMSG
  553. FDMDER:    DB    7,0                ;ERROR POSITION
  554. FILEMS:    DB    11,53,'File Offset ',0
  555. LOADMS:    DB    11,53,'Load Address',0
  556.  
  557. FDMDPN:    DB    14                ;FIELD COUNT
  558.     DB    02,00,'N  Next sector',0
  559.     DB    03,00,'P  Previous sector',0
  560.     DB    02,22,'T  Top of file',0
  561.     DB    03,22,'E  Last sector of file',0
  562.     DB    02,54,'Z  Exit from Superzap',0
  563.     DB    03,54,'L  Exit to file list',0
  564.     DB    04,00,'C  Change Sector',0
  565.     DB    04,22,'S  Select Sector',0
  566.     DB    04,54,'                        ',0    ;Deleted for C128
  567.     DB    11,04,'File-Name',0
  568.     DB    11,16,'Access',0
  569. CURMSG:    DB    11,36,'Current-Sector  ',0    ;OVERLAID BY SETMSG
  570. FILE:    DB    12,00
  571. DRIVNM:    DB    'd:'
  572. FILENM:    DB    'filename.typ',0
  573.     DB    12,17,'R/'
  574. FDMDRS:    DB    's ',0                ;ACCESS INDICATOR
  575. FSPMSG:    DB    06,00,'Scratchpad :- ',0
  576.  
  577. ; FILE STATISTICS FIELDS
  578.  
  579. WRSNFL:    DB    12,41,0
  580. WRFOFL:    DB    12,55,0
  581. SFSNIP:    DB    12,45,0
  582. ; FOLLOWING LINE CHANGED FOR C128 TO DELETE SECTOR CHANGE MODE COMMAND X
  583. FDMDLS:    DB    8,'NCPLTESZ'
  584. ;
  585. FDMDVC    EQU    $
  586.     DW    NXFS        ;NEXT FILE SECTOR
  587.     DW    FSCH        ;FILE SECTOR CHANGE
  588.     DW    PRFS        ;PREVIOUS FILE SECTOR
  589.     DW    SETD        ;SELECT DIRECTORY MODE
  590.     DW    FRFS        ;POSITION TO FIRST FILE SECTOR
  591.     DW    LSFS        ;POSITION TO LAST FILE SECTOR
  592.     DW    SFSN        ;SET FILE SECTOR NUMBER
  593.     DW    SETX        ;SET EXIT MODE
  594. ; LINE DELETED HERE FOR C128 (SCRATCHPAD ACTION VECTOR DELETED)
  595. ;
  596. FDMDSI:    DS    1        ;SI REQUEST FLAG
  597.  
  598.  
  599. ; NXFS - READ NEXT FILE SECTOR
  600.  
  601.     $RTN    NXFS
  602.     LD    HL,(RELREC)
  603.     INC    HL
  604.     LD    (RELREC),HL    ;INCREMENT RECORD NUMBER
  605.     CALL    RDFS        ;ATTEMPT TO READ RECORD
  606.     JR    NZ,NXFS02    ;IF GOOD READ
  607.     LD    A,TRUE
  608.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  609.     JR    NXFS01
  610. NXFS02    EQU    $        ;ELSE
  611.     CALL    ALRM        ;SOUND ALARM
  612. NXFS01    EQU    $        ;ENDIF
  613.     RET
  614.  
  615.  
  616. ; PRFS - READ PREVIOUS FILE SECTOR
  617.  
  618.     $RTN    PRFS
  619.     LD    HL,(RELREC)
  620.     LD    A,H
  621.     OR    L
  622.     JR    NZ,PRFS01    ;IF RECORD ZERO
  623.     CALL    ALRM        ;SOUND ALARM
  624.     JR    PRFS02
  625. PRFS01    EQU    $
  626.     DEC    HL
  627.     LD    (RELREC),HL    ;DECREMENT RECORD POINTER
  628.     CALL    RDFS        ;ATTEMPT TO READ IT
  629.     JR    NZ,PRFS03    ;IF GOOD READ
  630.     LD    A,TRUE
  631.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  632.     JP    PRFS04
  633. PRFS03    EQU    $        ;ELSE
  634.     CALL    ALRM        ;SOUND ALARM
  635. PRFS04    EQU    $        ;ENDIF
  636. PRFS02    EQU    $        ;ENDIF
  637.     RET
  638.  
  639.  
  640. ; FSCH - FILE SECTOR CHANGE
  641.  
  642.     $RTN    FSCH
  643.     LD    A,(RO)
  644.     OR    A
  645.     JR    Z,FSCH01    ;IF READ ONLY FILE
  646.     CALL    ALRM        ;SOUND THE ALARM
  647.     JR    FSCH02
  648. FSCH01    EQU    $        ;ELSE
  649.     CALL    SCCH        ;GO INTO SECTOR CHANGE MODE
  650.     LD    A,(SCCHWR)
  651.     OR    A
  652.     JR    Z,FSCH03    ;IF WRITE REQUIRED
  653.     CALL    WRFS        ;WRITE OUT SECTOR
  654.     JR    FSCH04
  655. FSCH03    EQU    $        ;ELSE
  656.     CALL    RDFS        ;READ SECTOR
  657. FSCH04    EQU    $        ;ENDIF
  658.     LD    A,TRUE
  659.     LD    (RPANEL),A    ;REDISPLAY FILE MODE PANEL
  660.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  661. FSCH02    EQU    $        ;ENDIF
  662.     RET            
  663.  
  664. ; FRFS - POSITION TO FIRST FILE SECTOR
  665.  
  666.     $RTN    FRFS
  667.     LD    HL,0
  668.     LD    (RELREC),HL
  669.     CALL    RDFS        ;READ THE SECTOR
  670.     LD    A,TRUE
  671.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  672.     RET
  673.  
  674. ; LSFS - POSITION TO LAST FILE SECTOR
  675.  
  676.     $RTN    LSFS
  677.     LD    DE,WRKFCB
  678.     LD    C,FILESZ    ;COMPUTE FILE SIZE
  679.     CALL    CPM
  680.     LD    HL,(WRKRR)
  681.     DEC    HL
  682.     LD    (RELREC),HL    ;SET UP RECORD TO READ
  683.     CALL    RDFS        ;READ THE RECORD
  684.     LD    A,TRUE
  685.     LD    (FDMDSI),A    ;REQUEST SI DISPLAY
  686.     RET
  687.  
  688. ; SFSN - SET FILE SECTOR NUMBER
  689.  
  690.     $RTN    SFSN
  691.     LD    HL,SELMSG
  692.     CALL    CFLD        ;CLEAR FUNCTION PROMPT
  693.     LD    HL,(RELREC)
  694.     LD    (SAVREC),HL    ;SAVE RECORD NUMBER
  695.     $FLD    SETMSG        ;DISPLAY SET MESSAGE
  696.     LD    HL,0
  697.     LD    (RELREC),HL    ;ZERO RECORD NUMBER
  698. SFSN01    EQU    $
  699.     CALL    DFSI        ;DISPLAY FILE SECTOR INFO
  700.     $IFLD    SFSNIP        ;POSITION AND GET INPUT
  701.     $MTCH    HEXCHR
  702.     JR    NZ,SFSN02    ;IF VALID
  703.     EX    DE,HL        ;DIGIT TO DE
  704.     LD    HL,(RELREC)
  705.     CALL    H16D        ;HL=HL*16+DIGIT
  706.     LD    (RELREC),HL    ;SAVE NEW RECORD NUMBER
  707.     JR    SFSN03
  708. SFSN02    EQU    $
  709.     CP    $ESC
  710.     JR    NZ,SFSN04    ;ELSE IF ESC
  711.     LD    HL,(SAVREC)
  712.     LD    (RELREC),HL    ;RESTORE SECTOR NUMBER
  713.     JR    SFSN03
  714. SFSN04    EQU    $
  715.     CP    $LEFT
  716.     JR    NZ,SFSN06    ;ELSE IF BACKSPACE
  717.     LD    HL,RELREC+1
  718.     XOR    A
  719.     RRD
  720.     DEC    HL
  721.     RRD            ;RELREC=RELREC/16
  722.     JR    SFSN03
  723. SFSN06    EQU    $
  724.     CP    CR
  725.     JR    NZ,SFSN07    ;ELSE IF C/R
  726.     CALL    RDFS        ;READ SECTOR
  727.     JR    Z,SFSN08    ;IF BAD READ
  728.     CALL    ALRM        ;SOUND THE ALARM
  729.     XOR    A
  730.     LD    (INCH),A    ;DONT EXIT
  731. SFSN08    EQU    $        ;ENDIF
  732.     JR    SFSN03
  733. SFSN07    EQU    $        ;ELSE 
  734.     CALL    ALRM        ;ERROR
  735. SFSN03    EQU    $
  736.     LD    A,(INCH)
  737.     CP    CR
  738.     JR    Z,SFSN99    ;EXITIF C/R
  739.     CP    $ESC
  740.     JR    Z,SFSN99    ;OR ESC
  741.     JP    SFSN01
  742. SFSN99    EQU    $        ;ENDLOOP
  743.     $FLD    CURMSG        ;REDISPLAY CURRENT SECTOR MESSAGE
  744.     LD    A,TRUE
  745.     LD    (FDMDSI),A    ;REQUEST DISPLAY
  746.     RET
  747.  
  748. ; FSPM - FILE SCRATCHPAD MODE
  749.  
  750.     $RTN    FSPM
  751.     $NPANEL    PSPMPN        ;DISPLAY PANEL
  752.     $FLD    PSPCUR        ;POSITION FOR CURRENT INFO
  753.     LD    A,(CURAN)
  754.     ADD    A,41H
  755.     CALL    CHRO        ;DISPLAY DRIVE
  756.     LD    A,':'
  757.     CALL    CHRO
  758.     $STRO    FILENM
  759.     $STRO    SPSMSG
  760.     $HEXW    RELREC        ;SECTOR
  761.     $FLD    PSPSPD        ;POSITION FOR S/P DATA
  762.     CALL    DSPD        ;DISPLAY SCRATCHPAD DATA
  763.     CALL    SPCI        ;GET COMMAND
  764.     $EXVA    FSPMV        ;PROCESS COMMAND
  765.     LD    A,0FFH
  766.     LD    (RPANEL),A    ;REQUEST PANEL
  767.     LD    (FDMDSI),A    ;REQUEST SECTOR INFO
  768.     RET
  769.  
  770. FSPMV:    DW    FSPX
  771.     DW    FLSP
  772.     DW    FXSP
  773.  
  774.     $RTN    FSPX
  775.     RET
  776.  
  777. ; SPCI - GET SCRATCHPAD COMMAND
  778.  
  779.     $RTN    SPCI
  780. SPCI01    EQU    $        ;LOOP
  781.     $IFLD    SELMSG        ;GET COMMAND
  782.     $MTCH    PSPML
  783.     JR    Z,SPCI02    ;EXIT IF VALID
  784.     CALL    ALRM        ;SOUND ALARM
  785.     JR    SPCI01
  786. SPCI02    EQU    $        ;ENDLOOP
  787.     RET
  788.  
  789. ; DSPI - DISPLAY S/P INFO
  790.  
  791.     $RTN    DSPI
  792.     LD    A,(SPTYPE)
  793.     OR    A
  794.     JR    NZ,DSPI01    ;IF EMPTY
  795.     $STRO    SPEMTY
  796.     JR    DSPI02
  797. DSPI01    EQU    $
  798.     DEC    A
  799.     JR    NZ,DSPI03    ;ELSE IF PHYSICAL
  800.     $STRO    SPDMSG
  801.     LD    A,(SPDRIV)
  802.     ADD    A,41H
  803.     CALL    CHRO        ;DISPLAY DRIVE
  804.     $STRO    SPTMSG
  805.     $HEXW    SPNAME        ;TRACK
  806.     $STRO    SPSMSG
  807.     $HEXW    SPSECT        ;SECTOR
  808.     JR    DSPI02
  809. DSPI03    EQU    $        ;ELSE FILE RELATIVE
  810.     LD    A,(SPDRIV)
  811.     ADD    A,041H
  812.     CALL    CHRO
  813.     LD    A,':'
  814.     CALL    CHRO
  815.     $STRO    SPNAME        ;DISPLAY FILE NAME
  816.     $STRO    SPSMSG
  817.     $HEXW    SPSECT        ;AND SECTOR
  818. DSPI02    EQU    $        ;ENDIF
  819.     RET
  820.  
  821.  
  822. ; FXSP - EXCHANGE WITH SCRATCHPAD
  823.  
  824.     $RTN    FXSP
  825.     LD    A,(SPTYPE)
  826.     OR    A
  827.     JR    NZ,FXSP01    ;IF PAD EMPTY
  828.     CALL    ALRM        ;RING BELL
  829.     JR    FXSP02
  830. FXSP01    EQU    $        ;ELSE
  831.     LD    A,(RO)
  832.     OR    A
  833.     JR    Z,FXSP03    ;IF READ ONLY
  834.     CALL    ALRM        ;ERROR
  835.     JR    FXSP04        ;ELSE
  836. FXSP03    EQU    $
  837.     LD    BC,(SPADDR)
  838.     CALL    dmaSet        ;SET CPM BUFFER
  839.     CALL    WRFS        ;WRITE BUFFER
  840.     LD    BC,FBUFF
  841.     CALL    dmaSet        ;RESTORE DMA
  842.     CALL    FLSP        ;COPY OLD BUFFER
  843.     CALL    RDFS        ;RE READ SECTOR
  844. FXSP04    EQU    $        ;ENDIF
  845. FXSP02    EQU    $        ;ENDIF
  846.     RET
  847.  
  848. ; FLSP - LOAD SCRATCHPAD (LOGICAL)
  849.  
  850.     $RTN    FLSP
  851.     LD    HL,FBUFF
  852.     LD    DE,(SPADDR)
  853.     LD    BC,128
  854.     LDIR            ;COPY THE BUFFER
  855.     LD    A,(CURAN)
  856.     LD    (SPDRIV),A    ;SET DRIV
  857.     LD    HL,FILENM
  858.     LD    DE,SPNAME
  859.     LD    BC,12
  860.     LDIR            ;COPY FILE NAME
  861.     LD    HL,(RELREC)
  862.     LD    (SPSECT),HL
  863.     LD    A,2
  864.     LD    (SPTYPE),A    ;SET THE TYPE
  865.     RET
  866.  
  867. ; DFSI - DISPLAY FILE SECTOR INFORMATION
  868.  
  869.     $RTN    DFSI
  870.     $FLD    WRSNFL        ;POSITION FOR SECTOR NUMBER
  871.     $HEXW    RELREC        ;DISPLAY RECORD NUMBER
  872.     $FLD    WRFOFL        ;POSITION FOR FILE OFFSET
  873.     LD    HL,(RELREC)    ;GET REC NO
  874.     XOR    A
  875.      SRL    H
  876.     RR    L
  877.     RRA
  878.     LD    (BASEAD+2),A
  879.     LD    A,(COMFLG)
  880.     OR    A
  881.     JR    Z,DFSI01    ;IF .COM FLAG
  882.     INC    HL
  883. DFSI01    EQU    $        ;ENDIF
  884.     LD    (BASEAD),HL    ;SAVE REC/2
  885.     CALL    PRTADR        ;PRINT 3 BYTE ADDRESS
  886.     RET
  887.  
  888. COMFLG:    DS    1        
  889.  
  890.  
  891. ; DRMD - DIRECTORY MODE
  892.  
  893.     $RTN    DRMD
  894.     LD    HL,(DRMDEF)
  895.     LD    (ERRFLD),HL    ;SET PANEL ERROR FIELD
  896.     LD    A,TRUE
  897.     LD    (DRMDLD),A    ;REQUEST LIST
  898. DRMD01    EQU    $        ;LOOP
  899.     LD    A,(DRMDLD)
  900.     OR    A
  901.     JR    Z,DRMD02    ;IF LIST REQUIRED
  902.     $NPANEL    DRMDPN        ;DISPLAY DIRECTORY LIST PANEL
  903.     CALL    DLST        ;DO DIRECTORY LIST
  904.     XOR    A
  905.     LD    (DRMDLD),A    ;RESET LIST REQUEST
  906. DRMD02    EQU    $        ;ENDIF
  907. DRMD06    EQU    $        ;LOOP
  908.     CALL    ERRP        ;PROCESS ERRORS
  909.     LD    A,(SELDE)
  910.     CALL    DIRPOS        ;POSITION OVER CURRENT ENTRY
  911.     CALL    CHRF
  912.     $MTCH    DRMDLS
  913.     JR    Z,DRMD05    ;EXITIF VALID
  914.     CALL    ALRM        ;SOUND ALARM
  915.     JR    DRMD06
  916. DRMD05    EQU    $        ;ENDLOOP
  917.     $EXVA    DRMDVC        ;PERFORM ACTION
  918.     LD    A,(WTG)
  919.     CP    'D'    
  920.     JR    NZ,DRMD07    ;EXIT IF MODE NO LONGER D
  921.     JP    DRMD01
  922. DRMD07    EQU    $        ;ENDLOOP
  923.     RET
  924.  
  925.  
  926. ; DIRECTORY MODE PANEL AND VECTOR
  927. ;
  928. ; Updated Jan 86 by JHB to include user number selection
  929.  
  930. DRMDPN:    DB    13    ;(Was 12)
  931.     DB    02,00,'^',$LEFT+040H,'  Cursor left',0
  932.     DB    03,00,'^',$RIGHT+040H,'  Cursor right',0
  933.     DB    04,00,'^',$UP+040H,'  Cursor up',0
  934.     DB    05,00,'^',$DOWN+040H,'  Cursor down',0
  935.     DB    02,22,'P  Previous directory page',0
  936.     DB    03,22,'N  Next directory page',0
  937.     db    04,22,'U  Change user number',0
  938.     DB    02,54,'Z  Exit from Superzap',0
  939.     DB    03,54,'C  Change disk',0
  940.     DB    04,54,'S  Select track/sector',0
  941. ; FOLLOWING LINE CHANGED FOR C128
  942.     DB    05,54,'                          ',0    ;M option deleted
  943. ;
  944.     DB    07,00,'E  Edit file',0
  945.     DB    07,22,'T  Type file',0
  946.  
  947. ; FOLLOWING LINE CHANGED FOR C128 TO DELETE M OPTION
  948. DRMDLS:    DB    14,$LEFT,$RIGHT,$UP,$DOWN,CR,'EZCSPNTU',$TAB
  949.  
  950. DRMDVC:    DW    FBS
  951.     DW    FFS
  952.     DW    FUP
  953.     DW    FDN
  954.     DW    FNL
  955.     DW    STFL
  956.     DW    SETX
  957.     DW    CHDD
  958. ; 1 LINE DELETED HERE FOR C128 TO DELETE ACTION VECTORS FOR M
  959.     DW    SETP
  960.     DW    DIRP
  961.     DW    DIRN
  962.     DW    TYPE
  963.     dw    chun
  964.     DW    FFS
  965.  
  966. DRMDEF:    DB    9,0
  967. NRFMSG:    DB    '** No records in file',0
  968. FNFMSG:    DB    '** File not found',0
  969.  
  970. DRMDLD:    DS    1        ;LIST DIRECTORY REQUEST FLAG
  971.  
  972.  
  973. ; DIRP - PAGE UP DIRECTORY
  974.  
  975.     $RTN    DIRP
  976.     LD    A,(DIROFF)
  977.     OR    A
  978.     JR    Z,DIRP01    ;IF NOT PAGE 0
  979.     SUB    32
  980.     LD    (DIROFF),A    ;SET PREV PAGE
  981.     XOR    A
  982.     LD    (SELDE),A    ;FIRST ENTRY ON PAGE
  983.     CALL    ERRP
  984.     LD    HL,DRAREA
  985.     CALL    CLRA        ;CLEAR AREA
  986.     CALL    DLST        ;DISPLAY PAGE
  987.     JR    DIRP02
  988. DIRP01    EQU    $        ;ELSE
  989.     CALL    ALRM        ;RING BELL
  990. DIRP02    EQU    $        ;ENDIF
  991.     RET
  992.  
  993. ; DIRN - PAGE DOWN DIRECTORY
  994.  
  995.     $RTN    DIRN
  996.     LD    A,(DIROFF)
  997.     ADD    A,32        ;POINT TO NEXT PAGE
  998.     LD    HL,DECNT
  999.     CP    (HL)
  1000.     JR    NC,DIRN01    ;IF AVAILABLE
  1001.     LD    (DIROFF),A    ;SAVE NEW POINTER
  1002.     XOR    A
  1003.     LD    (SELDE),A    ;SET FIRST ENTRY ON PAGE
  1004.     CALL    ERRP
  1005.     LD    HL,DRAREA
  1006.     CALL    CLRA        ;CLEAR DIRECTORY AREA
  1007.     CALL    DLST        ;DISPLAY DIRECTORY
  1008.     JR    DIRN02
  1009. DIRN01    EQU    $        ;ELSE
  1010.     CALL    ALRM        ;ALARM
  1011. DIRN02    EQU    $        ;ENDIF
  1012.     RET
  1013.  
  1014.  
  1015. ; FBS - BACKSPACE IN DIRECTORY
  1016.  
  1017.     $RTN    FBS
  1018.     LD    A,(DIROFF)
  1019.     LD    B,A
  1020.     LD    HL,DECNT
  1021. FBS01    EQU    $        ;REPEAT
  1022.     LD    A,(SELDE)
  1023.     DEC    A
  1024.     AND    31
  1025.     LD    (SELDE),A    ;SELECT PREVIOUS
  1026.     JR    Z,FBS02        ;EXIT IF FIRST POSN
  1027.     ADD    A,B
  1028.     CP    (HL)
  1029.     JR    NC,FBS01    ;UNTIL NEW<=MAX
  1030. FBS02    EQU    $
  1031.     RET
  1032.  
  1033. ; FUP - CURSOR UP IN DIRECTORY
  1034.  
  1035.     $RTN    FUP
  1036.     LD    A,(DIROFF)
  1037.     LD    B,A
  1038.     LD    HL,DECNT
  1039. FUP01    EQU    $        ;REPEAT
  1040.     LD    A,(SELDE)
  1041.     SUB    4
  1042.     AND    31
  1043.     LD    (SELDE),A    ;1 LINE UP
  1044.     JR    Z,FUP02        ;EXIT IF FIRST POSN
  1045.     ADD    A,B
  1046.     CP    (HL)
  1047.     JR    NC,FUP01    ;UNTIL NEW<=MAX
  1048. FUP02    EQU    $
  1049.     RET
  1050.  
  1051. ; FDN - CURSOR DOWN IN DIRECTORY
  1052.  
  1053.     $RTN    FDN
  1054.     LD    A,(DIROFF)
  1055.     LD    B,A
  1056.     LD    HL,DECNT
  1057. FDN01    EQU    $        ;REPEAT
  1058.     LD    A,(SELDE)
  1059.     ADD    A,4
  1060.     AND    31
  1061.     LD    (SELDE),A    ;1 LINE DOWN
  1062.     JR    Z,FDN02
  1063.     ADD    A,B
  1064.     CP    (HL)
  1065.     JR    NC,FDN01    ;UNTIL NEW<=MAX
  1066. FDN02    EQU    $
  1067.     RET
  1068.  
  1069. ; FNL - C/R IN DIRECTORY
  1070.  
  1071.     $RTN    FNL
  1072.     LD    A,(DIROFF)
  1073.     LD    B,A
  1074.     LD    HL,DECNT
  1075. FNL01    EQU    $        ;REPEAT
  1076.     LD    A,(SELDE)    ;PICK UP CURRENT
  1077.     ADD    A,4        ;MOVE TO NEXT LINE
  1078.     AND    01CH
  1079.     LD    (SELDE),A    ;START OF NEXT LINE
  1080.     JR    Z,FNL02
  1081.     ADD    A,B
  1082.     LD    HL,DECNT
  1083.     CP    (HL)
  1084.     JR    NC,FNL01    ;UNTIL NEW<=MAX
  1085. FNL02    EQU    $
  1086.     RET
  1087.  
  1088. ; FFS - CURSOR FORWARD IN DIRECTORY
  1089.  
  1090.     $RTN    FFS
  1091.     LD    A,(DIROFF)
  1092.     LD    B,A        ;GET START OF DISPLAY
  1093.     LD    HL,DECNT
  1094. FFS01    EQU    $        ;REPEAT
  1095.     LD    A,(SELDE)
  1096.     INC    A
  1097.     AND    31
  1098.     LD    (SELDE),A    ;NEXT ENTRY
  1099.     JR    Z,FFS02
  1100.     ADD    A,B
  1101.     CP    (HL)
  1102.     JR    NC,FFS01    ;UNTIL NEW<=MAX
  1103. FFS02    EQU    $
  1104.     RET
  1105.  
  1106. ; DIRPOS - POSITION TO PRINT DIRECTORY ENTRY
  1107.  
  1108. DIRPOS    EQU    $
  1109.     LD    (DIRNUM),A    ;SAVE ENTRY POSITION
  1110.     LD    HL,LPTAB
  1111.     RRCA
  1112.     RRCA            ;DIVIDE COUNT BY 4
  1113.     AND    0FH        ;MAKE IT LINE COUNT
  1114.     CALL    AAHL
  1115.     LD    B,(HL)        ;PICK UP LINE POSN
  1116.     LD    HL,DCTAB
  1117.     LD    A,(DIRNUM)    ;PICK UP ENTRY AGAIN
  1118.     AND    03        ;MAKE COUNT INTO COLUM NUMBER
  1119.     CALL    AAHL
  1120.     LD    H,(HL)        ;GET COLUMN POSITION
  1121.     LD    L,B        ;AND LINE NUMBER
  1122.     CALL    CURS        ;POSITION CURSOR
  1123.     RET
  1124. DIRNUM:    DS    1
  1125.  
  1126.  
  1127. ; STFL - SELECT FILE
  1128.  
  1129.     $RTN    STFL
  1130.     CALL    CFCB        ;COPY FCB FROM DIR LIST
  1131.     CALL    SETF        ;SET FILE MODE
  1132.     RET
  1133.  
  1134. ; CFCB - COPY FCB FROM DIRECTORY LIST
  1135.  
  1136.     $RTN    CFCB
  1137.     LD    A,(DECNT)
  1138.     OR    A
  1139.     JR    NZ,CFCB01    ;IF NO FILES
  1140.     CALL    ALRM        ;SOUND ALARM
  1141.     LD    HL,FNFMSG
  1142.     LD    (ERRTXT),HL    ;SET FILE NOT FOUND ERROR
  1143.     JR    CFCB02
  1144. CFCB01    EQU    $        ;ELSE
  1145.     LD    A,(SELDE)    ;GET SELECTED ENTRY NUMBER
  1146.     LD    B,A
  1147.     LD    A,(DIROFF)
  1148.     ADD    A,B        ;ADD DISPLAY START
  1149.     LD    H,0
  1150.     LD    L,A
  1151.     LD    DE,(MEMRY)    ;BASE OF TABLE
  1152.     CALL    H16D        ;HL=HL*16+DE
  1153.     LD    DE,WRKFN    ;START OF FILE NAME
  1154.     LD    BC,11
  1155.     LDIR            ;MOVE DE OVER TO FCB
  1156.     XOR    A
  1157.     LD    (WRKEX),A
  1158. CFCB02    EQU    $        ;ENDIF
  1159.     RET
  1160.  
  1161. ; TYPE - TYPE SELECTED FILE
  1162.  
  1163.     $RTN    TYPE
  1164.     CALL    CFCB        ;SET UP FCB
  1165.     CALL    TFLE        ;TEST FILE
  1166.     LD    A,(FLERR)
  1167.     OR    A
  1168.     JP    NZ,TYPE01    ;IF FILE FOUND
  1169.     XOR    A
  1170.     LD    (BUFPOS),A    ;BUFFER OFFSET 0
  1171.     LD    (BASEAD+1),A
  1172.     INC    A
  1173.     LD    (BASEAD),A    ;INITIALISE PAGE NUMBER 1
  1174.     CALL    TGET        ;PRIME FIRST CHARACTER
  1175.     LD    HL,(PGEPTR)
  1176.     LD    (CURPG@),HL    ;SET CURRENT PAGE ENTRY TO FIRST
  1177.     LD    (MAXPG@),HL    ;AND LAST
  1178.     LD    A,0FFH
  1179.     LD    (TYPEX),A    ;SET NO EXIT
  1180.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1181. TYPE03    EQU    $        ;LOOP
  1182.     LD    A,(TYDSP)
  1183.     OR    A
  1184.     JR    Z,TYPE09    ;IF DISPLAY REQUIRED
  1185.     XOR    A
  1186.     LD    (TYDSP),A    ;RESET REQUEST
  1187.     $NPANEL    TYPEPN        ;DISPLAY PANEL
  1188.     $FLD    PGENUM
  1189.     $HEXW    BASEAD        ;DISPLAY PAGE NUMBER
  1190.     $FLD    TYPEFN
  1191.     $STRO    DRIVNM        ;DISPLAY FILE NAME
  1192.     $FLD    RECNUM
  1193.     $HEXW    RELREC        ;DISPLAY RECORD NUMBER
  1194.     CALL    TYPG        ;DISPLAY PAGE
  1195. TYPE09    EQU    $        ;ENDIF
  1196. TYPE06    EQU    $        ;LOOP
  1197.     $IFLD    TYPIP        ;GET COMMAND
  1198.     $MTCH    TYPLST
  1199.     JR    Z,TYPE05    ;EXITIF VALID
  1200.     CALL    ALRM        ;SOUND ALARM
  1201.     JR    TYPE06
  1202. TYPE05    EQU    $        ;ENDLOOP
  1203.     $EXVA    TYPVEC        ;EXEC COMMAND
  1204.     LD    A,(TYPEX)
  1205.     OR    A
  1206.     JR    Z,TYPE04    ;EXITIF FLAG SET
  1207.     JR    TYPE03
  1208. TYPE04    EQU    $        ;ENDLOOP
  1209. TYPE01    EQU    $        ;ENDIF
  1210.     LD    A,TRUE
  1211.     LD    (DRMDLD),A    ;REQUEST DIRECTORY LIST
  1212.     RET
  1213.  
  1214. TYPEPN:    DB    6
  1215.     DB    01,00,'N  Next page',0
  1216.     DB    01,22,'R  Return after Paging',0
  1217.     DB    01,50,'L  Exit to file list',0
  1218.     DB    02,00,'P  Previous page',0
  1219.     DB    02,22,'T  Top of file',0
  1220.     DB    02,50,'Z  Exit from Superzap',0
  1221.  
  1222. PGENUM:    DB    4,66,'Page ',0
  1223. RECNUM:    DB    4,32,'Sector ',0
  1224. TYPEFN:    DB    4,0,0
  1225. TYPIP:    DB    02,77,'>',0        ;INPUT POSITION
  1226. TYPFL:    DB    6,0,0            ;FIRST CHR POSITION
  1227.  
  1228. TYPLST:    DB    6,'NRLPTZ'
  1229. TYPVEC:    DW    TYPF
  1230.     DW    TYPR
  1231.     DW    TYPL
  1232.     DW    TYPB
  1233.     DW    TYPT
  1234.     DW    TYPZ
  1235.  
  1236. TYPEX:    DS    1        ;EXIT FLAG
  1237. TYDSP:    DS    1        ;DISPLAY REQUEST
  1238. TYPEOP:    DS    1        ;END OF PAGE
  1239.  
  1240.  
  1241. ; TYPF - FORWARD PAGE
  1242.  
  1243.     $RTN    TYPF
  1244.     LD    A,(READST)
  1245.     OR    A
  1246.     JR    Z,TYPF01    ;IF EOF
  1247.     CALL    ALRM
  1248.     JR    TYPF02
  1249. TYPF01    EQU    $        ;ELSE
  1250.     LD    HL,(CURPG@)
  1251.     LD    DE,6
  1252.     ADD    HL,DE
  1253.     LD    (CURPG@),HL    ;UPDATE CURRENT POINTER
  1254.     LD    A,0FFH
  1255.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1256. TYPF02    EQU    $
  1257.     RET
  1258.  
  1259. ; TYPR - REURN AFTER PAGING
  1260.  
  1261.     $RTN    TYPR
  1262.     LD    HL,(CURPG@)
  1263.     LD    DE,(MAXPG@)
  1264.     XOR    A
  1265.     SBC    HL,DE
  1266.     JR    Z,TYPR01    ;IF NOT END OF FILE
  1267.     EX    DE,HL        ;RESTORE TOP OF QUEUE
  1268.     LD    DE,6
  1269.     XOR    A
  1270.     SBC    HL,DE
  1271.     CALL    LPGE        ;LOAD LAST PAGE
  1272.     LD    A,0FFH
  1273.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1274. TYPR01    EQU    $        ;ENDIF
  1275.     RET
  1276.  
  1277. ; TYPL - EXIT TYPE TO DIR LIST
  1278.  
  1279.     $RTN    TYPL
  1280.     XOR    A
  1281.     LD    (TYPEX),A    ;REQUEST EXIT
  1282.     RET
  1283.  
  1284. ; TYPB - PAGE BACKWARD
  1285.  
  1286.     $RTN    TYPB
  1287.     LD    DE,(CURPG@)
  1288.     LD    HL,(PGEPTR)
  1289.     XOR    A
  1290.     SBC    HL,DE
  1291.     JR    Z,TYPB01    ;IF NOT TOP OF FILE
  1292.     EX    DE,HL
  1293.     LD    DE,6
  1294.     XOR    A
  1295.     SBC    HL,DE
  1296.     CALL    LPGE        ;LOAD PAGE DATA
  1297.     LD    A,0FFH
  1298.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1299. TYPB01    EQU    $        ;ENDIF
  1300.     RET
  1301.  
  1302. ; TYPT - PAGE TO TOP OF FILE
  1303.  
  1304.     $RTN    TYPT
  1305.     LD    HL,(PGEPTR)
  1306.     CALL    LPGE        ;LOAD FIRST PAGE
  1307.     LD    A,0FFH
  1308.     LD    (TYDSP),A    ;REQUEST DISPLAY
  1309.     RET
  1310.  
  1311. ; TYPZ - EXIT TYPE TO CP/M
  1312.  
  1313.     $RTN    TYPZ
  1314.     CALL    SETX        ;EXIT SUPERZAP
  1315.     XOR    A
  1316.     LD    (TYPEX),A    ;REQUEST EXIT
  1317.     RET
  1318.  
  1319. ; TYPG - TYPE PAGE
  1320.  
  1321.     $RTN    TYPG
  1322.     CALL    QPGE        ;PUT PAGE ON QUEUE
  1323.     $FLD    TYPFL        ;POSITION FOR FIST CHAR
  1324.     $STRO    TYNPRF        ;RIGHT MARGIN
  1325.     XOR    A
  1326.     LD    (TYPEOP),A    ;RESET END OF PAGE
  1327.     LD    (PGECOL),A
  1328.     LD    (PGELNE),A    ;LINE 0 COL 0
  1329. TYPG01    EQU    $        ;LOOP
  1330.     LD    A,(TYPEOP)
  1331.     OR    A
  1332.     JR    NZ,TYPG02    ;EXIT IF EOP
  1333.     LD    A,(COMFLG)
  1334.     OR    A
  1335.     LD    A,(TYCURC)
  1336.     JR    Z,TYPG12    ;IF COM FILE
  1337.     CALL    TPUT        ;OUTPUT CHARACTER
  1338.     LD    A,(READST)
  1339.     OR    A
  1340.     JR    NZ,TYPG02    ;EXIT IF END OF FILE
  1341.     LD    A,(TYPEOP)
  1342.     OR    A
  1343.     JR    NZ,TYPG02    ;OR END OF PAGE
  1344.     CALL    TGET        ;GET NEXT CHARACTER
  1345.     JR    TYPG13
  1346. TYPG12    EQU    $        ;ELSE (NOT A COM FILE)
  1347.     CP    009H
  1348.     JR    NZ,TYPG04    ;IF TAB
  1349. TYPG05    EQU    $        ;REPEAT
  1350.     LD    A,' '
  1351.     CALL    TPUT        ;PUT SPACE
  1352.     LD    A,(PGECOL)
  1353.     AND    7
  1354.     JR    NZ,TYPG05    ;UNTIL TAB STOP
  1355.     JR    TYPG07
  1356. TYPG04    EQU    $
  1357.     CP    CR
  1358.     JR    NZ,TYPG08    ;ELSE IF C/R
  1359.     LD    A,(READST)
  1360.     OR    A
  1361.     JR    NZ,TYPG11    ;IF EOF
  1362.     LD    A,(BUFPOS)
  1363.     LD    HL,FBUFF
  1364.     CALL    AAHL
  1365.     LD    A,(HL)
  1366.     CP    00AH
  1367.     JR    NZ,TYPG11    ;OR NOT LINE FEED
  1368.     JR    TYPG09
  1369. TYPG11    EQU    $
  1370.     LD    A,CR
  1371.     CALL    TPUT        ;PUT CHAR
  1372.     JR    TYPG10
  1373. TYPG09    EQU    $        ;ELSE
  1374.     CALL    TYNL        ;TAKE NEW LINE
  1375.     CALL    TGET        ;SKIP L/F IN FILE
  1376. TYPG10    EQU    $        ;ENDIF
  1377.     JR    TYPG07
  1378. TYPG08    EQU    $        ;ELSE
  1379.     CALL    TPUT        ;PRINT CHR
  1380. TYPG07    EQU    $        ;ENDIF
  1381.     LD    A,(READST)
  1382.     OR    A
  1383.     JR    NZ,TYPG02    ;EXIT IF EOF
  1384.     CALL    TGET        ;GET NEXT CHR
  1385. TYPG13    EQU    $
  1386.     JR    TYPG01
  1387. TYPG02    EQU    $        ;ENDLOOP
  1388.     LD    HL,(BASEAD)
  1389.     LD    A,1
  1390.     ADD    A,L
  1391.     DAA
  1392.     LD    L,A
  1393.     LD    A,0
  1394.     ADC    A,H
  1395.     DAA
  1396.     LD    H,A
  1397.     LD    (BASEAD),HL    ;INC PAGE NUMBER
  1398. TYPG03    EQU    $        ;ENDIF
  1399.     RET
  1400. PGECOL:    DS    1
  1401. PGELNE:    DS    1
  1402. TYNPRF:    DB    ' ',0
  1403.  
  1404. ; QPGE - PUT PAGE DATA ON QUEUE
  1405.  
  1406.     $RTN    QPGE
  1407.     LD    HL,(MAXPG@)
  1408.     LD    DE,(CURPG@)
  1409.     XOR    A
  1410.     SBC    HL,DE
  1411.     JR    NZ,QPGE01    ;IF AT END OF Q
  1412.     LD    HL,TYCURC
  1413.     LD    DE,(MAXPG@)
  1414.     LD    BC,6
  1415.     LDIR            ;COPY PAGE DATA
  1416.     LD    (MAXPG@),DE    ;UPDATE MAX PTR
  1417. QPGE01    EQU    $        ;ENDIF
  1418.     RET
  1419.  
  1420.  
  1421. ; LPGE - LOAD PAGE DATA FROM QUEUE AT (HL)
  1422.  
  1423.     $RTN    LPGE
  1424.     LD    (CURPG@),HL    ;SET CURRENT POINTER
  1425.     LD    DE,TYCURC
  1426.     LD    BC,6
  1427.     LDIR            ;COPY PAGE DATA
  1428.     CALL    RDFS        ;READ FIRST SECTOR OF PAGE
  1429.     RET
  1430.  
  1431.  
  1432. ; TGET - GET CHARACTER FOR TYPE
  1433.  
  1434.     $RTN    TGET
  1435.     LD    A,(READST)
  1436.     OR    A
  1437.     JR    NZ,TGET02    ;IF NOT EOF
  1438.     LD    HL,BUFPOS
  1439.     LD    A,(HL)        ;GET CURRENT OFFSET
  1440.     INC    (HL)        ;INC FOR NEXT GET
  1441.     LD    HL,FBUFF
  1442.     CALL    AAHL        ;POINT TO CURRENT CHARACTER
  1443.     LD    A,(HL)
  1444.     LD    (TYCURC),A    ;GET CHARACTER
  1445.     LD    A,(BUFPOS)
  1446.     CP    080H
  1447.     JR    NZ,TGET01    ;IF BUFPOS=80
  1448.     LD    HL,(RELREC)
  1449.     INC    HL
  1450.     LD    (RELREC),HL    ;SET NEXT SECTOR
  1451.     XOR    A
  1452.     LD    (BUFPOS),A    ;BUFFER OFFSET=0
  1453.     CALL    RDFS        ;READ SECTOR
  1454. TGET01    EQU    $        ;ENDIF
  1455. TGET02    EQU    $        ;ENDIF
  1456.     LD    A,(TYCURC)    ;RETURN CHARACTER
  1457.     RET
  1458.  
  1459.  
  1460. ; TPUT - TYPE A CHARACTER
  1461.  
  1462.     $RTN    TPUT
  1463.     LD    B,A
  1464.     LD    A,(PGECOL)
  1465.     CP    76
  1466.     JR    NZ,TPUT01    ;IF COL=76
  1467.     CALL    TYNL        ;TAKE NEW LINE
  1468. TPUT01    EQU    $        ;ENDIF
  1469.     LD    A,(TYPEOP)
  1470.     OR    A
  1471.     JR    NZ,TPUT02    ;IF NOT EOP
  1472.     LD    A,B
  1473.     CALL    ASCO        ;OUTPUT CHARACTER
  1474.     LD    HL,PGECOL
  1475.     INC    (HL)        ;INC COL COUNT
  1476. TPUT02    EQU    $        ;ENDIF
  1477.     RET
  1478.  
  1479.  
  1480. ; TYNL - TYPE NEW LINE
  1481.  
  1482.     $RTN    TYNL
  1483.     XOR    A
  1484.     LD    (PGECOL),A    ;SET COL 0
  1485.     LD    HL,PGELNE
  1486.     INC    (HL)        ;INC LINE
  1487.     LD    A,18
  1488.     CP    (HL)
  1489.     JR    NZ,TYNL01    ;IF LINE = 18
  1490.     LD    A,0FFH
  1491.     LD    (TYPEOP),A    ;SET END OF PAGE
  1492.     JR    TYNL02
  1493. TYNL01    EQU    $        ;ELSE
  1494.     LD    A,00DH
  1495.     CALL    CHRO
  1496.     LD    A,00AH
  1497.     CALL    CHRO        ;OTPUT CRLF
  1498.     $STRO    TYNPRF        ;RIGHT MARGIN
  1499. TYNL02    EQU    $        ;ENDIF
  1500.     RET
  1501.  
  1502.  
  1503. ; chun - change user number    (Code mostly copied from CHDD)
  1504.  
  1505.     $rtn    chun
  1506.     ld    hl,unMsg
  1507.     call    cfld
  1508.     ld    a,true
  1509.     ld    (drmdld),a
  1510.     $ifld    unMsg
  1511.     cp    $esc
  1512.     ret    z
  1513.     sub    30h        ;Make user number 0-9
  1514.     jr    c,chun04    ;If illegal user number
  1515.     cp    10        ;Check for A..F
  1516.     jr    c,chun05
  1517.     sub    7
  1518. chun02:    cp    16
  1519.     jr    c,chun05
  1520. chun04:    call    alrm
  1521.     ret
  1522. chun05:    ld    e,a
  1523.     ld    c,userNo
  1524.     call    cpm
  1525.     ld    c,GETDEF
  1526.     call    cpm
  1527.     call    chdr
  1528.     xor    a
  1529.     ld    (selde),a
  1530.     ret
  1531.  
  1532. unMsg:    defb    12,20,'Enter user number or press ESC ===>',0
  1533.  
  1534. ; CHDD - CHANGE DIRECTORY DRIVE
  1535.  
  1536.     $RTN    CHDD
  1537.     LD    HL,DSKMSG
  1538.     CALL    CFLD        ;CLEAR PROMPT FIELD
  1539.     LD    A,TRUE
  1540.     LD    (DRMDLD),A    ;REQUEST LIST ON RETURN
  1541.     $IFLD    DSKMSG        ;PROMPT FOR DRIVE
  1542.     CP    $ESC
  1543.     JR    Z,CHDD03    ;IF NOT ESC
  1544.     SUB    041H        ;MAKE DRIVE ID
  1545.     CALL    CHDR        ;CHANGE DISK
  1546.     JR    NZ,CHDD04    ;IF ILLEGAL DISK
  1547.     CALL    ALRM        ;SOUND ALARM
  1548.     JR    CHDD05
  1549. CHDD04    EQU    $        ;ELSE
  1550.     XOR    A
  1551.     LD    (SELDE),A    ;SELECT FIRST ENTRY
  1552. CHDD05    EQU    $        ;ENDIF
  1553. CHDD03    EQU    $        ;ENDIF
  1554.     RET
  1555.  
  1556. DSKMSG:    DB    12,20,'Enter Drive Name or press ESC ===>',0
  1557. NFDMSG:    DB    '** No Files on Drive',0
  1558.  
  1559.  
  1560. ; SAFN - SET DIRECTORY LIST AFN
  1561.  
  1562.     $RTN    SAFN
  1563.     $NPANEL    AFNPNL        ;DISPLAY SET AFN PANEL
  1564.     LD    A,TRUE
  1565.     LD    (DRMDLD),A    ;REQUEST DIRECTORY LIST
  1566.     LD    HL,LMDFCB+1
  1567.     LD    DE,CPYAFN
  1568.     LD    BC,11
  1569.     LDIR            ;TAKE LOCAL COPY OF DIR SEARCH NAME
  1570.     CALL    DAFN        ;DISPLAY CURRENT MASK
  1571.     XOR    A
  1572.     LD    (IMODE),A    ;RESET INSERT MODE
  1573.     LD    (NMODE),A    ;SET FOR NAME PART
  1574.     LD    (AFNCNT),A    ;SET COUNT=0
  1575.     LD    HL,(AFNPNM)
  1576.     LD    (AFNCUR),HL    ;SET START ADDRESS ON SCREEN
  1577.     LD    A,8
  1578.     LD    (AFNMAX),A    ;SET LENGTH OF FIELD
  1579.     LD    HL,CPYAFN
  1580.     LD    (AFNCHP),HL    ;SAVE START ADDRESS IN MEMORY
  1581. SAFN01    EQU    $        ;LOOP
  1582.     CALL    AFNC        ;POSITION CURSOR
  1583.     CALL    CHRF        ;GET A CHARACTER
  1584.     CP    CR
  1585.     JR    Z,SAFN02    ;EXITIF C/R
  1586.     CP    $ESC
  1587.     JR    Z,SAFN02    ;OR ESCAPE
  1588.     $MTCH    AFNACD
  1589.     JR    NZ,SAFN03    ;IF VALID CONTROL
  1590.     $EXVA    AFNAVC        ;PERFORM ACTION
  1591.     JR    SAFN04
  1592. SAFN03    EQU    $        ;ELSE
  1593.     $MTCH    AFNINV
  1594.     JR    Z,SAFN05    ;IF NOT IN ILLEGAL CHARACTER SET
  1595.     CP    020H
  1596.     JP    C,SAFN05    ;AND NOT CONTROL CHARACTER
  1597.     CALL    PAFN        ;PUT CHARACTER IN STRING
  1598.     JR    SAFN06
  1599. SAFN05    EQU    $        ;ELSE
  1600.     CALL    ALRM        ;RING BELL
  1601. SAFN06    EQU    $        ;ENDIF
  1602. SAFN04    EQU    $        ;ENDIF
  1603.     JR    SAFN01
  1604. SAFN02    EQU    $        ;ENDLOOP
  1605.     CP    $ESC
  1606.     JR    Z,SAFN99    ;IF EXIT BY C/R
  1607.     LD    HL,CPYAFN
  1608.     CALL    LSEL        ;COPY NEW NAME TO FCB
  1609.     CALL    RDIR        ;READ DIRECTORY
  1610.     XOR    A
  1611.     LD    (SELDE),A    ;RESET CURRENT SELECTION
  1612. SAFN99    EQU    $        ;ENDIF
  1613.     RET
  1614.  
  1615. AFNINV:    DB    7,07FH,':;<>[]'    ;INVALID FILENAME CHARACTERS
  1616. IMODE:    DS    1        ;INSERT ON/OFF
  1617. NMODE:    DS    1        ;IN NAME/EXT PART
  1618. AFNCNT:    DS    1        ;CURENT POSITION IN NAME
  1619. AFNCUR:    DS    2        ;CURSOR POSITION OF CURRENT FIELD
  1620. AFNCHP:    DS    2        ;ADDRESS OF CURRENT FIELD
  1621. AFNMAX:    DS    1        ;LENGTH OF CURRENT PART
  1622. CPYAFN:    DS    11
  1623.  
  1624. AFNPNL    EQU    $
  1625.     DB    10        ;FIELD COUNT
  1626.     DB    02,00,'^',$LEFT+040H,'  Cursor Left',0
  1627.     DB    02,27,'^',$RIGHT+040H,'  Cursor Right',0
  1628.     DB    03,00,'^',$DELETE+040H,'  Delete Character',0
  1629.     DB    03,27,'^',$INSRT+040H,'  Insert On/Off',0  
  1630.     DB    02,54,'^',$TAB+040H,'  Edit Name/Type',0
  1631.     DB    03,54,'ESC Use Current Selection',0
  1632. AFNMSG:    DB    7,08,'Edit File Name ===>',0
  1633.     DB    7,37,'<=',0            ;FILENAME END MARKER
  1634.     DB    9,13,'File Type ===>',0
  1635.     DB    9,32,'<=',0            ;FILE TYPE END MARKER
  1636. AFNPNM:    DB    7,28,0                ;POSITION OF FILE NAME
  1637. AFNPEX:    DB    9,28,0                ;POSITION OF FILE TYPE
  1638.  
  1639. INSMSG:    DB    05,29,'Insert',0
  1640.  
  1641. AFNACD:    DB    8,$LEFT,$RIGHT,$DELETE,$INSRT,$TAB,' .*'
  1642.  
  1643. AFNAVC:    DW    AFNL        ;CURSROR LEFT
  1644.     DW    AFNR        ;CURSOR RIGHT
  1645.     DW    AFND        ;DELETE CHAR
  1646.     DW    AFNI        ;TOGGLE INSERT MODE
  1647.     DW    AFNT        ;TOGGLE NAME MODE
  1648.     DW    AFNS        ;SPACE FILL FIELD
  1649.     DW    AFNP        ;PERIOD
  1650.     DW    AFNQ        ; "?" FILL (USED BY "*")
  1651.  
  1652. ; AFNP - PERIOD IN AFN
  1653.  
  1654.     $RTN    AFNP
  1655.     LD    A,(NMODE)
  1656.     OR    A
  1657.     JR    NZ,AFNP01    ;IF IN NAME
  1658.     CALL    AFNS        ;SPACE FILL
  1659. AFNP01    EQU    $        ;ENDIF
  1660.     RET
  1661.  
  1662. ; AFND - DELETE CHARACTER IN AFN
  1663.  
  1664.     $RTN    AFND
  1665.     LD    HL,(AFNCHP)    ;ADDRESS OF CURRENT FIELD
  1666.     LD    A,(AFNCNT)
  1667.     LD    C,A        ;SAVE COUNT
  1668.     CALL    AAHL        ;ADDRESS OF CURRENT CHARACTER
  1669.     LD    D,H
  1670.     LD    E,L        ;DEST IN DE
  1671.     INC    HL        ;SOURCE IN HL
  1672.     LD    A,(AFNMAX)    ;LENGTH OF FIELD
  1673.     SUB    C        ;LENGTH REMAINING
  1674.     DEC    A        ;LENGTH TO MOVE
  1675.     JR    Z,AFND01    ;IF SOMETHING TO MOVE
  1676.     LD    B,0
  1677.     LD    C,A        ;SET UP COUNT
  1678.     LDIR            ;MOVE FIELD LEFT
  1679. AFND01    EQU    $        ;ENDIF
  1680.     LD    A,' '
  1681.     LD    (DE),A        ;BLANK LAST CHARACTER
  1682.     CALL    DAFN        ;DISPLAY NEW AFN
  1683.     RET
  1684.  
  1685. ; AFNS - SPACE FILL AFN
  1686.  
  1687.     $RTN    AFNS
  1688.     LD    A,' '
  1689.     LD    (FILLCH),A
  1690.     CALL    AFNF
  1691.     RET
  1692.  
  1693. ; AFNQ - "?" FILL AFN
  1694.  
  1695.     $RTN    AFNQ
  1696.     LD    A,'?'
  1697.     LD    (FILLCH),A
  1698.     CALL    AFNF
  1699.     RET
  1700.  
  1701. FILLCH:    DS    1        ;CHARACTER TO FILL AFN
  1702.  
  1703.  
  1704. ; AFNF - FILL AFN FIELD
  1705.  
  1706.     $RTN    AFNF
  1707.     LD    HL,(AFNCHP)
  1708.     LD    A,(AFNCNT)
  1709.     LD    B,A        ;SAVE COUNT
  1710.     CALL    AAHL        ;POSITION IN FIELD
  1711.     LD    A,(AFNMAX)
  1712.     SUB    B
  1713.     LD    B,A        ;SAVE COUNT
  1714.     LD    A,(FILLCH)
  1715. AFNF01    EQU    $        ;REPEAT
  1716.     LD    (HL),A        ;INSERT SPACE
  1717.     INC    HL        ;POINT NEXT CHARACTER
  1718.     DJNZ    AFNF01        ;UNTIL END OF FIELD
  1719.     CALL    DAFN        ;DISPLAY FIELD
  1720.     CALL    AFNT        ;POSITION IN OTHER HALF
  1721.     RET
  1722.  
  1723.  
  1724. ; DAFN - DISPLAY DIRECTORY SEARCH NAME
  1725.  
  1726.     $RTN    DAFN
  1727.     $FLD    AFNPNM        ;POSITION FOR NAME
  1728.     LD    B,8
  1729.     LD    HL,CPYAFN
  1730. DAFN01    EQU    $        ;LOOP
  1731.     LD    A,(HL)
  1732.     CALL    CHRO        ;PRINT A CHARCTER
  1733.     INC    HL        ;POINT TO NEXT
  1734.     DJNZ    DAFN01        ;UNTIL END OF FIELD
  1735.     $FLD    AFNPEX        ;POSITION FOR TYPE
  1736.     LD    HL,CPYAFN+8
  1737.     LD    B,3
  1738. DAFN02    EQU    $        ;REPEAT
  1739.     LD    A,(HL)
  1740.     CALL    CHRO        ;PRINT CHAR
  1741.     INC    HL        ;POINT TO NEXT
  1742.     DJNZ    DAFN02        ;UNTIL END OF FIELD
  1743.     RET
  1744.  
  1745.  
  1746. ; PAFN - PUT CHARACTER IN STRING
  1747.  
  1748.     $RTN    PAFN
  1749.     PUSH    AF        ;SAVE CHARACTER
  1750.     LD    A,(IMODE)
  1751.     OR    A    
  1752.     JR    Z,PAFN01    ;IF INSERT ON
  1753.     CALL    AFNM        ;MAKE SPACE
  1754. PAFN01    EQU    $        ;ENDIF
  1755.     LD    HL,(AFNCHP)    ;GET CHARACTER POSITION
  1756.     LD    A,(AFNCNT)
  1757.     CALL    AAHL        ;ADD COUNT TO HL
  1758.     POP    AF        ;RESTORE CHARACTER
  1759.     LD    (HL),A        ;PUT IT IN STRING
  1760.     CALL    CHRO        ;DISPLAY CHARACTER
  1761.     LD    A,(IMODE)
  1762.     OR    A
  1763.     JR    Z,PAFN02    ;IF INSERT ON
  1764.     CALL    DAFN        ;DISPLAY FULL NAME
  1765. PAFN02    EQU    $        ;ENDIF
  1766.     CALL    AFNR        ;MOVE CURSOR
  1767.     RET
  1768.  
  1769. ; AFNM - MAKE SPACE FOR INSERT
  1770.  
  1771.     $RTN    AFNM
  1772.     LD    HL,(AFNCHP)    ;ADDRESS OF CURRENT FIELD
  1773.     LD    A,(AFNMAX)
  1774.     DEC    A        ;ADJUST COUNT TO OFFSET
  1775.     CALL    AAHL        ;ADDRESS OF LAST CHARACTER
  1776.     LD    D,H
  1777.     LD    E,L        ;DEST IN DE
  1778.     DEC    HL        ;SOURCE IN HL
  1779.     LD    A,(AFNCNT)    ;CURRENT OFFSET
  1780.     LD    C,A
  1781.     LD    A,(AFNMAX)
  1782.     SUB    C        ;LENGTH REMAINING
  1783.     DEC    A        ;LENGTH TO MOVE
  1784.     JR    Z,AFNM01    ;IF SOMETHING TO MOVE
  1785.     LD    B,0
  1786.     LD    C,A        ;SET UP COUNT
  1787.     LDDR            ;MOVE FIELD RIGHT
  1788. AFNM01    EQU    $        ;ENDIF
  1789.     RET
  1790.  
  1791. ; AFNL - CURSOR LEFT IN AFN
  1792.  
  1793.     $RTN    AFNL
  1794.     LD    A,(AFNCNT)
  1795.     OR    A
  1796.     JR    Z,AFNL01    ;IF NOT START OF FIELD
  1797.     DEC    A        ;POSITION TO PREVIOUS
  1798.     JR    AFNL02
  1799. AFNL01    EQU    $        ;ELSE
  1800.     CALL    AFNT        ;TOGGLE MODE
  1801.     LD    A,(AFNMAX)    ;GET END OF FIELD COUNT
  1802.     DEC    A        ;POINT TO LAST CHAR IN FIELD
  1803.     LD    B,A        ;SET COUNT
  1804.     DEC    A        ;POINT TO PREVIOUS
  1805.     LD    HL,(AFNCHP)
  1806.     CALL    AAHL
  1807.     LD    A,' '
  1808. AFNL03    EQU    $        ;REPEAT
  1809.     CP    (HL)
  1810.     JR    NZ,AFNL04    ;EXITIF PREVIOUS NOT SPACE
  1811.     DEC    HL
  1812.     DJNZ    AFNL03        ;UNTIL END OF FIELD
  1813. AFNL04    EQU    $        ;ENDLOOP
  1814.     LD    A,B        ;RESTORE COUNT
  1815. AFNL02    EQU    $        ;ENDIF
  1816.     LD    (AFNCNT),A    ;BACKSPACE POSITION
  1817.     RET
  1818.  
  1819.  
  1820. ; AFNR - CURSOR RIGHT IN AFN
  1821.  
  1822.     $RTN    AFNR
  1823.     LD    HL,(AFNCHP)
  1824.     LD    A,(AFNCNT)
  1825.     CALL    AAHL        ;POINT TO CURRENT CHARACTER
  1826.     LD    A,(HL)
  1827.     CP    ' '
  1828.     JR    NZ,AFNR02    ;IF SPACE
  1829.     CALL    AFNT        ;CHANGE MODE
  1830.     JR    AFNR03
  1831. AFNR02    EQU    $        ;ELSE
  1832.     LD    A,(AFNMAX)    ;GET FIELD MAX
  1833.     LD    HL,AFNCNT
  1834.     INC    (HL)        ;INC POSITION
  1835.     CP    (HL)
  1836.     JP    NZ,AFNR01    ;IF OUT OF RANGE
  1837.     CALL    AFNT        ;TOGGLE MODE
  1838. AFNR01    EQU    $        ;ENDIF
  1839. AFNR03    EQU    $        ;ENDIF
  1840.     RET
  1841.  
  1842. ; AFNI - TOGGLE AFN INSERT MODE
  1843.  
  1844.     $RTN    AFNI
  1845.     LD    A,(IMODE)
  1846.     CPL
  1847.     LD    (IMODE),A    ;TOGGLE MODE FLAG
  1848.     LD    HL,INSMSG    ;POINT TO INSERT MESSAGE
  1849.     OR    A
  1850.     JR    Z,AFNI01    ;IF NOW INSERT MODE
  1851.     CALL    DFLD        ;DISPLAY IT
  1852.     JR    AFNI02
  1853. AFNI01    EQU    $        ;ELSE
  1854.     CALL    CFLD        ;CLEAR IT
  1855. AFNI02    EQU    $        ;ENDIF
  1856.     RET
  1857.  
  1858.  
  1859. ; AFNT - TOGGLE AFN MODE
  1860.  
  1861.     $RTN    AFNT
  1862.     XOR    A
  1863.     LD    (AFNCNT),A    ;RESET COUNT
  1864.     LD    A,(NMODE)
  1865.     CPL
  1866.     LD    (NMODE),A    ;TOGLE MODE FLAG
  1867.     OR    A
  1868.     JR    NZ,AFNT01    ;IF NOW NAME MODE
  1869.     LD    A,8        ;GET MAX LENGTH
  1870.     LD    HL,(AFNPNM)    ;GET START POSITION
  1871.     LD    DE,CPYAFN
  1872.     JR    AFNT02        
  1873. AFNT01    EQU    $        ;ELSE
  1874.     LD    A,3        ;GET MAX FOR EXTENSION
  1875.     LD    HL,(AFNPEX)    ;GET POSITION FOR EXTENSION
  1876.     LD    DE,CPYAFN+8
  1877. AFNT02    EQU    $        ;ENDIF
  1878.     LD    (AFNMAX),A    ;SET MAX
  1879.     LD    (AFNCUR),HL    ;SET START POSITION
  1880.     LD    (AFNCHP),DE    ;SET START ADDRESS
  1881.     RET
  1882.  
  1883.  
  1884. ; AFNC - POSITION CURSOR IN AFN
  1885.  
  1886.     $RTN    AFNC
  1887.     LD    HL,(AFNCUR)    ;GET START OF FIELD
  1888.     LD    A,(AFNCNT)    ;GET OFFSET
  1889.     ADD    A,H
  1890.     LD    H,A        ;OFFSET CURSOR
  1891.     CALL    CURS        ;POSITION CURSOR
  1892.     RET
  1893.  
  1894.  
  1895. ; TFLE - TEST FILE
  1896.  
  1897.     $RTN    TFLE
  1898.     XOR    A
  1899.     LD    (FLERR),A    ;RESET ERROR FLAG
  1900.     LD    DE,WRKFCB    ;POINT TO WORK FCB
  1901.     LD    C,OPEN
  1902.     CALL    CPM        ;ATTEMPT TO OPEN FILE
  1903.     INC    A
  1904.     JR    NZ,TFLE01    ;IF OPEN ERROR
  1905.     LD    HL,FNFMSG
  1906.     LD    (ERRTXT),HL    ;SET FILE NOT FOUND ERROR
  1907.     LD    A,0FFH
  1908.     LD    (FLERR),A    ;SET ERROR FLAG
  1909.     JP    TFLE02
  1910. TFLE01    EQU    $        ;ELSE
  1911.     LD    HL,0
  1912.     LD    (RELREC),HL    ;INITIALISE RECORD COUNTER
  1913.     LD    (SAVFSC),HL
  1914.     LD    DE,WRKFN
  1915.     CALL    FMTN
  1916.     LD    A,(WRKDR)
  1917.     ADD    A,040H
  1918.     LD    (DRIVNM),A    ;FORMAT NAME AND DRIVE
  1919.     CALL    RDFS        ;READ SECTOR
  1920.     JR    Z,TFLE03    ;IF READ BAD
  1921.     LD    HL,NRFMSG
  1922.     LD    (ERRTXT),HL    ;SET NO RECORDS ON FILE ERROR
  1923.     LD    A,0FFH
  1924.     LD    (FLERR),A    ;SET ERROR FLAG
  1925. TFLE03    EQU    $        ;ENDIF
  1926. TFLE02    EQU    $        ;ENDIF
  1927.     RET
  1928. FLERR:    DS    1
  1929.  
  1930.  
  1931. ; PSMD - PHYSICAL SECTOR MODE
  1932.  
  1933.     $RTN    PSMD
  1934.     LD    HL,(PSMDER)
  1935.     LD    (ERRFLD),HL    ;SET ERROR FIELD POINTER
  1936.     LD    A,0FFH
  1937.     LD    (PMNEWD),A    ;FLAG NEW DISK
  1938.     LD    (RPANEL),A    ;REQUEST PANEL
  1939. PSMD05    EQU    $        ;LOOP 
  1940.     CALL    ZBSA        ;CLEAR ADDRESS COUNTER
  1941.     LD    A,(PMNEWD)
  1942.     OR    A
  1943.     JP    Z,PSMD01    ;IF NEW DISK
  1944.     XOR    A
  1945.     LD    (PMNEWD),A    ;RESET FLAG
  1946.     LD    A,(CURAN)
  1947.     LD    C,A
  1948.     CALL    SELDSK        ;SELECT PHYSICAL DISK
  1949.     CALL    HOME        ;HOME THE DISK
  1950.     LD    HL,0
  1951.     LD    (PSMDSC),HL    ;SET SECTOR TO 0
  1952. ;    LD    (PSMDTR),HL    ;SET TRACK TO 0
  1953. ; The above used to set the track to 0 but I found that is not very useful so
  1954. ; I changed it to point to the beginning of the directory:-
  1955.     ld    hl,(dpbOff)
  1956.     ld    (psmdtr),hl
  1957. PSMD01    EQU    $        ;ENDIF
  1958.     LD    A,(RPANEL)
  1959.     OR    A
  1960.     JR    Z,PSMD06    ;IF PANEL REQUIRED
  1961.     XOR    A
  1962.     LD    (RPANEL),A    ;RESET FLAG
  1963.     $NPANEL    PSMDPN        ;DISPLAY PHYSICAL MODE PANEL
  1964.     $FLD    PSPMSG
  1965.     CALL    DSPI        ;DISPLAY SCRATCHPAD DATA
  1966. PSMD06    EQU    $
  1967.     CALL    PRDD        ;READ AND DISPLAY SECTOR
  1968.     CALL    ERRP        ;PROCESS ERROR MESSAGES
  1969. PSMD03    EQU    $        ;LOOP
  1970.     $IFLD    SELMSG        ;ISSUE SELMSG, GET COMMAND
  1971.     $MTCH    PSMDLS
  1972.     JR    Z,PSMD02    ;EXITIF VALID
  1973.     CALL    ALRM        ;SOUND THE ALARM
  1974.     JR    PSMD03
  1975. PSMD02    EQU    $        ;ENDLOOP
  1976.     $EXVA    PSMDVC        ;EXEC ACTION
  1977.     LD    A,(WTG)
  1978.     CP    'P'
  1979.     JR    NZ,PSMD04    ;EXIT IF NEXT MODE <> P
  1980.     JP    PSMD05
  1981. PSMD04    EQU    $        ;ENDLOOP
  1982.     RET
  1983. PMNEWD:    DS    1        ;NEW DISK FLAG
  1984.  
  1985. BIOS3:                ;General BIOS entry for CP/M 3.1
  1986.     ld    (hlVal),hl    ;Save caller's register values
  1987.     ld    (deVal),de    ; in BIOS parameter block
  1988.     ld    (bcVal),bc    ;
  1989.     ld    (aVal),a    ;
  1990.     pop    hl        ;Get return address for figuring which
  1991.                 ; routine was called.  (Also leaves proper
  1992.                 ; return address on stack!)
  1993.     ld    de,LBIOS-3    ;Base of jump table
  1994.     xor    a        ;Clear carry flag
  1995.     sbc    hl,de        ;(BIOS function) * 3 now in HL
  1996.     ld    b,a
  1997.     ld    a,l
  1998. fnCalc:
  1999.     sub    3        ;Figure out which BIOS function was called
  2000.     jr    z,gotFn
  2001.     inc    b
  2002.     jr    fnCalc
  2003. gotFn:
  2004.     ld    a,b        ;Stash it in the BIOS parameter block
  2005.     ld    de,BIOSfn
  2006.     ld    (de),a
  2007.     ld    c,50        ;CP/M Plus direct BIOS call
  2008.     call    cpm
  2009.     ret
  2010.  
  2011. BIOSfn:    defs    1        ;CP/M Plus BIOS parameter block
  2012. aVal:    defs    1
  2013. bcVal:    defs    2
  2014. deVal:    defs    2
  2015. hlVal:    defs    2
  2016.  
  2017. ; LOCAL DISK PARAMETER HEADER
  2018. ;
  2019. ; It seems that the DPH layouts for CP/M 2.x and CP/M 3.x are different.
  2020. ; In particular, there are 10 bytes between DPHXLT and DPHDPB instead
  2021. ; of the 8 shown here.  We will correct for this when we are making a
  2022. ; local copy of the DPB.
  2023. ;
  2024. ; Note that the labels DPHDIR, DPHCSV and DPHALV are not used anywhere.
  2025.  
  2026. DPHLCL    EQU    $
  2027. DPHXLT:    DS    2
  2028.     DS    6        ;FILLER
  2029. DPHDIR:    DS    2
  2030. DPHDPB:    DS    2
  2031. DPHCSV:    DS    2
  2032. DPHALV:    DS    2
  2033.  
  2034. dphdp3    equ    dphdpb+2    ;Equivalence for CP/M 3.x
  2035.  
  2036. ; LOCAL DISK PARAMETER BLOCK
  2037.  
  2038. DPBLCL    EQU    $
  2039. DPBSPT:    DS    2        ;CP/M LOGICAL SECTORS PER TRACK
  2040. DPBBSH:    DS    1
  2041. DPBBLM:    DS    1        ;LOGICAL SECTORS PER BLOCK - 1
  2042. DPBEXM:    DS    1
  2043. DPBDSM:    DS    2        ;FILE BLOCKS PER DISK
  2044. DPBDRM:    DS    2
  2045. DPBAL0:    DS    1
  2046. DPBAL1:    DS    1
  2047. DPBCKS:    DS    2
  2048. DPBOFF:    DS    2
  2049. dpbPSH:    DS    1        ;CP/M 3 only
  2050. dpbPSM:    DS    1        ;CP/M 3 only
  2051.  
  2052. ; LOCAL DISK PARAMETER EXTENSIONS
  2053.  
  2054. DPETPD:    DS    2        ;TRACKS PER DISK
  2055. DPESPB:    DS    2        ;SECTORS PER BLOCK
  2056. DPERSC:    DS    2        ;RESERVED SECTORS
  2057.  
  2058.  
  2059. PSMDTR:    DS    2
  2060. PSMDSC:    DS    2
  2061. PSMDBL:    DS    2
  2062.  
  2063. PhySec:    ds    2
  2064.  
  2065. ; PHYSICAL DISK MODE MESSAGES, PANEL AND ACTION VECTOR
  2066.  
  2067. TRKMSG:    DB    11,04,'Enter Hex Track',0    ;OVERLAID BY CTRMSG
  2068. SECMSG:    DB    11,23,'Enter Hex Sector',0    ;OVERLAID BY CSCMSG
  2069. BLKMSG:    DB    11,42,'Enter Hex Block',0    ;OVERLAID BY CBLMSG
  2070. DIDMSG:    DB    11,61,'Enter Drive ID',0    ;OVERLAID BY CDKMSG
  2071.  
  2072. PSMDPN:    DB    16                ;FIELD COUNT
  2073.     DB    02,00,'N  Next sector',0
  2074.     DB    03,00,'P  Previous sector',0
  2075.     DB    04,00,'I  Next track',0
  2076.     DB    05,00,'O  Previous track',0
  2077.     DB    02,27,'T  Select track',0
  2078.     DB    03,27,'S  Select sector',0
  2079.     DB    04,27,'B  Select block',0
  2080.     DB    05,27,'D  Select drive',0
  2081.     DB    02,54,'Z  Exit from Superzap',0
  2082.     DB    03,54,'L  Exit to file list',0
  2083.     DB    04,54,'X  Scratchpad operations',0
  2084.     DB    05,54,'C  Change sector',0
  2085.  
  2086. CTRMSG:    DB    11,04,'Current-Track  ',0    ;OVERLAID BY TRKMSG
  2087. CSCMSG:    DB    11,23,'Current-Sector  ',0    ;OVERLAID BY SECMSG
  2088. CBLMSG:    DB    11,42,'Current-Block  ',0    ;OVERLAID BY BLKMSG
  2089. CDKMSG:    DB    11,61,'Current-Drive ',0    ;OVERLAID BY DIDMSG
  2090.  
  2091. PSMDER:    DB    8,0        ;ERROR FIELD
  2092. PSPMSG:    DB    07,00,'Scratchpad :- ',0
  2093.  
  2094. ; FILE STATISTICS FIELDS
  2095.  
  2096. PSTRFL:    DB    12,11,0
  2097. PSTRIP:    DB    12,15,0
  2098. PSSCFL:    DB    12,28,0
  2099. PSSCIP:    DB    12,32,0 
  2100. PSBLFL:    DB    12,47,0
  2101. PSBLIP:    DB    12,51,0
  2102. PSDKFL:    DB    12,67,0
  2103.  
  2104. PSMDLS:    DB    12,'NCPSITOZLBDX'
  2105. PSMDVC    EQU    $
  2106.     DW    NXPS        ;NEXT PHYSICAL SECTOR
  2107.     DW    PSCH        ;PHYSICAL SECTOR CHANGE MODE
  2108.     DW    PRPS        ;PREVIOUS PHYSICAL SECTOR
  2109.     DW    SPSN        ;SET PHYSICAL SECTOR
  2110.     DW    FRTR        ;FORWARD TRACK
  2111.     DW    SPTN        ;SET PHYSICAL TRACK
  2112.     DW    BWTR        ;BACKWARD TRACK
  2113.     DW    SETX        ;SET EXIT MODE
  2114.     DW    PTOD        ;CHANGE TO DIRECTORY MODE
  2115.     DW    SPBL        ;SET PHYSICAL BLOCK
  2116.     DW    CHPD        ;CHANGE PHYSICAL DISK
  2117.     DW    PSPM        ;PHYSICAL S/P MANAGER
  2118.  
  2119. ; PTOD - CHANGE TO DIRECTORY
  2120.  
  2121.     $RTN    PTOD
  2122.     LD    A,(CURAN)
  2123.     CALL    CHDR        ;RESET DISKS
  2124.     CALL    SETD        ;SET D MODE
  2125.     RET
  2126.  
  2127. ; CHPD - CHANGE PHYSICAL DISK
  2128.  
  2129.     $RTN    CHPD
  2130.     $FLD    DIDMSG        ;DISPLAY PROMP
  2131. CHPD01    EQU    $        ;LOOP
  2132.     $FLD    PSDKFL        ;POSITION FOR DISK ID
  2133.     LD    A,(CURAN)    ;GET ABSOLUTE DRIVE NUMBER
  2134.     ADD    A,041H        ;MAKE IT ALPHA
  2135.     CALL    CHRO        ;DISPLAY DRIVE ID
  2136.     CALL    CHRF
  2137.     CP    $ESC
  2138.     JR    Z,CHPD02    ;EXIT IF ESCAPE
  2139.     CP    CR
  2140.     JR    Z,CHPD02    ;OR CR
  2141.     SUB    041H        ;MAKE IT DISK NUMBER
  2142.     CALL    CHDR        ;CHANGE DRIVE
  2143.     JR    NZ,CHPD02    ;EXITIF NON ZERO DPH
  2144.     CALL    ALRM        ;RING BELL
  2145.     JR    CHPD01
  2146. CHPD02    EQU    $        ;ENDLOOP
  2147.     CP    $ESC
  2148.     JR    Z,CHPD03    ;IF NOT ESC
  2149.     LD    A,0FFH
  2150.     LD    (PMNEWD),A    ;FLAG NEW DISK
  2151. CHPD03    EQU    $
  2152.     $FLD    CDKMSG        ;REDISPLAY CURRENT
  2153.     RET
  2154.  
  2155.  
  2156. ; PRDD - READ AND DISPLAY PHYSICAL SECTOR
  2157.  
  2158.     $RTN    PRDD
  2159.     CALL    PSRD        ;READ PHYSICAL SECTOR
  2160.     LD    HL,FBUFF
  2161.     CALL    WRBF        ;DISPLAY BUFFER CONTENTS
  2162.     CALL    UBLK        ;UPDATE BLOCK
  2163.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  2164.     RET
  2165.  
  2166. ; DPSI - DISPLAY SECTOR INFORMATION
  2167.  
  2168.     $RTN    DPSI
  2169.     $FLD    PSTRFL        ;POSITION CURSOR FOR TRACK NUMBER
  2170.     $HEXW    PSMDTR        ;DISPLAY TRACK
  2171.     $FLD    PSSCFL        ;POSITION FOR SECTOR NUMBER
  2172.     $HEXW    PSMDSC        ;DISPLAY SECTOR
  2173.     $FLD    PSBLFL        ;POSITION FOR BLOCK NUMBER
  2174.     $HEXW    PSMDBL        ;DISPLAY BLOCK
  2175.     $FLD    PSDKFL        ;POSITION FOR DISK ID
  2176.     LD    A,(CURAN)    ;GET ABSOLUTE DRIVE NUMBER
  2177.     ADD    A,041H        ;MAKE IT ALPHA
  2178.     CALL    CHRO        ;DISPLAY DRIVE ID
  2179.     RET
  2180.  
  2181.  
  2182. ; UBLK - UPDATE BLOCK NUMBER
  2183.  
  2184.     $RTN    UBLK
  2185.     LD    DE,(PSMDTR)
  2186.     LD    BC,(DPBSPT)
  2187.     CALL    MULT
  2188.     LD    DE,(PSMDSC)
  2189.     ADD    HL,DE        ;CALCULATE ABSOLUTE SECTOR
  2190.     LD    DE,(DPERSC)
  2191.     OR    A
  2192.     SBC    HL,DE
  2193.     JR    NC,UBLK01    ;IF WITHIN SYSTEM AREA
  2194.     LD    DE,0        ;SET BLOCK ZERO
  2195.     JR    UBLK02
  2196. UBLK01    EQU    $        ;ELSE
  2197.     EX    DE,HL
  2198.     LD    BC,(DPESPB)
  2199.     CALL    DIVD        ;CALCULATE BLOCK NUMBER
  2200.     LD    HL,(DPBDSM)
  2201.     OR    A
  2202.     SBC    HL,DE
  2203.     JR    NC,UBLK04    ;IF BLOCK NOT IN RANGE
  2204.     LD    DE,0        ;SET BLOCK ZERO
  2205. UBLK04    EQU    $        ;ENDIF
  2206. UBLK02    EQU    $        ;ENDIF
  2207.     LD    (PSMDBL),DE    ;SET NEW BLOCK NUMBER
  2208.     RET
  2209.  
  2210.  
  2211. ; NXPS - NEXT PHYSICAL SECTOR
  2212.  
  2213.     $RTN    NXPS
  2214.     LD    HL,(PSMDSC)
  2215.     INC    HL
  2216.     LD    (PSMDSC),HL    ;INCREMENT PHYSICAL SECTOR
  2217.     LD    DE,(DPBSPT)
  2218.     OR    A
  2219.     SBC    HL,DE
  2220.     JR    C,NXPS01    ;IF TRACK OVERFLOW
  2221.     LD    HL,0
  2222.     LD    (PSMDSC),HL    ;SET TO FIRST SECTOR
  2223.     CALL    FRTR        ;ADVANCE TRACK
  2224. NXPS01    EQU    $        ;ENDIF
  2225.     RET
  2226.  
  2227.  
  2228. ; PRPS - PREVIOUS PHSICAL SECTOR
  2229.  
  2230.     $RTN    PRPS
  2231.     LD    HL,(PSMDSC)
  2232.     LD    A,H
  2233.     OR    L
  2234.     JR    NZ,PRPS01    ;IF SECTOR IS ZERO
  2235.     CALL    BWTR        ;GO BACK A TRACK
  2236.     LD    HL,(DPBSPT)    ;SET UP FOR DECREMENT
  2237. PRPS01    EQU    $        ;ENDIF
  2238.     DEC    HL
  2239.     LD    (PSMDSC),HL    ;DECREMENT TO PREVIOUS SECTOR
  2240.     RET
  2241.  
  2242.  
  2243. ; SPSN - SET PHYSICAL SECTOR NUMBER
  2244.  
  2245.     $RTN    SPSN
  2246.     LD    HL,SELMSG
  2247.     CALL    CFLD
  2248.     LD    HL,(PSMDSC)
  2249.     LD    (SAVPSC),HL    ;SAVE RECORD NUMBER
  2250.     $FLD    SECMSG        ;DISPLAY SET SECTOR
  2251.     LD    HL,0
  2252.     LD    (PSMDSC),HL    ;ZERO RECORD NUMBER
  2253. SPSN01    EQU    $
  2254.     CALL    UBLK
  2255.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  2256.     $IFLD    PSSCIP        ;POSITION AND GET INPUT
  2257.     $MTCH    HEXCHR
  2258.     JR    NZ,SPSN02    ;IF VALID HEX
  2259.     EX    DE,HL
  2260.     LD    HL,(PSMDSC)
  2261.     CALL    H16D        ;HL=HL*16+DIGIT
  2262.     LD    (PSMDSC),HL    ;SAVE NEW SECTOR NUMBER
  2263.     JR    SPSN03
  2264. SPSN02    EQU    $
  2265.     CP    $ESC
  2266.     JR    NZ,SPSN04    ;ELSEIF ESCAPE
  2267.     LD    HL,(SAVPSC)
  2268.     LD    (PSMDSC),HL    ;RESTORE SECTOR NUMBER
  2269.     JR    SPSN03
  2270. SPSN04    EQU    $
  2271.     CP    $LEFT
  2272.     JR    NZ,SPSN05    ;ELSEIF BACKSPACE
  2273.     LD    HL,PSMDSC+1
  2274.     XOR    A
  2275.     RRD
  2276.     DEC    HL
  2277.     RRD            ;SECTOR=SECTOR/16
  2278.     JR    SPSN03
  2279. SPSN05    EQU    $
  2280.     CP    CR
  2281.     JR    NZ,SPSN06    ;ELSEIF CR
  2282.     OR    A
  2283.     LD    HL,(PSMDSC)
  2284.     LD    DE,(DPBSPT)
  2285.     SBC    HL,DE
  2286.     JR    C,SPSN07    ;IF SECTOR OUT OF RANGE
  2287.     CALL    ALRM        ;SIGNAL ERROR
  2288.     LD    HL,(SAVPSC)
  2289.     LD    (PSMDSC),HL    ;RESTORE TO ORIGINAL
  2290.     XOR    A
  2291.     LD    (INCH),A    ;DONT EXIT
  2292. SPSN07    EQU    $
  2293.     JR    SPSN03
  2294. SPSN06    EQU    $        ;ELSE
  2295.     CALL    ALRM        ;ERROR
  2296. SPSN03    EQU    $        ;ENDIF
  2297.     LD    A,(INCH)
  2298.     CP    CR
  2299.     JR    Z,SPSN08    ;EXIT IF CR
  2300.     CP    $ESC
  2301.     JR    Z,SPSN08    ;EXIT IF ESC
  2302.     JP    SPSN01
  2303. SPSN08    EQU    $        ;ENDLOOP
  2304.     $FLD    CSCMSG        ;DISPLAY CURRENT SECTOR MESSAGE
  2305.     RET
  2306.  
  2307. SAVPSC:    DS    2
  2308.  
  2309.  
  2310. ; FRTR - FORWARD TRACK
  2311.  
  2312.     $RTN    FRTR
  2313.     LD    HL,(PSMDTR)
  2314.     INC    HL
  2315.     LD    (PSMDTR),HL
  2316.     LD    DE,(DPETPD)
  2317.     OR    A
  2318.     SBC    HL,DE
  2319.     JR    C,FRTR01    ;IF DISK OVERFLOW
  2320.     LD    HL,0
  2321.     LD    (PSMDTR),HL    ;SET TO FIRST TRACK
  2322. FRTR01    EQU    $
  2323.     RET
  2324.  
  2325.  
  2326. ; SPTN - SET PHYSICAL TRACK NUMBER
  2327.  
  2328.     $RTN    SPTN
  2329.     LD    HL,SELMSG
  2330.     CALL    CFLD
  2331.     LD    HL,(PSMDTR)
  2332.     LD    (SAVPTR),HL    ;SAVE TRACK NUMBER
  2333.     $FLD    TRKMSG        ;DISPLAY TRKMSG
  2334.     LD    HL,0
  2335.     LD    (PSMDTR),HL    ;ZERO TRACK NUMBER
  2336. SPTN01    EQU    $
  2337.     CALL    UBLK
  2338.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  2339.     $IFLD    PSTRIP        ;POSITION AND GET INPUT
  2340.     $MTCH    HEXCHR
  2341.     JR    NZ,SPTN02    ;IF VALID HEX
  2342.     EX    DE,HL
  2343.     LD    HL,(PSMDTR)
  2344.     CALL    H16D        ;HL=HL*16+DIGIT
  2345.     LD    (PSMDTR),HL    ;SAVE NEW TRACK NUMBER
  2346.     JR    SPTN03
  2347. SPTN02    EQU    $
  2348.     CP    $ESC
  2349.     JR    NZ,SPTN04    ;ELSEIF ESCAPE
  2350.     LD    HL,(SAVPTR)
  2351.     LD    (PSMDTR),HL    ;RESTORE TRACK NUMBER
  2352.     JR    SPTN03
  2353. SPTN04    EQU    $
  2354.     CP    $LEFT
  2355.     JR    NZ,SPTN05    ;ELSEIF BACKSPACE
  2356.     LD    HL,PSMDTR+1
  2357.     XOR    A
  2358.     RRD
  2359.     DEC    HL
  2360.     RRD            ;TRACK=TRACK/16
  2361.     JR    SPTN03
  2362. SPTN05    EQU    $
  2363.     CP    CR
  2364.     JR    NZ,SPTN06    ;ELSEIF CR
  2365.     OR    A
  2366.     LD    HL,(PSMDTR)
  2367.     LD    DE,(DPETPD)
  2368.     SBC    HL,DE
  2369.     JR    C,SPTN07    ;IF TRACK OUT OF RANGE
  2370.     CALL    ALRM        ;SIGNAL ERROR
  2371.     LD    HL,(SAVPTR)
  2372.     LD    (PSMDTR),HL    ;RESTORE TO ORIGINAL
  2373.     XOR    A
  2374.     LD    (INCH),A    ;DONT EXIT
  2375. SPTN07    EQU    $        ;ENDIF
  2376.     JR    SPTN03
  2377. SPTN06    EQU    $        ;ELSE
  2378.     CALL    ALRM        ;ERROR
  2379. SPTN03    EQU    $        ;ENDIF
  2380.     LD    A,(INCH)
  2381.     CP    CR
  2382.     JR    Z,SPTN08    ;EXIT IF CR
  2383.     CP    $ESC
  2384.     JR    Z,SPTN08    ;EXIT IF ESC
  2385.     JP    SPTN01
  2386. SPTN08    EQU    $        ;ENDLOOP
  2387.     $FLD    CTRMSG        ;REDISPLY TRACK MESSAGE
  2388.     RET
  2389.  
  2390. SAVPTR:    DS    2
  2391.  
  2392.  
  2393. ; BWTR - BACKWARD TRACK
  2394.  
  2395.     $RTN    BWTR
  2396.     LD    HL,(PSMDTR)
  2397.     LD    A,H
  2398.     OR    L
  2399.     JR    NZ,BWTR01    ;IF TRACK IS ZERO
  2400.     LD    HL,(DPETPD)    ;SET UP FOR DECREMENT
  2401. BWTR01    EQU    $        ;ENDIF
  2402.     DEC    HL
  2403.     LD    (PSMDTR),HL    ;DECREMENT TO PREVIOUS TRACK
  2404.     RET
  2405.  
  2406.  
  2407. ; SPBL - SET PHYSICAL BLOCK
  2408.  
  2409.     $RTN    SPBL
  2410.     LD    HL,SELMSG
  2411.     CALL    CFLD
  2412.     LD    HL,(PSMDBL)
  2413.     LD    (SAVPBL),HL    ;SAVE BLOCK NUMBER
  2414.     $FLD    BLKMSG        ;DISPLAY BLKMSG
  2415.     LD    HL,0
  2416.     LD    (PSMDBL),HL    ;ZERO BLOCK NUMBER
  2417. SPBL01    EQU    $
  2418.     CALL    DPSI        ;DISPLAY PHYSICAL SECTOR INFO
  2419.     $IFLD    PSBLIP        ;POSITION AND GET INPUT
  2420.     $MTCH    HEXCHR
  2421.     JR    NZ,SPBL02    ;IF VALID HEX
  2422.     EX    DE,HL
  2423.     LD    HL,(PSMDBL)
  2424.     CALL    H16D        ;BLOCK=BLOCK*16+DIGIT
  2425.     LD    (PSMDBL),HL    ;SAVE NEW BLOCK NUMBER
  2426.     JR    SPBL03
  2427. SPBL02    EQU    $
  2428.     CP    $ESC
  2429.     JR    NZ,SPBL04    ;ELSEIF ESCAPE
  2430.     LD    HL,(SAVPBL)
  2431.     LD    (PSMDBL),HL    ;RESTORE BLOCK NUMBER
  2432.     JR    SPBL03
  2433. SPBL04    EQU    $
  2434.     CP    $LEFT
  2435.     JR    NZ,SPBL05    ;ELSEIF BACKSPACE
  2436.     LD    HL,PSMDBL+1
  2437.     XOR    A
  2438.     RRD
  2439.     DEC    HL
  2440.     RRD            ;BLOCK=BLOCK/16
  2441.     JR    SPBL03
  2442. SPBL05    EQU    $
  2443.     CP    CR
  2444.     JR    NZ,SPBL06    ;ELSEIF CR
  2445.     OR    A
  2446.     LD    DE,(PSMDBL)
  2447.     LD    HL,(DPBDSM)
  2448.     SBC    HL,DE
  2449.     JP    P,SPBL07    ;IF BLOCK OUT OF RANGE
  2450.     CALL    ALRM        ;SIGNAL ERROR
  2451.     LD    HL,(SAVPBL)
  2452.     LD    (PSMDBL),HL    ;RESTORE TO ORIGINAL
  2453.     XOR    A
  2454.     LD    (INCH),A    ;DONT EXIT
  2455.     JR    SPBL08
  2456. SPBL07    EQU    $        ;ELSE
  2457.     LD    DE,(PSMDBL)
  2458.     LD    BC,(DPESPB)
  2459.     CALL    MULT
  2460.     LD    DE,(DPERSC)
  2461.     ADD    HL,DE        ;CALCULATE ABSOLUTE SECTOR
  2462.     EX    DE,HL
  2463.     LD    BC,(DPBSPT)
  2464.     CALL    DIVD
  2465.     LD    (PSMDTR),DE    ;SET TRACK
  2466.     LD    (PSMDSC),HL    ;SET SECTOR
  2467. SPBL08    EQU    $        ;ENDIF
  2468.     JR    SPBL03
  2469. SPBL06    EQU    $        ;ELSE
  2470.     CALL    ALRM        ;ERROR
  2471. SPBL03    EQU    $        ;ENDIF
  2472.     LD    A,(INCH)
  2473.     CP    CR
  2474.     JR    Z,SPBL09    ;EXIT IF CR
  2475.     CP    $ESC
  2476.     JR    Z,SPBL09    ;EXIT IF ESC
  2477.     JP    SPBL01
  2478. SPBL09    EQU    $        ;ENDLOOP
  2479.     $FLD    CBLMSG        ;REDISPLAY CURRENT BLOCK MESSAGE
  2480.     RET
  2481.  
  2482. SAVPBL:    DS    2
  2483.  
  2484.  
  2485. ; PSPM - PHYSICAL SCRATCHPAD MODE
  2486.  
  2487.     $RTN    PSPM
  2488.     $NPANEL    PSPMPN        ;DISPLAY PANEL
  2489.     $FLD    PSPCUR        ;POSITION FOR CURRENT INFO
  2490.     $STRO    SPDMSG
  2491.     LD    A,(CURAN)
  2492.     ADD    A,41H
  2493.     CALL    CHRO        ;DISPLAY DRIVE
  2494.     $STRO    SPTMSG
  2495.     $HEXW    PSMDTR        ;TRACK
  2496.     $STRO    SPSMSG
  2497.     $HEXW    PSMDSC        ;SECTOR
  2498.     $FLD    PSPSPD        ;POSITION FOR S/P DATA
  2499.     CALL    DSPD
  2500.     CALL    SPCI        ;GET COMMAND
  2501.     $EXVA    PSPMV        ;PROCESS COMMAND
  2502.     LD    A,0FFH
  2503.     LD    (RPANEL),A    ;REQUEST PANEL
  2504.     RET
  2505.  
  2506. PSPMPN:    DB    3
  2507.     DB    2,0,'ESC Return to sector display',0
  2508.     DB    3,0,'C   Copy current sector to scratchpad',0
  2509.     DB    4,0,'E   Exchange current sector with scratchpad',0
  2510.  
  2511. PSPCUR:    DB    11,0,'Current    :- ',0
  2512. PSPSPD:    DB    12,0,'Scratchpad :- ',0
  2513.  
  2514. PSPML:    DB    3,$ESC,'CE'
  2515. PSPMV:    DW    PSPX
  2516.     DW    PLSP
  2517.     DW    PXSP
  2518.  
  2519.     $RTN    PSPX
  2520.     RET
  2521.  
  2522.  
  2523. ; PXSP - EXCHANGE WITH SCRATCHPAD
  2524.  
  2525.     $RTN    PXSP
  2526.     LD    A,(SPTYPE)
  2527.     OR    A
  2528.     JR    NZ,PXSP01    ;IF PAD EMPTY
  2529.     CALL    ALRM        ;RING BELL
  2530.     JR    PXSP02
  2531. PXSP01    EQU    $        ;ELSE
  2532.     LD    BC,(SPADDR)
  2533.     CALL    dmaSet        ;SET CPM BUFFER
  2534.     CALL    PSWR        ;WRITE BUFFER
  2535.     LD    BC,FBUFF
  2536.     CALL    dmaSet        ;RESTORE DMA
  2537.     CALL    PLSP        ;COPY OLD BUFFER
  2538. PXSP02    EQU    $        ;ENDIF
  2539.     RET
  2540.  
  2541. ; PLSP - LOAD SCRATCHPAD (PHYSICAL)
  2542.  
  2543.     $RTN    PLSP
  2544.     LD    HL,FBUFF
  2545.     LD    DE,(SPADDR)
  2546.     LD    BC,128
  2547.     LDIR            ;COPY THE BUFFER
  2548.     LD    A,(CURAN)
  2549.     LD    (SPDRIV),A    ;SET DRIV
  2550.     LD    HL,(PSMDTR)
  2551.     LD    (SPNAME),HL    ;SET TRACK
  2552.     LD    HL,(PSMDSC)
  2553.     LD    (SPSECT),HL    ;SET SECTOR
  2554.     LD    A,1
  2555.     LD    (SPTYPE),A    ;SET THE TYPE
  2556.     RET
  2557.  
  2558.  
  2559. ; DSPD DISPLAY S/P DATA
  2560.  
  2561.     $RTN    DSPD
  2562.     CALL    DSPI        ;DISPLAY SP INFO
  2563.     LD    A,(SPTYPE)
  2564.     OR    A
  2565.     JR    Z,DSPD01    ;IF SP NOT EMPTY
  2566.     CALL    ZBSA        ;CLEAR ADDRESS COUNTER
  2567.     LD    HL,(SPADDR)
  2568.     CALL    WRBF        ;DISPLAY IT
  2569. DSPD01    EQU    $        ;ENDIF
  2570.     RET
  2571.  
  2572.  
  2573. ; LSEL - LIST FILE SELECTION STUB MASK POINTED TO BY HL
  2574.  
  2575.     $RTN    LSEL
  2576.     LD    DE,LMDFN
  2577.     LD    BC,11
  2578.     LDIR
  2579.     RET
  2580.  
  2581. ; PSCH - PHYSICAL SECTOR CHANGE
  2582.  
  2583.     $RTN    PSCH
  2584.     CALL    SCCH        ;GO INTO SECTOR CHANGE MODE
  2585.     LD    A,(SCCHWR)
  2586.     OR    A
  2587.     JR    Z,PSCH03    ;IF WRITE REQUIRED
  2588.     CALL    PSWR        ;WRITE OUT SECTOR
  2589. PSCH03    EQU    $        ;ENDIF
  2590.     LD    A,0FFH
  2591.     LD    (RPANEL),A    ;REQUEST PANEL
  2592.     RET            
  2593.  
  2594.  
  2595. ; SCCH - SECTOR CHANGE MODE
  2596.  
  2597.     $RTN    SCCH
  2598.     LD    HL,HLAREA
  2599.     CALL    CLRA        ;CLEAR THE HELP AREA
  2600.     $PANEL    SCCHPN        ;DISPLAY SECTOR CHANGE PANEL
  2601.     LD    A,FALSE
  2602.     LD    (SCCHWR),A    ;WRITE FLAG FALSE
  2603.     LD    (ASCII),A    ;ASCII FALSE
  2604.     LD    (SCCHEX),A    ;EXIT FALSE
  2605.     LD    (LOORD),A    ;START WITH HO HEX DIGIT
  2606.     XOR    A
  2607.     LD    (BUFPOS),A    ;BUFFER POSITION 0
  2608. SCCH03    EQU    $        ;LOOP
  2609.     CALL    SLCP
  2610.     CALL    UDCP        ;POSITION CURSOR
  2611.     CALL    CHRI
  2612.     CP    020H
  2613.     JP    NC,SCCH04    ;IF CONTROL CODE
  2614.     $MTCH    SCCHLS
  2615.     JR    Z,SCCH05    ;IF NOT VALID
  2616.     CALL    ALRM        ;SOUND THE ALARM
  2617.     JR    SCCH06
  2618. SCCH05    EQU    $        ;ELSE
  2619.     $EXVA    SCCHVC        ;ACTION CONTROL CODE
  2620. SCCH06    EQU    $        ;ENDIF
  2621.     JR    SCCH08
  2622. SCCH04    EQU    $        ;ELSE
  2623.     LD    A,(ASCII)
  2624.     OR    A
  2625.     JR    Z,SCCH09    ;IF ASCII MODE
  2626.     CALL    MACH        ;MAKE ASCII CHANGE
  2627.     JR    SCCH10
  2628. SCCH09    EQU    $        ;ELSE
  2629.     CALL    MHCH        ;MAKE HEX CHANGE
  2630. SCCH10    EQU    $        ;ENDIF
  2631. SCCH08    EQU    $        ;ENDIF
  2632.     LD    A,(SCCHEX)
  2633.     OR    A
  2634.     JR    NZ,SCCH11    ;EXIT IF END OF UPDATES
  2635.     JR    SCCH03
  2636. SCCH11    EQU    $        ;ENDLOOP
  2637.     RET
  2638.  
  2639. SCCHEX:    DB    0
  2640. SCCHWR:    DB    0
  2641.  
  2642.  
  2643. ; SECTOR CHANGE MODE PANEL AND ACTION VECTOR
  2644.  
  2645. SCCHPN:    DB    8
  2646.     DB    2,0,'^',$LEFT+040H,'  Cursor left',0
  2647.     DB    2,40,'^',$RIGHT+040H,'  Cursor right',0
  2648.     DB    3,0,'^',$UP+040H,'  Cursor up',0
  2649.     DB    3,40,'^',$DOWN+040H,'  Cursor down',0
  2650.     DB    4,0,'^',$TAB+040H,'  Change Side',0
  2651.     DB    4,40,'CR  New Line',0
  2652.     DB    5,0,'^',$QUIT+040H,'  Cancel changes',0
  2653.     DB    5,40,'^',$END+040H,'  Save Changes',0
  2654.  
  2655. SCCHLS:    DB    8,$LEFT,$TAB,$DOWN,$UP,$RIGHT,CR,$END,$QUIT
  2656.  
  2657. SCCHVC    EQU    $
  2658.     DW    LEFT
  2659.     DW    TOGL
  2660.     DW    DOWN
  2661.     DW    UPWD
  2662.     DW    RGHT
  2663.     DW    NWLN
  2664.     DW    CHND
  2665.     DW    QUIT
  2666.  
  2667.  
  2668. ; LEFT - MOVE CURSOR LEFT
  2669.  
  2670.     $RTN    LEFT
  2671.     LD    A,(LOORD)
  2672.     OR    A
  2673.     JR    NZ,LEFT01    ;IF HIGH OR ASCII
  2674.     LD    A,(BUFPOS)
  2675.     DEC    A
  2676.     AND    07FH
  2677.     LD    (BUFPOS),A    ;DECREMENT POSITION
  2678. LEFT01    EQU    $
  2679.     LD    A,(ASCII)
  2680.     OR    A
  2681.     JR    NZ,LEFT02    ;IF HEX MODE
  2682.     LD    A,(LOORD)
  2683.     CPL
  2684.     LD    (LOORD),A    ;TOGGLE DIGIT
  2685. LEFT02    EQU    $
  2686.     RET
  2687.  
  2688.  
  2689. ; TOGL - TOGGLE BETWEEN HEX AND ASCII
  2690.  
  2691.     $RTN    TOGL
  2692.     LD    A,(ASCII)
  2693.     CPL
  2694.     LD    (ASCII),A    ;TOGGLE MODE FLAG
  2695.     LD    A,FALSE
  2696.     LD    (LOORD),A    ;INDICATE HO DIGIT
  2697.     RET
  2698.  
  2699.  
  2700. ; DOWN - MOVE CURSOR DOWN ONE LINE
  2701.  
  2702.     $RTN    DOWN
  2703.     LD    A,(BUFPOS)
  2704.     ADD    A,16
  2705.     AND    07FH
  2706.     LD    (BUFPOS),A
  2707.     RET
  2708.  
  2709.  
  2710. ; UPWD - MOVE CURSOR UP ONE LINE
  2711.  
  2712.     $RTN    UPWD
  2713.     LD    A,(BUFPOS)
  2714.     SUB    16
  2715.     AND    07FH        ;MODULO 128
  2716.     LD    (BUFPOS),A
  2717.     RET
  2718.  
  2719.  
  2720. ; RGHT - MOVE CURSOR RIGHT
  2721.  
  2722.     $RTN    RGHT
  2723.     LD    A,(ASCII)
  2724.     OR    A
  2725.     JR    NZ,RGHT01    ;IF HEX MODE
  2726.     LD    A,(LOORD)
  2727.     CPL            ;TOGGLE HEX DIGIT
  2728.     LD    (LOORD),A
  2729. RGHT01    EQU    $        ;ENDIF
  2730.     LD    A,(LOORD)
  2731.     OR    A
  2732.     JR    NZ,RIGH02    ;IF HIGH ORD OR ASCII
  2733.     LD    A,(BUFPOS)
  2734.     INC    A
  2735.     AND    07FH
  2736.     LD    (BUFPOS),A    ;INCREMENT POSITION
  2737. RIGH02    EQU    $        ;ENDIF
  2738.     RET
  2739.  
  2740.  
  2741. ; NWLN - MOV CURSOR TO START OF NEW LINE
  2742.  
  2743.     $RTN    NWLN
  2744.     LD    A,FALSE
  2745.     LD    (LOORD),A    ;INDICATE HO HEX DIGIT
  2746.     LD    A,(BUFPOS)
  2747.     ADD    A,16
  2748.     AND    070H
  2749.     LD    (BUFPOS),A    ;NEW BUFFER ADDR
  2750.     RET
  2751.  
  2752.  
  2753. ; CHND - CHANGE END AND WRITE
  2754.  
  2755.     $RTN    CHND
  2756.     LD    A,TRUE
  2757.     LD    (SCCHEX),A    ;SIGNAL EXIT
  2758.     LD    (SCCHWR),A    ;SIGNAL WRITE
  2759.     RET
  2760.  
  2761.  
  2762. ; QUIT - END WITHOUT SAVING UPDATES
  2763.  
  2764.     $RTN    QUIT
  2765.     LD    A,TRUE
  2766.     LD    (SCCHEX),A    ;SIGNAL EXIT
  2767.     RET
  2768.  
  2769.  
  2770. ; WRBF - DISPLAY FILE DATA IN SECTOR BUFFER
  2771.  
  2772.     $RTN    WRBF
  2773.     EX    DE,HL
  2774.     XOR    A
  2775.     LD    (BUFPOS),A    ;SET OFFSET TO 0
  2776. WRBF01    EQU    $        ;LOOP (HEX AND ASCII LINE)
  2777.     PUSH    DE        ;SAVE BUFFER POINTER
  2778.     PUSH    DE        ;AND FOR ASCII
  2779.     XOR    A
  2780.     LD    (CPOS),A    ;POSITION 1
  2781.     CALL    STLP        ;SET LINE CURSOR POSITION
  2782.     CALL    UDCP        ;UPDATE CURSOR
  2783.     CALL    PRTADR        ;DISPLAY ADDRESS
  2784.     LD    A,(BASEAD+2)
  2785.     ADD    A,010H
  2786.     LD    (BASEAD+2),A    ;INC ADDR FOR NEXT LINE
  2787.     CALL    SHCP        ;SET UP CURSOR POSN IN HEX AREA
  2788.     CALL    UDCP        ;UPDATE CURSOR
  2789.     POP    DE        ;GET CURRENT ADDRESS
  2790. WRBF03    EQU    $        ;LOOP (BYTES IN HEX)
  2791.     LD    A,(DE)        ;GET CHARACTER THERE
  2792.     INC    DE        ;INCREMENT BUFF POINTER
  2793.     CALL    HEXO        ;PRINT BYTE
  2794.     CALL    SPCO        ;PRINT SPACE
  2795.     LD    HL,BUFPOS
  2796.     INC    (HL)        ;INC TO NEXT COL
  2797.     LD    A,3
  2798.     AND    (HL)
  2799.     JR    NZ,WRBF04    ;IF END OF GROUP
  2800.     CALL    SPCO        ;PRINT SPACE
  2801. WRBF04    EQU    $        ;ENDIF
  2802.     LD    A,0FH
  2803.     AND    (HL)
  2804.     JR    NZ,WRBF03    ;UNTIL 16 BYTES DISPLAYED
  2805.  
  2806.     LD    A,(HL)
  2807.     SUB    16
  2808.     LD    (HL),A        ;RESET BUFFER OFFSET
  2809.     CALL    SACP        ;POSITION FOR ASCII
  2810.     LD    HL,CPOS
  2811.     DEC    (HL)        ;BACK OFF 1 FOR MARGIN
  2812.     CALL    UDCP        ;POSITION CURSOR
  2813.     LD    A,'|'
  2814.     CALL    CHRO        ;PRINT MARGIN
  2815.     POP    DE        ;RESTORE CHAR POINTER
  2816. WRBF02    EQU    $        ;LOOP (BYTES IN ASCII)
  2817.     LD    A,(DE)        ;GET CURRENT CHARACTER
  2818.     INC    DE        ;INCREMENT POINTER
  2819.     CALL    ASCO        ;PRINT CHAR
  2820.     LD    HL,BUFPOS
  2821.     INC    (HL)        ;INCREMENT BUFFER OFFSET
  2822.     LD    A,0FH
  2823.     AND    (HL)
  2824.     JR    NZ,WRBF02    ;UNTIL 16 BYTES DISPLAYED
  2825.     LD    A,'|'
  2826.     CALL    CHRO        ;PRINT MARGIN
  2827.  
  2828.     LD    A,(HL)
  2829.     AND    07FH
  2830.     JP    NZ,WRBF01    ;UNTIL 128 BYTES DISPLAYED
  2831.     RET
  2832.  
  2833.  
  2834. ; CURSOR POSITON TABLES FOR HEX AND ASCII DISPLAY
  2835.  
  2836. LPTAB:    DB    14,15,16,17,18,19,20,21
  2837.  
  2838. HCTAB:    DB     9,12,15,18,22,25,28,31,35,38,41,44,48,51,54,57
  2839. ACTAB:    DB    63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78
  2840.  
  2841. DCTAB:    DB    00,20,40,60 
  2842.  
  2843.  
  2844. ; ZBSA - ZERO BASE ADDRESS
  2845.  
  2846.     $RTN    ZBSA
  2847.     XOR    A
  2848.     LD    (BASEAD),A
  2849.     LD    (BASEAD+1),A
  2850.     LD    (BASEAD+2),A
  2851.     RET
  2852.  
  2853.  
  2854. ; PRTADR - PRINT FILE ADDRESS
  2855.  
  2856.     $RTN    PRTADR
  2857.     $HEXW    BASEAD        ;DISPLAY 2 BYTES
  2858.     LD    A,(BASEAD+2)
  2859.     CALL    HEXO
  2860.     RET
  2861.  
  2862.  
  2863. ; SLCP - SET CURSOR TO CURRENT LINE AND COLUMN POSITION IN BUFFER
  2864.  
  2865.     $RTN    SLCP
  2866.     CALL    STLP
  2867.     CALL    STCP
  2868.     RET
  2869.  
  2870.  
  2871. ; STLP - SET UP LINE POSITION
  2872.  
  2873.     $RTN    STLP
  2874.     LD    HL,LPTAB    ;GET BASE OF LINE TABLE
  2875.     LD    A,(BUFPOS)
  2876.     RRA
  2877.     RRA
  2878.     RRA
  2879.     RRA
  2880.     AND    0FH        ;MOV TO LOW ORDER
  2881.     CALL    AAHL
  2882.     LD    A,(HL)        ;GET VALUE
  2883.     LD    (LPOS),A    ;SET UP FOR UDCP
  2884.     RET
  2885.  
  2886. ; STCP - SET UP COLUMN POSITION IN BUFFER
  2887.  
  2888.     $RTN    STCP
  2889.     LD    A,(ASCII)
  2890.     OR    A
  2891.     JR    Z,STCP01    ;IF IN ASCII DISPLAY MODE
  2892.     CALL    SACP        ;SET UP ASCII DISPLAY
  2893.     JR    STCP02
  2894. STCP01    EQU    $        ;ELSE
  2895.     CALL    SHCP        ;SET UP FOR HEX DISPLAY
  2896.     LD    A,(LOORD)
  2897.     OR    A
  2898.     JR    Z,STCP03    ;IF LOW ORDER DIGIT
  2899.     LD    HL,CPOS
  2900.     INC    (HL)        ;INCREMENT COLUMN POS
  2901. STCP03    EQU    $        ;ENDIF
  2902. STCP02    EQU    $        ;ENDIF
  2903.     RET
  2904.  
  2905. ASCII:    DB    0
  2906. LOORD:    DB    0
  2907.  
  2908.  
  2909. ; SHCP - SET CURSOR ADDRESS FOR HEX DISPLAY
  2910.  
  2911.     $RTN    SHCP
  2912.     LD    HL,HCTAB
  2913.     LD    A,(BUFPOS)
  2914.     AND    0FH
  2915.     CALL    AAHL
  2916.     LD    A,(HL)        ;PICK UP VALUE
  2917.     LD    (CPOS),A    ;SET POSITION
  2918.     RET
  2919.  
  2920.  
  2921. ; SACP - SET CURSOR ADDRESS FOR ASCII DISPLAY
  2922.  
  2923.     $RTN    SACP
  2924.     LD    HL,ACTAB
  2925.     LD    A,(BUFPOS)
  2926.     AND    0FH
  2927.     CALL    AAHL
  2928.     LD    A,(HL)
  2929.     LD    (CPOS),A
  2930.     RET
  2931.  
  2932.  
  2933. ; MACH - UPDATE BUFFER IN ASCII FORMAT
  2934.  
  2935.     $RTN    MACH
  2936.     LD    A,(INCH)
  2937.     CP    020H
  2938.     JR    C,MACH01
  2939.     CP    080H
  2940.     JR    C,MACH02    ;IF CHARACTER OUT OF RANGE
  2941. MACH01    EQU    $
  2942.     CALL    ALRM        ;SOUND THE ALARM
  2943.     JR    MACH03
  2944. MACH02    EQU    $        ;ELSE
  2945.     PUSH    AF
  2946.     PUSH    AF        ;SAVE CHAR
  2947.     LD    A,(BUFPOS)    ;GET BUFFER OFFSET
  2948.     LD    HL,FBUFF
  2949.     CALL    AAHL        ;POINT TO CHARACTER
  2950.     POP    AF        ;RESTORE CHAR
  2951.     LD    (HL),A        ;CHARACTER TO BUFFER
  2952.     CALL    ASCO        ;ECHO IT
  2953.     CALL    SHCP        
  2954.     CALL    UDCP        ;POSITION IN HEX AREA
  2955.     POP    AF        ;RESTORE CHAR
  2956.     CALL    HEXO
  2957.     CALL    RGHT        ;MOVE CURSOR FOR NEXT
  2958. MACH03    EQU    $        ;ENDIF
  2959.     RET
  2960.  
  2961.  
  2962. ; MHCH - UPDATE BUFFER CONTENTS IN HEX
  2963.  
  2964.     $RTN    MHCH
  2965.     LD    A,(INCH)    ;GET INPUT CHARACTER
  2966.     CALL    FOLD
  2967.     LD    (INCH),A    ;SAVE FOLDED VERSION
  2968.     $MTCH    HEXCHR
  2969.     JR    Z,MHCH02    ;IF NOT VALID HEX
  2970.     CALL    ALRM        ;SOUND THE ALARM
  2971.     JR    MHCH03
  2972. MHCH02    EQU    $
  2973.     LD    C,L        ;SET HEX VALUE OF NIBBLE IN C
  2974.     LD    A,(INCH)
  2975.     CALL    ASCO        ;ECHO IT
  2976.     LD    A,(BUFPOS)    ;GET OFFSET
  2977.     LD    HL,FBUFF    ;BASE OF BUFFET
  2978.     CALL    AAHL        ;HL=A(CURRENT CHAR)
  2979.     LD     B,(HL)        ;B = CURRENT CHARACTER
  2980.     LD    A,(LOORD)
  2981.     OR    A
  2982.     JR    Z,MHCH04    ;IF LO ORDER NIBBLE
  2983.     LD    A,0F0H        ;SET MASK
  2984.     JR    MHCH05
  2985. MHCH04    EQU    $        ;ELSE
  2986.     LD    A,C        ;CHAR TO A REG
  2987.     RLCA
  2988.     RLCA
  2989.     RLCA
  2990.     RLCA            ;HEX=HEX*16
  2991.     AND    0F0H        ;CLEAR ANY MINCE LEFT
  2992.     LD    C,A        ;BACK TO C REG
  2993.     LD    A,00FH        ;SET MASK
  2994. MHCH05    EQU    $        ;ENDIF
  2995.     AND    B        ;MASK NIBBLE
  2996.     OR    C        ;INSERT NEW VALUE
  2997.     LD    (HL),A        ;REPLACE IN BUFFER
  2998.     PUSH    AF        ;SAVE IT FOR ASCII
  2999.     CALL    SACP
  3000.     CALL    UDCP        ;TOGGLE TO ASCII DISP
  3001.     POP    AF        ;PICK UP NEW CHAR
  3002.     CALL     ASCO        ;DISPLAY IT
  3003.     CALL    RGHT        ;ADVANCE CURSOR
  3004. MHCH03    EQU    $        ;ENDIF
  3005.     RET
  3006.  
  3007. HEXCHR:    DB    16,'0123456789ABCDEF'    ;VALID HEX CHARACTERS
  3008.  
  3009.  
  3010. ; CHDR - CHANGE TO DRIVE IN A
  3011.  
  3012.     $RTN    CHDR
  3013.     LD    (SAVDRV),A    ;SAVE REQUESTED DRIVE
  3014.     LD    C,A
  3015.     CALL    SELDSK        ;LOCATE DPH
  3016.     LD    A,H
  3017.     OR    L
  3018.     JR    NZ,CHDR01    ;IF INVALID DISK
  3019.     LD    A,(CURAN)    ;GET CURRENT ID
  3020.     LD    C,A
  3021.     CALL    SELDSK        ;RE-SELECT IT
  3022.     XOR    A
  3023.     JP    CHDR02
  3024. CHDR01    EQU    $        ;ELSE
  3025.     PUSH    HL        ;SAVE DPH
  3026.     LD    C,RESET
  3027.     CALL    CPM        ;RESET DISKS
  3028.     ld    hl,-1        ;Clear prvTrk and prvSec to force
  3029.     ld    (prvTrk),hl    ; physical I/O on next access
  3030.     ld    (prvSec),hl
  3031.  
  3032. ;        <<< INITIALISE PHYSICAL CONTROL BLOCKS >>>
  3033. ; If CP/M 3.1 then the DPH is not necessarily in the same memory bank as
  3034. ; this program but the banked BDOS does us the favour of making a local
  3035. ; copy in common memory.
  3036.  
  3037.     POP    HL        ;RESTORE DPH
  3038.     LD    DE,DPHLCL
  3039.     LD    BC,16
  3040.     LDIR            ;TAKE LOCAL COPY OF DPH
  3041.     LD    HL,(DPHDPB)    ;DPB pointer for CP/M 2.x
  3042.     ld    a,(cpm3)    ;Check which version of CP/M so we get
  3043.     or    a        ; the DPB pointer right
  3044.     jr    z,copyDPB    ;Skip reload if 2.2
  3045.     ld    hl,(dphdp3)    ;Get CP/M 3 DPB pointer
  3046. copyDPB:
  3047.     LD    DE,DPBLCL
  3048.     LD    BC,17        ;Increased from 15 for CP/M+
  3049.     LDIR            ;TAKE LOCAL COPY OF DPB
  3050.     LD    DE,(DPBSPT)
  3051.     LD    BC,(DPBOFF)
  3052.     CALL    MULT        ;HL RETURNS NUMBER OF SYSTEM SECTORS
  3053.     PUSH    HL
  3054.     LD    (DPERSC),HL    ;SAVE RESERVED SECTORS
  3055.     LD    A,(DPBBLM)
  3056.     LD    D,0
  3057.     LD    E,A
  3058.     INC    DE
  3059.     LD    (DPESPB),DE    ;SAVE SECTORS PER BLOCK
  3060.     LD    BC,(DPBDSM)
  3061.     CALL    MULT        ;HL RETURNS NUMBER OF FILE SECTORS
  3062.     POP    DE
  3063.     ADD    HL,DE        ;HL CONTAINS SECTORS PER DISK
  3064.     LD    DE,(DPBSPT)
  3065.     DEC    DE
  3066.     ADD    HL,DE        ;READY TO ROUND UP
  3067.     EX    DE,HL
  3068.     LD    BC,(DPBSPT)
  3069.     CALL    DIVD        ;DE RETURNS TRACKS PER DISK
  3070.     LD    (DPETPD),DE    ;SAVE TRACKS PER DISK
  3071. ;    FOLLOWING CODE CALCULATES CORRECT NUMBER OF LOGICAL
  3072. ;    TRACKS/DISK FOR C128. ORIGINAL SUPERZAP CODE GETS WRONG NUMBER.
  3073. ;
  3074.     inc    de        ;Increment # tracks/disk
  3075.     ld    a,0        
  3076.     cp    d        ;Is disk double-sided?
  3077.     jr    z,single    ;Jump if single-sided
  3078.     inc    de        ;Increment again if double-sided
  3079. single    equ    $        ;Jump target
  3080.     ld    (dpetpd),de    ;Now # of tracks/disk is correct
  3081. ;    END OF THIS CORRECTION SECTOR FOR C128
  3082. ;
  3083.                 ;INITIALISE FILE CONTROL BLOCKS
  3084.     LD    A,(SAVDRV)    ;RESTORE REQUESTED DRIVE
  3085.     LD    (CURAN),A    ;SAVE AS ABSOLUTE DISK NUMBER
  3086.     INC    A    
  3087.     LD    (WRKDR),A    ;PUT IT IN WORK FCB
  3088.     LD    (LMDDR),A    ;AND DIRECTORY FCB
  3089.     CALL    RDIR        ;READ DIRECTORY
  3090.     LD    A,0FFH
  3091.     OR    A        ;SET NON-ZERO FLAGS
  3092. CHDR02    EQU    $        ;ENDIF
  3093.     RET
  3094.  
  3095. SAVDRV:    DS    1
  3096.  
  3097.  
  3098. ; DLST - DIRECTORY LISTING
  3099.  
  3100.     $RTN    DLST
  3101.     $FLD    DDLMSG
  3102.     LD    A,(CURAN)    ;GET DISK ID
  3103.     ADD    A,41H        ;CONVERT TO ASCII LETTER
  3104.     LD    (DRIVNM),A    ;PUT DRIVE NAME IN MESSAGE
  3105.     LD    DE,LMDFN
  3106.     CALL    FMTN
  3107.     $STRO    DRIVNM
  3108.     LD    DE,(FSTDE@)
  3109.     LD    A,(DIROFF)    ;GET STARTING ENTRY
  3110.     LD    H,0
  3111.     LD    L,A
  3112.     CALL    H16D        ;HL=COUNT*LENGTH+FIRST
  3113.     LD    (NXTDE@),HL    ;POINT TO FIRST DISPLAY
  3114.     XOR    A
  3115.     LD    (PRTCNT),A
  3116. DLST02    EQU    $        ;LOOP
  3117.     LD    A,(DIROFF)
  3118.     LD    B,A
  3119.     LD    A,(DECNT)
  3120.     SUB    B
  3121.     LD    HL,PRTCNT
  3122.     CP    (HL)
  3123.     JR    Z,DLST03    ;EXIT IF ALL ENTRIES PROCESSED
  3124.     LD    A,(HL)        ;GET DISPLAY COUNTER
  3125.     CALL    DIRPOS        ;POSITION TO DISPLAY
  3126.     LD    A,(FLAGCH)    ;LOAD FLAG CHARACTER
  3127.     CALL    CHRO        ;PRINT IT
  3128.     CALL    SPCO        ;AND SPACE
  3129.     LD    DE,(NXTDE@)    ;POINT ENTRY TO PRINT
  3130.     CALL    FMTN        ;FORMAT FILE NAME
  3131.     $STRO    FILENM        ;PRINT NAME
  3132.     LD    HL,(NXTDE@)
  3133.     LD    DE,16
  3134.     ADD    HL,DE
  3135.     LD    (NXTDE@),HL    ;UPDATE TABLE POINTER
  3136.     LD    HL,PRTCNT
  3137.     INC    (HL)        ;INCREMENT DISPLAY COUNTER
  3138.     LD    A,32
  3139.     CP    (HL)
  3140.     JR    Z,DLST03    ;EXIT DISPLAY FULL
  3141.     JR    DLST02
  3142. DLST03    EQU    $        ;ENDLOOP
  3143.     RET
  3144.  
  3145. DDLMSG:    DB    12,20,'Directory list - ',0
  3146.  
  3147.  
  3148. ; RDIR - READ DIRECTORY
  3149.  
  3150.     $RTN    RDIR
  3151.     XOR    A
  3152.     LD    (DECNT),A    ;NO ENTRIES IN TABLE
  3153.     LD    (SELDE),A    ;SELECT LIST ENTRY 0
  3154.     LD    (DIROFF),A    ;DISPLAY STARTS AT 0
  3155.     LD    HL,(MEMRY)
  3156.     LD    (NXTDE@),HL    ;WHERE TO INSERT POINTER
  3157.     LD    (FSTDE@),HL    ;START OF TABLE POINTER
  3158.     DEC    HL
  3159.     LD    (TOPDE@),HL    ;TOP OF TABLE
  3160.     LD    DE,LMDFCB
  3161.     LD    C,FNDFST
  3162.     CALL    CPM        ;GET FIRST DIRECTORY ENTRY
  3163.     CP    0FFH
  3164.     JR    Z,RDIR01    ;QUIT IF NO FILE MATCHED
  3165.     RRCA
  3166.     RRCA
  3167.     RRCA            ;MULTIPY BY 32
  3168.     LD    HL,FBUFF    ;POINT TO RECORD
  3169.     CALL    AAHL        ;ADDRESS OF CURRENT ENTRY
  3170.     LD    (NEWDE@),HL    ;SAVE IT
  3171.     CALL    INSRT        ;PUT MATCHED ENTRY IN TABLE
  3172.     LD    HL,(TOPDE@)
  3173.     LD    DE,16
  3174.     ADD    HL,DE
  3175.     LD    (TOPDE@),HL    ;MARK TOP OF TABLE
  3176. RDIR02    EQU    $        ;LOOP
  3177.     LD    DE,LMDFCB
  3178.     LD    C,FNDNXT
  3179.     CALL    CPM        ;FIND NEXT MATCH
  3180.     CP    0FFH
  3181.     JR    Z,RDIR03    ;EXITIF NO MORE
  3182.     RRCA
  3183.     RRCA
  3184.     RRCA            ;MULTIPLY DIR CODE BY 32
  3185.     LD    HL,FBUFF    ;POINT TO RECORD
  3186.     CALL    AAHL
  3187.     LD    (NEWDE@),HL    ;SAVE IT
  3188.     CALL    ORDER        ;FIND OUT WHERE TO PUT IT
  3189.     CALL    INSRT        ;PUT ENTRY IN TABLE
  3190.     JR    RDIR02
  3191. RDIR03    EQU    $        ;ENDLOOP
  3192. RDIR01    EQU    $        ;ENDIF
  3193.     LD    HL,(TOPDE@)
  3194.     INC    HL
  3195.     LD    (PGEPTR),HL    ;MARK START OF PAGING POINTERS
  3196.     RET
  3197.  
  3198. ; INSRT - PUT DIRECTORY ENTRY IN TABLE
  3199.  
  3200. INSRT    EQU    $
  3201.     LD    DE,(NXTDE@)    ;GET TABLE POINTER
  3202.     LD    HL,(NEWDE@)    ;GET ADDRESS OF NEW ENTRY
  3203.     INC    HL        ;DONT COPY DRIVE BYTE
  3204.     LD    BC,16        ;LENGTH OF ENTRY
  3205.     LDIR            ;SAVE ENTRY
  3206.     LD    HL,DECNT
  3207.     INC    (HL)        ;ADD ONE TO ENTRY COUNT
  3208.     RET
  3209.  
  3210. ; ORDER - UPDATE THE DIRECTORY TABLE
  3211.  
  3212. ORDER    EQU    $
  3213.     LD    HL,(FSTDE@)
  3214. ORDER1    EQU    $        ;LOOP
  3215.     LD    DE,(TOPDE@)
  3216.     EX    DE,HL
  3217.     OR    A
  3218.     SBC    HL,DE
  3219.     JP    M,ORDER2    ;EXIT IF END OF TABLE
  3220.     PUSH    DE        ;SAVE CURRENT POINTER
  3221.     LD    HL,(NEWDE@)    ;POINT TO NEW ENTRY
  3222.     INC    HL        ;IGNORE DRIVE ID FIELD
  3223.     LD    BC,11        ;LENGTH OF FILE NAME
  3224.     CALL    CPST        ;COMPARE FILENAME
  3225.     POP    DE        ;RESTORE CURRENT POINTER
  3226.     JP    M,ORDER2    ;EXIT IF CURRENT>NEW
  3227.     LD    HL,16
  3228.     ADD    HL,DE        ;POINT TO NEXT ENTRY
  3229.     JP    ORDER1
  3230. ORDER2    EQU    $        ;ENDLOOP
  3231.     LD    (NXTDE@),DE    ;SAVE INSERT ADDRESS
  3232.     LD    HL,(TOPDE@)
  3233.     INC    HL
  3234.     OR    A
  3235.     SBC    HL,DE
  3236.     LD    B,H
  3237.     LD    C,L        ;LENGTH TO MOVE
  3238.     LD    HL,(TOPDE@)    ;CURRENT TOP OF TABLE
  3239.     PUSH    HL        ;SAVE CURRENT TOP
  3240.     LD    DE,16
  3241.     ADD    HL,DE        ;NEW TOP OF TABLE
  3242.     LD    (TOPDE@),HL    ;SAVE NEW TOP
  3243.     POP    DE        ;RESTORE OLD TOP
  3244.     LD    A,B
  3245.     OR    C
  3246.     JP    Z,ORDER3    ;QUIT IF NOTHING TO MOVE
  3247.     EX    DE,HL        ;DEST=NEW,SRC=OLD TOP ADDRESS
  3248.     LDDR            ;MOVE TABLE UP 16 BYTES
  3249. ORDER3    EQU    $        ;ENDIF
  3250.     RET
  3251.  
  3252.  
  3253. ; CPST - COMPARE STRING (HL)0:6 WITH (DE)0:6 LENGTH (BC) 
  3254.  
  3255.     $RTN    CPST
  3256.     XOR    A
  3257.     LD    (CPSTCN),A    ;COMPARE CONDITION IS =
  3258. CPST01    EQU    $        ;LOOP
  3259.     LD    A,C
  3260.     OR    B
  3261.     JR    Z,CPST02    ;EXITIF DONE
  3262.     PUSH    BC        ;SAVE COUNTER
  3263.     LD    A,(DE)        ;GET 2ND STR CHAR
  3264.     AND    07FH        ;IGNORE HIGH BIT
  3265.     LD    B,A        ;SAVE IT
  3266.     LD    A,(HL)        ;GET 1ST STR CHAR
  3267.     AND    07FH        ;IGNORE HI BIT
  3268.     SUB    B        ;COMPARE CURRENT CHARS
  3269.     LD    (CPSTCN),A    ;SAVE RESULT
  3270.     POP    BC        ;RETRIEVE COUNTER
  3271.     JR    NZ,CPST02    ;EXITIF NOT EQUAL
  3272.     INC    HL
  3273.     INC    DE
  3274.     DEC    BC        ;POINT TO NEXT CHARS
  3275.     JR    CPST01
  3276. CPST02    EQU    $        ;ENDLOOP
  3277.     LD    A,(CPSTCN)    ;PICK UP CONDITIONS
  3278.     OR    A        ;SET CPU FLAGS
  3279.     RET
  3280.  
  3281. CPSTCN:    DS    1        ;COMPARE CONDITION
  3282.  
  3283. ; CLRA - CLEAR AREA FROM LINE H FOR L
  3284.  
  3285.     $RTN    CLRA
  3286.     LD    A,H
  3287.     LD    B,L
  3288. CLRA01    EQU    $
  3289.     CALL    CLRL
  3290.     INC    A
  3291.     DJNZ    CLRA01
  3292.     LD    HL,0
  3293.     LD    (PRVERR),HL    ;NO ERROR NOW DISPLAYED
  3294.     RET
  3295.  
  3296. ; FMTN - FORMAT FILE NAME FROM FCB POINTED TO BY DE INTO FILENM
  3297.  
  3298.     $RTN    FMTN
  3299.     LD    HL,FILENM
  3300.     LD    B,8        ;LENGTH 8
  3301. FMTN01    EQU    $        ;LOOP
  3302.     LD    A,(DE)
  3303.     AND    07FH        ;STRIP OFF HIGH BIT
  3304.     LD    (HL),A        ;COPY CHARACTER
  3305.     INC    HL
  3306.     INC    DE
  3307.     DJNZ    FMTN01        ;UNTIL NAME DONE
  3308.     LD    (HL),'.'    ;INSERT SEPERATOR
  3309.     INC    HL
  3310.     LD    A,(DE)
  3311.     AND    80H
  3312.     LD    (RO),A        ;SET RO FLAG
  3313.     LD    B,3        ;LENGTH 3
  3314. FMTN02    EQU    $        ;REPEAT
  3315.     LD    A,(DE)
  3316.     AND    07FH        ;STRIP OFF HIGH BIT
  3317.     LD    (HL),A        ;COPY CHARACTER
  3318.     INC    HL
  3319.     INC    DE        ;POINT TO NEXT
  3320.     DJNZ    FMTN02        ;UNTIL TYPE DONE
  3321.     LD    A,(RO)
  3322.     OR    A        ;TEST RO FLAG
  3323.     LD    A,'W'        ;ASSUME R/W MODE
  3324.     JR    Z,FMTN03    ;IF READ ONLY
  3325.     LD    A,'O'        ;SELECT R/O MODE
  3326. FMTN03    EQU    $        ;ELSE 
  3327.     LD    (FDMDRS),A    ;SET MODE
  3328.     XOR    A
  3329.     LD    (COMFLG),A    ;CLEAR .COM FLAG
  3330.     LD    HL,COMSTR
  3331.     LD    DE,FILENM+9    ;POINT TO TYPE
  3332.     LD    BC,3
  3333.     CALL    CPST
  3334.     JR    NZ,FMTN04    ;IF .COM FILE
  3335.     LD    A,0FFH
  3336.     LD    (COMFLG),A    ;SET FLAG
  3337. FMTN04    EQU    $        ;ENDIF
  3338.     RET
  3339.  
  3340.  
  3341. ; UDCP - UPDATE CURSOR POSITION TO LPOS/CPOS
  3342.  
  3343. UDCP    EQU    $
  3344.     PUSH    HL
  3345.     PUSH    AF
  3346.     LD    A,(LPOS)    ;GET LINE NUMBER
  3347.     LD    L,A
  3348.     LD    A,(CPOS)    ;GET COLUM POSITION
  3349.     LD    H,A
  3350.     CALL    CURS        ;PUT CURSOR THERE
  3351.     POP    AF
  3352.     POP    HL
  3353.     RET
  3354.  
  3355. LPOS:    DB    0
  3356. CPOS:    DB    0
  3357.  
  3358. ;---------------
  3359. ; FILE I/O ROUTINES
  3360. ;---------------
  3361.  
  3362. ; IOaddr - Set the data transfer address for disk operations
  3363.  
  3364.     $rtn    IOaddr
  3365.     ld    de,(DMA)
  3366.     ld    c,sDMA
  3367.     call    cpm        ;Could just JP CPM but this is
  3368.     ret            ;easier when using Z8E debugger
  3369.  
  3370. ; DMAset - Record the data transfer address for disk operations
  3371.  
  3372.     $rtn    DMAset
  3373.     ld    (DMA),bc
  3374.     ret
  3375.  
  3376. DMA:    defw    80h        ;(Default at entry to this program)
  3377.  
  3378. ; RDFS - READ FILE RELATIVE SECTOR
  3379.  
  3380.     $RTN    RDFS
  3381.     XOR    A
  3382.     LD    (WRKOV),A    ;CLEAR OVERFLOW FLAG
  3383.     LD    HL,(WRKRR)
  3384.     LD    (SAVFSC),HL    ;SAVE CURRENT RECORD
  3385.     LD    HL,(RELREC)
  3386.     LD    (WRKRR),HL    ;SET RECORD NUMBER
  3387.     call    IOaddr        ;Set data pointer
  3388.     LD    DE,WRKFCB    ;POINT TO FCB
  3389.     LD    C,READRN
  3390.     CALL    CPM        ;READ THE RECORD
  3391.     LD    (READST),A    ;SAVE STATUS
  3392.     OR    A
  3393.     JR    Z,RDFS01    ;IF BAD READ
  3394.     LD    HL,(SAVFSC)
  3395.     LD    (RELREC),HL    ;RESTORE RECORD NUMBER
  3396.     LD    (WRKRR),HL    
  3397. RDFS01    EQU    $
  3398.     RET
  3399.  
  3400.  
  3401. ; WRFS - WRITE FILE RELATIVE SECTOR BACK TO DISK
  3402.  
  3403.  
  3404.     $RTN    WRFS
  3405.     call    IOaddr        ;Set data pointer
  3406.     LD    DE,WRKFCB    ;POINT TO FCB
  3407.     LD    C,WRITRN    ;RANDOM WRITE
  3408.     CALL    CPM        ;GO DO IT
  3409.     RET
  3410.  
  3411. ; PHYS3 - Test if CP/M Plus and if so then change sector number to
  3412. ;      conform to physical sector size.
  3413.  
  3414.     $rtn    phys3
  3415.     ld    a,(cpm3)
  3416.     or    a
  3417.     push    af        ;Save result for caller
  3418.     jr    z,pExit        ;No transformation needed for 2.x
  3419.     ld    a,(dpbpsh)    ;Pick up physical sector size from DPH
  3420.     inc    a        ;Pre-increment for shift loop
  3421. pshift:
  3422.     dec    a        ;Count down the number of shifts
  3423.     jr    z,pExit        ;Exit when done
  3424.     srl    b        ;BC := BC/2
  3425.     sra    c
  3426.     jr    pshift        ;Around again
  3427. pExit:
  3428.     pop    af
  3429.     ret
  3430.  
  3431. ; secPnt    Build address of 128-byte "logical" sector within psBuff
  3432. ;        On exit, HL holds required address and BC contains the
  3433. ;        value 128 (ready for an LDIR instruction)
  3434.  
  3435.     $rtn    secPnt
  3436.     ld    hl,(psmdsc)    ;Get sector number
  3437.     ld    a,(dpbpsm)    ;Get physical sector mask
  3438.     and    l        ;Calculate which 128-byte chunk
  3439.     ld    hl,psBuff
  3440.     ld    bc,128        ;Chunk size
  3441. pOff:    ret    z        ;Exit now if address calculated
  3442.     add    hl,bc        ;Otherwise increment pointer
  3443.     dec    a
  3444.     jr    pOff
  3445.  
  3446. ; PSRD - READ PHYSICAL SECTOR
  3447.  
  3448.     $RTN    PSRD
  3449.     call    IOaddr        ;We'll override this later if CP/M 3.x
  3450.     LD    BC,(PSMDTR)
  3451. ; FOLLOWING LINE ADDED FOR C128
  3452.     ld    (tmptrk),bc    ;Temporary save of track #
  3453. ;
  3454.     CALL    SETTRK        ;SELECT TRACK
  3455.     LD    BC,(PSMDSC)
  3456.     call    phys3        ;If CP/M 3.x then change to physical
  3457.     push    bc        ;Save sector number during tests
  3458.     jr    z,pRead        ;If CP/M 2.x then do the read
  3459.     ld    hl,(prvSec)    ;See if same physical sector as last time
  3460.     sbc    hl,bc        ;(Carry flag is already clear)
  3461.     jr    nz,pRead    ;Do read if different
  3462.     ld    bc,(prvTrk)    ;Check track
  3463.     ld    hl,(psmdtr)
  3464.     sbc    hl,bc
  3465.     jr    nz,pRead    ;Do read if different
  3466.  
  3467. ;If we get here then we are running under CP/M+ and we already have the
  3468. ;correct physical sector in memory.  All we have to do is deliver the
  3469. ;appropriate logical sector to the rest of the program.
  3470.  
  3471.     pop    bc        ;Align stack
  3472.     call    secPnt        ;Build pointer into psBuff
  3473.     ld    de,(DMA)    ;Where to put the data
  3474.     ldir            ;Move 128 bytes
  3475.     ret
  3476. pRead:
  3477.     pop    bc
  3478.     ld    (prvSec),bc    ;Record sector ..
  3479.     LD    HL,(PSMDTR)
  3480.     ld    (prvTrk),hl    ;.. and track
  3481. ;    LD    DE,(DPBOFF)
  3482. ;    OR    A
  3483. ;    SBC    HL,DE
  3484. ;    JR    C,STSA01    ;IF NOT SYSTEM TRACK
  3485.     LD    DE,(DPHXLT)
  3486.     CALL    SECTRN        ;DO SECTOR TRANSLATION
  3487.     LD    B,H
  3488.     LD    C,L
  3489. STSA01    EQU    $
  3490. ; FOLLOWING LINE ADDED FOR C128
  3491.     ld    (tmpsec),bc    ;Temporary save of sector #
  3492. ;
  3493.     CALL    SETSEC
  3494.     ld    a,(cpm3)    ;If CP/M 3 then ..
  3495.     or    a
  3496.     jr    z,doRead
  3497.     ld    bc,psBuff    ;.. use physical sector buffer
  3498.     call    setdma
  3499. doRead:    CALL    READ        ;READ SECTOR
  3500.     push    af        ;Preserve result
  3501.     ld    a,(cpm3)
  3502.     or    a
  3503.     jr    z,psrdx        ;Exit if CP/M 2.2
  3504.     call    IOaddr        ;Restore DMA
  3505.     call    secPnt        ;Calculate address in psBuff
  3506.     ld    de,(DMA)    ;Where to put the data
  3507.     ldir            ;Copy it
  3508. psrdx:    pop    af
  3509.     RET
  3510.  
  3511.  
  3512. ; PSWR - WRITE PHYSICAL SECTOR
  3513.  
  3514.     $RTN    PSWR
  3515. ; FOLLOWING 4 LINES ADDED FOR C128
  3516.     ld    bc,(tmptrk)
  3517.     call    settrk        ;Set track to value of previous read
  3518.     ld    bc,(tmpsec)
  3519.     call    setsec        ;Set sector to value of previous read
  3520. ;
  3521.     ld    a,(cpm3)    ;Decide which method to use
  3522.     or    a
  3523.     jr    z,pswr2
  3524.     call    secPnt        ;Calculate address within psBuff
  3525.     ex    de,hl        ;Put destination address into DE
  3526.     ld    hl,(DMA)    ;Where to put the data
  3527.     ldir            ;Move the data
  3528.     ld    bc,psBuff    ;Set address for data transfer
  3529.     call    setdma
  3530. pswr2:
  3531.     LD    C,WRDIR        ;USE WRITE DIRECTORY TO FORCE WRITE
  3532.     CALL    WRITE        ;WRITE SECTOR
  3533.     push    af        ;Save result
  3534.     call    IOaddr        ;Restore data address
  3535.     pop    af
  3536.     RET
  3537.  
  3538. WRDIR    EQU    1        ;BIOS DIRECTORY WRITE CODE
  3539.  
  3540. ; FOLLOWING 2 LINES ADDED FOR C128
  3541. tmptrk:    dw    0        ;Temp. storage for track #
  3542. tmpsec:    dw    0        ;Temp. storage for sector #
  3543. ;
  3544. prvSec:    defw    -1
  3545. prvTrk:    defw    -1
  3546.  
  3547. ;----------------
  3548. ; UTILITY ROUTINES
  3549. ;----------------
  3550.  
  3551. ; H16D - HL * 16 + DE
  3552.  
  3553.     $RTN    H16D
  3554.     ADD    HL,HL
  3555.     ADD    HL,HL
  3556.     ADD    HL,HL
  3557.     ADD    HL,HL        ;HL=HL*16
  3558.     ADD    HL,DE        ; + DE
  3559.     RET
  3560.  
  3561. ; ERRP - PROCESS ERROR DISPLAYS
  3562.  
  3563.     $RTN    ERRP
  3564.     LD    HL,(PRVERR)
  3565.     LD    A,H
  3566.     OR    L
  3567.     JR    Z,ERRP01    ;IF PREVIOS ERROR
  3568.     PUSH    HL        ;SAVE TEXT ADDRESS
  3569.     $FLD    ERRFLD        ;POSITION CURSOR
  3570.     POP    HL
  3571.     CALL    CSTR        ;CLEAR STRING
  3572.     LD    HL,0
  3573.     LD    (PRVERR),HL    ;CLEAR POINTER
  3574. ERRP01    EQU    $        ;ENDIF
  3575.     LD    HL,(ERRTXT)
  3576.     LD    A,H
  3577.     OR    L
  3578.     JR    Z,ERRP02    ;IF ERROR SET
  3579.     PUSH    HL        ;SAVE TEXT POINTER
  3580.     $FLD    ERRFLD        ;POSITION CURSOR
  3581.     POP    HL
  3582.     LD    (PRVERR),HL    ;SAVE TEXT ADDRESS
  3583.     CALL    STRO        ;OUTPUT TEXT
  3584.     CALL    ALRM        ;SOUND ALARM
  3585.     LD    HL,0
  3586.     LD    (ERRTXT),HL    ;CLEAR TEXT POINTER
  3587. ERRP02    EQU    $        ;ENDIF
  3588.     RET
  3589.  
  3590. ; MTCH - BYTE LIST MATCHER
  3591.  
  3592.     $RTN    MTCH
  3593.     PUSH    BC        ;SAVE BC
  3594.     LD    B,0
  3595.     LD    C,(HL)        ;BC=LENGTH
  3596.     INC    HL        ;POINT TO START OF LIST
  3597.     PUSH    BC        ;SAVE LENGTH
  3598.     CPIR            ;SCAN LIST
  3599.     POP    HL        ;RESTORE LENGTH TO HL
  3600.     JR    NZ,MTCH01    ;IF FOUND
  3601.     OR    A
  3602.     SBC    HL,BC        ;SUBTRACT RESIDUE TO GIVE OFFSET+1
  3603.     DEC    HL        ;HL IS OFFSET
  3604.     CP    A        ;SET Z FLAG
  3605. MTCH01    EQU    $
  3606.     POP    BC        ;RESTORE BC
  3607.     RET
  3608.  
  3609.  
  3610. ; EXVA - JUMP TO ROUTINE AT OFFSET 2*HL FROM DE
  3611.  
  3612.     $RTN    EXVA
  3613.     ADD    HL,HL
  3614.     ADD    HL,DE        ;DERIVE ACTION ADDR
  3615.     CALL    LDHL
  3616.     JP    (HL)
  3617.  
  3618.  
  3619. ; LDHL - LOAD HL WITH (HL)
  3620.  
  3621.     $RTN    LDHL
  3622.     PUSH    AF
  3623.     LD    A,(HL)
  3624.     INC    HL
  3625.     LD    H,(HL)
  3626.     LD    L,A        ;HL = (HL)
  3627.     POP    AF
  3628.     RET
  3629.  
  3630.  
  3631. ; AAHL - ADD A TO HL
  3632.  
  3633.     $RTN    AAHL
  3634.     PUSH    DE        ;SAVE DE
  3635.     LD    E,A
  3636.     LD    D,0
  3637.     ADD    HL,DE
  3638.     POP    DE        ;RESTORE DE
  3639.     RET
  3640.  
  3641. ; MULT - MULTIPLY DE BY BC TO GIVE RESULT IN HL AND OVERFLOW IN DE
  3642.  
  3643.     $RTN    MULT
  3644.     LD    A,16        ;SET A TO LOOP COUNT
  3645.     LD    HL,0        ;ZERO RESULT
  3646.     OR    A        ;CLEAR CARRY
  3647. MULT01    EQU    $        ;LOOP
  3648.     EX    DE,HL
  3649.     ADC    HL,HL        ;SHIFT DE LEFT 1 (AND INTO CARRY)
  3650.     EX    DE,HL
  3651.     JP    NC,MULT02    ;IF BIT SHIFTED OUT OF DE IS SET
  3652.     ADD    HL,BC        ;ADD MULTIPLICAND TO RESULT
  3653.     JP    NC,MULT03    ;IF RESULT OVERFLOWED
  3654.     INC    DE        ;PROPAGATE INTO DE
  3655. MULT03    EQU    $        ;ENDIF
  3656. MULT02    EQU    $        ;ENDIF
  3657.     DEC    A        ;DECREMENT LOOP COUNT
  3658.     JP    Z,MULT04    ;IF LOOP COUNT IS ZERO EXIT
  3659.     ADD    HL,HL        ;SHIFT LEFT 1 (OVERFLOW ADDED BY ADC)
  3660.     JP    MULT01
  3661. MULT04    EQU    $        ;ENDLOOP
  3662.     RET
  3663.  
  3664. ; DIVD - DIVIDE DE BY BC TO GIVE REMAINDER IN HL AND QUOTIENT IN DE
  3665.  
  3666.     $RTN    DIVD
  3667.     LD    A,16        ;SET A TO LOOP COUNT
  3668.     LD    HL,0        ;ZERO REMAINDER
  3669. DIVD01    EQU    $        ;LOOP
  3670.     ADD    HL,HL        ;SHIFT REMAINDER LEFT 1
  3671.     EX    DE,HL
  3672.     ADD    HL,HL        ;SHIFT DIVISOR LEFT 1
  3673.     EX    DE,HL
  3674.     JP    NC,DIVD02    ;IF CARRY SET
  3675.     INC    HL        ;INCREMENT RESULT
  3676. DIVD02    EQU    $        ;ENDIF
  3677.     OR    A        ;RESET CARRY FLAG
  3678.     SBC    HL,BC        ;SUBTRACT DIVISOR
  3679.     INC    DE        ;INCREMENT QUOTIENT
  3680.     JP    P,DIVD03    ;IF RESULT IS NEGATIVE
  3681.     ADD    HL,BC        ;BACK OFF SUBTRACT
  3682.     DEC    DE        ;DECREMENT QUOTIENT
  3683. DIVD03    EQU    $        ;ENDIF
  3684.     DEC    A        ;DECREMENT LOOP COUNT
  3685.     JP    Z,DIVD04    ;IF LOOP COUNT ZERO EXIT
  3686.     JP    DIVD01
  3687. DIVD04    EQU    $        ;ENDLOOP
  3688.     RET
  3689.  
  3690.  
  3691. ; SETD - SET DIRECTORY MODE
  3692.  
  3693.     $RTN    SETD
  3694.     LD    A,'D'
  3695.     LD    (WTG),A        ;NEXT MODE IS DIRECTORY
  3696.     RET
  3697.  
  3698.  
  3699. ; SETF - SET FILE MODE
  3700.  
  3701.     $RTN    SETF
  3702.     LD    A,'F'
  3703.     LD    (WTG),A        ;NEXT MODE IS FILE
  3704.     RET
  3705.  
  3706.  
  3707. ; SETP - SET PHYSICAL SECTOR MODE
  3708.  
  3709.     $RTN    SETP
  3710.     LD    A,'P'
  3711.     LD    (WTG),A        ;NEXT MODE IS PHYSICAL SECTOR
  3712.     RET
  3713.  
  3714.  
  3715. ; SETX - SET EXIT MODE
  3716.  
  3717.     $RTN    SETX
  3718.     LD    A,'X'
  3719.     LD    (WTG),A        ;NEXT MODE IS EXIT
  3720.     RET
  3721.  
  3722. ;----------------
  3723. ; SCREEN I/O ROUTINES
  3724. ;----------------
  3725.  
  3726. ; CHRI - INPUT CHARACTER
  3727. ;     USE BIOS CALL TO SUPPORT SYSTEMS WITH SOFTWARE CURSOR
  3728.  
  3729.     $RTN    CHRI
  3730.     PUSH    HL
  3731.     PUSH    DE
  3732.     PUSH    BC
  3733.     CALL    CONIN
  3734.     LD    (INCH),A
  3735.     POP    BC
  3736.     POP    DE
  3737.     POP    HL
  3738.     RET
  3739.  
  3740.  
  3741. ; FOLD - FOLD CHARACTER IN A TO UPPER CASE IF REQUIRED
  3742.  
  3743.     $RTN    FOLD
  3744.     CP    'a'
  3745.     JR    C,FOLD01
  3746.     CP    'z'+1
  3747.     JR    NC,FOLD01    ;IF NOT UPPER CASE
  3748.     AND    05FH        ;FOLD CHARACTER
  3749. FOLD01    EQU    $        ;ENDIF
  3750.     RET
  3751.  
  3752.  
  3753. ; CHRF - GET FOLDED CHARACTER
  3754.  
  3755.     $RTN    CHRF
  3756.     CALL    CHRI
  3757.     CALL    FOLD
  3758.     RET
  3759.  
  3760. ; CHRO - OUTPUT CHARACTER IN A 
  3761.  
  3762.     $RTN    CHRO
  3763.     PUSH    BC
  3764.     PUSH    DE
  3765.     PUSH    HL
  3766.     PUSH    AF
  3767.     LD    E,A        ;INPUT TO PARM REG
  3768.     LD    C,CONIO        ;DIRECT OUTPUT
  3769.     CALL    CPM        ;CALL CPM 
  3770.     POP    AF
  3771.     POP    HL
  3772.     POP    DE
  3773.     POP    BC
  3774.     RET
  3775.  
  3776.  
  3777. ; ALRM - SOUND THE CONSOLE BELL
  3778.  
  3779.     $RTN    ALRM
  3780.     PUSH    AF
  3781.     LD    A,07H
  3782.     CALL    CHRO
  3783.     POP    AF
  3784.     RET
  3785.  
  3786.  
  3787. ; SPCO - OUTPUT SPACE TO SCREEN
  3788.  
  3789.     $RTN    SPCO
  3790.     PUSH    AF
  3791.     LD    A,' '
  3792.     CALL    CHRO
  3793.     POP    AF
  3794.     RET
  3795.  
  3796.  
  3797. ; CLRS - CLEAR SCREEN AND HOME CURSOR
  3798.  
  3799.     $RTN    CLRS
  3800.     PUSH    AF
  3801.     PUSH    HL
  3802.     $strl    CLSSTR        ;PRINT CLEAR SCREEN STRING
  3803.     LD    HL,0
  3804.     LD    (PRVERR),HL    ;CLEAR PREV ERROR
  3805.     POP    HL
  3806.     POP    AF
  3807.     RET
  3808.  
  3809.  
  3810. ; DHDR - CLEAR SCREEN AND DISPLAY HEADER
  3811.  
  3812.     $RTN    DHDR
  3813.     CALL    CLRS
  3814.     $FLD    HDRMSG
  3815.     RET
  3816.  
  3817. ; CLRL - CLEAR LINE CONTAINED IN A
  3818.  
  3819.     $RTN    CLRL
  3820.     PUSH    AF
  3821.     PUSH    HL
  3822.     LD    H,0        ;COLUMN ZERO
  3823.     LD    L,A        ;LINE (A)
  3824.     CALL    CURS        ;POSITION TO LINE
  3825.     $strl    CLLSTR        ;PRINT CLEAR LINE STRING
  3826.     POP    HL
  3827.     POP    AF
  3828.     RET
  3829.  
  3830.  
  3831. ; CURS - SET CURSOR POSITION TO LINE L COLUMN H
  3832.  
  3833.     $RTN    CURS
  3834.     PUSH    AF
  3835.     PUSH    HL
  3836.     $strl    cpPref        ;OUTPUT CURSOR POSITION PREFIX
  3837.     pop    hl
  3838.     push    hl
  3839.     ld    a,(row1st)    ;Row or column?
  3840.     or    a
  3841.     push    af        ;Save row/column flag
  3842.     call    coord
  3843.     $strl    cpMid        ;Output cursor position infix
  3844.     pop    af        ;Recover row/column flag
  3845.     dec    a        ;Toggle it for 2nd coordinate
  3846.     POP    HL
  3847.     call    coord
  3848.     $strl    cpEnd
  3849.     POP    AF
  3850.     RET
  3851.  
  3852. ; coord - outputs a cursor-position coordinate.
  3853. ;      H contains horizontal position
  3854. ;      L contains line number
  3855. ;      Z flag is set if H coord required, reset if L
  3856.  
  3857.     $rtn    coord
  3858.     jr    z,doHor
  3859.     ld    a,(rowOff)
  3860.     add    a,l
  3861.     jr    either
  3862. doHor:    ld    a,(colOff)
  3863.     add    a,h
  3864. either:    ld    e,a
  3865.     ld    a,(cpBin)
  3866.     or    a
  3867.     jr    nz,coBin
  3868.     call    decOut
  3869.     ret
  3870. coBin:    ld    a,e
  3871.     call    chro
  3872.     ret
  3873.  
  3874. ; decOut - Convert 16-bit number in DE to decimal and output to the screen
  3875. ;       Leading zeros are suppressed.  Number is treated as unsigned.
  3876.  
  3877.     $rtn    decOut
  3878.     push    hl
  3879.     push    de
  3880.     push    bc
  3881.     ex    de,hl
  3882.     ld    bc,-10        ;Radix
  3883.     ld    de,-1        ;Initialise quotient
  3884. dvlp:    add    hl,bc        ;Subtract radix
  3885.     inc    de        ;Increment quotient
  3886.     jr    c,dvlp        ;(Slow way to divide)
  3887.     sbc    hl,bc        ;Correct for extra subtract
  3888.     ex    de,hl
  3889.     ld    a,h
  3890.     or    l        ;Test for zero
  3891.     call    nz,decOut    ;Recursive call
  3892.     ld    a,'0'        ;Convert digit for display
  3893.     add    a,e
  3894.     call    chro        ;Write to screen
  3895.     pop    bc        ;Restore stack
  3896.     pop    de
  3897.     pop    hl
  3898.     ret
  3899.  
  3900. ; DPNL - DISPLAY PANEL
  3901.  
  3902.     $RTN    DPNL
  3903.     LD    B,(HL)
  3904.     INC    HL
  3905. DPNL01    EQU    $
  3906.     PUSH    BC
  3907.     CALL    DFLD        ;DISPLAY FIELD
  3908.     POP    BC
  3909.     DJNZ    DPNL01
  3910.     RET
  3911.  
  3912.  
  3913. ; DFLD - DISPLAY FIELD
  3914.  
  3915.     $RTN    DFLD
  3916.     PUSH    HL
  3917.     CALL    LDHL
  3918.     CALL    CURS        ;SET CURSOR POSITION
  3919.     POP    HL
  3920.     INC    HL
  3921.     INC    HL
  3922.     CALL    STRO        ;OUPUT STRING
  3923.     RET
  3924.  
  3925. ; CFLD - CLEAR FIELD
  3926.  
  3927.     $RTN    CFLD
  3928.     PUSH    HL
  3929.     CALL    LDHL
  3930.     CALL    CURS        ;SET CURSOR POSITION
  3931.     POP    HL
  3932.     INC    HL
  3933.     INC    HL
  3934.     CALL    CSTR        ;CLEAR STRING
  3935.     RET
  3936.  
  3937. ; CSTR - CLEAR STRING POINTED TO BY HL
  3938.  
  3939.     $RTN    CSTR
  3940. CSTR01    EQU    $        ;LOOP
  3941.     LD    A,(HL)        ;PICK UP FIELD CHARACTER
  3942.     OR    A
  3943.     JR    Z,CSTR02    ;EXIT IF NULL
  3944.     CALL    SPCO        ;OUTPUT BLANK
  3945.     INC    HL        ;POINT TO NEXT CHARACTER
  3946.     JR    CSTR01
  3947. CSTR02    EQU    $        ;ENDLOOP
  3948.     INC    HL
  3949.     RET
  3950.  
  3951. ; STRO - OUTPUT STRING POINTED TO BY HL AND DELIMITED BY A NULL
  3952.  
  3953.     $RTN    STRO
  3954. STRO01    EQU    $
  3955.     LD    A,(HL)
  3956.     OR    A
  3957.     JR    Z,STRO02
  3958.     CALL    CHRO
  3959.     INC    HL
  3960.     JR    STRO01
  3961. STRO02    EQU    $
  3962.     INC    HL
  3963.     RET
  3964.  
  3965. ; strl - Output length-prefixed string pointed to by HL
  3966.  
  3967.     $rtn    strl
  3968.     push    bc
  3969.     ld    b,(hl)
  3970.     inc    b
  3971. strllp:    inc    hl
  3972.     dec    b
  3973.     jr    z,strlxt
  3974.     ld    a,(hl)
  3975.     push    hl
  3976.     call    chro
  3977.     pop    hl
  3978.     jr    strllp
  3979. strlxt:    pop    bc
  3980.     ret
  3981.  
  3982. ; ASCO - OUTPUT ASCII CHARACTER OR '.' TO SCREEN
  3983. ;
  3984. ;    Modified Jan 86 by JHB to display ASCII chars with high bit
  3985. ;    set in reverse video.  The idea is to make displays of file
  3986. ;    names in directory sectors more readable.
  3987.  
  3988.     $RTN    ASCO
  3989.     push    hl
  3990.     PUSH    AF
  3991.     bit    7,a        ;Check high bit
  3992.     push    af        ;Save high bit flag
  3993.     push    af        ;Save character during video mode change
  3994.     call    nz,vmInv    ;Turn on highlight
  3995.     pop    af        ;Recover character for display
  3996.     and    7Fh        ;Mask off high bit
  3997.     ld    hl,maxASC    ;Check for graphic
  3998.     CP    (hl)
  3999.     JR    NC,ASCO01
  4000.     CP    20H
  4001.     JR    NC,ASCO02
  4002. ASCO01    EQU    $
  4003.     LD    A,'.'
  4004. ASCO02    EQU    $
  4005.     CALL    CHRO
  4006.     pop    af        ;Did we highlight?
  4007.     call    nz,vmNorm    ;If so then return to normal video
  4008.     POP    AF
  4009.     pop    hl
  4010.     RET
  4011.  
  4012.  
  4013. ; HEXO - OUTPUT BYTE IN A IN HEX TO SCREEN
  4014.  
  4015.     $RTN    HEXO
  4016.     PUSH    AF
  4017.     RRA
  4018.     RRA
  4019.     RRA
  4020.     RRA            ;REVERSE NIBBLES
  4021.     CALL    HEXC        ;PRINT HO NIBBLE
  4022.     POP    AF
  4023.     CALL    HEXC        ;PRINT LO NIBBLE
  4024.     RET
  4025.  
  4026. ;
  4027. ; HEXW - OUTPUT WORD IN HL TO SCREEN
  4028. ;
  4029.     $RTN    HEXW
  4030.     PUSH    AF
  4031.     LD    A,H
  4032.     CALL    HEXO
  4033.     LD    A,L
  4034.     CALL    HEXO
  4035.     POP    AF
  4036.     RET
  4037.  
  4038.  
  4039. ; HEXC - OUTPUT LO NIBBLE IN A IN HEX TO SCREEN
  4040.  
  4041.     $RTN    HEXC
  4042.     AND    0FH        ;LOSE HO NIBBLE
  4043.     ADD    A,90H
  4044.     DAA
  4045.     ADC    A,40H
  4046.     DAA
  4047.     CALL    CHRO        ;OUTPUT HEX CHARACTER
  4048.     RET
  4049.  
  4050. ; Video functions
  4051.  
  4052.     $rtn    vmInv        ;Inverse video
  4053.     ld    hl,vInv
  4054.     jr    vmSet
  4055.  
  4056.     $rtn    vmNorm        ;Normal video
  4057.     ld    hl,vNorm
  4058. vmSet:    call    strl
  4059.     ret
  4060.  
  4061. ;    END OF CODE
  4062.  
  4063. psBuff    equ    $        ;Physical sector I/O buffer
  4064. ENDCDE    equ    $+2048
  4065.     .list            ;Enable symbols for Z8E
  4066.     END    INIT
  4067.