home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / p2dos11.lbr / P2DOS.MZC / P2DOS.MAC
Encoding:
Text File  |  1993-10-25  |  74.1 KB  |  2,485 lines

  1.         TITLE    'P2 DISK OPERATING SYSTEM'
  2.     .Z80
  3.     ASEG
  4. ;
  5. ;******************************************************************************
  6. ;*                                          *
  7. ;*  P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 1.1          *
  8. ;*                                          *
  9. ;*  COPYRIGHT (C) 1985 BY:     H.A.J. TEN BRUGGE                  *
  10. ;*  ALL RIGHTS RESERVED         MOLENSTRAAT 33                      *
  11. ;*                  NL-7491 BD DELDEN                  *
  12. ;*                 THE NETHERLANDS                  *
  13. ;*                 TEL:..31-5407-1980                  *
  14. ;*  P2DOS WAS WRITTEN BY HERMAN TEN BRUGGE, WHO ASSUMES NO RESPONSIBILITY     *
  15. ;*  OR LIABILITY FOR ITS USE. P2DOS IS RELEASED TO THE PUBLIC DOMAIN FOR      *
  16. ;*  NON-COMMERCIAL USE ONLY.                              *
  17. ;*                                          *
  18. ;*  THE PULBLIC IS ENCOURAGED TO FREELY COPY AND USE THIS PROGRAM FOR         *
  19. ;*  NON-COMMERCIAL PURPOSES. ANY COMMERCIAL USE OF P2DOS IS PROHIBITED        *
  20. ;*  UNLESS APPROVED BY THE AUTHOR, H.A.J. TEN BRUGGE, IN WRITING.          *
  21. ;*                                          *
  22. ;*  THIS IS MOD 0.1 TO THE RELEASE VERSION OF P2DOS                  *
  23. ;*                                          *
  24. ;******************************************************************************
  25. ;
  26. RAMLOW    EQU    00000H            ; START ADDRESS MEMORY
  27. ;
  28. INCLUDE    DOS.LIB
  29. BASE    EQU    (MSIZE-7)*1024
  30. P2DOS    EQU    BASE+0800H            ; START ADDRESS P2DOS
  31. P2BIOS    EQU    P2DOS+0E00H        ; START ADDRESS P2BIOS
  32. ;
  33.     PAGE    84            ; 84 LINES/PAGE
  34. ;
  35. ;  P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 1.1
  36. ;
  37. ;
  38. ;
  39. ; NEW FEATURES OF P2DOS ARE:
  40. ;  - TEST CONSOLE STATUS AFTER 256 CHARACTERS OUTPUT. THIS MAKES IT POSSIBLE TO
  41. ;    EXIT A PROGRAM, AFTER YOU HIT ACCIDENTALY A KEY, BY TYPING ^S FOLLOWED BY ^C.  
  42. ;  - ERROR ROUTINES GIVE MORE INFORMATION.
  43. ;      P2DOS ERROR ON D: BAD SECTOR
  44. ;             SELECT
  45. ;             FILE R/O
  46. ;             R/O
  47. ;      FUNCTION =XXX (FILE =FILENAME.TYP)
  48. ;    AS YOU CAN SEE THE ERROR IS DISPLAYED WITH THE P2DOS FUNCTION CALL.
  49. ;    THE OPTION 'FILE =FILENAME.TYP' IS ONLY DISPLAYED IF THE P2DOS FUNCTION
  50. ;    USES A FILENAME. AFTER ALL ERRORS A WARM BOOT IS DONE.
  51. ;  - PUBLIC FILES ARE SUPPORTED. YOU CAN ACCESS A PUBLIC FILE FROM ANY USER NUMBER.
  52. ;    THIS MAKES IT POSSIBLE TO PUT FOR EXAMPLE ALL '.COM' IN A SPECIAL USER NUMBER
  53. ;    AND MAKE ALL THOSE FILES PUBLIC. YOU CAN ACCESS ALL THE FILES FROM ANY USER
  54. ;    USER NUMBER ON THE SAME DISK. 
  55. ;    A PUBLIC FILE IS A FILE WITH BIT F2 (BIT 7 FROM FILENAME LETTER 2) SET TO ONE.
  56. ;    PUBLIC FILES CAN ONLY BE REFERENCED BY THERE EXACT NAME AND NOT BY WILD CARD
  57. ;    CHARACTERS. 
  58. ;  - SEARCH PATH IS IMPLEMENTED JUST AS IN ZCPR2 TO FIND FILES ON OTHER DRIVES AND
  59. ;    IN OTHER USER AREAS. THE FILES MUST BE SYSTEM FILES AND MUST BE REFERENCED
  60. ;    BY THERE EXACT NAME AS IN PUBLIC FILE NAMES ABOVE.
  61. ;  - AUTOMATIC DATE AND TIME STAMP IS IMPLEMENTED. THE CREATION DATE AND TIME IS
  62. ;    SET WHEN THE FUNCTION MAKE IS EXECUTED. THE UPDATE DATE AND TIME IS SET AS
  63. ;    THE FILE IS CLOSED. TO LET THIS FEATURE WORK YOU NEED TO HAVE A REAL TIME
  64. ;    CLOCK AND THE CORRECT P2BIOS DRIVER ROUTINE. YOU ALSO HAVE TO INITIALISE YOUR
  65. ;    DIRECTORY FOR TIME STAMPS.   
  66. ;  - FILE R/O ERROR MESSAGE OCCURS IF ONE OF THE FOLLOWING FILE TYPES IS ACTIVE:
  67. ;     PUBLIC FILE (F2)
  68. ;     FILE R/O    (T1)
  69. ;     SYSTEM FILE (T2)
  70. ;    THIS MEANS THAT A SYSTEM FILE OR PUBLIC FILE CANNOT BE ERASED ACCIDENTALY.
  71. ;  - NEW FUNCTION GET TIME (200) IS IMPLEMENTED TO GET THE CORRECT DATE AND TIME.
  72. ;    ENTRY DE IS ADDRESS TO PUT TIME. THE DATE AND TIME RECORD HAS THE FOLLOWING
  73. ;    LAYOUT:
  74. ;    DATE:    DEFS    2    DATE = 1     (SU 01-JAN-1978)
  75. ;                DATE = 65535 (SU 05-JUN-2157)     
  76. ;    HOUR:    DEFS    1    HOUR IN BCD
  77. ;    MINUTE:    DEFS    1    MINUTE IN BCD
  78. ;    SECOND:    DEFS    1    SECOND IN BCD
  79. ;    FUNCTION WORKS ONLY IF CORRECT P2BIOS FUNCTION CALL IS INSTALLED.
  80. ;  - NEW FUNCTION SET TIME (201) IS IMPLEMENTED TO SET THE CORRECT DATE AND TIME.
  81. ;    ENTRY DE IS ADDRESS NEW TIME. THE DATE AND TIME LAYOUT IS AS ABOVE.
  82. ;    FUNCTION WORKS ONLY IF CORRECT P2BIOS FUNCTION CALL IS INSTALLED.
  83. ;  - DISK SIZE CAN BE AS LARGE AS 65536*16K=1 048 576 K BYTE=1 G BYTE. 
  84. ;  - FILE SIZE CAN BE AS LARGE AS 32*64*16K=32 768K BYTE=32 M BYTE.  
  85. ;
  86. ;
  87. ; YOU CAN ENABLE/DISABLE THE FUNCTIONS MENTIONED ABOVE WITH THE FOLLOWING DATA AND
  88. ; ADDRESSES.
  89. ;  - ENABLE PATH NAME BY PUTTING ADDRESS OF PATH IN P2DOS+11H. IF THIS VALUE IS 0000H
  90. ;    NO PATH IS USED. THIS ADDRESS IS NORMALLY SET TO 0040H.
  91. ;  - ENABLE P2DOS TIME AND DATE STAMPING BY PUTTING THE CORRECT P2BIOS ADDRESS AT
  92. ;    P2DOS+13H. THIS ADDRESS IS NORMALY SET TO THE P2BIOS CONSOLE STATUS FUNCTION. 
  93. ;  - YOU CAN ENABLE THE 256 CHARACTER DELAY FUNCTION BY SETTING BIT 0 OF ADDRESS
  94. ;    P2DOS+15H. THIS BIT IS NORMALLY SET TO 1.
  95. ;  - YOU CAN ENABLE PUBLIC FILES BY SETTING BIT 1 OF ADDRESS P2DOS+15H TO 1. THIS
  96. ;    BIT IS NORMALLY SET TO 1.
  97. ;
  98. ;
  99. ;
  100. ; ENTRY ADDRESSES P2BIOS
  101. ;
  102. ; FUNC    NAME    INPUT PARAMETERS    RETURNED VALUES
  103. ;  0    BOOT    NONE            NONE
  104. ;  1    WBOOT    NONE            NONE
  105. ;  2    CONST    NONE            A=0FFH IF READY
  106. ;                    A=000H IF NOT READY
  107. ;  3    CONIN    NONE            A=CONSOLE CHARACTER
  108. ;  4    CONOUT    C=CONSOLE CHARACTER    NONE
  109. ;  5    LIST    C=LIST CHARACTER    NONE
  110. ;  6    PUNCH    C=PUNCH CHARACTER    NONE
  111. ;  7    READER    NONE            A=READER CHARACTER
  112. ;  8    HOME    NONE            NONE
  113. ;  9    SELDSK    C=DRIVE NUMBER (0..15)    HL=DISK PARAMETER HEADER ADDRESS
  114. ;        E=INIT SELECT FLAG    HL=0000H IF INVALID DRIVE
  115. ; 10    SETTRK    BC=TRACK NUMBER        NONE
  116. ; 11    SETSEC    BC=SECTOR NUMBER    NONE
  117. ; 12    SETDMA    BC=DMA ADDRESS        NONE
  118. ; 13    READ    NONE            A=00H IF NO ERROR
  119. ;                    A=01H IF ERROR
  120. ; 14    WRITE    C=0 WRITE DATA        A=00H IF NO ERROR
  121. ;        C=1 WRITE DIRECTORY    A=01H IF ERROR
  122. ;        C=2 WRITE NEW DATA
  123. ; 15    LISTST    NONE            A=000H IF READY
  124. ;                    A=0FFH IF NOT READY
  125. ; 16    SECTRN    BC=LOGICAL SECTOR    HL=PHYSICAL SECTOR NUMBER
  126. ;            NUMBER
  127. ;        DE=TRANSLATION TABEL
  128. ;            ADDRESS
  129. ; XX    TIME    C=000H GET TIME        HL=POINTER TO TIME TABLE
  130. ;        C=0FFH UPDATE CLOCK        HL+0:DATE LSB SINCE 1,1,1978
  131. ;        HL=POINTER TO TIME        HL+1:DATE MSB
  132. ;            TABLE            HL+2:HOURS  (BCD)
  133. ;                        HL+3:MINUTES (BCD)
  134. ;                        HL+4:SECONDS (BCD)
  135. ;
  136. BOOT    EQU    P2BIOS+00000H        ; P2 SYSTEM COLD BOOT
  137. WBOOT    EQU    P2BIOS+00003H        ; P2 SYSTEM WARM BOOT
  138. CONST    EQU    P2BIOS+00006H        ; P2 SYSTEM CONSOLE STATUS
  139. CONIN    EQU    P2BIOS+00009H        ; P2 SYSTEM CONSOLE INPUT
  140. CONOUT    EQU    P2BIOS+0000CH        ; P2 SYSTEM CONSOLE OUTPUT
  141. LIST    EQU    P2BIOS+0000FH        ; P2 SYSTEM LIST OUTPUT
  142. PUNCH    EQU    P2BIOS+00012H        ; P2 SYSTEM PUNCH OUTPUT
  143. READER    EQU    P2BIOS+00015H        ; P2 SYSTEM READER INPUT
  144. HOME    EQU    P2BIOS+00018H        ; P2 SYSTEM HOME DISK
  145. SELDSK    EQU    P2BIOS+0001BH        ; P2 SYSTEM SELECT DISK
  146. SETTRK    EQU    P2BIOS+0001EH        ; P2 SYSTEM SELECT TRACK
  147. SETSEC    EQU    P2BIOS+00021H        ; P2 SYSTEM SELECT SECTOR
  148. SETDMA    EQU    P2BIOS+00024H        ; P2 SYSTEM SET DMA ADDRESS
  149. READ    EQU    P2BIOS+00027H        ; P2 SYSTEM READ 128 BYTES
  150. WRITE    EQU    P2BIOS+0002AH        ; P2 SYSTEM WRITE 128 BYTES
  151. LISTST    EQU    P2BIOS+0002DH        ; P2 SYSTEM LIST STATUS
  152. SECTRN    EQU    P2BIOS+00030H        ; P2 SYSTEM SECTOR TRANSLATION
  153. TIME    EQU    P2BIOS+00006H        ; P2 SYSTEM GET/SET TIME
  154.                     ; MUST BE CHANGED IF ROUTINE PRESENT
  155. ;
  156. ; INTERNAL DEFINITIONS
  157. ;
  158. CONTC    EQU    003H            ; KEY TO GENERATE WARM BOOT
  159. CONTE    EQU    005H            ; BREAK LINE
  160. CONTH    EQU    008H            ; BACKSPACE
  161. TAB    EQU    009H            ; TAB
  162. LF    EQU    00AH            ; LINE FEED
  163. CR    EQU    00DH            ; CARRIAGE RETURN
  164. CONTP    EQU    010H            ; SET/RESET PRINT FLAG
  165. CONTR    EQU    012H            ; REPEAT LINE
  166. CONTS    EQU    013H            ; STOP CONSOLE OUTPUT
  167. CONTU    EQU    015H            ; DELETE LINE
  168. CONTX    EQU    018H            ; DELETE LINE (BACKSPACES)
  169. DRVSEP    EQU    03AH            ; DRIVE SEPERATOR (:)
  170. RUBOUT    EQU    07FH            ; DELETE LAST CHAR
  171. ;
  172. MAXCMD    EQU    40            ; NUMBER OF VALID P2DOS COMMANDS
  173. ;
  174.     ORG    0100H
  175.     .PHASE    P2DOS
  176. ; START PROGRAM
  177. ;
  178. VERS:    DEFB    000H            ; VERSION NUMBER NOT IMPLEMENTED
  179.     DEFB    000H
  180.     DEFB    000H
  181.     DEFB    000H
  182.     DEFB    000H
  183.     DEFB    000H
  184. ;
  185. ; START P2DOS
  186. ;
  187. START:    JP    ENTRY            ; JUMP TO ENTRY POINT P2DOS
  188. ;
  189. ; ERROR MESSAGES P2DOS
  190. ;
  191. STBDSC:    DEFW    BADSEC            ; BAD SECTOR MESSAGE
  192. STSEL:    DEFW    SELERR            ; SELECT ERROR
  193. STRO:    DEFW    RDONLY            ; DRIVE READ ONLY
  194. SFILRO:    DEFW    FILRO            ; FILE READ ONLY
  195. ;
  196. ; EXTERNAL PATH NAME
  197. ;
  198. PATH:    DEFW    RAMLOW+00040H        ; PATHNAME FOR OPEN FILE COMMAND
  199. ;
  200. ; TIME ADDRESS P2BIOS
  201. ;
  202. TIMEAD:    DEFW    TIME            ; TIME ROUTINE ADDRESS FOR TIME
  203.                     ; AND DATE STAMPS
  204. ;
  205. ; FLAGS FOR SPECIALS
  206. ; BIT 0: PUBLIC FILE ENABLE(1)/DISABLE(0)
  207. ; BIT 1: DELAY 256 CHARACTERS ACTIVE(1)/DISABLE(0)
  208. ;
  209. FLAGS:    DEFB    0FFH            ; FLAG BITE
  210. ;
  211. ; ENTRY POINT P2DOS COMMANDS
  212. ;
  213. ENTRY:    LD    A,C            ; GET FUNCTION NUMBER
  214.     LD    (FUNCT),A        ; SAVE IT FOR LATER USE
  215.     LD    HL,0            ; SET HL TO ZERO
  216.     LD    (PEXIT),HL        ; CLEAR EXIT CODE
  217.     XOR    A            ; CLEAR A
  218.     LD    (FLDRV),A        ; RESET DRIVE SELECT DONE FLAG
  219.     LD    (RDWR),A        ; RESET READ/WRITE FLAG
  220.     LD    (SPSAVE),SP        ; SAVE STACK POINTER
  221.     LD    SP,P2DOSS        ; GET INTERNAL STACK POINTER
  222.     PUSH    IX            ; SAVE INDEX REGISTER
  223.     PUSH    DE            ; SAVE PARAMETER REGISTER
  224.     POP    IX            ; GET IT BACK IN IX
  225.     LD    HL,P2EXIT        ; GET EXIT ADDRESS P2DOS
  226.     PUSH    HL            ; SAVE IT ON STACK TO RETURN FROM P2DOS
  227.     LD    A,C            ; GET FUNCTION CODE
  228.     CP    200            ; TEST GET TIME
  229.     JP    Z,GETTIM        ; YES THEN GET TIME
  230.     CP    201            ; TEST SET TIME
  231.     JP    Z,SETTIM        ; YES THEN SET TIME
  232.     CP    MAXCMD+1        ; TEST GREATER THEN MAXCMD 
  233.     RET    NC            ; IF SO RETURN TO CALLER AND DO NOTHING
  234.     LD    HL,CTABLE        ; LOAD TABLE
  235.     LD    B,0            ; PREPARE 16 BIT ADD
  236.     ADD    HL,BC            ; ADD
  237.     ADD    HL,BC            ; ADD TWICE TO GET WORD VALUE
  238.     LD    A,(HL)            ; GET LSB
  239.     INC    HL            ; POINTER TO MSB
  240.     LD    H,(HL)            ; GET MSB
  241.     LD    L,A            ; SAVE LSB IN L 
  242.     JP    (HL)            ; JUMP TO ROUTINE
  243. ;
  244. ; COMMAND TABLE
  245. ;
  246. ;
  247. ; FUNC    NAME            INPUT PARAMETERS    RETURNED VALUES
  248. ;   0    BOOT            NONE            NONE
  249. ;   1    CONSOLE INPUT        NONE            A=CHARACTER
  250. ;   2    CONSOLE OUTPUT        E=CHARACTER        A=00H
  251. ;   3    READER INPUT        NONE            A=CHARACTER
  252. ;   4    PUNCH OUTPUT        E=CHARACTER        A=00H
  253. ;   5    LIST OUTPUT        E=CHARACTER        A=00H
  254. ;   6    DIRECT CONSOLE I/O    E=0FFH            A=INPUT CHARACTER
  255. ;                            A=00H IF NO CHARACTER PRESENT
  256. ;                E=0FEH            A=CONSOLE STATUS
  257. ;                E=000H..0FDH        A=00H
  258. ;   7    GET I/O BYTE        NONE            A=I/O BYTE (RAMLOW+03H)
  259. ;   8    SET I/O BYTE        E=I/O BYTE        A=00H
  260. ;   9    PRINT STRING        DE=ADDRESS STRING    A=00H
  261. ;  10    READ CONSOLE BUFFER    DE=ADDRESS BUFFER    A=00H
  262. ;  11    GET CONSOLE STATUS    NONE            A=00H IF NO CHARACTER PRESENT
  263. ;                            A=01H IF CHARACTER PRESENT
  264. ;  12    RETURN VERSION NUMBER    NONE            A=VERSION NUMBER (022H)
  265. ;  13    RESET DISK SYSTEM    NONE            A=00H NO $*.* FILE
  266. ;                            A=FFH $*.* FILE PRESENT
  267. ;  14    SELECT DISK        E=DISK NUMBER        A=00H
  268. ;  15    OPEN FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  269. ;  16    CLOSE FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  270. ;  17    SEARCH FOR FIRST    DE=ADDRESS FCB        A=DIRECTORY CODE
  271. ;  18    SEARCH FOR NEXT        DE=ADDRESS FCB        A=DIRECTORY CODE
  272. ;  19    DELETE FILE        DE=ADDRESS FCB        A=ERROR CODE
  273. ;  20    READ SEQUENTIAL        DE=ADDRESS FCB        A=READ/WRITE CODE
  274. ;  21    WRITE SEQUENTIAL    DE=ADDRESS FCB        A=READ/WRITE CODE
  275. ;  22    MAKE FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  276. ;  23    RENAME FILE        DE=ADDRESS FCB        A=ERROR CODE
  277. ;  24    RETURN LOGIN VECTOR    NONE            HL=LOGIN VECTOR
  278. ;  25    RETURN CURRENT DISK    NONE            A=CURRENT DISK
  279. ;  26    SET DMA ADDRESS        DE=DMA ADDRESS        A=00H
  280. ;  27    GET ALLOCATION ADDRESS    NONE            HL=ADDRESS ALLOCATION VECTOR
  281. ;  28    WRITE PROTECT DISK    NONE            A=00H
  282. ;  29    GET R/O VECTOR        NONE            HL=R/O VECTOR
  283. ;  30    SET FILE ATTRIBUTES    DE=ADDRESS FCB        A=ERROR CODE
  284. ;  31    GET ADDRESS DPB        NONE            HL=ADDRESS DPB
  285. ;  32    SET/GET USER CODE    E=0FFH            A=USER NUMBER
  286. ;                E=USER NUMBER        A=00H
  287. ;  33    READ RANDOM        DE=ADDRESS FCB        A=READ/WRITE CODE
  288. ;  34    WRITE RANDOM        DE=ADDRESS FCB        A=READ/WRITE CODE
  289. ;  35    COMPUTE FILE SIZE    DE=ADDRESS FCB        A=ERROR CODE
  290. ;  36    SET RANDOM RECORD    DE=ADDRESS FCB        A=00H
  291. ;  37    RESET MULTIPLE DRIVE    DE=MASK            A=00H
  292. ;  38    NOT IMPLEMENTED        NONE            A=00H
  293. ;  39    NOT IMPLEMENTED        NONE            A=00H
  294. ;  40    WRITE RANDOM WITH    DE=ADDRESS FCB        A=READ/WRITE CODE
  295. ;     ZERO FILL
  296. ; 200    GET TIME        DE=ADDRESS TO PUT TIME    A=00H
  297. ; 201    SET TIME        DE=ADDRESS TIME        A=00H
  298. ;
  299. ; DIRECTORY CODE : A=00H,01H,02H,03H IF NO ERROR
  300. ;                  A=0FFH IF ERROR
  301. ; ERROR CODE     : A=00H IF NO ERROR
  302. ;                  A=0FFH IF ERROR
  303. ; READ/WRITE CODE: A=00H IF NO ERROR
  304. ;           A=01H READ  => END OF FILE
  305. ;             WRITE => DIRECTORY FULL
  306. ;           A=02H DISK FULL
  307. ;
  308. CTABLE:    DEFW    WBOOT            ; WARM BOOT 
  309.     DEFW    RDCON            ; CONSOLE INPUT
  310.     DEFW    BWRCON            ; CONSOLE OUTPUT
  311.     DEFW    RDRDR            ; READER INPUT
  312.     DEFW    WPUNCH            ; PUNCH OUTPUT
  313.     DEFW    WLIST            ; LIST OUTPUT
  314.     DEFW    DCIO            ; DIRECT CONSOLE I/O
  315.     DEFW    GIOST            ; GET I/O BYTE
  316.     DEFW    SIOST            ; SET I/O BYTE
  317.     DEFW    MESS            ; PRINT STRING
  318.     DEFW    RDBUF            ; READ CONSOLE BUFFER
  319.     DEFW    TSTCS            ; GET CONSOLE STATUS
  320.     DEFW    CMND12            ; RETURN VERSION NUMBER
  321.     DEFW    CMND13            ; RESET DISK SYSTEM
  322.     DEFW    CMND14            ; SELECT DISK
  323.     DEFW    CMND15            ; OPEN FILE
  324.     DEFW    CMND16            ; CLOSE FILE
  325.     DEFW    CMND17            ; SEARCH FOR FIRST
  326.     DEFW    CMND18            ; SEARCH FOR NEXT
  327.     DEFW    CMND19            ; DELETE FILE
  328.     DEFW    CMND20            ; READ SEQUENTIAL
  329.     DEFW    CMND21            ; WRITE SEQUENTIAL
  330.     DEFW    CMND22            ; MAKE FILE
  331.     DEFW    CMND23            ; RENAME FILE
  332.     DEFW    CMND24            ; RETURN LOGIN VECTOR
  333.     DEFW    CMND25            ; RETURN CURRENT DISK
  334.     DEFW    CMND26            ; SET DMA ADDRESS
  335.     DEFW    CMND27            ; GET ADDRESS ALLOCATION VECTOR
  336.     DEFW    CMND28            ; WRITE PROTECT DISK
  337.     DEFW    CMND29            ; GET R/O VECTOR
  338.     DEFW    CMND30            ; SET FILE ATTRIBUTES
  339.     DEFW    CMND31            ; GET ADDRESS DISK PARAMETER HEADER(DPH) 
  340.     DEFW    CMND32            ; GET/SET USER CODE
  341.     DEFW    CMND33            ; READ RANDOM
  342.     DEFW    CMND34            ; WRITE RANDOM
  343.     DEFW    CMND35            ; COMPUTE FILE SIZE
  344.     DEFW    CMND36            ; SET RANDOM RECORD
  345.     DEFW    CMND37            ; RESET MULTIPLE DRIVE
  346.     DEFW    DUMMY            ; NOT IMPLEMENTED 
  347.     DEFW    DUMMY            ; NOT IMPLEMENTED 
  348.     DEFW    CMND40            ; WRITE RANDOM WITH ZERO FILL
  349. ;
  350. ; I/O ROUTINES
  351. ;
  352. ; P2DOS CONSOLE INPUT
  353. ;
  354. ; READ CHARACTER FROM CONSOLE AND ECHO
  355. ;  IF CHAR=CR,LF,TAB,CONTH OR >=SPACE
  356. ;
  357. RDCON:    CALL    GETCH            ; GET CHARACTER
  358.     CALL    TSTCH            ; TEST IF CR,LF,TAB,CONTH OR >=SPACE
  359.     JR    C,EXIT            ; NO THEN EXIT
  360.     CALL    WRCON            ; ECHO CHARACTER
  361. EXIT:    LD    (PEXIT),A        ; RETURN CHARACTER 
  362. DUMMY:    RET                ; AND EXIT P2DOS
  363. ;
  364. ; P2DOS WRITE CONSOLE
  365. ;
  366. BWRCON:    LD    A,E            ; COPY CHARAKTER
  367.     JR    WRCON            ; AND OUTPUT IT
  368. ;
  369. ; READ READER
  370. ;
  371. RDRDR:    CALL    READER            ; GET CHARACTER FROM READER
  372.     JR    EXIT            ; AND RETURN IT TO CALLER 
  373. ;
  374. ; WRITE PUNCH
  375. ;
  376. WPUNCH:    LD    C,E            ; COPY CHARACTER
  377.     JP    PUNCH            ; AND OUTPUT IT TO PUNCH DEVICE
  378. ;
  379. ; WRITE LIST
  380. ;
  381. WLIST:    LD    C,E            ; COPY CHARACTER
  382.     JP    LIST            ; AND OUTPUT IT TO LIST DEVICE
  383. ;
  384. ; DIRECT CONSOLE INPUT/OUTPUT
  385. ;
  386. DCIO:    LD    C,E            ; COPY CHARACTER
  387.     INC    E            ; TEST IF 0FFH
  388.     JR    Z,DCIO0            ; YES DO INPUT
  389.     INC    E            ; TEST IF 0FEH
  390.     JP    NZ,CONOUT        ; NO THEN OUTPUT CHARACTER
  391.     CALL    CONST            ; GET CONSOLE STATUS
  392.     JR    EXIT            ; AND RETURN IT TO CALLER
  393. DCIO0:    CALL    CONST            ; GET CONSOLE STATUS
  394.     OR    A            ; TEST IT
  395.     RET    Z            ; EXIT IF NO CHARACTER PRESENT
  396.     CALL    CONIN            ; GET CHARACTER
  397.     JR    EXIT            ; AND RETURN IT TO CALLER
  398. ;
  399. ; GET I/O STATUS BYTE
  400. ;
  401. GIOST:    LD    A,(RAMLOW+00003H)    ; GET I/O BYTE FROM RAM
  402.     JR    EXIT            ; AND RETURN IT TO CALLER
  403. ;
  404. ; SET I/O STATUS BYTE
  405. ;
  406. SIOST:    LD    A,E            ; COPY I/O BYTE
  407.     LD    (RAMLOW+00003H),A    ; AND SAVE IT IN RAM
  408.     RET                ; EXIT TO CALLER
  409. ;
  410. ; TEST CONSOLE STATUS
  411. ;
  412. TSTCS:    CALL    GCONST            ; GET CONSOLE STATUS
  413.     JR    EXIT            ; AND RETURN IT TO CALLER
  414. ;
  415. ; OUTPUT CHAR (CONTROL CHAR = ^CHAR)
  416. ;
  417. OUTCH:    CALL    TSTCH            ; TEST IT CR,LF,TAB,CONTH OR >=SPACE
  418.     JR    NC,WRCON        ; YES THEN JUMP
  419.     PUSH    AF            ; SAVE CHARACTER
  420.     LD    A,'^'            ; LOAD A WITH '^' 
  421.     CALL    WRCON            ; OUTPUT IT
  422.     POP    AF            ; GET CHARACTER BACK
  423.     PUSH    AF            ; SAVE IT AGAIN
  424.     ADD    A,'A'-1            ; ADD OFFSET
  425.     CALL    WRCON            ; OUTPUT IT
  426.     POP    AF            ; GET CHARACTER
  427.     RET                ; RETURN TO CALLER
  428. ;
  429. ; ECHO CR,LF
  430. ;
  431. CROUT:    LD    A,CR            ; A=CARRIAGE RETURN
  432.     CALL    WRCON            ; OUTPUT IT
  433.     LD    A,LF            ; A=LINE FEED
  434.                     ; FALL THROUGH TO OUTPUT ROUTINE
  435. ;
  436. ; WRITE CHARACTER ON CONSOLE
  437. ;
  438. WRCON:    CP    TAB            ; TEST IF TAB
  439.     JR    NZ,WRCON1        ; NO THEN JUMP
  440. WRCON0:    LD    A,' '            ; EXPAND TAB WITH SPACES
  441.     CALL    WRCON            ; WRITE SPACE
  442.     LD    A,(TABCNT)        ; GET TAB COUNT
  443.     AND    7            ; TEST IF DONE
  444.     JR    NZ,WRCON0        ; NO THEN REPEAT
  445.     LD    A,TAB            ; RETURN TAB
  446.     RET                ; RETURN TO CALLER
  447. WRCON1:    PUSH    AF            ; SAVE CHARACTER
  448.     CALL    GCONST            ; TEST STATUS AND CONTS/CONTC
  449.     POP    AF            ; GET CHARACTER BACK
  450.     PUSH    AF            ; SAVE IT AGAIN
  451.     LD    C,A            ; COPY IT
  452.     CALL    CONOUT            ; OUTPUT IT
  453.     POP    AF            ; GET CHARACTER BACK
  454.     PUSH    AF            ; SAVE IT AGAIN
  455.     LD    C,A            ; COPY IT
  456.     LD    A,(FCONTP)        ; GET PRINTER ECHO FLAG 
  457.     OR    A            ; TEST IT
  458.     CALL    NZ,LIST            ; NON ZERO => OUTPUT CHAR TO PRINTER
  459.     LD    A,(FLAGS)        ; GET FLAG BYTE
  460.     BIT    1,A            ; TEST DELAY 256 BYTES ACTIVE
  461.     JR    Z,WRCON2        ; NO THEN EXIT
  462.     LD    HL,DELAY        ; GET DELAY COUNTER
  463.     XOR    A            ; A=0 
  464.     OR    (HL)            ; TEST COUNTER=0
  465.     JR    Z,WRCON2        ; YES THEN EXIT
  466.     DEC    (HL)            ; ELSE DECREMENT COUNTER
  467. WRCON2:    POP    AF            ; RESTORE CHARACTER
  468.                     ; FALL THROUGH TO COUNT ROUTINE
  469. ;
  470. ; COUNT CHARAKTERS IN LINE
  471. ;
  472. COUNTC:    LD    HL,TABCNT        ; GET POINTER TO TAB COUNTER
  473.     CP    RUBOUT            ; TEST IF CHARACTER = RUBOUT
  474.     RET    Z            ; YES NO UPDATE TAB COUNTER
  475.     INC    (HL)            ; INCREMENT TAB COUNTER
  476.     CP    ' '            ; TEST IF CHAR >= ' '
  477.     RET    NC            ; YES, NORMAL CHARACTER THEN EXIT
  478.     DEC    (HL)            ; CONTROL CHARACTER, DECREMENT TAB COUNT
  479.     CP    CONTH            ; TEST BACKSPACE
  480.     JR    NZ,COUNT0        ; NO BACKSPACE THEN JUMP
  481.     DEC    (HL)            ; DECREMENT TAB COUNTER
  482.     RET                ; AND EXIT
  483. COUNT0:    CP    CR            ; TEST CARRIAGE RETURN
  484.     JR    NZ,COUNT1        ; NO THEN JUMP
  485.     LD    (HL),0            ; RESET TAB COUNT
  486.     RET                ; AND EXIT
  487. COUNT1:    CP    TAB            ; TEST TAB CHARACTER
  488.     RET    NZ            ; NO THEN EXIT
  489.     PUSH    AF            ; SAVE CHARACTER
  490.     LD    A,(HL)            ; GET TAB COUNT
  491.     ADD    A,8            ; ADVANCE IT 8 POSITION
  492.     AND    0F8H            ; SET IT TO NEXT TAB POSITION
  493.     LD    (HL),A            ; SAVE IT
  494.     POP    AF            ; RESTORE CHARACTER 
  495.     RET                ; AND EXIT
  496. ;
  497. ; GET CHARAKTER FROM CONSOLE
  498. ;
  499. GETCH:    LD    HL,LASTCH        ; GET POINTER TO LAST INPUT CHARACTER
  500.     LD    A,(HL)            ; GET CHARACTER
  501.     LD    (HL),0            ; RESET LAST CHARACTER
  502.     OR    A            ; TEST IF CHARACTER PRESENT
  503.     RET    NZ            ; RETURN IF SO
  504.     JP    CONIN            ; ELSE GET CHARACTER
  505. ;
  506. ; GET CONSOLE STATUS
  507. ;
  508. GCONST:    LD    A,(DELAY)        ; GET 256 BYTES DELAY
  509.     OR    A            ; TEST IT
  510.     JR    NZ,GCONS0        ; NON ZERO, DELAY STIL ACTIVE OR DISABLED
  511.     CALL    CONST            ; GET CONSOLE STATUS
  512.     AND    1            ; TEST IT
  513.     JR    NZ,GCONS1        ; NON ZERO THEN GET CHARACTER
  514. GCONS0:    LD    A,(LASTCH)        ; GET LAST CHARACTER
  515.     OR    A            ; TEST IT
  516.     JR    NZ,GCONS3        ; NON ZERO THEN CHARACTER PRESENT
  517.     CALL    CONST            ; GET CONSOLE STATUS
  518.     AND    1            ; TEST IT
  519.     RET    Z            ; RETURN IF NO CHARACTER PRESENT
  520. GCONS1:    CALL    CONIN            ; GET CHARACTER
  521.     CP    CONTS            ; TEST STOP CHARACTER
  522.     JR    NZ,GCONS2        ; NOT THEN EXIT CHARACTER
  523.     CALL    CONIN            ; GET NEXT CHARACTER
  524.     CP    CONTC            ; TEST IF USER WANTS TO EXIT
  525.     JP    Z,RAMLOW+00000H        ; YES THEN WARM BOOT
  526.     JR    GCONST            ; TEST AGAIN
  527. GCONS2:    LD    (LASTCH),A        ; SAVE CHARACTER
  528.     LD    A,0FFH            ; SET DELAY COUNTER
  529.     LD    (DELAY),A        ; AND SAVE IT
  530. GCONS3:    LD    A,1            ; CHARACTER PRESENT CODE
  531.     RET                ; RETURN TO CALLER
  532. ;
  533. ; TEST CHARACTER
  534. ;  EXIT CARRY=0: CR,LF,TAB,CONTH OR >=SPACE
  535. ;       CARRY=1: ALL OTHER CHARACTERS
  536. ;
  537. TSTCH:    CP    CR            ; TEST CARRIAGE RETURN
  538.     RET    Z            ; RETURN IF SO
  539.     CP    LF            ; TEST LINE FEED
  540.     RET    Z            ; RETURN IF SO
  541.     CP    TAB            ; TEST TAB
  542.     RET    Z            ; RETURN IF SO
  543.     CP    CONTH            ; TEST BACKSPACE
  544.     RET    Z            ; RETURN IF SO
  545.     CP    ' '            ; TEST >=SPACE
  546.     RET                ; RETURN TO CALLER
  547. ;
  548. ; WRITE BACKSPACE,SPACE,BACKCPACE
  549. ;
  550. WCONTH:    CALL    WCONT0            ; WRITE BACKSPACE
  551.     LD    C,' '            ; LOAD SPACE
  552.     CALL    CONOUT            ; AND OUTPUT IT
  553. WCONT0:    LD    C,CONTH            ; LOAD BACKSPACE
  554.     JP    CONOUT            ; AND OUTPUT IT
  555. ;
  556. ; OUTPUT MESSAGE
  557. ;
  558. MESS:    LD    A,(DE)            ; GET BYTE FROM BUFFER
  559.     CP    '$'            ; TEST LAST BYTE
  560.     RET    Z            ; YES, THEN RETURN TO CALLER
  561.     INC    DE            ; POINT TO NEXT BYTE
  562.     PUSH    DE            ; SAVE POINTER
  563.     CALL    WRCON            ; OUTPUT CHARACTER
  564.     POP    DE            ; RESTORE POINTER
  565.     JR    MESS            ; AND TEST AGAIN
  566. ;
  567. ; AGAIN PRINTS #,CR,LF AND ADVANCES TO TABCX1
  568. ;
  569. AGAIN:    LD    A,'#'            ; LOAD '#'
  570.     CALL    WRCON            ; OUTPUT IT
  571. AGAIN0:    CALL    CROUT            ; OUTPUT CARRIAGE RETURN/LINE FEED
  572. AGAIN1:    LD    HL,TABCNT        ; GET TAB COUNT POINTER
  573.     LD    A,(TABCX1)        ; GET POSITION FIRST CHARACTER LINE
  574.     CP    (HL)            ; CHECK IT
  575.     RET    Z            ; RETURN IF ON SAME POSITION
  576.     LD    A,' '            ; LOAD SPACE
  577.     CALL    WRCON            ; OUTPUT IT
  578.     JR    AGAIN1            ; AND TEST AGAIN
  579. ;
  580. ; DELETE CHAR
  581. ;  ENTRY : HL=START BUFFER-1
  582. ;          B =CHARACTER COUNTER (ALWAYS>0)
  583. ;
  584. DELCH:    DEC    B            ; DECREMENT CHARACTER COUNTER
  585.     LD    A,(TABCNT)        ; GET TAB COUNTER
  586.     PUSH    AF            ; SAVE IT
  587.     PUSH    BC            ; SAVE CHARACTER COUNTER
  588.     LD    A,(TABCX1)        ; GET POSITION FIRST CHARACTER LINE
  589.     LD    (TABCNT),A        ; SAVE IT IN TAB COUNTER
  590. DELCH0:    LD    A,B            ; COPY CHARACTER COUNTER
  591.     OR    A            ; TEST IF 0
  592.     JR    Z,DELCH2        ; YES THEN JUMP
  593.     DEC    B            ; DECREMENT IT
  594.     INC    HL            ; INCREMENT BUFFER POINTER
  595.     LD    A,(HL)            ; GET CHARACTER FROM BUFFER
  596.     PUSH    HL            ; SAVE BUFFER POINTER
  597.     CALL    TSTCH            ; TEST IF CR,LF,TAB,CONTH OR >=SP
  598.     JR    NC,DELCH1        ; YES THEN JUMP
  599.     RRA                ; ELSE MUST BE CONTROL CHARACTER
  600.     CALL    COUNTC            ; COUNT CONTROL CHARACTER TWICE
  601. DELCH1:    CALL    COUNTC            ; COUNT CHARACTER
  602.     POP    HL            ; GET BUFFER POINTER
  603.     JR    DELCH0            ; AND TEST AGAIN
  604. DELCH2:    POP    BC            ; RESTORE CHARACTER COUNTER
  605.     POP    AF            ; AND TAB COUNTER
  606.     PUSH    HL            ; SAVE BUFFER POINTER
  607.     PUSH    BC            ; AND CHARACTER COUNTER
  608.     LD    HL,TABCNT        ; GET TAB COUNTER POINTER
  609.     SUB    (HL)            ; CALCULATE DIFFERENCE
  610. DELCH3:    DEC    A            ; DECREMENT IT
  611.     CP    8            ; COMPARE WITH 8
  612.     JR    NC,DELCH4        ; JUMP IF >=8
  613.     PUSH    AF            ; SAVE DIFFERENCE
  614.     CALL    WCONTH            ; REMOVE CHARACTER END LINE
  615.     POP    AF            ; RESTORE COUNTER
  616.     JR    DELCH3            ; REMOVE MORE CHARACTERS
  617. DELCH4:    POP    BC            ; RESTORE CHARACTER COUNTER
  618.     POP    HL            ; RESTORE BUFFER POINTER
  619.     RET                ; AND RETURN TO CALLER 
  620. ;
  621. ; READ BUFFER
  622. ;
  623. RDBUF:    LD    A,(TABCNT)        ; GET CURRENT POSITION CURSOR
  624.     LD    (TABCX1),A        ; SAVE IT
  625. RDBUF0:    PUSH    IX            ; SAVE START ADDRESS BUFFER
  626.     POP    HL            ; GET IT IN HL
  627.     LD    C,(HL)            ; GET MAXIMUM LINE LENGHT
  628.     INC    HL            ; INCREMENT TO LINE LENGHT POSITION
  629.     LD    B,0            ; CLEAR LINE LENGHT COUNTER
  630.     PUSH    HL            ; SAVE START LINE - 1
  631. RDBUF1:    PUSH    HL            ; SAVE REGISTERS
  632.     PUSH    BC
  633. RDBUF2:    CALL    GETCH            ; GET CHARACTER
  634.     POP    BC            ; RESTORE REGISTERS
  635.     POP    HL
  636.     AND    07FH            ; MASK CHARACTER
  637.     CP    CONTE            ; TEST IF CONTE
  638.     JR    NZ,RDBUF3        ; NOT THEN JUMP 
  639.     PUSH    HL            ; SAVE REGISTERS
  640.     PUSH    BC
  641.     CALL    AGAIN0            ; MOVE CURSOR TO NEXT LINE
  642.     JR    RDBUF2            ; AND GET NEXT CHAR
  643. RDBUF3:    CP    CONTH            ; TEST BACKSPACE
  644.     JR    NZ,RDBUF4        ; NOT THEN JUMP
  645.     LD    A,B            ; TEST IF DELETING CHAR FROM EMPTY LINE
  646.     OR    A
  647.     JR    Z,RDBUF1        ; YES THEN GET NEXT CHAR
  648.     POP    HL            ; GET START LINE
  649.     PUSH    HL            ; AND SAVE IT AGAIN
  650.     CALL    DELCH            ; DELETE CHARACTER
  651.     JR    RDBUF1            ; GET NEXT CHARACTER
  652. RDBUF4:    CP    CONTP            ; TEST PRINT ENABLE/DISABLE
  653.     JR    NZ,RDBUF6        ; NOT THEN JUMP
  654.     LD    A,(FCONTP)        ; COMPLEMENT PRINT FLAG
  655.     CPL
  656.     LD    (FCONTP),A
  657. RDBUF5:    JR    RDBUF1            ; AND GET NEXT CHARACTER
  658. RDBUF6:    CP    CONTR            ; TEST REPEAT LINE
  659.     JR    NZ,RDBUFA        ; NOT THEN JUMP
  660.     PUSH    BC            ; SAVE REGISTERS
  661.     CALL    AGAIN            ; MOVE CURSOR TO NEXT LINE
  662.     POP    BC            ; RESTORE REGISTERS
  663.     POP    HL            ; GET START LINE
  664.     PUSH    HL            ; SAVE IT AGAIN
  665.     PUSH    BC            ; SAVE LINE COUNTER/MAXIMUM LINE LENGHT
  666. RDBUF7:    LD    A,B            ; TEST LAST CHARACTER ECHOED 
  667.     OR    A
  668.     JR    Z,RDBUF8        ; YES THEN JUMP
  669.     INC    HL            ; INCREMENT POINTER
  670.     LD    A,(HL)            ; GET CHARACTER
  671.     DEC    B            ; DECREMENT LINE COUNTER
  672.     PUSH    HL            ; SAVE REGISTERS
  673.     PUSH    BC
  674.     CALL    OUTCH            ; OUTPUT CHARACTER
  675.     POP    BC            ; RESTORE REGISTERS
  676.     POP    HL
  677.     JR    RDBUF7            ; AND TEST END LINE
  678. RDBUF8:    POP    BC            ; RESTORE LINE COUNTER/MAXIMUM LINE LENGHT
  679. RDBUF9:    JR    RDBUF5            ; AND GET NEXT CHAR
  680. RDBUFA:    CP    CONTU            ; TEST DELETE LINE
  681.     JR    NZ,RDBUFC        ; NOT THEN JUMP
  682.     POP    HL            ; GET START LINE
  683.     CALL    AGAIN            ; MOVE CURSOR TO NEXT LINE
  684. RDBUFB:    JR    RDBUF            ; AND START ROUTINE AGAIN
  685. RDBUFC:    CP    CONTX            ; TEST DELETE LINE
  686.     JR    NZ,RDBUFE        ; NOT THEN JUMP
  687. RDBUFD:    POP    HL            ; GET START LINE
  688.     LD    A,B            ; TEST IF LAST CHARACTER DELETED
  689.     OR    A
  690.     JR    Z,RDBUFB        ; YES START ROUTINE AGAIN
  691.     PUSH    HL            ; SAVE POINTER
  692.     CALL    DELCH            ; DELETE LAST CHARACTER LINE
  693.     JR    RDBUFD            ; TEST LAST CHARACTER DELETED
  694. RDBUFE:    CP    RUBOUT            ; TEST DELETE LAST CHARACTER
  695.     JR    NZ,RDBUFF        ; NOT THEN JUMP
  696.     LD    A,B            ; TEST FIRST CHARACTER LINE
  697.     OR    A
  698.     JR    Z,RDBUF9        ; YES, DO NOT DELETE
  699.     LD    A,(HL)            ; GET LAST CHARACTER
  700.     DEC    HL            ; DECREMENT POINTER LINE
  701.     DEC    B            ; DECREMENT LINE COUNTER
  702.     JR    RDBUFG            ; ECHO LAST CHARACTER
  703. RDBUFF:    CP    CR            ; TEST CARRIAGE RETURN
  704.     JR    Z,RDBUFI        ; YES, THEN EXIT
  705.     CP    LF            ; TEST LINE FEED
  706.     JR    Z,RDBUFI        ; YES THEN EXIT
  707.     INC    HL            ; INCREMENT POINTER
  708.     LD    (HL),A            ; AND SAVE CHARACTER
  709.     INC    B            ; INCREMENT LINE COUNTER
  710. RDBUFG:    PUSH    HL            ; SAVE REGISTERS
  711.     PUSH    BC
  712.     CALL    OUTCH            ; ECHO CHARACTER
  713.     POP    BC            ; RESTORE REGISTERS
  714.     POP    HL
  715.     CP    CONTC            ; TEST WARM BOOT
  716.     LD    A,B            ; GET LINE COUNT
  717.     JR    NZ,RDBUFH        ; NO WARM BOOT THEN JUMP
  718.     CP    1            ; TEST CONTC IS FIRST CHARACTER LINE 
  719.     JP    Z,RAMLOW+00000H        ; YES THEN EXECUTE WARM BOOT
  720. RDBUFH:    CP    C            ; TEST LINE LENGHT=MAXIMUM LINE LENGHT
  721.     JR    NZ,RDBUF9        ; NOT THEN GET NEXT CHARACTER
  722. RDBUFI:    POP    HL            ; GET START LINE - 1
  723.     LD    (HL),B            ; SAVE LINE COUNTER
  724.     LD    A,CR            ; LOAD CARRIAGE RETURN
  725.     JP    WRCON            ; AND ECHO IT
  726. ;
  727. ;******************************************************************************
  728. ;*                                          *
  729. ;*     DISK FUNCTIONS                                  *
  730. ;*                                          *
  731. ;******************************************************************************
  732. ;
  733. ; RETURN VERSION NUMBER
  734. ;
  735. CMND12:    LD    A,22H            ; SET VERSION NUMBER
  736.     JR    CMD25A            ; AND EXIT
  737. ;
  738. ; RESET DISK SYSTEM
  739. ;
  740. CMND13:    LD    HL,0            ; LOAD ZERO
  741.     LD    (LOGIN),HL        ; ALL DRIVES LOGED OUT
  742.     LD    (DSKRO),HL        ; ALL DRIVES READ/WRITE
  743.     LD    HL,RAMLOW+00080H    ; SET UP DMA ADDRESS
  744.     LD    (DMA),HL        ; AND SAVE IT
  745.     CALL    STDMA            ; DO P2BIOS CALL
  746.     XOR    A            ; SET DEFAULT DRIVE = 'A'
  747.     LD    (DEFDRV),A        ; SAVE IT
  748.     CALL    SELDK            ; SELECT DRIVE 'A'
  749.     LD    A,(SUBFLG)        ; GET SUBMIT FLAG
  750.     JR    CMD25A            ; EXIT
  751. ;
  752. ; SEARCH FOR FILE
  753. ;
  754. CMND17:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  755.     LD    A,(IX+0)        ; GET DRIVE NUMBER FROM FCB
  756.     SUB    '?'            ; TEST IF '?'
  757.     JR    Z,CMD17B        ; IF SO ALL ENTRIES MATCH
  758.     LD    A,(IX+14)        ; GET SYSTEM BYTE
  759.     CP    '?'            ; TEST IF '?' 
  760.     JR    Z,CMD17A        ; YES, JUMP
  761.     LD    (IX+14),0        ; LOAD SYSTEM BYTE WITH ZERO
  762. CMD17A:    LD    A,15            ; TEST FIRST 15 ITEMS IN FCB
  763. CMD17B:    CALL    SEARCH            ; DO SEARCH
  764. CMD17C:    LD    HL,(DIRBUF)        ; COPY DIRECTORY BUFFER 
  765.     LD    DE,(DMA)        ; TO DMA ADDRESS
  766.     LD    BC,128            ; DIRECTORY=128 BYTES 
  767.     LDIR
  768.     RET                ; EXIT
  769. ;
  770. ; SEARCH FOR NEXT OCCURENCE FILE
  771. ;
  772. CMND18:    LD    IX,(DCOPY)        ; GET LAST FCB USED BY SEARCH
  773.     CALL    SELDRV            ; SELEXT DRIVE FROM FCB
  774.     CALL    SEARCN            ; SEARCH NEXT FILE MATCH
  775.     JR    CMD17C            ; AND COPY DIRECTORY TO DMA ADDRESS
  776. ;
  777. ; DELETE FILE
  778. ;
  779. CMND19:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  780.     CALL    DELETE            ; DELETE FILE
  781. CMD19A:    LD    A,(SEAREX)        ; GET EXIT BYTE 00=FILE FOUND,0FFH NOT
  782.     JR    CMD25A            ; AND EXIT
  783. ;
  784. ; RENAME FILE
  785. ;
  786. CMND23:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  787.     CALL    RENAM            ; RENAME FILE
  788.     JR    CMD19A            ; AND EXIT
  789. ;
  790. ; RETURN LOGIN VECTOR
  791. ;
  792. CMND24:    LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  793. CMD24A:    LD    (PEXIT),HL        ; SAVE IT
  794.     RET                ; AND EXIT
  795. ;
  796. ; RETURN CURRENT DRIVE
  797. ;
  798. CMND25:    LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  799. CMD25A:    JP    EXIT            ; AND EXIT
  800. ;
  801. ; RETURN ALV VECTOR
  802. ;
  803. CMND27:    LD    HL,(ALV)        ; GET ALLOCATION VECTOR
  804.     JR    CMD24A            ; AND EXIT
  805. ;
  806. ; RETURN DISK R/O VECTOR
  807. ;
  808. CMND29:    LD    HL,(DSKRO)        ; GET DISK R/O VECTOR
  809.     JR    CMD24A            ; AND EXIT
  810. ;
  811. ; CHANGE STATUS
  812. ;
  813. CMND30:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  814.     CALL    CSTAT            ; CHANGE STATUS
  815.     JR    CMD19A            ; AND EXIT
  816. ;
  817. ; RETURN DRIVE TABEL
  818. ;
  819. CMND31:    LD    HL,(IXP)        ; GET DRIVE TABLE
  820.     JR    CMD24A            ; AND EXIT
  821. ;
  822. ; SET/GET USER CODE
  823. ;
  824. CMND32:    LD    A,E            ; GET USER CODE
  825.     INC    A            ; TEST IF 0FFH
  826.     LD    A,(USER)        ; GET OLD USER CODE
  827.     JR    Z,CMD25A        ; IF 0FFH THEN EXIT
  828.     LD    A,E            ; GET NEW USER CODE
  829.     AND    01FH            ; MASK IT
  830.     LD    (USER),A        ; SAVE IT
  831.     RET                ; AND EXIT
  832. ;
  833. ; COMPUTE FILE SIZE COMMAND
  834. ;
  835. CMND35:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  836.     CALL    FILSZ            ; COMPUTE FILE SIZE
  837.     JR    CMD19A            ; AND EXIT
  838. ;
  839. ; SET RANDOM RECORD COUNT
  840. ;
  841. CMND36:    LD    HL,32            ; SET POINTER TO NEXT RECORD
  842.     CALL    CALRRC            ; CALCULATE RANDOM RECORD COUNT
  843. LDRRC:    LD    (IX+33),D        ; AND SAVE RANDOM RECORD COUNT
  844.     LD    (IX+34),C
  845.     LD    (IX+35),B
  846.     RET                ; AND EXIT
  847. ;
  848. ; RESET MULTIPLE LOGIN DRIVE
  849. ;
  850. CMND37:    LD    A,E            ; GET MASK LSB
  851.     CPL                ; COMPLEMENT IT
  852.     LD    E,A 
  853.     LD    A,D            ; GET MASK MSB
  854.     CPL                ; COMPLEMENT IT
  855.     LD    D,A
  856.     LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  857.     LD    A,E            ; MASK LOGIN VECTOR
  858.     AND    L            ; LSB
  859.     LD    L,A
  860.     LD    A,D            ; MASK LOGIN VECTOR
  861.     AND    H            ; MSB
  862.     LD    H,A
  863.     LD    (LOGIN),HL        ; SAVE LOGIN VECTOR
  864.     EX    DE,HL            ; USE LOGIN VECTOR AS MASK
  865.     LD    HL,(DSKRO)        ; GET DRIVE R/O VECTOR
  866.     LD    A,E            ; MASK DRIVE R/O VECTOR
  867.     AND    L            ; LSB
  868.     LD    L,A
  869.     LD    A,D            ; MASK DRIVE R/O VECTOR
  870.     AND    H            ; LSB
  871.     LD    H,A
  872.     LD    (DSKRO),HL        ; SAVE DRIVE R/O VECTOR
  873.     RET                ; AND EXIT
  874. ;
  875. ;******************************************************************************
  876. ;*                                          *
  877. ;*     ERROR ROUTINES                                  *
  878. ;*                                          *
  879. ;******************************************************************************
  880. ;
  881. ; BAD SECTOR ERROR
  882. ;
  883. BADSEC:    LD    DE,MBADSC        ; LOAD BAD SECTOR MESSAGE
  884.     JR    DERROR            ; AND DISPLAY ERROR
  885. ;
  886. ; SELECT ERROR
  887. ;
  888. SELERR:    LD    DE,MSEL            ; LOAD SELECT ERROR MESSAGE
  889.     JR    DERROR            ; AND DIPLAY ERROR
  890. ;
  891. ; FILE READ ONLY ERROR
  892. ;
  893. FILRO:    LD    DE,MFILRO        ; LOAD FILE R/O MESSAGE
  894.     LD    A,0FFH            ; SET FILE R/O MESSAGE FLAG
  895.     JR    ERROR            ; AND DISPLAY ERROR
  896. ;
  897. ; DRIVE READ ONLY ERROR
  898. ;
  899. RDONLY:    LD    DE,MRO            ; LOAD DRIVE R/O MESSAGE
  900. DERROR:    XOR    A            ; SET NO FILE R/O MESSAGE
  901. ;
  902. ; DISPLAY ERROR MESSAGE
  903. ;
  904. ; P2DOS ERROR ON D: ERROR MESSAGE
  905. ; FUNCTION = NN  [FILE = FILENAME.TYP]
  906. ;
  907. ERROR:    LD    C,A            ; SAVE FILE R/O MESSAGE FLAG
  908.     PUSH    BC
  909.     PUSH    DE            ; SAVE ERROR MESSAGE POINTER
  910.     CALL    CROUT            ; DIPLAY CR/LF
  911.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  912.     ADD    A,'A'            ; MAKE ASCII
  913.     LD    (MDRIVE),A        ; SAVE IT
  914.     LD    DE,MBERR        ; LOAD MESSAGE "P2DOS ERROR ON D:"
  915.     CALL    MESS            ; DISPLAY MESSAGE
  916.     POP    DE            ; GET ERROR MESSAGE POINTER
  917.     CALL    MESS            ; DISPLAY MESSAGE
  918.     CALL    CROUT            ; DISPLAY CR/LF
  919.     LD    DE,MBFUNC        ; LOAD MESSAGE "FUNCTION ="
  920.     CALL    MESS            ; DISPLAY MESSAGE
  921.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  922.     PUSH    AF            ; SAVE IT
  923.     LD    BC,100            ; DISPLAY NUMBER / 100
  924.     CALL    NUM
  925.     LD    C,10            ; DISPLAY NUMBER / 10
  926.     CALL    NUM
  927.     LD    BC,101H            ; ALWAYS DISPLAY NUMBER / 1
  928.     CALL    NUM
  929.     POP    AF            ; GET FUNCTION NUMBER
  930.     POP    BC            ; GET FILE R/O FLAG
  931.     CP    15            ; TEST IF FCB USED IN COMMAND
  932.     JR    C,ERROR3
  933.     CP    24
  934.     JR    C,ERROR1
  935.     CP    30
  936.     JR    Z,ERROR1
  937.     CP    33
  938.     JR    C,ERROR3
  939.     CP    37
  940.     JR    C,ERROR1
  941.     CP    40
  942.     JR    NZ,ERROR3
  943. ERROR1:    PUSH    IX            ; YES THEN DISPLAY "FILE ="
  944.     SUB    19            ; TEST DELETE FILE FUNCTION
  945.     JR    NZ,ERROR2        ; NOT THEN JUMP
  946.     OR    C            ; TEST FILE R/O FLAG
  947.     JR    Z,ERROR2        ; NO FILE R/O THEN JUMP
  948.     CALL    CALDIR            ; GET FCB FROM DIRECTORY BUFFER
  949.     EX    (SP),HL            ; SAVE IT
  950. ERROR2:    LD    DE,MFILE        ; GET MESSAGE " FILE ="
  951.     CALL    MESS            ; DISPLAY MESSAGE
  952.     POP    HL            ; GET POINTER FCB
  953.     LD    B,8            ; DISPLAY FISRT 8 CHARACTERS
  954.     CALL    FILENM
  955.     LD    A,'.'            ; LOAD '.'
  956.     PUSH    HL            ; SAVE FCB POINTER
  957.     CALL    WRCON            ; ECHO IT
  958.     POP    HL            ; RESTORE FCB POINTER
  959.     LD    B,3            ; DISPLAY LAST 3 CHARACTERS 
  960.     CALL    FILENM
  961. ERROR3:    CALL    GCONST            ; TEST IF CHARACTER PRESENT
  962.     OR    A
  963.     JR    Z,ERROR4        ; NO THEN JUMP
  964.     CALL    GETCH            ; GET CHARACTER
  965.     JR    ERROR3            ; AND TEST AGAIN
  966. ERROR4:    CALL    GETCH            ; GET CHARACTER
  967.     JP    RAMLOW+00000H        ; AND DO WARM BOOT
  968. ;
  969. ; DISPLAY NUMBER
  970. ;
  971. NUM:    LD    D,-1            ; LOAD NUMBER -1
  972. NUM1:    INC    D            ; INCREMENT NUMBER
  973.     SUB    C            ; DIVIDE BY C
  974.     JR    NC,NUM1            ; NOT FINISHED THEN LOOP
  975.     ADD    A,C            ; RESTORE LAST VALUE
  976.     PUSH    AF            ; SAVE IT
  977.     LD    A,D            ; TEST IF "0"
  978.     OR    B            ; AND IF LEADING ZERO
  979.     JR    Z,NUM2            ; YES, THEN EXIT 
  980.     LD    B,D            ; SET NO LEADING ZERO 
  981.     LD    A,D            ; GET NUMBER
  982.     ADD    A,'0'            ; MAKE ASCII
  983.     PUSH    BC            ; SAVE REGISTERS
  984.     CALL    WRCON            ; ECHO NUMBER
  985.     POP    BC            ; RESTORE REGISTERS
  986. NUM2:    POP    AF            ; RESTORE NUMBER
  987.     RET                ; AND EXIT
  988. ;
  989. ; DISPLAY FILNAME.TYP
  990. ;
  991. FILENM:    INC    HL            ; INCREMENT POINTER FCB
  992.     LD    A,(HL)            ; GET CHARACTER FROM FCB
  993.     AND    07FH            ; MASK IT
  994.     PUSH    HL            ; SAVE REGISTERS
  995.     PUSH    BC
  996.     CALL    WRCON            ; ECHO CHARACTER
  997.     POP    BC            ; RESTORE REGISTERS
  998.     POP    HL
  999.     DJNZ    FILENM            ; REPEAT B TIMES
  1000.     RET                ; AND EXIT
  1001. ;
  1002. ; ERROR MESSAGES
  1003. ;
  1004. MBADSC:    DEFM    'Bad sector$'
  1005. ;
  1006. MSEL:    DEFM    'Select$'
  1007. ;
  1008. MFILRO:    DEFM    'File '
  1009. ;
  1010. MRO:    DEFM    'R/O$'
  1011. ;
  1012. MBERR:    DEFM    'P2DOS error on '
  1013. MDRIVE:    DEFB    0
  1014.     DEFB    DRVSEP
  1015.     DEFM    ' $'
  1016. ;
  1017. MBFUNC:    DEFM    'Function =$'
  1018. ;
  1019. MFILE:    DEFM    ' File =$'
  1020. ;
  1021. ; SELECT DISK FROM FCB
  1022. ;
  1023. SELDRV:    LD    A,0FFH            ; SET DISK SELECT DONE FLAG
  1024.     LD    (FLDRV),A
  1025.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  1026.     LD    (DRIVE),A        ; SAVE IT IN MEMORY
  1027.     LD    E,A            ; SAVE IT IN REGISTER E
  1028.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  1029.     LD    (FCB0),A        ; SAVE IT
  1030.     CP    '?'            ; TEST IF '?'
  1031.     JR    Z,CMND14        ; YES, THEN SELECT DRIVE FROM REGISTER E
  1032.     AND    01FH            ; MASK DRIVE
  1033.     LD    A,E            ; TEST IF ZERO
  1034.     JR    Z,SELDR0        ; SELECT DRIVE FROM REGISTER E
  1035.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  1036.     DEC    A            ; DECREMENT DRIVE
  1037. SELDR0:    CALL    SELDK            ; SELECT DRIVE
  1038.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  1039.     AND    0E0H            ; REMOVE DRIVE BITS
  1040.     LD    B,A            ; SAVE REGISTER
  1041.     LD    A,(USER)        ; GET USER NUMBER
  1042.     OR    B            ; INSERT USER NUMBER IN FCB
  1043.     LD    (IX+0),A
  1044.     RET                ; AND EXIT
  1045. ;
  1046. ; SELECT DISK
  1047. ;
  1048. CMND14:    LD    A,E            ; COPY DRIVE NUMBER
  1049. ;
  1050. ; SELECT DISK
  1051. ;
  1052. SELDK:    AND    0FH            ; MASK DRIVE NUMBER
  1053.     LD    B,A            ; SAVE COUNTER
  1054.     LD    DE,(LOGIN)        ; GET LOGIN VECTOR
  1055.     OR    A            ; TEST DRIVE 'A'
  1056.     JR    Z,SELDK1        ; YES THEN JUMP
  1057. SELDK0:    RR    D            ; SHIFT LOGIN VECTOR
  1058.     RR    E            ; UNTIL BIT 0 REGISTER E
  1059.     DJNZ    SELDK0            ; IS CURRENT DRIVE
  1060. SELDK1:    LD    HL,DEFDRV        ; GET POINTER LAST DRIVE
  1061.     BIT    0,E            ; TEST IF DRIVE LOGGED IN
  1062.     JR    Z,SELDK2        ; NO, LOGIN DRIVE
  1063.     CP    (HL)            ; TEST SAME DRIVE
  1064.     RET    Z            ; YES THEN EXIT
  1065. SELDK2:    LD    (HL),A            ; SAVE NEW CURRENT DRIVE
  1066.     PUSH    DE            ; SAVE DRIVE LOGGED IN FLAG
  1067.     LD    C,A            ; COPY DRIVE NUMBER
  1068.     CALL    SELDSK            ; DO P2BIOS SELECT 
  1069.     LD    A,H            ; TEST IF ERROR 
  1070.     OR    L
  1071.     JR    Z,SELDK3        ; YES, ILLEGAL DRIVE NUMBER
  1072.     LD    E,(HL)            ; GET LSB TRANSLATION VECTOR
  1073.     INC    HL            ; INCREMENT POINTER
  1074.     LD    D,(HL)            ; GET MSB TRANSLATION VECTOR
  1075.     INC    HL            ; INCREMENT POINTER
  1076.     LD    (TRANS),DE        ; SAVE TRANSLATION VECTOR
  1077.     LD    (TEMP0),HL        ; SAVE ADDRESS TEMP0
  1078.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  1079.     INC    HL
  1080.     LD    (TEMP1),HL        ; SAVE ADDRESS TEMP1
  1081.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  1082.     INC    HL
  1083.     LD    (TEMP2),HL        ; SAVE ADDRESS TEMP2
  1084.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  1085.     INC    HL
  1086.     LD    DE,DIRBUF        ; LOAD DIRBUF POINTER
  1087.     LD    BC,8            ; COPY 8 BYTES
  1088.     LDIR
  1089.     LD    HL,(IXP)        ; GET DRIVE PARAMETER ADDRESS
  1090.     LD    C,15            ; COPY 15 BYTES
  1091.     LDIR
  1092.     POP    DE            ; GET DRIVE LOGGED IN FLAG
  1093.     BIT    0,E            ; TEST IT
  1094.     RET    NZ            ; DRIVE LOGGED IN SO RETURN
  1095.     LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  1096.     CALL    SDRVB            ; SET DRIVE BIT IN LOGIN VECTOR
  1097.     LD    (LOGIN),HL        ; SAVE LOGIN VECTOR
  1098.     JR    INITDR            ; AND SETUP DRIVE TABLES
  1099. SELDK3:    LD    HL,(STSEL)        ; LOAD ERROR MESSAGE ADDRESS
  1100.     JP    (HL)            ; AND DISPLAY ERROR
  1101. ;
  1102. ; INIT DRIVE
  1103. ;  CLEAR ALV BIT BUFFER AFTER DRIVE RESET
  1104. ;
  1105. INITDR:    LD    DE,(MAXLEN)        ; GET LENGHT ALV BUFFER-1 (BITS)
  1106.     LD    A,3            ; DIVIDE BY 8
  1107. INITD0:    SRL    D            ; TO GET BYTES
  1108.     RR    E
  1109.     DEC    A
  1110.     JR    NZ,INITD0
  1111.     INC    DE            ; INCREMENT, SO ALL BITS ARE CLEARED
  1112.     LD    HL,(ALV)        ; GET POINTER ALV BUFFER
  1113.     PUSH    HL
  1114. INITD1:    LD    (HL),0            ; CLEAR 8 BITS
  1115.     INC    HL            ; INCREMENT POINTER
  1116.     DEC    DE            ; DECREMENT COUNTER
  1117.     LD    A,D            ; TEST IF COUNTER ZERO
  1118.     OR    E
  1119.     JR    NZ,INITD1        ; NOT THEN JUMP
  1120.     POP    HL            ; GET ALV POINTER
  1121.     LD    DE,(NDIR0)        ; GET FIRST TWO BYTES ALV BUFFER 
  1122.     LD    (HL),E            ; SAVE LSB
  1123.     INC    HL            ; INCREMENT POINTER
  1124.     LD    (HL),D            ; SAVE MSB
  1125.     LD    HL,(TEMP0)        ; CLEAR NUMBER OF FILES
  1126.     XOR    A            ; ON THIS DRIVE
  1127.     LD    (HL),A            ; CLEAR LSB
  1128.     INC    HL            ; INCREMENT POINTER
  1129.     LD    (HL),A            ; CLEAR MSB
  1130.     LD    (SUBFLG),A        ; CLEAR SUBMIT FLAG (RESET DISK COMMAND)
  1131.     CALL    SETFCT            ; SET FILE COUNT
  1132. INITD2:    LD    A,0FFH            ; UPDATE DIRECTORY CHECKSUM
  1133.     CALL    RDDIR            ; READ FCB'S FROM DIRECTORY
  1134.     CALL    TSTFCT            ; TEST LAST FCB
  1135.     RET    Z            ; YES THEN EXIT
  1136.     CALL    CALDIR            ; CALCULATE ENTRY POINT FCB
  1137.     LD    A,(HL)            ; GET FIRST BYTE FCB
  1138.     CP    0E5H            ; TEST EMPTY DIRECTORY ENTRY
  1139.     JR    Z,INITD2        ; YES THEN GET NEXT FCB
  1140.     CP    021H            ; TEST TIME STAMP
  1141.     JR    Z,INITD2        ; YES THEN GET NEXT FCB
  1142.     LD    A,(USER)        ; GET USER NUMBER
  1143.     CP    (HL)            ; TEST IF USER IS SAME
  1144.     JR    NZ,INITD3        ; NO THEN JUMP
  1145.     INC    HL            ; POINT TO FILE NAME
  1146.     LD    A,(HL)            ; GET FIRST CHAR FILENAME
  1147.     SUB    '$'            ; TEST IF '$'
  1148.     JR    NZ,INITD3        ; NOT THEN JUMP
  1149.     DEC    A            ; LOAD A WITH 0FFH
  1150.     LD    (SUBFLG),A        ; SAVE IT IN SUBFLG 
  1151. INITD3:    LD    C,1            ; SET BIT IN ALV BUFFER
  1152.     CALL    FILLBB            ; SET BITS FROM FCB IN ALV BUFFER
  1153.     CALL    SETLF            ; UPDATE LAST FILE COUNT
  1154.     JR    INITD2            ; AND GET NEXT FCB
  1155. ;
  1156. ; SET DRIVE BIT IN HL
  1157. ;
  1158. SDRVB:    EX    DE,HL            ; COPY HL=>DE 
  1159.     LD    HL,1            ; GET MASK DRIVE "A"
  1160.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  1161.     OR    A            ; TEST IF DRIVE "A"
  1162.     JR    Z,SDRVB1        ; YES THEN DONE
  1163. SDRVB0:    ADD    HL,HL            ; GET NEXT MASK
  1164.     DEC    A            ; DECREMENT DRIVE COUNTER
  1165.     JR    NZ,SDRVB0        ; AND TEST IF DONE
  1166. SDRVB1:    LD    A,D            ; HL=HL OR DE
  1167.     OR    H
  1168.     LD    H,A
  1169.     LD    A,E
  1170.     OR    L
  1171.     LD    L,A
  1172.     RET                ; EXIT
  1173. ;
  1174. ; CALCULATE SECTOR/TRACK DIRECTORY
  1175. ;
  1176. STDIR:    LD    HL,(FILCNT)        ; GET FCB COUNTER DIRECTORY
  1177.     SRL    H            ; DIVIDE BY 4
  1178.     RR    L            ; (4 FCB'S / SECTOR)
  1179.     SRL    H
  1180.     RR    L
  1181.     LD    (RECDIR),HL        ; SAVE VALUE (USED BY CHECKSUM)
  1182.     EX    DE,HL            ; COPY IT TO DE
  1183.     LD    HL,0            ; CLEAR HL
  1184. ;
  1185. ; CALCULATE SECTOR/TRACK
  1186. ;  ENTRY: HL,DE=SECTOR NUMBER (128 BYTE SECTOR)
  1187. ;  RESULT SET TRACK  =HL,DE  /  MAXSEC
  1188. ;         SET SECTOR =HL,DE MOD MAXSEC
  1189. ;
  1190. CALST:    LD    BC,(MAXSEC)        ; GET SECTORS/TRACK
  1191.     LD    A,17            ; SET UP LOOP COUNTER
  1192. CALST0:    OR    A            ; TEST HL>=BC
  1193.     SBC    HL,BC
  1194.     CCF
  1195.     JR    C,CALST1        ; YES THEN JUMP
  1196.     ADD    HL,BC            ; NO THEN RETORE HL
  1197.     OR    A            ; AND CLEAR CARRY
  1198. CALST1:    RL    E            ; SHIFT RESULT IN DE
  1199.     RL    D
  1200.     DEC    A            ; TEST LAST BIT DONE
  1201.     JR    Z,CALST2        ; YES THEN EXIT
  1202.     RL    L            ; SHIFT NEXT BIT IN HL
  1203.     RL    H
  1204.     JR    CALST0            ; CONTINUE
  1205. CALST2:    PUSH    HL            ; SAVE SECTOR NUMBER
  1206.     LD    HL,(NFTRK)        ; GET FIRST TRACK
  1207.     ADD    HL,DE            ; ADD TRACK NUMBER
  1208.     LD    B,H            ; COPY IT TO BC
  1209.     LD    C,L
  1210.     CALL    SETTRK            ; P2BIOS CALL SET TRACK
  1211.     POP    BC            ; RESTORE SECTOR NUMBER
  1212.     LD    DE,(TRANS)        ; GET TRANSLATION TABLE ADDRESS
  1213.     CALL    SECTRN            ; P2BIOS CALL SECTOR TRANSLATION 
  1214.     LD    B,H            ; COPY RESULT TO BC
  1215.     LD    C,L
  1216.     JP    SETSEC            ; P2BIOS CALL SET SECTOR
  1217. ;
  1218. ; GET DISK MAP BLOCK NUMBER FROM FCB
  1219. ;  EXIT HL=ADDRESS FCB
  1220. ;       DE=DM
  1221. ;       BC=OFFSET IN DM
  1222. ;
  1223. GETDM:    LD    C,(IX+32)        ; GET NEXT RECORD
  1224.     LD    A,(NBLOCK)        ; GET NUMBER OF BLOCKS
  1225.     LD    B,A            ; SAVE IT 
  1226. GETDM0:    SRL    C            ; SHIFT NEXT RECORD 
  1227.     DJNZ    GETDM0            ; NUMBER OF BLOCKS TIMES
  1228. GETDM1:    CPL                ; COMPLEMENT NUMBER OF BLOCKS
  1229.     ADD    A,9            ; ADD 9
  1230.     LD    B,A            ; B=8-NUMBER OF BLOCKS
  1231.     LD    A,(NEXTND)        ; GET EXTEND MASK
  1232.     AND    (IX+12)            ; MASK WITH EXTEND
  1233.     RRCA                ; ROTATE ONE RIGHT
  1234. GETDM2:    RLCA                ; ROTATE ONE LEFT
  1235.     DJNZ    GETDM2            ; 8-NUMBER OF BLOCKS TIMES
  1236. GETDM3:    ADD    A,C            ; ADD THE TWO VALUES TO GET ENTRY FCB
  1237. GETDM4:    PUSH    IX            ; GET FCB ADDRESS
  1238.     POP    HL
  1239.     LD    C,16            ; ADD OFFSET 16 TO POINT TO DM
  1240.     ADD    HL,BC
  1241.     LD    C,A            ; ADD ENTRY FCB
  1242.     ADD    HL,BC
  1243.     LD    A,(MAXLEN+1)        ; TEST 8 BITS/16 BITS FCB ENTRY
  1244.     OR    A
  1245.     JR    NZ,GETDM5        ; 16 BITS => JUMP
  1246.     LD    E,(HL)            ; GET 8 BIT VALUE
  1247.     LD    D,0            ; MAKE MSB ZERO
  1248.     RET                ; AND EXIT
  1249. GETDM5:    ADD    HL,BC            ; ADD TWICE (16 BIT VALUES)
  1250.     LD    E,(HL)            ; GET LSB
  1251.     INC    HL            ; INCREMENT POINTER
  1252.     LD    D,(HL)            ; GET MSB
  1253.     DEC    HL            ; DECREMENT POINTER
  1254.     RET                ; AND EXIT
  1255. ;
  1256. ; CALCULATE SECTOR NUMBER 
  1257. ;  ENTRY: DE=BLOCK NUMBER FROM FCB
  1258. ;
  1259. CALSEC:    LD    HL,0            ; CLEAR MSB SECTOR NUMBER
  1260.     LD    A,(NBLOCK)        ; GET LOOP COUNTER
  1261.     LD    B,A            ; SAVE IT IN B
  1262. CALSC0:    SLA    E            ; SHIFT L,D,E 
  1263.     RL    D
  1264.     RL    L
  1265.     DJNZ    CALSC0            ; B TIMES
  1266. CALSC1:    LD    A,(NMASK)        ; GET SECTOR MASK
  1267.     AND    (IX+32)            ; AND WHIT NEXT RECORD
  1268.     OR    E            ; SET UP LSB SECTOR NUMBER
  1269.     LD    E,A
  1270.     RET                ; AND EXIT
  1271. ;
  1272. ; CALCULATE DIRBUF ENTRY POINT
  1273. ;
  1274. CALDIR:    LD    HL,(DIRBUF)        ; GET START ADDRESS DIRBUF
  1275.     LD    A,(SECPNT)        ; GET SECTOR POINTER
  1276.     ADD    A,L            ; ADD L=L+A
  1277.     LD    L,A
  1278.     RET    NC            ; NO CARRY EXIT
  1279.     INC    H            ; INCREMENT H
  1280.     RET                ; AND EXIT
  1281. ;
  1282. ; INIT FILE COUNT
  1283. ;
  1284. SETFCT:    LD    HL,-1            ; SET UP FILE COUNT
  1285.     LD    (FILCNT),HL        ; SAVE IT
  1286.     RET                ; AND EXIT
  1287. ;
  1288. ; TEST FILE COUNT
  1289. ;
  1290. TSTFCT:    LD    HL,(FILCNT)        ; TEST FILE COUNT=0FFFFH
  1291.     LD    A,H            ; GET MSB 
  1292.     AND    L            ; AND LSB
  1293.     INC    A            ; TEST IF RESULT=0FFH
  1294.     RET                ; AND EXIT
  1295. ;
  1296. ; SET LAST FILE
  1297. ;
  1298. SETLF:    CALL    TSTLF            ; TEST LAST FILE
  1299.     RET    C            ; NO THEN EXIT
  1300.     INC    DE            ; INCREMENT LAST FILE
  1301.     LD    (HL),D            ; SAVE IT IN TEMP0
  1302.     DEC    HL
  1303.     LD    (HL),E
  1304.     RET                ; AND EXIT
  1305. ;
  1306. ; TEST LAST FILE
  1307. ;
  1308. TSTLF:    LD    HL,(TEMP0)        ; GET POINTER TO LAST FILE 
  1309.     LD    DE,(FILCNT)        ; GET FILE COUNTER
  1310.     LD    A,E            ; SUBTRACT DE-(HL)
  1311.     SUB    (HL)
  1312.     INC    HL
  1313.     LD    A,D
  1314.     SBC    A,(HL)
  1315.     RET                ; EXIT
  1316. ;
  1317. ; GET NEXT FCB FROM DRIVE
  1318. ; ENTRY A=0 CHECK CHECKSUM, A=0FFH UPDATE CHECKSUM
  1319. ;
  1320. RDDIR:    LD    C,A            ; SAVE CHECKSUM FLAG
  1321.     LD    HL,(FILCNT)        ; GET FILE COUNTER
  1322.     INC    HL            ; INCREMENT IT
  1323.     LD    (FILCNT),HL        ; AND SAVE IT
  1324.     LD    DE,(NFILES)        ; GET MAXIMUM NUMBER OF FILES
  1325.     OR    A            ; CLEAR CARRY
  1326.     SBC    HL,DE            ; TEST IF LAST FILE
  1327.     ADD    HL,DE
  1328.     JR    Z,RDDIR0        ; NO JUMP
  1329.     JR    NC,SETFCT        ; YES SET FILE COUNT TO 0FFFFH
  1330. RDDIR0:    LD    A,L            ; GET FILE COUNT LSB
  1331.     ADD    A,A            ; *32 
  1332.     ADD    A,A
  1333.     ADD    A,A
  1334.     ADD    A,A
  1335.     ADD    A,A
  1336.     AND    060H            ; MASK IT
  1337.     LD    (SECPNT),A        ; SAVE IT FOR LATER USE
  1338.     RET    NZ            ; RETURN IF NOT FISRT FCB SECTOR
  1339.     PUSH    BC            ; SAVE CHECKSUM FLAG
  1340.     CALL    STDIR            ; CALCULATE SECTOR/TRACK DIRECTORY
  1341.     CALL    READDR            ; READ SECTOR DIRECTORY
  1342.     POP    BC            ; RESTORE CHECKSUM FLAG
  1343. ;
  1344. ; UPDATE/CHECK CHECKSUM DIRECTORY
  1345. ; ENTRY C=0 CHECK CHECKSUM, C=0FFH UPDATE CHECKSUM
  1346. ;
  1347. CHKDIR:    LD    HL,(NCHECK)        ; GET NUMBER OF CHECKED RECORDS
  1348.     LD    DE,(RECDIR)        ; GET CURRENT RECORD
  1349.     OR    A            ; CLEAR CARRY
  1350.     SBC    HL,DE            ; TEST CURRENT RECORD 
  1351.     RET    Z            ; EXIT IF ZERO
  1352.     RET    C            ; EXIT IF GREATER THEN NCHECK
  1353.     LD    HL,(DIRBUF)        ; GET DIRBUF
  1354.     LD    B,128            ; SET UP COUNTER
  1355.     XOR    A            ; CLEAR CHECKSUM
  1356. CHKDR0:    ADD    A,(HL)            ; ADD CHECKSUM
  1357.     INC    HL            ; INCREMENT POINTER
  1358.     DJNZ    CHKDR0            ; 128 TIMES
  1359.     LD    HL,(CSV)        ; GET POINTER CHECKSUM DIRECTORY
  1360.     ADD    HL,DE            ; ADD CURRENT RECORD
  1361.     INC    C            ; TEST CHECKSUM FLAG
  1362.     JR    Z,CHKDR1        ; 0FFH=> UPDATE CHECKSUM
  1363.     CP    (HL)            ; TEST CHECKSUM
  1364.     RET    Z            ; EXIT IF OK
  1365.     JP    SETWPD            ; SET WRITE PROTECT DISK
  1366. CHKDR1:    LD    (HL),A            ; UPDATE CHECKSUM
  1367.     RET                ; AND EXIT
  1368. ;
  1369. ; READ SECTOR FROM DRIVE
  1370. ;
  1371. READR:    CALL    READ            ; P2BIOS CALL READ SECTOR
  1372.     JR    WRITE0            ; TEST EXIT CODE
  1373. ;
  1374. ; WRITE SECTOR ON DRIVE
  1375. ;
  1376. WRITER:    CALL    WRITE            ; P2BIOS CALL WRITE SECTOR
  1377. WRITE0:    OR    A            ; TEST EXIT CODE
  1378.     RET    Z            ; EXIT IF OK
  1379.     LD    HL,(STBDSC)        ; LOAD BAD SECTOR MESSAGE POINTER
  1380.     JP    (HL)            ; P2DOS ERROR ON D: BAD SECTOR
  1381. ;
  1382. ; READ DIRECTORY FROM DRIVE
  1383. ;
  1384. READDR:    CALL    DMADIR            ; SET UP DMA DIRECTORY
  1385.     CALL    READR            ; READ RECORD
  1386.     JR    STDMA            ; SET UP DMA USER
  1387. ;
  1388. ; WRITE DIRECTORY ON DRIVE
  1389. ;
  1390. WRITDR:    LD    C,0FFH            ; UPDATE CHECKSUM DIRECTORY
  1391.     CALL    CHKDIR
  1392.     CALL    DMADIR            ; SET UP DMA DIRECTORY 
  1393.     LD    C,1            ; WRITE DIRECTORY FLAG
  1394.     CALL    WRITER            ; WRITE RECORD
  1395.     JR    STDMA            ; SET UP DMA USER
  1396. ;
  1397. ; SET DMA ADDRESS COMMAND
  1398. ;
  1399. CMND26:    LD    (DMA),DE        ; SAVE DMA ADDRESS
  1400. ;
  1401. ; SET DMA ADDRESS
  1402. ;
  1403. STDMA:    LD    BC,(DMA)        ; GET DMA ADDRESS
  1404.     JR    DMADR0            ; AND DO P2BIOS CALL
  1405. ;
  1406. ; SET DMA ADDRESS DIRECTORY
  1407. ;
  1408. DMADIR:    LD    BC,(DIRBUF)        ; GET DMA ADDRESS DIRECTORY
  1409. DMADR0:    JP    SETDMA            ; P2BIOS CALL SET DMA
  1410. ;
  1411. ; GET BIT FROM ALV BUFFER
  1412. ;  ENTRY DE=BLOCK NUMBER
  1413. ;  EXIT  A =BIT IN LSB
  1414. ;        B =BITNUMBER IN A
  1415. ;        HL=POINTER IN ALV BUFFER
  1416. ;
  1417. GETBIT:    LD    A,E            ; GET BIT NUMBER
  1418.     AND    7            ; MASK IT
  1419.     INC    A            ; ADD 1
  1420.     LD    B,A            ; SAVE IT
  1421.     LD    C,A            ; TWICE
  1422.     SRL    D            ; GET BYTE NUMBER
  1423.     RR    E            ; DE=DE/8
  1424.     SRL    D
  1425.     RR    E
  1426.     SRL    D
  1427.     RR    E
  1428.     LD    HL,(ALV)        ; GET START ADDRESS ALV BUFFER
  1429.     ADD    HL,DE            ; ADD BYTE NUMBER
  1430.     LD    A,(HL)            ; GET 8 BITS
  1431. GETBT0:    RLCA                ; GET CORRECT BIT
  1432.     DJNZ    GETBT0
  1433.     LD    B,C            ; RESTORE BIT NUMBER
  1434.     RET                ; AND RETURN TO CALLER
  1435. ;
  1436. ; SET/RESET BIT IN ALV BUFFER
  1437. ;  ENTRY DE=BLOCK NUMBER
  1438. ;        C =0 RESET BIT, C=1 SET BIT
  1439. ;
  1440. SETBIT:    PUSH    BC            ; SAVE SET/RESET BIT
  1441.     CALL    GETBIT            ; GET BIT
  1442.     AND    0FEH            ; MASK IT
  1443.     POP    DE            ; GET SET/RESET BIT
  1444.     OR    E            ; SET/RESET BIT
  1445. SETBT0:    RRCA                ; ROTATE BIT IN CORRECT POSITION
  1446.     DJNZ    SETBT0
  1447.     LD    (HL),A            ; SAVE 8 BITS
  1448.     RET                ; AND RETURN TO CALLER
  1449. ;
  1450. ; FILL BIT BUFFER FROM FCB IN DIRBUF
  1451. ;  ENTRY C=0 RESET BIT, C=1 SET BIT
  1452. ;
  1453. FILLBB:    CALL    CALDIR            ; GET DIRECTORY ENTRY
  1454.     LD    DE,16            ; GET OFFSET DM BLOCK
  1455.     ADD    HL,DE            ; ADD OFFSET
  1456.     LD    B,E            ; GET BLOCK COUNTER
  1457. FILLB0:    LD    E,(HL)            ; GET LSB BLOCK NUMBER
  1458.     INC    HL            ; INCREMENT POINTER
  1459.     LD    D,0            ; RESET MSB BLOCK NUMBER
  1460.     LD    A,(MAXLEN+1)        ; TEST >256 BLOCKS PRESENT
  1461.     OR    A
  1462.     JR    Z,FILLB1        ; NO THEN JUMP
  1463.     DEC    B            ; DECREMENT BLOCK COUNTER
  1464.     LD    D,(HL)            ; GET CORRECT MSB
  1465.     INC    HL            ; INCREMENT POINTER
  1466. FILLB1:    LD    A,D            ; TEST BLOCK NUMBER
  1467.     OR    E            
  1468.     JR    Z,FILLB2        ; ZERO THEN GET NEXT BLOCK
  1469.     PUSH    HL            ; SAVE POINTER
  1470.     PUSH    BC            ; SAVE COUNTER AND SET/RESET BIT
  1471.      LD    HL,(MAXLEN)        ; GET MAXIMUM LENGHT ALV BUFFER
  1472.     OR    A            ; RESET CARRY
  1473.     SBC    HL,DE            ; TEST DE<=MAXLEN ALV BUFFER 
  1474.     CALL    NC,SETBIT        ; YES THEN INSERT BIT
  1475.     POP    BC            ; GET COUNTER AND SET/RESET BIT
  1476.     POP    HL            ; GET POINTER
  1477. FILLB2:    DJNZ    FILLB0            ; REPEAT FOR ALL DM ENTRIES
  1478.     RET                ; AND RETURN TO CALLER
  1479. ;
  1480. ; SET WRITE PROTECT DISK COMMAND
  1481. ;
  1482. CMND28:
  1483. ;
  1484. ; SET WRITE PROTECT DISK
  1485. ;
  1486. SETWPD:    LD    HL,(DSKRO)        ; GET DISK R/O VECTOR
  1487.     CALL    SDRVB            ; INCLUDE DRIVE BIT
  1488.     LD    (DSKRO),HL        ; SAVE DISK R/O BIT
  1489.     LD    DE,(NFILES)        ; GET MAXIMUM NUMBER OF FILES-1 
  1490.     INC    DE            ; INCREMENT IT 
  1491.     LD    HL,(TEMP0)        ; GET POINTER TO DISK PARAMETER BLOCK 
  1492.     LD    (HL),E            ; AND SAVE NUMBER OF FILES
  1493.     INC    HL
  1494.     LD    (HL),D
  1495.     RET                ; AND RETURN TO CALLER
  1496. ;
  1497. ; CHECK FILE R/O BIT
  1498. ;
  1499. CHKFRO:    CALL    CALDIR            ; GET DIRECTORY ENTRY
  1500. CHKFR0:    LD    DE,2            ; OFFSET TO PUBLIC FILE BIT
  1501.     ADD    HL,DE            ; ADD OFFSET
  1502.     BIT    7,(HL)            ; TEST PUBLIC FILE
  1503.     JR    NZ,CHKFR1        ; YES THEN ERROR
  1504.     LD    E,7            ; OFFSET TO FILE R/O BIT
  1505.     ADD    HL,DE            ; ADD OFFSET
  1506.     BIT    7,(HL)            ; TEST FILE R/O
  1507.     JR    NZ,CHKFR1        ; YES THEN ERROR
  1508.     INC    HL            ; INCREMENT TO SYSTEM FILE 
  1509.     BIT    7,(HL)            ; TEST SYSTEM FILE
  1510.     RET    Z            ; NO SYSTEM FILE THEN OK
  1511. CHKFR1:    LD    HL,(SFILRO)        ; GET POINTER TO FILE R/O MESSAGE
  1512.     JP    (HL)            ; DISPLAY MESSAGE
  1513. ;
  1514. ; CHECK DRIVE READ ONLY
  1515. ;
  1516. CHKRO:    LD    HL,(DSKRO)        ; GET DRIVE R/O VECTOR
  1517.     CALL    SDRVB            ; SET DRIVE BIT
  1518.     SBC    HL,DE            ; TEST EXTRA BIT ADDED
  1519.     RET    NZ            ; YES THEN DRIVE NOT R/O
  1520.     LD    HL,(STRO)        ; GET POINTER TO DRIVE R/O MESSAGE
  1521.     JP    (HL)            ; DISPLAY MESSAGE
  1522. ;
  1523. ; GET FREE BLOCK FROM ALV BUFFER
  1524. ;  ENTRY DE=OLD BLOCK NUMBER
  1525. ;  EXIT  DE=NEW BLOCK NUMBER (0 IF NO FREE BLOCK)
  1526. ;   HL COUNTS UP,DE COUNTS DOWN
  1527. ;
  1528. GETFRE:    LD    H,D            ; COPY OLD BLOCK TO HL
  1529.     LD    L,E
  1530. GETFR0:    LD    A,D            ; TEST DOWN COUNTER IS ZERO
  1531.     OR    E
  1532.     JR    Z,GETFR1        ; YES THEN JUMP
  1533.     DEC    DE            ; DECREMEMT DOWN COUNTER
  1534.     PUSH    HL            ; SAVE UP/DOWN COUNTER
  1535.     PUSH    DE
  1536.     CALL    GETBIT            ; GET BIT FROM ALV BUFFER
  1537.     RRA                ; TEST IF ZERO
  1538.     JR    NC,GETFR3        ; YES THEN FOUND EMPTY BLOCK
  1539.     POP    DE            ; GET UP/DOWN COUNTER
  1540.     POP    HL
  1541. GETFR1:    LD    BC,(MAXLEN)        ; GET MAXIMUM ALV LENGHT-1 IN BC
  1542.     OR    A            ; CLEAR CARRY
  1543.     SBC    HL,BC            ; TEST HL>=LENGHT ALV-1
  1544.     ADD    HL,BC            ; RESTORE HL (FLAGS ARE NOT AFFECTED)
  1545.     JR    NC,GETFR2        ; END BUFFER THEN JUMP
  1546.     INC    HL            ; INCREMENT UP COUNTER
  1547.     PUSH    DE            ; SAVE DOWN/UP COUNTER
  1548.     PUSH    HL
  1549.     EX    DE,HL            ; SAVE UP COUNTER IN DE
  1550.     CALL    GETBIT            ; GET BIT FROM ALV BUFFER
  1551.     RRA                ; TEST IF ZERO
  1552.     JR    NC,GETFR3        ; YES THEN FOUND EMPTY BLOCK
  1553.     POP    HL            ; GET DOWN/UP COUNTER
  1554.     POP    DE
  1555.     JR    GETFR0            ; AND TEST NEXT BLOCK 
  1556. GETFR2:    LD    A,D            ; TEST IF LAST BLOCK TESTED
  1557.     OR    E
  1558.     JR    NZ,GETFR0        ; NO THEN TEST NEXT BLOCK
  1559.     RET                ; EXIT (DE=0)
  1560. GETFR3:    SCF                ; SET BLOCK NUMBER USED
  1561.     RLA                ; SAVE BIT
  1562.     CALL    SETBT0            ; PUT BIT IN ALV BUFFER
  1563.     POP    DE            ; GET CORRECT COUNTER
  1564.     POP    HL            ; RESTORE STACK POINTER
  1565.     RET                ; EXIT (DE=BLOCK NUMBER)
  1566. ;
  1567. ; SEARCH FOR FILE NAME
  1568. ;  ENTRY: A : NUMBER OF BYTES TO SEARCH FOR
  1569. ;
  1570. SEARCH:    LD    (SEARNB),A        ; SAVE NUMBER OF BYTES
  1571.     LD    A,0FFH            ; SET EXIT CODE TO 0FFH (NOT FOUND)
  1572.     LD    (SEAREX),A
  1573.     LD    (DCOPY),IX        ; COPY FCB POINTER TO RAM (SEARCH NEXT)
  1574.     CALL    SETFCT            ; INITIATE FILE COUNTER
  1575. ;
  1576. ; SEARCH NEXT FILE NAME
  1577. ;
  1578. SEARCN:    XOR    A            ; CHECK CHECKSUM DIRECTORY
  1579.     CALL    RDDIR            ; GET FCB FROM DIRECTORY
  1580.     CALL    TSTFCT            ; TEST IF PAST LAST ENTRY
  1581.     JR    Z,SEARC8        ; YES THEN JUMP
  1582.     LD    DE,(DCOPY)        ; GET FCB POINTER
  1583.     LD    A,(DE)            ; GET FIRST BYTE
  1584.     CP    0E5H            ; TEST IF SEARCHING EMPTY DIRECTORY
  1585.     JR    Z,SEARC1        ; YES THEN JUMP
  1586.     PUSH    DE            ; SAVE FCB POINTER
  1587.     CALL    TSTLF            ; TEST LAST FILE ON THIS DRIVE
  1588.     POP    DE            ; RESTORE FCB POINTER
  1589.     JR    NC,SEARC8        ; YES THEN JUMP
  1590. SEARC1:    CALL    CALDIR            ; GET ENTRY IN DIRECTORY
  1591.     LD    A,(HL)            ; GET FIRST BYTE DIRECTORY ENTRY
  1592.     CP    021H            ; TEST TIME STAMP
  1593.     JR    Z,SEARCN        ; YES THEN GET NEXT DIRECTORY ENTRY
  1594.     LD    A,(SEARNB)        ; GET NUMBER OF BYTES TO SEARCH FOR
  1595.     LD    B,A            ; SAVE IT IN COUNTER
  1596.     XOR    A            ; CLEAR ACCU
  1597.     LD    (SEARQU),A        ; CLEAR QUESTION MARK DETECTED FLAG
  1598.     LD    (SEARPU),A        ; CLEAR PUBLIC FILE FLAG
  1599.     LD    C,A            ; CLEAR COUNTER
  1600. SEARC2:    LD    A,B            ; TEST IF COUNTER IS ZERO
  1601.     OR    A
  1602.     JR    Z,SEARC9        ; YES THEN JUMP
  1603.     LD    A,(DE)            ; GET BYTE FROM FCB
  1604.     SUB    '?'            ; TEST IF QUESTION MARK
  1605.     JR    Z,SEARC6        ; YES THEN JUMP
  1606.     LD    A,C            ; GET FCB COUNTER
  1607.     OR    A            ; TEST FIRST BYTE
  1608.     JR    NZ,SEARC3        ; NO THEN JUMP
  1609.     LD    A,(FLAGS)        ; GET FLAG BYTE
  1610.     BIT    0,A            ; TEST PUBLIC FILE ENABLE
  1611.     JR    Z,SEARC3        ; NO THEN JUMP
  1612.     INC    HL            ; GET POINTER TO PUBLIC BIT
  1613.     INC    HL
  1614.     BIT    7,(HL)            ; TEST PUBLIC BIT DIRECTORY
  1615.     DEC    HL            ; RESTORE POINTER
  1616.     DEC    HL
  1617.     JR    Z,SEARC3        ; NO PUBLIC FILE THEN JUMP
  1618.     LD    A,(DE)            ; GET FIRST BYTE FCB
  1619.     CP    0E5H            ; TEST IF SEARCHING EMPTY DIRECTORY
  1620.     JR    Z,SEARC3        ; YES THEN JUMP
  1621.     XOR    (HL)            ; TEST FCB=DIRECTORY ENTRY
  1622.     AND    07FH            ; MASK IT
  1623.     JR    Z,SEARC5        ; YES THEN JUMP
  1624.     AND    0E0H            ; MASK USER NUMBER
  1625.     JR    NZ,SEARC3        ; NOT THE SAME THEN JUMP
  1626.     DEC    A            ; A=0FFH
  1627.     LD    (SEARPU),A        ; SET PUBLIC FILE FOUND
  1628.     JR    SEARC5            ; JUMP FOUND
  1629. SEARC3:    LD    A,C            ; GET FCB COUNTER
  1630.     CP    13            ; TEST IF USER CODE
  1631.     JR    Z,SEARC5        ; YES THEN NO TEST
  1632.     CP    12            ; TEST IF EXTEND NUMBER
  1633.     LD    A,(DE)            ; GET BYTE FROM FCB
  1634.     JR    Z,SEARC7        ; JUMP IF EXTEND NUMBER
  1635.     XOR    (HL)            ; TEST BYTE FCB=BYTE DIRECTORY ENTRY
  1636.     AND    07FH            ; MASK IT
  1637. SEARC4:    JR    NZ,SEARCN        ; NOT THE SAME THEN GET NEXT ENTRY
  1638. SEARC5:    INC    DE            ; INCREMENT POINTER FCB
  1639.     INC    HL            ; INCREMENT POINTER DIRECTORY ENTRY
  1640.     INC    C            ; INCREMENT COUNTER
  1641.     DEC    B            ; DECREMENT COUNTER
  1642.     JR    SEARC2            ; TEST NEXT BYTE
  1643. SEARC6:    DEC    A            ; SET QUESTION MARK FOUND FLAG
  1644.     LD    (SEARQU),A        
  1645.     JR    SEARC5            ; JUMP FOUND
  1646. SEARC7:    PUSH    BC            ; SAVE COUNTERS
  1647.     XOR    (HL)            ; TEST EXTENDS
  1648.     LD    B,A            ; SAVE IT
  1649.     LD    A,(NEXTND)        ; GET EXTEND MASK
  1650.     CPL                ; COMPLEMENT IT
  1651.     AND    01FH            ; MASK IT
  1652.     AND    B            ; MASK EXTENDS
  1653.     POP    BC            ; RETORE COUNTERS
  1654.     JR    SEARC4            ; AND TEST RESULT
  1655. SEARC8:    CALL    SETFCT            ; ERROR SET FILE COUNTER
  1656.     LD    A,0FFH            ; AND SET EXIT CODE
  1657.     LD    (PEXIT),A
  1658.     RET                ; RETURN TO CALLER
  1659. SEARC9:    LD    A,(SEARQU)        ; GET QUESTION MARK FOUND FLAG
  1660.     LD    B,A            ; SAVE IT
  1661.     LD    A,(SEARPU)        ; GET PUBLIC FILE FLAG
  1662.     AND    B            ; TEST IF PUBLIC FILE AND QUESTION MARK
  1663.     JR    NZ,SEARC4        ; YES THEN SEARCH FOR NEXT ENTRY
  1664.     CALL    SETLF            ; UPDATE LAST FILE COUNT (EMPTY FCB)
  1665.     LD    A,(FILCNT)        ; GET FILE COUNTER
  1666.     AND    3            ; MASK IT
  1667.     LD    (PEXIT),A        ; AND SET EXIT CODE
  1668.     XOR    A            ; CLEAR EXIT CODE SEARCH
  1669.     LD    (SEAREX),A
  1670.     RET                ; AND RETURN TO CALLER
  1671. ;
  1672. ;DELETE FILE
  1673. ;
  1674. DELETE:    CALL    CHKRO            ; CHECK DISK R/O
  1675.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  1676.     CALL    SEARCH            ; SEARCH FILE
  1677. DEL0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  1678.     RET    Z            ; NOT THEN EXIT
  1679.     CALL    CHKFRO            ; CHECK FILE R/O
  1680.     CALL    CALDIR            ; GET ENTRY POINT DIRECTORY
  1681.     LD    (HL),0E5H        ; REMOVE FILE
  1682.     LD    C,0            ; REMOVE BITS ALV BUFFER
  1683.     CALL    FILLBB 
  1684.     CALL    WRFCB1            ; WRITE DIRECTORY BUFFER ON DISK
  1685.     CALL    SEARCN            ; SEARCH NEXT ENTRY
  1686.     JR    DEL0            ; AND TEST IT
  1687. ;
  1688. ; RENAME FILE
  1689. ;
  1690. RENAM:    CALL    CHKRO            ; CHECK DISK R/O
  1691.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  1692.     CALL    SEARCH            ; SEARCH FILE
  1693. RENAM0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  1694.     RET    Z            ; NOT THEN EXIT
  1695.     CALL    CHKFRO            ; CHECK FILE R/O
  1696.     LD    BC,12*256+16        ; COPY FCB+16 TO DIRECTORY+0 12 TIMES
  1697.     CALL    WRFCB            ; AND WRITE DIRECTORY ON DISK
  1698.     CALL    SEARCN            ; SEARCH NEXT FILE
  1699.     JR    RENAM0            ; AND TEST IT
  1700. ;
  1701. ; CHANGE STATUS FILE
  1702. ;
  1703. CSTAT:    CALL    CHKRO            ; CHECK DISK R/O
  1704.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  1705.     CALL    SEARCH            ; SEARCH FILE
  1706. CSTAT0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  1707.     RET    Z            ; NOT THEN EXIT
  1708.     LD    BC,12*256+0        ; COPY FCB+0 TO DIRECTORY+0 12 TIMES
  1709.     CALL    WRFCB            ; AND WRITE DIRECTORY TO DISK
  1710.     CALL    SEARCN            ; SEARCH NEXT FILE
  1711.     JR    CSTAT0            ; AND TEST IT
  1712. ;
  1713. ; COMPUTE FILE SIZE
  1714. ;
  1715. FILSZ:    LD    BC,0            ; RESET FILE SIZE LENGHT
  1716.     LD    D,C
  1717.     CALL    LDRRC            ; SAVE IT IN FCB+33,34,35
  1718.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  1719.     CALL    SEARCH            ; SEARCH FILE
  1720. FILSZ0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  1721.     RET    Z            ; NOT THEN EXIT
  1722.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  1723.     EX    DE,HL            ; COPY TO DE
  1724.     LD    HL,15            ; OFFSET TO NEXT RECORD
  1725.     CALL    CALRRC            ; CALCULATE RANDOM RECORD COUNT
  1726.     LD    A,D            ; TEST LSB < (IX+33)
  1727.     SUB    (IX+33)
  1728.     LD    A,C            ; TEST ISB < (IX+34)
  1729.     SBC    A,(IX+34)
  1730.     LD    A,B            ; TEST MSB < (IX+35)
  1731.     SBC    A,(IX+35)
  1732.     CALL    NC,LDRRC        ; WRITE NEW MAXIMUM
  1733.     CALL    SEARCN            ; SEARCH NEXT FILE
  1734.     JR    FILSZ0            ; AND TEST IT
  1735. ;
  1736. ; WRITE FCB ON DISK
  1737. ;
  1738. WRFCB:    CALL    CALDIR            ; GET DIRECTORY ENTRY
  1739.     PUSH    HL            ; SAVE POINTER
  1740.     LD    A,(HL)            ; GET USER CODE
  1741.     EX    DE,HL            ; COPY TO DE
  1742.     PUSH    IX            ; SAVE FCB ENTRY
  1743.     POP    HL            ; GET IT IN HL
  1744.     PUSH    BC            ; SAVE BC
  1745.     LD    B,0            ; RESET B FOR ADD
  1746.     ADD    HL,BC            ; ADD OFFSET FCB
  1747.     POP    BC            ; RESTORE BC
  1748.     LD    C,B            ; GET NUMBER OF BYTES TO MOVE
  1749.     LD    B,0            ; RESET B FOR LDIR
  1750.     LDIR                ; MOVE BYTES
  1751.     POP    HL            ; GET POINTER USER CODE
  1752.     LD    (HL),A            ; RESTORE IT
  1753. WRFCB1:    CALL    STDIR            ; CALCULATE SECTOR/TRACK DIRECTORY
  1754.     JP    WRITDR            ; WRITE DIRECTORY ON DISK
  1755. ;
  1756. ; FIND FILE
  1757. ;
  1758. FINDF:    LD    A,15            ; NUMBER OF BYTES TO SEARCH FOR 
  1759.     CALL    SEARCH            ; SEARCH FILE
  1760.     CALL    TSTFCT            ; TEST IF FILE PRESENT
  1761.     RET    NZ            ; YES THEN EXIT
  1762.     LD    A,(RDWR)        ; TEST IF WRITE FUNCTION
  1763.     OR    A            
  1764.     RET    NZ            ; YES THEN EXIT
  1765.     LD    A,(SEARQU)        ; TEST IF QUESTION MARK USED
  1766.     OR    A
  1767.     RET    NZ            ; YES THEN EXIT
  1768.     LD    HL,(PATH)        ; GET PATH ADDRESS
  1769.     LD    A,H            ; TEST IF ZERO (NO PATH)
  1770.     OR    L
  1771.     RET    Z            ; YES THEN EXIT
  1772. FINDF0:    LD    A,(HL)            ; GET FIRST ENTRY PATH NAME
  1773.     INC    HL            ; INCREMENT POINTER
  1774.     OR    A            ; TEST IF LAST ENTRY
  1775.     JP    Z,SEARC8        ; YES THEN ERROR EXIT 
  1776.     AND    07FH            ; MASK DRIVE NUMBER
  1777.     CP    '$'            ; TEST IF CURRENT DRIVE
  1778.     JR    NZ,FINDF1        ; NO THEN JUMP
  1779.     LD    A,(DRIVE)        ; GET CURRENT DRIVE
  1780.     INC    A            ; INCREMENT DRIVE NUMBER
  1781. FINDF1:    DEC    A            ; DECREMENT DRIVE NUMBER
  1782.     PUSH    HL            ; SAVE PATH POINTER
  1783.     CALL    SELDK            ; SELECT DRIVE
  1784.     POP    HL            ; RESTORE PATH POINTER
  1785.     LD    A,(HL)            ; GET USER NUMBER
  1786.     INC    HL            ; ADVANCE POINTER
  1787.     AND    07FH            ; MASK USER NUMBER
  1788.     CP    '$'            ; TEST IF CURRENT USER
  1789.     JR    NZ,FINDF2        ; NO THEN JUMP
  1790.     LD    A,(USER)        ; GET CURRENT USER
  1791. FINDF2:    AND    01FH            ; MASK USER NUMBER
  1792.     LD    B,A            ; SAVE IT
  1793.     LD    A,(IX+0)        ; GET FCB BYTE 0
  1794.     AND    0E0H            ; REMOVE USER NUMBER
  1795.     OR    B            ; ADD NEW USER NUMBER
  1796.     LD    (IX+0),A        ; AND SAVE IT
  1797.     PUSH    HL            ; SAVE PATH POINTER
  1798.     LD    A,15            ; SET NUMBER OF BYTES TO SEARCH FOR
  1799.     CALL    SEARCH            ; SEARCH FILE 
  1800.     CALL    TSTFCT            ; TEST IF FILE PRESENT
  1801.     POP    HL            ; RESTORE PATH POINTER
  1802.     JR    Z,FINDF0        ; NO THEN TEST NEXT PATH ENTRY
  1803.     PUSH    HL            ; SAVE PATH POINTER
  1804.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  1805.     LD    DE,10            ; ADD OFFSET SYSTEM BIT
  1806.     ADD    HL,DE
  1807.     BIT    7,(HL)            ; TEST SYSTEM FILE
  1808.     POP    HL            ; RESTORE PATH POINTER
  1809.     JR    Z,FINDF0        ; NO SYSTEM FILE THEN TEST NEXT PATH ENTRY
  1810.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  1811.     INC    A            ; INCREMENT DRIVE NUMBER
  1812.     LD    (FCB0),A        ; SAVE IT IN EXIT FCB0
  1813.     RET                ; AND RETURN TO CALLER
  1814. ;
  1815. ; OPEN FILE COMMAND
  1816. ;
  1817. CMND15:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1818.     LD    (IX+14),0        ; CLEAR FCB+14
  1819. ;
  1820. ; OPEN FILE
  1821. ;
  1822. OPENF:    CALL    FINDF            ; FIND FILE (USE PATH NAME)
  1823.     CALL    TSTFCT            ; TEST FILE FOUND
  1824.     RET    Z            ; NO THEN EXIT
  1825. OPENF0:    LD    A,(IX+12)        ; GET EXTEND NUMBER FROM FCB
  1826.     PUSH    AF            ; SAVE IT
  1827.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  1828.     PUSH    IX            ; SAVE FCB ENTRY
  1829.     POP    DE            ; GET IN IN DE
  1830.     LD    BC,32            ; NUMBER OF BYTES TO MOVE
  1831.     LDIR                ; MOVE DIRECTORY TO FCB
  1832.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  1833.     LD    B,(IX+12)        ; GET EXTEND NUMBER
  1834.     LD    C,(IX+15)        ; GET NEXT RECORD NUMBER
  1835.     POP    AF            ; GET OLD EXTEND NUMBER
  1836.     LD    (IX+12),A        ; SAVE IT
  1837.     CP    B            ; COMPARE OLD AND NEW EXTEND NUMBER
  1838.     JR    Z,OPENF1        ; SAME THEN JUMP
  1839.     LD    C,0            ; SET NEXT RECORD COUNT TO 0
  1840.     JR    NC,OPENF1        ; OLD EXTEND >= NEW EXTEND THEN JUMP
  1841.     LD    C,80H            ; SET NEXT RECORD COUNT TO MAXIMUM
  1842. OPENF1:    LD    (IX+15),C        ; SAVE NEXT RECORD COUNT
  1843.     RET                ; AND RETURN TO CALLER
  1844. ;
  1845. ; CLOSE FILE COMMAND
  1846. ;
  1847. CMND16:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1848. ;
  1849. ; CLOSE FILE
  1850. ;
  1851. CLOSE:    BIT    7,(IX+14)        ; TEST FCB/FILE MODIFIED
  1852.     RET    NZ            ; NOT THEN NO CLOSE REQUIRED
  1853.     CALL    CHKRO            ; TEST DISK R/O
  1854.     LD    A,15            ; NUMBER OF BYTES TO SEARCH FOR
  1855.     CALL    SEARCH            ; SEARCH FILE
  1856.     CALL    TSTFCT            ; TEST FILE PRESENT
  1857.     RET    Z            ; NO THEN EXIT
  1858.     CALL    CHKFRO            ; CHECK FILE R/O
  1859.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  1860.     LD    BC,16            ; OFFSET TO DM BLOCK 
  1861.     ADD    HL,BC            ; ADD OFFSET
  1862.     EX    DE,HL            ; SAVE HL IN DE
  1863.     PUSH    IX            ; SAVE FCB POINTER
  1864.     POP    HL            ; GET IT IN HL
  1865.     ADD    HL,BC            ; ADD OFFSET
  1866.     LD    A,(MAXLEN+1)        ; TEST NUMBER OF BLOCK >= 256
  1867.     OR    A            
  1868.     JR    Z,CLOSE0        ; NO THEN JUMP
  1869.     DEC    B            ; SET FLAG
  1870. CLOSE0:    CALL    COPYDM            ; COPY AND TEST BLOCKS
  1871.     EX    DE,HL            ; EXCHANGE COPY DIRECTION
  1872.     CALL    COPYDM            ; COPY AND TEST BLOCKS
  1873.     EX    DE,HL            ; EXCHANGE COPY DIRECTION
  1874.     JR    NZ,CLOSE4        ; BLOCK NOT THE SAME THEN ERROR
  1875.     INC    HL            ; INCREMENT POINTER FCB
  1876.     INC    DE            ; INCREMENT POINTER DIRECTORY
  1877.     BIT    0,B            ; TEST NUMBER OF BLOCK >= 256
  1878.     JR    Z,CLOSE1        ; NO THEN JUMP
  1879.     INC    HL            ; INCREMENT POINTER FCB
  1880.     INC    DE            ; INCREMENT POINTER DIRECTORY
  1881.     DEC    C            ; DECREMENT COUNTER
  1882. CLOSE1:    DEC    C            ; DECREMENT COUNTER
  1883.     JR    NZ,CLOSE0        ; NOT READY THEN JUMP
  1884.     LD    HL,-20            ; ADD -20 TO GET EXTEND NUMBER
  1885.     ADD    HL,DE            ; HL CONTAINS POINTER TO EXTEND NUMBER
  1886.     LD    A,(IX+12)        ; GET EXTEND NUMBER FCB
  1887.     CP    (HL)            ; COMPARE WITH EXTEND NUMBER DIRECTORY
  1888.     JR    C,CLOSE3        ; FCB < DIRECTORY THEN JUMP
  1889.     LD    (HL),A            ; SAVE EXTEND NUMBER IN DIRECTORY
  1890.     INC    HL            ; GET POINTER TO NEXT RECORD
  1891.     INC    HL
  1892.     INC    HL
  1893.     LD    A,(IX+15)        ; GET NEXT RECORD FCB
  1894. ;
  1895. ; THESE LINES HAVE TO BE REMOVED TO LET SUBMIT WORK CORRECTLY
  1896. ;
  1897. ;    JR    NZ,CLOSE2        ; EXTENDS NOT EQUAL THEN JUMP
  1898. ;    CP    (HL)            ; TEST FCB < DIRECTORY
  1899. ;    JR    C,CLOSE3        ; IF SO THEN JUMP
  1900. ;
  1901. CLOSE2:    LD    (HL),A            ; SAVE NEXT RECORD IN DIRECTORY
  1902. CLOSE3:    LD    E,5            ; SET LAST UPDATE DATE/TIME
  1903.     CALL    STIME            ; UPDATE TIME
  1904.     JP    WRFCB1            ; WRITE FCB ON DISK
  1905. CLOSE4:    LD    A,0FFH            ; FLAG ERROR
  1906.     LD    (PEXIT),A 
  1907.     RET                ; AND RETURN TO CALLER
  1908. ;
  1909. ; COPY AND TEST DISK MAP
  1910. ;  ENTRY : HL : POINTER TO FIRST FCB
  1911. ;          DE : POINTER TO SECOND FCB
  1912. ;          B  : 000H LESS THEN 256 BLOCKS
  1913. ;               0FFH MORE OR EQUAL TO 256 BLOCKS
  1914. ;  EXIT  : ZERO : 1 BLOCKS ARE THE SAME
  1915. ;                 0 BLOCKS ARE NOT THE SAME
  1916. ;
  1917. COPYDM:    LD    A,(HL)            ; GET BYTE FIRST FCB
  1918.     BIT    0,B            ; TEST NUMBER OF BLOCKS >=256
  1919.     JR    Z,COPYD0        ; NO THEN JUMP
  1920.     INC    HL            ; INCREMENT POINTER
  1921.     OR    (HL)            ; TEST BYTE =0
  1922.     DEC    HL            ; DECREMENT POINTER
  1923. COPYD0:    OR    A            ; TEST BLOCK NUMBER IS ZERO
  1924.     JR    NZ,COPYD1        ; NO THEN COMPARE BLOCKS
  1925.     LD    A,(DE)            ; COPY BLOCK FROM OTHER FCB IN EMPTY LOCATION
  1926.     LD    (HL),A 
  1927.     BIT    0,B            ; TEST NUMBER OF BLOCKS >=256
  1928.     RET    Z            ; NO THEN EXIT
  1929.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBERS
  1930.     INC    DE
  1931.     LD    A,(DE)            ; COPY BLOCK FROM OTHER FCB IN EMPTY LOCATION
  1932.     LD    (HL),A
  1933.     JR    COPYD2            ; JUMP TRICK TO SAVE SPACE
  1934. COPYD1:    LD    A,(DE)            ; GET BLOCK NUMBER FIRST FCB
  1935.     SUB    (HL)            ; TEST IF THE SAME
  1936.     RET    NZ            ; NOT THEN RETURN
  1937.     OR    B            ; TEST IF >=256 BLOCKS
  1938.     RET    Z            ; NO THEN RETURN
  1939.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBERS
  1940.     INC    DE
  1941. COPYD2:    LD    A,(DE)            ; GET BLOCK NUMBER FIRST FCB
  1942.     SUB    (HL)            ; TEST IF THE SAME
  1943.     DEC    HL            ; DECREMENT BLOCK FCB POINTERS
  1944.     DEC    DE
  1945.     RET                ; AND EXIT TO CALLER
  1946. ;
  1947. ; MAKE FILE COMMAND
  1948. ;
  1949. CMND22:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1950.     LD    (IX+14),0        ; CLEAR FCB+14
  1951. ;
  1952. ; MAKE FILE
  1953. ;
  1954. MAKE:    CALL    CHKRO            ; CHECK DRIVE R/O
  1955.     LD    A,(IX+0)        ; GET FIRST BYTE FCB
  1956.     PUSH    AF            ; SAVE IT
  1957.     LD    (IX+0),0E5H        ; SET FIRST BYTE TO EMPTY FILE
  1958.     LD    A,1            ; SEARCH FOR 1 BYTE
  1959.     CALL    SEARCH            ; SEARCH EMTY FILE
  1960.     POP    AF            ; GET FIRST BYTE FCB
  1961.     LD    (IX+0),A        ; RESTORE IT
  1962.     CALL    TSTFCT            ; TEST EMPTY FILE FOUND
  1963.     RET    Z            ; NO THEN RETURN ERROR
  1964.     XOR    A            ; CLEAR FCB+13
  1965.     LD    (IX+13),A
  1966.     PUSH    IX            ; SAVE FCB POINTER
  1967.     POP    HL            ; GET IT BACK IN HL
  1968.     LD    DE,15            ; PREPARE OFFSET
  1969.     ADD    HL,DE            ; ADD IT
  1970.     LD    B,17            ; SET LOOP COUNTER
  1971. MAKE0:    LD    (HL),A            ; CLEAR FCB+15 UNP TO FCB+31
  1972.     INC    HL            ; INCREMENT POINTER
  1973.     DJNZ    MAKE0            ; AND CLEAR ALL BYTES
  1974.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  1975.     LD    A,(IX+0)        ; GET FIRST BYTE FCB
  1976.     LD    (HL),A            ; SAVE IT IN DIRECTORY (WRITE FCB NEEDS THIS)
  1977.     LD    E,1            ; SET CREATION DATE/TIME
  1978.     CALL    STIME            ; UPDATE TIME IN DIRECTORY 
  1979.     LD    E,5            ; SET LAST UPDATE DATE/TIME
  1980.     CALL    STIME            ; UPDATE TIME IN DIRECTORY
  1981.     LD    BC,32*256+0        ; COPY FCB+0 TO DIRECTOTY+0 32 TIMES
  1982.     CALL    WRFCB            ; WRITE FCB ON DISK
  1983.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  1984.     RET                ; AND RETURN TO CALLER
  1985. ;
  1986. ; OPEN NEXT EXTEND
  1987. ;
  1988. OPENEX:    BIT    7,(IX+14)        ; TEST IF FCB/FILE MODIFIED (WRITE)
  1989.     JR    NZ,OPENX2        ; NOT THEN JUMP
  1990.     CALL    CLOSE            ; CLOSE CURRENT FCB
  1991.     LD    A,(PEXIT)        ; GET EXIT CODE
  1992.     INC    A            ; TEST IF ERROR
  1993.     RET    Z            ; YES THEN EXIT
  1994.     CALL    CALNEX            ; CALCULATE NEXT EXTEND
  1995.     JR    C,OPENX3        ; ERROR THEN JUMP
  1996.     JR    NZ,OPENX5        ; FCB PRESENT FROM CLOSE THEN JUMP
  1997. OPENX0:    LD    A,15            ; SEARCH FIRST 15 BYTES
  1998.     CALL    SEARCH            ; SEARCH FOR FILE
  1999. OPENX1:    CALL    TSTFCT            ; TEST IF FILE FOUND
  2000.     JR    NZ,OPENX5        ; YES THEN JUMP
  2001.     LD    A,(RDWR)        ; TEST READ/WRITE FLAG
  2002.     OR    A            ; TEST IF READ
  2003.     JR    Z,OPENX3        ; YES THEN ERROR
  2004.     CALL    MAKE            ; MAKE NEW EXTEND IF WRITE
  2005.     CALL    TSTFCT            ; TEST IF SUCCESFULL
  2006.     JR    NZ,OPENX6        ; YES THEN EXIT
  2007.     JR    OPENX3            ; NO THEN ERROR
  2008. OPENX2:    CALL    CALNEX            ; CALCULATE NEXT EXTEND
  2009.     JR    C,OPENX3        ; ERROR THEN JUMP
  2010.     BIT    7,(IX+10)        ; TEST SYSTEM FILE BIT
  2011.     JR    Z,OPENX0        ; NO SYSTEM FILE THEN JUMP
  2012.     CALL    FINDF            ; SEARCH PATH FOR FILE
  2013.     JR    OPENX1            ; USE SAME ROUTINE
  2014. OPENX3:    SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED 
  2015.     LD    A,0FFH            ; SET EXIT CODE
  2016. OPENX4:    LD    (PEXIT),A        
  2017.     RET                ; AND RETURN TO CALLER
  2018. OPENX5:    CALL    OPENF0            ; OPEN FILE
  2019. OPENX6:    XOR    A            ; AND CLEAR EXIT CODE
  2020.     JR    OPENX4            ; USE SAME ROUTINE 
  2021. ;
  2022. ; CALCULATE NEXT EXTEND
  2023. ;  EXIT: CARRY=1 => OVERFLOW DETECTED
  2024. ;        ZERO =1 => SEARCH NEXT EXTEND
  2025. ;     ZERO =0 => NEXT EXTEND PRESENT (CLOSE)
  2026. ;
  2027. CALNEX:    LD    B,(IX+12)        ; GET EXTEND NUMBER
  2028.     LD    C,(IX+14)        ; GET FCB+14
  2029.     BIT    6,C            ; TEST ERROR BIT RANDOM RECORD
  2030.     SCF                ; SET ERROR FLAG
  2031.     RET    NZ            ; NON ZERO THEN ERROR EXIT
  2032.     INC    B            ; INCREMENT EXTEND NUMBER
  2033.     LD    A,B            ; GET EXTEND NUMBER
  2034.     AND    01FH            ; MASK IT
  2035.     LD    B,A            ; SAVE IT IN B
  2036.     JR    NZ,CALNX0        ; NON ZERO THEN JUMP
  2037.     INC    C            ; INCREMENT FCB+14
  2038.     LD    A,C            ; GET IT IN A
  2039.     AND    03FH            ; MASK IT
  2040.     LD    C,A            ; SAVE IT IN C
  2041.     SCF                ; SET ERROR FLAG
  2042.     RET    Z            ; AND RETURN IF FILE OVERFLOW
  2043.     XOR    A            ; CLEAR ZERO FLAG (NOT SAME EXTEND)
  2044.     JR    CALNX1            ; AND SAVE EXTEND NUMBER AND FCB+14
  2045. CALNX0:    LD    A,(NEXTND)        ; GET NEXT EXTEND MASK
  2046.     AND    B            ; TEST IF SAME EXTEND (CLOSE)
  2047. CALNX1:    LD    (IX+12),B        ; SAVE EXTEND NUMBER
  2048.     LD    (IX+14),C        ; SAVE FCB+14
  2049.     RET                ; AND RETURN TO CALLER
  2050. ;
  2051. ; READ RANDOM RECORD COMMAND
  2052. ;
  2053. CMND33:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  2054. ;
  2055. ; READ RANDOM SECTOR
  2056. ;
  2057. RDRAN:    XOR    A            ; SET READ/WRITE FLAG
  2058.     CALL    LDFCB            ; LOAD RANDOM RECORD IN FCB
  2059.     JR    Z,READS            ; NO ERROR THEN READ SECTOR
  2060.     RET                ; RETURN ERROR 
  2061. ;
  2062. ; READ SEQUENTIAL
  2063. ;
  2064. CMND20:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  2065. ;
  2066. ; READ SECTOR
  2067. ;
  2068. READS:    XOR    A            ; SET READ/WRITE FLAG
  2069.     LD    (RDWR),A        ; SAVE IT
  2070.     LD    A,(IX+32)        ; GET RECORD COUNTER
  2071.     CP    080H            ; TEST IF LAST RECORD THIS EXTEND
  2072.     JR    NC,READS1        ; YES THEN OPEN NEXT EXTEND
  2073.     CP    (IX+15)            ; TEST IF GREATER THEN CURRENT RECORD
  2074.     JR    C,READS2        ; NO THEN GET RECORD
  2075. READS0:    LD    A,1            ; SET END OF FILE FLAG
  2076.     LD    (PEXIT),A        ; SAVE IT
  2077.     RET                ; AND RETURN TO CALLER
  2078. READS1:    CALL    OPENEX            ; OPEN NEXT EXTEND
  2079.     LD    A,(PEXIT)        ; GET EXIT CODE
  2080.     OR    A
  2081.     JR    NZ,READS0        ; YES THEN END OF FILE
  2082.     LD    (IX+32),0        ; CLEAR RECORD COUNTER
  2083. READS2:    CALL    GETDM            ; GET BLOCK NUMBER FROM DM IN FCB
  2084.     LD    A,D            ; TEST BLOCK NUMBER = 0
  2085.     OR    E
  2086.     JR    Z,READS0        ; YES THEN END FILE
  2087.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  2088.     CALL    CALST            ; CALCULATE SECTOR/TRACK NUMBER
  2089.     CALL    READR            ; READ DATA
  2090.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  2091.     CP    20            ; TEST IF READ SEQUENTIAL
  2092.     RET    NZ            ; NO THEN RETURN
  2093.     INC    (IX+32)            ; INCREMENT NEXT RECORD COUNTER
  2094.     RET                ; AND RETURN TO CALLER
  2095. ;
  2096. ; WRITE RANDOM SECTOR WITH ZERO FILL COMMAND
  2097. ;
  2098. CMND40:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  2099. ;
  2100. ; WRITE RANDOM SECTOR WITH ZERO FILL
  2101. ;
  2102. WRRANZ:    LD    A,0FFH            ; SET READ/WRITE FLAG
  2103.     CALL    LDFCB            ; LOAD FCB FROM RANDOM RECORD
  2104.     JR    Z,WRITES        ; NO ERROR THEN WRITE RECORD
  2105.     RET                ; RETURN ERROR
  2106. ;
  2107. ; WRITE RANDOM RECORD COMMAND
  2108. ;
  2109. CMND34:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  2110. ;
  2111. ; WRITE RANDOM SECTOR
  2112. ;
  2113. WRRAN:    LD    A,0FFH            ; SET READ/WRITE FLAG
  2114.     CALL    LDFCB            ; LOAD FCB FROM RANDOM RECORD
  2115.     JR    Z,WRITES        ; NO ERROR THEN WRITE RECORD
  2116.     RET                ; RETURN ERROR
  2117. ;
  2118. ; WRITE SEQUENTIAL
  2119. ;
  2120. CMND21:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  2121. ;
  2122. ; WRITE SECTOR
  2123. ;
  2124. WRITES:    LD    A,0FFH            ; SET READ/WRITE FLAG
  2125.     LD    (RDWR),A        ; AND SAVE IT
  2126.     CALL    CHKRO            ; CHECK DISK R/O
  2127.     PUSH    IX            ; SAVE FCB POINTER
  2128.     POP    HL            ; GET IT BACK IN HL
  2129.     CALL    CHKFR0            ; CHECK FILE R/O
  2130.     LD    A,(IX+32)        ; GET RECORD COUNT
  2131.     CP    080H            ; TEST IF END THIS EXTEND
  2132.     JR    C,WRITS0        ; YES THEN OPEN NEXT EXTEND
  2133.     CALL    OPENEX            ; OPEN NEXT EXTEND
  2134.     LD    A,(PEXIT)        ; GET ERROR CODE
  2135.     OR    A        
  2136.     JP    NZ,WRITS9        ; ERROR THEN DIRECTORY FULL ERROR
  2137.     LD    (IX+32),0        ; CLEAR RECORD COUNTER
  2138. WRITS0:    CALL    GETDM            ; GET BLOCK NUMBER FROM FCB
  2139.     LD    A,D            ; TEST IF BLOCK NUMBER = 0
  2140.     OR    E
  2141.     JR    NZ,WRITS5        ; NO THEN WRITE SECTOR
  2142.     PUSH    HL            ; SAVE POINTER TO BLOCK NUMBER
  2143.     LD    A,C            ; TEST FIRST BLOCK NUMBER IN EXTEND
  2144.     OR    A
  2145.     JR    Z,WRITS1        ; YES THEN JUMP
  2146.     DEC    A            ; DECREMENT POINTER TO BLOCK NUMBER
  2147.     CALL    GETDM4            ; GET PREVIOUS BLOCKNUMBER
  2148. WRITS1:    CALL    GETFRE            ; GET NEAREST FREE BLOCK
  2149.     POP    HL            ; GET POINTER TO BLOCK NUMBER
  2150.     LD    A,D            ; TEST IF BLOCKNUMBER = 0
  2151.     OR    E
  2152.     JR    Z,WRITS8        ; YES THEN DISK FULL ERROR
  2153.     RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED
  2154.     LD    (HL),E            ; SAVE BLOCKNUMBER
  2155.     LD    A,(MAXLEN+1)        ; GET NUMBER OF BLOCKS
  2156.     OR    A            ; TEST IF <256
  2157.     JR    Z,WRITS2        ; YES THEN JUMP
  2158.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBER
  2159.     LD    (HL),D            ; SAVE MSB BLOCK NUMBER
  2160. WRITS2:    LD    C,2            ; SET WRITE NEW BLOCK FLAG
  2161.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  2162.     SUB    40            ; TEST IF WRITE RR WITH ZERO FILL
  2163.     JR    NZ,WRITS6        ; NO THEN JUMP
  2164.     PUSH    DE            ; SAVE BLOCKNUMBER
  2165.      LD    HL,DIRBUF        ; USE DIRECTORY BUFFER FOR ZERO FILL
  2166.     LD    B,128            ; 128 BYTES TO CLEAR
  2167. WRITS3:    LD    (HL),A            ; CLEAR DIRECTORY BUFFER
  2168.     INC    HL            ; INCREMENT POINTER
  2169.     DJNZ    WRITS3            ; CLEAR ALL BYTES
  2170.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  2171.     LD    A,(NMASK)        ; GET SECTOR MASK
  2172.     LD    B,A            ; COPY IT
  2173.     INC    B            ; INCREMENT IT TO GET NUMBER OF WRITES
  2174.     CPL                ; COMPLEMENT SECTOR MASK
  2175.     AND    E            ; MASK SECTOR NUMBER
  2176.     LD    E,A            ; AND SAVE IT
  2177.     LD    C,2            ; SET WRITE NEW BLOCK FLAG
  2178. WRITS4:    PUSH    HL            ; SAVE REGISTERS
  2179.     PUSH    DE
  2180.     PUSH    BC
  2181.     CALL    CALST            ; CALCULATE SECTOR/TRACK
  2182.     CALL    DMADIR            ; SET DMA DIRECTORY BUFFER
  2183.     POP    BC            ; GET WRITE NEW BLOCK FLAG
  2184.     PUSH    BC            ; SAVE IT AGAIN
  2185.     CALL    WRITER            ; WRITE RECORD ON DISK
  2186.     POP    BC            ; RESTORE REGISTERS
  2187.     POP    DE
  2188.     POP    HL
  2189.     LD    C,0            ; CLEAR WRITE NEW BLOCK FLAG
  2190.     INC    E            ; INCREMENT SECTOR NUMBER
  2191.     DJNZ    WRITS4            ; WRITE ALL BLOCKS
  2192.     CALL    STDMA            ; SET USER DMA ADDRESS
  2193.     POP    DE            ; GET BLOCK NUMBER
  2194. WRITS5:    LD    C,0            ; CLEAR WRITE NEW BLOCK FLAG 
  2195. WRITS6:    RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED FLAG
  2196.     PUSH    BC            ; SAVE IT
  2197.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  2198.     CALL    CALST            ; CALCULATE SECTOR/TRACK
  2199.     POP    BC            ; GET WRITE NEW BLOCK FLAG
  2200.     CALL    WRITER            ; WRITE RECORD ON DISK
  2201.     LD    A,(IX+32)        ; GET RECORD COUNTER
  2202.     CP    (IX+15)            ; COMPARE WITH NEXT RECORD
  2203.     JR    C,WRITS7        ; IF LESS THEN JUMP
  2204.     INC    A            ; INCREMENT RECORD COUNT 
  2205.     LD    (IX+15),A        ; SAVE IT ON NEXT RECORD POSITION
  2206.     RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED FLAG
  2207. WRITS7:    LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  2208.     CP    21            ; TEST WRITE SEQUENTIAL
  2209.     RET    NZ            ; NOT THEN RETURN
  2210.     INC    (IX+32)            ; INCREMENT RECORD COUNT
  2211.     RET                ; AND RETURN TO CALLER
  2212. WRITS8:    LD    A,2            ; SET DISK FULL ERROR
  2213.     LD    (PEXIT),A
  2214.     RET                ; AND RETURN TO CALLER
  2215. WRITS9:    LD    A,1            ; SET DIRECTORY FULL FLAG
  2216.     LD    (PEXIT),A
  2217.     RET                ; AND RETURN TO CALLER
  2218. ;
  2219. ; LOAD FCB FOR RANDOM READ/WRITE
  2220. ;  EXIT : ZERO FLAG : 1 NO ERROR
  2221. ;                     0 ERROR OCCURED
  2222. ;
  2223. LDFCB:    LD    (RDWR),A        ; SAVE READ/WRITE FLAG
  2224.     LD    A,(IX+33)        ; GET FIRST BYTE RANDOM RECORD
  2225.     LD    D,A            ; SAVE IT IN D
  2226.     RES    7,D            ; RESET MSB TO GET NEXT RECORD
  2227.     RLA                ; SHIFT MSB IN CARRY
  2228.     LD    A,(IX+34)        ; LOAD NEXT BYTE RANDOM RECORD
  2229.     RLA                ; SHIFT CARRY
  2230.     PUSH    AF            ; SAVE IT
  2231.     AND    01FH            ; MASK NEXT EXTEND
  2232.     LD    C,A            ; SAVE IT IN C
  2233.     POP    AF            ; GET BYTE
  2234.     RLA                ; SHIFT 4 TIMES
  2235.     RLA
  2236.     RLA
  2237.     RLA
  2238.     AND    0FH            ; MASK IT
  2239.     LD    B,A            ; SAVE FCB+14
  2240.     LD    A,(IX+35)        ; GET NEXT BYTE RANDOM RECORD
  2241.     LD    E,6            ; SET RANDOM RECORD TO LARGE FLAG
  2242.     CP    4            ; TEST RANDOM RECORD TO LARGE 
  2243.     JR    NC,LDFCB8        ; YES THEN ERROR
  2244.     RLCA                ; SHIFT 4 TIMES
  2245.     RLCA
  2246.     RLCA
  2247.     RLCA
  2248.     ADD    A,B            ; ADD BYTE
  2249.     LD    B,A            ; SAVE FCB+14 IN B
  2250.     LD    (IX+32),D        ; SET NEXT RECORD COUNT
  2251.     LD    D,(IX+14)        ; GET FCB+14
  2252.     BIT    6,D            ; TEST ERROR RANDOM RECORD
  2253.     JR    NZ,LDFCB0        ; YES THEN JUMP
  2254.     LD    A,C            ; GET NEW EXTEND NUMBER
  2255.     CP    (IX+12)            ; COMPARE WITH FCB
  2256.     JR    NZ,LDFCB0        ; NOT EQUAL THEN OPEN NEXT EXTEND
  2257.     LD    A,B            ; GET NEW FCB+14
  2258.     XOR    (IX+14)            ; COMPARE WITH FCB+14
  2259.     AND    03FH            ; MASK IT
  2260.     JR    Z,LDFCB6        ; EQUAL THEN RETURN
  2261. LDFCB0:    BIT    7,D            ; TEST FCB MODIFIED (WRITE)
  2262.     JR    NZ,LDFCB1        ; NO THEN JUMP
  2263.     PUSH    DE            ; SAVE REGISTERS
  2264.     PUSH    BC
  2265.     CALL    CLOSE            ; CLOSE EXTEND
  2266.     POP    BC            ; RESTORE REGISTERS
  2267.     POP    DE
  2268.     LD    E,3            ; SET CLOSE ERROR
  2269.     LD    A,(PEXIT)        ; GET EXIT CODE
  2270.     INC    A
  2271.     JR    Z,LDFCB7        ; ERROR THEN EXIT
  2272. LDFCB1:    LD    (IX+12),C        ; SAVE NEW EXTEND NUMBER
  2273.     LD    (IX+14),B        ; SAVE NEW FCB+14
  2274.     BIT    7,D            ; TEST FCB MODIFIED (PREVIOUS FCB)
  2275.     JR    NZ,LDFCB3        ; NO THEN JUMP
  2276. LDFCB2:    LD    A,15            ; SET NUMBER OF BYTES TO SEARCH FOR
  2277.     CALL    SEARCH            ; SEARCH NEXT FCB
  2278.     JR    LDFCB4            ; JUMP
  2279. LDFCB3:    BIT    7,(IX+10)        ; TEST IF SYSTEM FILE
  2280.     JR    Z,LDFCB2        ; NO USE SEARCH
  2281.     CALL    FINDF            ; OPEN FILE (USE PATH NAME)
  2282. LDFCB4:    LD    A,(PEXIT)        ; GET ERROR CODE
  2283.     INC    A
  2284.     JR    NZ,LDFCB5        ; NO ERROR THEN EXIT
  2285.     LD    A,(RDWR)        ; GET READ/WRITE FLAG
  2286.     LD    E,4            ; SET READ EMPTY RECORD
  2287.     INC    A
  2288.     JR    NZ,LDFCB7        ; READ THEN ERROR
  2289.     CALL    MAKE            ; MAKE MEW FCB
  2290.     LD    E,5            ; SET MAKE ERROR
  2291.     LD    A,(PEXIT)        ; GET ERROR CODE
  2292.     INC    A
  2293.     JR    Z,LDFCB7        ; ERROR THEN EXIT
  2294.     JR    LDFCB6            ; NO ERROR EXIT (ZERO SET)
  2295. LDFCB5:    CALL    OPENF0            ; OPEN FILE
  2296. LDFCB6:    XOR    A            ; SET ZERO FLAG AND CLEAR ERROR CODE
  2297.     LD    (PEXIT),A
  2298.     RET                ; AND RETURN TO CALLER
  2299. LDFCB7:    LD    (IX+14),0C0H        ; SET RANDOM RECORD ERROR
  2300. LDFCB8:    LD    A,E            ; GET ERROR CODE
  2301.     LD    (PEXIT),A        ; AND SAVE IT
  2302.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  2303.     OR    A            ; CLEAR ZERO FLAG
  2304.     RET                ; AND RETURN TO CALLER
  2305. ;
  2306. ; CALCULATE RANDOM RECORD
  2307. ;  ENTRY HL=OFFSET IN FCB
  2308. ;        DE=FCB POINTER
  2309. ;  EXIT  D=LSB RANDOM RECORD
  2310. ;        C=ISB RANDOM RECORD
  2311. ;        B=MSB RANDOM RECORD
  2312. ;
  2313. CALRRC:    ADD    HL,DE            ; POINTER TO FCB+15 OR FCB+32
  2314.     LD    A,(HL)            ; GET BYTE
  2315.     LD    HL,12            ; OFFSET TO EXTEND NUMBER
  2316.     ADD    HL,DE            ; GET POINTER TO EXTEND BYTE
  2317.     LD    D,A            ; SAVE FIRST BYTE
  2318.     LD    A,(HL)            ; GET EXTEND BYTE
  2319.     AND    01FH            ; MASK IT
  2320.     RL    D            ; SHIFT MSB IN CARRY
  2321.     ADC    A,0            ; ADD CARRY
  2322.     RRA                ; SHIFT 1 TIME (16 BITS)
  2323.     RR    D
  2324.     LD    C,A            ; SAVE ISB
  2325.     INC    HL            ; INCREMENT TO FCB+14
  2326.     INC    HL
  2327.     LD    A,(HL)            ; GET FCB+14
  2328.     RRCA                ; SHIFT 4 TIMES
  2329.     RRCA
  2330.     RRCA
  2331.     RRCA
  2332.     PUSH    AF            ; SAVE IT
  2333.     AND    03H            ; MASK MSB
  2334.     LD    B,A            ; SAVE IT
  2335.     POP    AF            ; GET LSB
  2336.     AND    0F0H            ; MASK IT
  2337.     ADD    A,C            ; ADD WITH ISB
  2338.     LD    C,A            ; SAVE ISB
  2339.     RET    NC            ; NO CARRY THEN RETURN
  2340.     INC    B            ; INCREMENT MSB
  2341.     RET                ; AND RETURN TO CALLER
  2342. ;
  2343. ; SET TIME AND DATE
  2344. ;  ENTRY: E : 1 : SET CREATION TIME/DATE
  2345. ;             5 : SET LAST UPDATE TIME/DATE
  2346. ;  TIME RETURN POINTER IN HL
  2347. ;   HL+0 : LOW  BYTE DATE SINCE JAN,1,1978
  2348. ;   HL+1 : HIGH BYTE DATE SINCE JAN,1,1978
  2349. ;   HL+2 : HOURS   (BCD)
  2350. ;   HL+3 : MINUTES (BCD)
  2351. ;   HL+4 : SECONDS (BCD) (NOT USED IN TIME STAMP)
  2352. ;
  2353. STIME:    LD    HL,(DIRBUF)        ; GET DIRECTORY ENTRY
  2354.     LD    BC,060H            ; OFFSET ENTRY POINT TIME/DATE STAMP
  2355.     ADD    HL,BC            ; ADD OFFSET
  2356.     LD    A,(HL)            ; GET BYTE
  2357.     SUB    021H            ; TEST IF TIME STAMP PRESENT
  2358.     RET    NZ            ; NO THEN RETURN
  2359.     LD    D,A            ; CLEAR D
  2360.     ADD    HL,DE            ; ADD ENTRY (UPDATE/CREATE)
  2361.     LD    A,(SECPNT)        ; GET SECTOR POINTER
  2362.     RRCA                ; SHIFT 2 TIMES
  2363.     RRCA
  2364.     LD    E,A            ; SAVE IT
  2365.     RRCA                ; SHIFT 2 TIMES
  2366.     RRCA
  2367.     ADD    A,E            ; ADD IT (A=0,10,20)
  2368.     LD    E,A            ; SAVE IN E
  2369.     ADD    HL,DE            ; ADD OFFSET
  2370.     PUSH    HL            ; SAVE RESULT
  2371.     LD    C,0            ; RETURN POINTER IN HL
  2372.                     ; C=FF MEANS SET DATE POINTED TO BY HL
  2373.     CALL    BTIME            ; RETURN POINTER IN HL
  2374.     POP    DE            ; GET POINTER
  2375.     LD    BC,4            ; SET 4 BYTES
  2376.     LDIR                ; COPY 4 BYTES
  2377.     RET                ; AND RETURN TO CALLER
  2378. ;
  2379. ; GET TIME
  2380. ;
  2381. GETTIM:    PUSH    DE            ; SAVE ADDRESS TO PUT TIME 
  2382.     LD    C,0            ; GET TIME ADDRESS
  2383.     CALL    BTIME            ; EXECUTE P2BIOS CALL
  2384.     POP    DE            ; RESTORE ADDRESS TO PUT TIME
  2385.     LD    BC,5            ; 5 BYTES TO MOVE
  2386.     LDIR                ; STORE THE TIME
  2387.     RET                ; AND RETURN TO CALLER
  2388. ;
  2389. ; SET TIME
  2390. ;
  2391. SETTIM:    EX    DE,HL            ; GET ADDRESS TIME IN HL 
  2392.     LD    C,0FFH            ; SET TIME ADDRESS
  2393.                     ; AND FALL THROUGH TO P2BIOS CALL 
  2394. ;
  2395. ; EXECUTE P2BIOS TIME ROUTINE
  2396. ;
  2397. BTIME:    PUSH    HL            ; SAVE VALUE IN HL
  2398.     LD    HL,(TIMEAD)        ; GET ADDRESS TIME ROUTINE
  2399.     EX    (SP),HL            ; PUT ADDRESS ON STACK AND RESTORE HL
  2400.     RET                ; EXECUTE TIME ROUTINE
  2401. ;
  2402. ; P2DOS EXIT ROUTINE
  2403. ;
  2404. P2EXIT:    LD    A,(FLDRV)        ; TEST DRIVE SELECT USED FLAG
  2405.     OR    A            
  2406.     JR    Z,P2EXT0        ; NO THEN EXIT
  2407.     LD    A,(FCB0)        ; GET FCB BYTE 0
  2408.     LD    (IX+0),A        ; SAVE IT
  2409.     LD    A,(DRIVE)        ; GET OLD DRIVE NUMBER
  2410.     CALL    SELDK            ; SELECT DISK
  2411. P2EXT0:    PUSH    IX            ; SAVE IX
  2412.     POP    DE            ; RESTORE DE
  2413.     POP    IX            ; RESTORE IX
  2414.     LD    SP,(SPSAVE)        ; GET OLD SP
  2415.     LD    HL,(PEXIT)        ; GET EXIT CODE
  2416.     LD    A,(FUNCT)        ; GET FUNCTION CODE
  2417.     LD    C,A            ; RESTORE C
  2418.     LD    A,L            ; COPY FUNCTION CODE
  2419.     LD    B,H
  2420.     RET                ; AND RETURN TO CALLER
  2421. ;
  2422. ; RAM AREA
  2423. ;
  2424. TABCNT:    DEFB    0            ; TAB COUNTER
  2425. TABCX1:    DEFB    0            ; TEMPORARY TAB COUNTER (USED BY RDBUF)
  2426. FCONTP:    DEFB    0            ; LIST ENABLE FLAG (CONTROL P)
  2427. LASTCH:    DEFB    0            ; LAST CHARACTER
  2428. DELAY:    DEFB    0FFH            ; DELAY COUNTER
  2429. ;
  2430. TRANS:    DEFW    0            ; TRANSLATION VECTOR
  2431. TEMP0:    DEFW    0            ; NUMBER OF FILES ON DRIVE 
  2432. TEMP1:    DEFW    0            ; NOT USED 
  2433. TEMP2:    DEFW    0            ; NOT USED
  2434. DIRBUF:    DEFW    0            ; DIRECTORY BUFFER
  2435. IXP:    DEFW    0            ; DISK PARAMETER BLOCK
  2436. CSV:    DEFW    0            ; CHECK SUM POINTER
  2437. ALV:    DEFW    0            ; ALLOCATION VECTOR POINTER
  2438. ;
  2439. MAXSEC:    DEFW    0            ; MAXIMUM NUMBER OF SECTORS/TRACK
  2440. NBLOCK:    DEFB    0            ; NUMBER OF BLOCKS
  2441. NMASK:    DEFB    0            ; MASK NUMBER OF BLOCKS
  2442. NEXTND:    DEFB    0            ; EXTEND MASK
  2443. MAXLEN:    DEFW    0            ; MAXIMUM BLOCK NUMBER-1
  2444. NFILES:    DEFW    0            ; MAXIMUM NUMBER OF FILES-1
  2445. NDIR0:    DEFB    0            ; FIRST TWO ENTRIES ALV BUFFER
  2446. NDIR1:    DEFB    0
  2447. NCHECK:    DEFW    0            ; NUMBER OF CHECKSUM ENTRUIES
  2448. NFTRK:    DEFW    0            ; FIRST TRACK NUMBER
  2449. ;
  2450. DSKRO:    DEFW    0            ; DISK R/O VECTOR
  2451. LOGIN:    DEFW    0            ; LOGIN VECTOR
  2452. DMA:    DEFW    080H            ; DMA ADDRESS
  2453. ;
  2454. FUNCT:    DEFB    0            ; FUNCTION NUMBER
  2455. PEXIT:    DEFW    0            ; EXIT CODE
  2456. FLDRV:    DEFB    0            ; DRIVE SELECT USED FLAG
  2457. RDWR:    DEFB    0            ; READ/WRITE FLAG
  2458. ;
  2459. FCB0:    DEFB    0            ; FCB BYTE 0
  2460. USER:    DEFB    0            ; USER NUMBER
  2461. DRIVE:    DEFB    0            ; DRIVE NUMBER
  2462. DEFDRV:    DEFB    0            ; DEFAULT DRIVE NUMBER
  2463. RECDIR:    DEFW    0            ; RECORD DIRECTORY (CHECKSUM)
  2464. FILCNT:    DEFW    0            ; FILE COUNTER
  2465. SECPNT:    DEFB    0            ; SECTOR POINTER
  2466. SUBFLG:    DEFB    0            ; SUBMIT FLAG (RESET DISK COMMAND)
  2467. ;
  2468. DCOPY:    DEFW    0            ; COPY ADDRESS FCB
  2469. SEAREX:    DEFB    0            ; EXIT CODE SEARCH
  2470. SEARNB:    DEFB    0            ; SEARCH NUMBER OF BYTES
  2471. SEARQU:    DEFB    0            ; SEARCH QUESTION MARK USED
  2472. SEARPU:    DEFB    0            ; SEARCH PUBLIC FILE
  2473. ;
  2474. SPSAVE:    DEFW    0            ; STACK POINTER LOCATION
  2475.     DEFS    64            ; 64 BYTES STACK
  2476. P2DOSS:                    ; P2DOS STACK
  2477.     DEFB    '*END*'            ; JUST A REMINDER
  2478.     DEFS    40H,2AH            ; FOR ALL THE SPACE THAT'S LEFT
  2479.     DEFB    '48 BYTES RESERVE'
  2480.     DEFB    'D TO ACCOMODATE '
  2481.     DEFB    'THE ZCPR-2 STACK'
  2482. ;
  2483.     .DEPHASE
  2484.     END                ; END PROGRAM
  2485.