home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / BEEHIVE / OS / SUPRDOS2.ARC / DOS2.MAC < prev    next >
Text File  |  1990-09-21  |  44KB  |  1,498 lines

  1. ;       
  2. ; SELECT DISK
  3. ;
  4. CMND14:    LD    A,E            ; COPY DRIVE NUMBER
  5. ;
  6. ; SELECT DISK
  7. ;
  8. SELDK:    AND    0FH            ; MASK DRIVE NUMBER
  9.     LD    B,A            ; SAVE COUNTER
  10.     LD    DE,(LOGIN)        ; GET LOGIN VECTOR
  11.     OR    A            ; TEST DRIVE 'A'
  12.     JR    Z,SELDK1        ; YES THEN JUMP
  13. SELDK0:    RR    D            ; SHIFT LOGIN VECTOR
  14.     RR    E            ; UNTIL BIT 0 REGISTER E
  15.     DJNZ    SELDK0            ; IS CURRENT DRIVE
  16. SELDK1:    LD    HL,DEFDRV        ; GET POINTER LAST DRIVE
  17.     BIT    0,E            ; TEST IF DRIVE LOGGED IN
  18.     JR    Z,SELDK2        ; NO, LOGIN DRIVE
  19.     CP    (HL)            ; TEST SAME DRIVE
  20.     RET    Z            ; YES THEN EXIT
  21. SELDK2:    LD    (HL),A            ; SAVE NEW CURRENT DRIVE
  22.     PUSH    DE            ; SAVE DRIVE LOGGED IN FLAG
  23.     LD    C,A            ; COPY DRIVE NUMBER
  24.     CALL    SELDSK            ; DO P2BIOS SELECT 
  25.     LD    A,H            ; TEST IF ERROR 
  26.     OR    L
  27.     JR    Z,SELDK3        ; YES, ILLEGAL DRIVE NUMBER
  28.     LD    E,(HL)            ; GET LSB TRANSLATION VECTOR
  29.     INC    HL            ; INCREMENT POINTER
  30.     LD    D,(HL)            ; GET MSB TRANSLATION VECTOR
  31.     INC    HL            ; INCREMENT POINTER
  32.     LD    (TRANS),DE        ; SAVE TRANSLATION VECTOR
  33.     LD    (TEMP0),HL        ; SAVE ADDRESS TEMP0
  34.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  35.     INC    HL
  36.     LD    (TEMP1),HL        ; SAVE ADDRESS TEMP1
  37.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  38.     INC    HL
  39.     LD    (TEMP2),HL        ; SAVE ADDRESS TEMP2
  40.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  41.     INC    HL
  42.     LD    DE,DIRBUF        ; LOAD DIRBUF POINTER
  43.     LD    BC,8            ; COPY 8 BYTES
  44.     LDIR
  45.     LD    HL,(IXP)        ; GET DRIVE PARAMETER ADDRESS
  46.     LD    C,15            ; COPY 15 BYTES
  47.     LDIR
  48.     POP    DE            ; GET DRIVE LOGGED IN FLAG
  49.     BIT    0,E            ; TEST IT
  50.     RET    NZ            ; DRIVE LOGGED IN SO RETURN
  51.     LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  52.     CALL    SDRVB            ; SET DRIVE BIT IN LOGIN VECTOR
  53.     LD    (LOGIN),HL        ; SAVE LOGIN VECTOR
  54.     JR    INITDR            ; AND SETUP DRIVE TABLES
  55. SELDK3:    LD    HL,(STSEL)        ; LOAD ERROR MESSAGE ADDRESS
  56.     JP    (HL)            ; AND DISPLAY ERROR
  57. ;
  58. ; INIT DRIVE
  59. ;  CLEAR ALV BIT BUFFER AFTER DRIVE RESET
  60. ;
  61. INITDR:    LD    DE,(MAXLEN)        ; GET LENGTH ALV BUFFER-1 (BITS)
  62.     LD    A,3            ; DIVIDE BY 8
  63. INITD0:    SRL    D            ; TO GET BYTES
  64.     RR    E
  65.     DEC    A
  66.     JR    NZ,INITD0
  67.     INC    DE            ; INCREMENT, SO ALL BITS ARE CLEARED
  68.     LD    HL,(ALV)        ; GET POINTER ALV BUFFER
  69.     PUSH    HL
  70. INITD1:    LD    (HL),0            ; CLEAR 8 BITS
  71.     INC    HL            ; INCREMENT POINTER
  72.     DEC    DE            ; DECREMENT COUNTER
  73.     LD    A,D            ; TEST IF COUNTER ZERO
  74.     OR    E
  75.     JR    NZ,INITD1        ; NOT THEN JUMP
  76.     POP    HL            ; GET ALV POINTER
  77.     LD    DE,(NDIR0)        ; GET FIRST TWO BYTES ALV BUFFER 
  78.     LD    (HL),E            ; SAVE LSB
  79.     INC    HL            ; INCREMENT POINTER
  80.     LD    (HL),D            ; SAVE MSB
  81.     LD    HL,(TEMP0)        ; CLEAR NUMBER OF FILES
  82.     XOR    A            ; ON THIS DRIVE
  83.     LD    (HL),A            ; CLEAR LSB
  84.     INC    HL            ; INCREMENT POINTER
  85.     LD    (HL),A            ; CLEAR MSB
  86.     LD    (SUBFLG),A        ; CLEAR SUBMIT FLAG (RESET DISK COMMAND)
  87.     CALL    SETFCT            ; SET FILE COUNT
  88. INITD2:    LD    A,0FFH            ; UPDATE DIRECTORY CHECKSUM
  89.     CALL    RDDIR            ; READ FCB'S FROM DIRECTORY
  90.     CALL    TSTFCT            ; TEST LAST FCB
  91.     RET    Z            ; YES THEN EXIT
  92.     CALL    CALDIR            ; CALCULATE ENTRY POINT FCB
  93.     LD    A,(HL)            ; GET FIRST BYTE FCB
  94.     CP    0E5H            ; TEST EMPTY DIRECTORY ENTRY
  95.     JR    Z,INITD2        ; YES THEN GET NEXT FCB
  96.     CP    021H            ; TEST TIME STAMP
  97.     JR    Z,INITD2        ; YES THEN GET NEXT FCB
  98.     LD    A,(USER)        ; GET USER NUMBER
  99.     CP    (HL)            ; TEST IF USER IS SAME
  100.     JR    NZ,INITD3        ; NO THEN JUMP
  101.     INC    HL            ; POINT TO FILE NAME
  102.     LD    A,(HL)            ; GET FIRST CHAR FILENAME
  103.     SUB    '$'            ; TEST IF '$'
  104.     JR    NZ,INITD3        ; NOT THEN JUMP
  105.     DEC    A            ; LOAD A WITH 0FFH
  106.     LD    (SUBFLG),A        ; SAVE IT IN SUBFLG 
  107. INITD3:    LD    C,1            ; SET BIT IN ALV BUFFER
  108.     CALL    FILLBB            ; SET BITS FROM FCB IN ALV BUFFER
  109.     CALL    SETLF            ; UPDATE LAST FILE COUNT
  110.     JR    INITD2            ; AND GET NEXT FCB
  111. ;
  112. ; SET DRIVE BIT IN HL
  113. ;
  114. SDRVB:    EX    DE,HL            ; COPY HL=>DE 
  115.     LD    HL,1            ; GET MASK DRIVE "A"
  116.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  117.     OR    A            ; TEST IF DRIVE "A"
  118.     JR    Z,SDRVB1        ; YES THEN DONE
  119. SDRVB0:    ADD    HL,HL            ; GET NEXT MASK
  120.     DEC    A            ; DECREMENT DRIVE COUNTER
  121.     JR    NZ,SDRVB0        ; AND TEST IF DONE
  122. SDRVB1:    LD    A,D            ; HL=HL OR DE
  123.     OR    H
  124.     LD    H,A
  125.     LD    A,E
  126.     OR    L
  127.     LD    L,A
  128.     RET                ; EXIT
  129. ;
  130. ; CALCULATE SECTOR/TRACK DIRECTORY
  131. ;
  132. STDIR:    LD    HL,(FILCNT)        ; GET FCB COUNTER DIRECTORY
  133.     SRL    H            ; DIVIDE BY 4
  134.     RR    L            ; (4 FCB'S / SECTOR)
  135.     SRL    H
  136.     RR    L
  137.     LD    (RECDIR),HL        ; SAVE VALUE (USED BY CHECKSUM)
  138.     EX    DE,HL            ; COPY IT TO DE
  139.     LD    HL,0            ; CLEAR HL
  140. ;
  141. ; CALCULATE SECTOR/TRACK
  142. ;  ENTRY: HL,DE=SECTOR NUMBER (128 BYTE SECTOR)
  143. ;  RESULT SET TRACK  =HL,DE  /  MAXSEC
  144. ;         SET SECTOR =HL,DE MOD MAXSEC
  145. ;
  146. CALST:    LD    BC,(MAXSEC)        ; GET SECTORS/TRACK
  147.     LD    A,17            ; SET UP LOOP COUNTER
  148. CALST0:    OR    A            ; TEST HL>=BC
  149.     SBC    HL,BC
  150.     CCF
  151.     JR    C,CALST1        ; YES THEN JUMP
  152.     ADD    HL,BC            ; NO THEN RETORE HL
  153.     OR    A            ; AND CLEAR CARRY
  154. CALST1:    RL    E            ; SHIFT RESULT IN DE
  155.     RL    D
  156.     DEC    A            ; TEST LAST BIT DONE
  157.     JR    Z,CALST2        ; YES THEN EXIT
  158.     RL    L            ; SHIFT NEXT BIT IN HL
  159.     RL    H
  160.     JR    CALST0            ; CONTINUE
  161. CALST2:    PUSH    HL            ; SAVE SECTOR NUMBER
  162.     LD    HL,(NFTRK)        ; GET FIRST TRACK
  163.     ADD    HL,DE            ; ADD TRACK NUMBER
  164.     LD    B,H            ; COPY IT TO BC
  165.     LD    C,L
  166.     CALL    SETTRK            ; P2BIOS CALL SET TRACK
  167.     POP    BC            ; RESTORE SECTOR NUMBER
  168.     LD    DE,(TRANS)        ; GET TRANSLATION TABLE ADDRESS
  169.     CALL    SECTRN            ; P2BIOS CALL SECTOR TRANSLATION 
  170.     LD    B,H            ; COPY RESULT TO BC
  171.     LD    C,L
  172.     JP    SETSEC            ; P2BIOS CALL SET SECTOR
  173. ;
  174. ; GET DISK MAP BLOCK NUMBER FROM FCB
  175. ;  EXIT HL=ADDRESS FCB
  176. ;       DE=DM
  177. ;       BC=OFFSET IN DM
  178. ;
  179. GETDM:    LD    C,(IX+32)        ; GET NEXT RECORD
  180.     LD    A,(NBLOCK)        ; GET NUMBER OF BLOCKS
  181.     LD    B,A            ; SAVE IT 
  182. GETDM0:    SRL    C            ; SHIFT NEXT RECORD 
  183.     DJNZ    GETDM0            ; NUMBER OF BLOCKS TIMES
  184. GETDM1:    CPL                ; COMPLEMENT NUMBER OF BLOCKS
  185.     ADD    A,9            ; ADD 9
  186.     LD    B,A            ; B=8-NUMBER OF BLOCKS
  187.     LD    A,(NEXTND)        ; GET EXTENT MASK
  188.     AND    (IX+12)            ; MASK WITH EXTENT
  189.     RRCA                ; ROTATE ONE RIGHT
  190. GETDM2:    RLCA                ; ROTATE ONE LEFT
  191.     DJNZ    GETDM2            ; 8-NUMBER OF BLOCKS TIMES
  192. GETDM3:    ADD    A,C            ; ADD THE TWO VALUES TO GET ENTRY FCB
  193. GETDM4:    PUSH    IX            ; GET FCB ADDRESS
  194.     POP    HL
  195.     LD    C,16            ; ADD OFFSET 16 TO POINT TO DM
  196.     ADD    HL,BC
  197.     LD    C,A            ; ADD ENTRY FCB
  198.     ADD    HL,BC
  199.     LD    A,(MAXLEN+1)        ; TEST 8 BITS/16 BITS FCB ENTRY
  200.     OR    A
  201.     JR    NZ,GETDM5        ; 16 BITS => JUMP
  202.     LD    E,(HL)            ; GET 8 BIT VALUE
  203.     LD    D,0            ; MAKE MSB ZERO
  204.     RET                ; AND EXIT
  205. GETDM5:    ADD    HL,BC            ; ADD TWICE (16 BIT VALUES)
  206.     LD    E,(HL)            ; GET LSB
  207.     INC    HL            ; INCREMENT POINTER
  208.     LD    D,(HL)            ; GET MSB
  209.     DEC    HL            ; DECREMENT POINTER
  210.     RET                ; AND EXIT
  211. ;
  212. ; CALCULATE SECTOR NUMBER 
  213. ;  ENTRY: DE=BLOCK NUMBER FROM FCB
  214. ;
  215. CALSEC:    LD    HL,0            ; CLEAR MSB SECTOR NUMBER
  216.     LD    A,(NBLOCK)        ; GET LOOP COUNTER
  217.     LD    B,A            ; SAVE IT IN B
  218. CALSC0:    SLA    E            ; SHIFT L,D,E 
  219.     RL    D
  220.     RL    L
  221.     DJNZ    CALSC0            ; B TIMES
  222. CALSC1:    LD    A,(NMASK)        ; GET SECTOR MASK
  223.     AND    (IX+32)            ; AND WHIT NEXT RECORD
  224.     OR    E            ; SET UP LSB SECTOR NUMBER
  225.     LD    E,A
  226.     RET                ; AND EXIT
  227. ;
  228. ; CALCULATE DIRBUF ENTRY POINT
  229. ;
  230. CALDIR:    LD    HL,(DIRBUF)        ; GET START ADDRESS DIRBUF
  231.     LD    A,(SECPNT)        ; GET SECTOR POINTER
  232.     ADD    A,L            ; ADD L=L+A
  233.     LD    L,A
  234.     RET    NC            ; NO CARRY EXIT
  235.     INC    H            ; INCREMENT H
  236.     RET                ; AND EXIT
  237. ;
  238. ; INIT FILE COUNT
  239. ;
  240. SETFCT:    LD    HL,-1            ; SET UP FILE COUNT
  241.     LD    (FILCNT),HL        ; SAVE IT
  242.     RET                ; AND EXIT
  243. ;
  244. ; TEST FILE COUNT
  245. ;
  246. TSTFCT:    LD    HL,(FILCNT)        ; TEST FILE COUNT=0FFFFH
  247.     LD    A,H            ; GET MSB 
  248.     AND    L            ; AND LSB
  249.     INC    A            ; TEST IF RESULT=0FFH
  250.     RET                ; AND EXIT
  251. ;
  252. ; SET LAST FILE
  253. ;
  254. SETLF:    CALL    TSTLF            ; TEST LAST FILE
  255.     RET    C            ; NO THEN EXIT
  256.     INC    DE            ; INCREMENT LAST FILE
  257.     LD    (HL),D            ; SAVE IT IN TEMP0
  258.     DEC    HL
  259.     LD    (HL),E
  260.     RET                ; AND EXIT
  261. ;
  262. ; TEST LAST FILE
  263. ;
  264. TSTLF:    LD    HL,(TEMP0)        ; GET POINTER TO LAST FILE 
  265.     LD    DE,(FILCNT)        ; GET FILE COUNTER
  266.     LD    A,E            ; SUBTRACT DE-(HL)
  267.     SUB    (HL)
  268.     INC    HL
  269.     LD    A,D
  270.     SBC    A,(HL)
  271.     RET                ; EXIT
  272. ;
  273. ; GET NEXT FCB FROM DRIVE
  274. ; ENTRY A=0 CHECK CHECKSUM, A=0FFH UPDATE CHECKSUM
  275. ;
  276. RDDIR:    LD    C,A            ; SAVE CHECKSUM FLAG
  277.     LD    HL,(FILCNT)        ; GET FILE COUNTER
  278.     INC    HL            ; INCREMENT IT
  279.     LD    (FILCNT),HL        ; AND SAVE IT
  280.     LD    DE,(NFILES)        ; GET MAXIMUM NUMBER OF FILES
  281.     OR    A            ; CLEAR CARRY
  282.     SBC    HL,DE            ; TEST IF LAST FILE
  283.     ADD    HL,DE
  284.     JR    Z,RDDIR0        ; NO JUMP
  285.     JR    NC,SETFCT        ; YES SET FILE COUNT TO 0FFFFH
  286. RDDIR0:    LD    A,L            ; GET FILE COUNT LSB
  287.     ADD    A,A            ; *32 
  288.     ADD    A,A
  289.     ADD    A,A
  290.     ADD    A,A
  291.     ADD    A,A
  292.     AND    060H            ; MASK IT
  293.     LD    (SECPNT),A        ; SAVE IT FOR LATER USE
  294.     RET    NZ            ; RETURN IF NOT FISRT FCB SECTOR
  295.     PUSH    BC            ; SAVE CHECKSUM FLAG
  296.     CALL    STDIR            ; CALCULATE SECTOR/TRACK DIRECTORY
  297.     CALL    READDR            ; READ SECTOR DIRECTORY
  298.     POP    BC            ; RESTORE CHECKSUM FLAG
  299. ;
  300. ; UPDATE/CHECK CHECKSUM DIRECTORY
  301. ; ENTRY C=0 CHECK CHECKSUM, C=0FFH UPDATE CHECKSUM
  302. ;
  303. CHKDIR:    LD    HL,(NCHECK)        ; GET NUMBER OF CHECKED RECORDS
  304.     LD    DE,(RECDIR)        ; GET CURRENT RECORD
  305.     OR    A            ; CLEAR CARRY
  306.     SBC    HL,DE            ; TEST CURRENT RECORD 
  307.     RET    Z            ; EXIT IF ZERO
  308.     RET    C            ; EXIT IF GREATER THEN NCHECK
  309.     LD    HL,(DIRBUF)        ; GET DIRBUF
  310.     LD    B,128            ; SET UP COUNTER
  311.     XOR    A            ; CLEAR CHECKSUM
  312. CHKDR0:    ADD    A,(HL)            ; ADD CHECKSUM
  313.     INC    HL            ; INCREMENT POINTER
  314.     DJNZ    CHKDR0            ; 128 TIMES
  315.     LD    HL,(CSV)        ; GET POINTER CHECKSUM DIRECTORY
  316.     ADD    HL,DE            ; ADD CURRENT RECORD
  317.     INC    C            ; TEST CHECKSUM FLAG
  318.     JR    Z,CHKDR1        ; 0FFH=> UPDATE CHECKSUM
  319.     CP    (HL)            ; TEST CHECKSUM
  320.     RET    Z            ; EXIT IF OK
  321. ;Automatic disk logging--instead of setting read/only flag when disk is
  322. ;changed, a disk changed flag is set.  The disk is reset when the SEARCH
  323. ;routine is called.
  324. ;    JP    SETWPD
  325.     LD    A,TRUE            ; set disk changed flag
  326.     LD    (DIFF),A
  327.     JP    SETFN            ; set number of files
  328. CHKDR1:    LD    (HL),A            ; UPDATE CHECKSUM
  329.     RET                ; AND EXIT
  330. ;
  331. ; READ SECTOR FROM DRIVE
  332. ;
  333. ;
  334. ;Readr and Writer modified to give separate error messages--B.H.
  335. READR:    CALL    READ            ; P2BIOS CALL READ SECTOR
  336.     LD    HL,(SRDERR)
  337.     JR    WRITE0
  338. ;
  339. ; WRITE SECTOR ON DRIVE
  340. ;
  341. WRITER:    CALL    WRITE            ; P2BIOS CALL WRITE SECTOR
  342.     LD    HL,(SWRTER)
  343. WRITE0:    OR    A            ; TEST EXIT CODE
  344.     RET    Z            ; EXIT IF OK
  345.     LD    A,1
  346.     LD    (RETFLG),A
  347.     JP    (HL)            ; P2DOS ERROR ON D: BAD SECTOR
  348. ;
  349. ; READ DIRECTORY FROM DRIVE
  350. ;
  351. READDR:    CALL    DMADIR            ; SET UP DMA DIRECTORY
  352.     CALL    READR            ; READ RECORD
  353.     JR    STDMA            ; SET UP DMA USER
  354. ;
  355. ; WRITE DIRECTORY ON DRIVE
  356. ;
  357. WRITDR:    LD    C,0FFH            ; UPDATE CHECKSUM DIRECTORY
  358.     CALL    CHKDIR
  359.     CALL    DMADIR            ; SET UP DMA DIRECTORY 
  360.     LD    C,1            ; WRITE DIRECTORY FLAG
  361.     CALL    WRITER            ; WRITE RECORD
  362.     JR    STDMA            ; SET UP DMA USER
  363. ;
  364. ; SET DMA ADDRESS COMMAND
  365. ;
  366. CMND26:    LD    (DMA),DE        ; SAVE DMA ADDRESS
  367. ;
  368. ; SET DMA ADDRESS
  369. ;
  370. STDMA:    LD    BC,(DMA)        ; GET DMA ADDRESS
  371.     JR    DMADR0            ; AND DO P2BIOS CALL
  372. ;
  373. ; SET DMA ADDRESS DIRECTORY
  374. ;
  375. DMADIR:    LD    BC,(DIRBUF)        ; GET DMA ADDRESS DIRECTORY
  376. DMADR0:    JP    SETDMA            ; P2BIOS CALL SET DMA
  377. ;
  378. ; GET BIT FROM ALV BUFFER
  379. ;  ENTRY DE=BLOCK NUMBER
  380. ;  EXIT  A =BIT IN LSB
  381. ;        B =BITNUMBER IN A
  382. ;        HL=POINTER IN ALV BUFFER
  383. ;
  384. GETBIT:    LD    A,E            ; GET BIT NUMBER
  385.     AND    7            ; MASK IT
  386.     INC    A            ; ADD 1
  387.     LD    B,A            ; SAVE IT
  388.     LD    C,A            ; TWICE
  389.     SRL    D            ; GET BYTE NUMBER
  390.     RR    E            ; DE=DE/8
  391.     SRL    D
  392.     RR    E
  393.     SRL    D
  394.     RR    E
  395.     LD    HL,(ALV)        ; GET START ADDRESS ALV BUFFER
  396.     ADD    HL,DE            ; ADD BYTE NUMBER
  397.     LD    A,(HL)            ; GET 8 BITS
  398. GETBT0:    RLCA                ; GET CORRECT BIT
  399.     DJNZ    GETBT0
  400.     LD    B,C            ; RESTORE BIT NUMBER
  401.     RET                ; AND RETURN TO CALLER
  402. ;
  403. ; SET/RESET BIT IN ALV BUFFER
  404. ;  ENTRY DE=BLOCK NUMBER
  405. ;        C =0 RESET BIT, C=1 SET BIT
  406. ;
  407. SETBIT:    PUSH    BC            ; SAVE SET/RESET BIT
  408.     CALL    GETBIT            ; GET BIT
  409.     AND    0FEH            ; MASK IT
  410.     POP    DE            ; GET SET/RESET BIT
  411.     OR    E            ; SET/RESET BIT
  412. SETBT0:    RRCA                ; ROTATE BIT IN CORRECT POSITION
  413.     DJNZ    SETBT0
  414.     LD    (HL),A            ; SAVE 8 BITS
  415.     RET                ; AND RETURN TO CALLER
  416. ;
  417. ; FILL BIT BUFFER FROM FCB IN DIRBUF
  418. ;  ENTRY C=0 RESET BIT, C=1 SET BIT
  419. ;
  420. FILLBB:    CALL    CALDIR            ; GET DIRECTORY ENTRY
  421.     LD    DE,16            ; GET OFFSET DM BLOCK
  422.     ADD    HL,DE            ; ADD OFFSET
  423.     LD    B,E            ; GET BLOCK COUNTER
  424. FILLB0:    LD    E,(HL)            ; GET LSB BLOCK NUMBER
  425.     INC    HL            ; INCREMENT POINTER
  426.     LD    D,0            ; RESET MSB BLOCK NUMBER
  427.     LD    A,(MAXLEN+1)        ; TEST >256 BLOCKS PRESENT
  428.     OR    A
  429.     JR    Z,FILLB1        ; NO THEN JUMP
  430.     DEC    B            ; DECREMENT BLOCK COUNTER
  431.     LD    D,(HL)            ; GET CORRECT MSB
  432.     INC    HL            ; INCREMENT POINTER
  433. FILLB1:    LD    A,D            ; TEST BLOCK NUMBER
  434.     OR    E            
  435.     JR    Z,FILLB2        ; ZERO THEN GET NEXT BLOCK
  436.     PUSH    HL            ; SAVE POINTER
  437.     PUSH    BC            ; SAVE COUNTER AND SET/RESET BIT
  438.      LD    HL,(MAXLEN)        ; GET MAXIMUM LENGTH ALV BUFFER
  439.     OR    A            ; RESET CARRY
  440.     SBC    HL,DE            ; TEST DE<=MAXLEN ALV BUFFER 
  441.     CALL    NC,SETBIT        ; YES THEN INSERT BIT
  442.     POP    BC            ; GET COUNTER AND SET/RESET BIT
  443.     POP    HL            ; GET POINTER
  444. FILLB2:    DJNZ    FILLB0            ; REPEAT FOR ALL DM ENTRIES
  445.     RET                ; AND RETURN TO CALLER
  446. ;
  447. ; SET WRITE PROTECT DISK COMMAND
  448. ;
  449. CMND28:
  450. ;
  451. ; SET WRITE PROTECT DISK
  452. ;
  453. SETWPD:    LD    HL,(DSKRO)        ; GET DISK R/O VECTOR
  454.     CALL    SDRVB            ; INCLUDE DRIVE BIT
  455.     LD    (DSKRO),HL        ; SAVE DISK R/O BIT
  456. SETFN:    LD    DE,(NFILES)        ; GET MAXIMUM NUMBER OF FILES-1 
  457.     INC    DE            ; INCREMENT IT 
  458.     LD    HL,(TEMP0)        ; GET POINTER TO DISK PARAMETER BLOCK 
  459.     LD    (HL),E            ; AND SAVE NUMBER OF FILES
  460.     INC    HL
  461.     LD    (HL),D
  462.     RET                ; AND RETURN TO CALLER
  463. ;
  464. ; CHECK FILE R/O BIT
  465. ;
  466. CHKFRO:    CALL    CALDIR            ; GET DIRECTORY ENTRY
  467. CHKFR0:    LD    DE,2            ; OFFSET TO PUBLIC FILE BIT
  468.     ADD    HL,DE            ; ADD OFFSET
  469.     BIT    7,(HL)            ; TEST PUBLIC FILE
  470.     JR    NZ,CHKFR1        ; YES THEN ERROR
  471.     LD    E,7            ; OFFSET TO FILE R/O BIT
  472.     ADD    HL,DE            ; ADD OFFSET
  473.     BIT    7,(HL)            ; TEST FILE R/O
  474.     JR    NZ,CHKFR1        ; YES THEN ERROR
  475. ;system files should not be r/o for CP/M compatibility-B.H.
  476. ;    INC    HL            ; INCREMENT TO SYSTEM FILE 
  477. ;    BIT    7,(HL)            ; TEST SYSTEM FILE
  478.     RET    Z            ; NO SYSTEM FILE THEN OK
  479. CHKFR1:    LD    HL,(SFILRO)        ; GET POINTER TO FILE R/O MESSAGE
  480.     JP    (HL)            ; DISPLAY MESSAGE
  481. ;
  482. ; CHECK DRIVE READ ONLY
  483. ;
  484. CHKRO:    LD    HL,(DSKRO)        ; GET DRIVE R/O VECTOR
  485.     CALL    SDRVB            ; SET DRIVE BIT
  486.     SBC    HL,DE            ; TEST EXTRA BIT ADDED
  487.     RET    NZ            ; YES THEN DRIVE NOT R/O
  488.     LD    HL,(STRO)        ; GET POINTER TO DRIVE R/O MESSAGE
  489.     JP    (HL)            ; DISPLAY MESSAGE
  490. ;
  491. ; GET FREE BLOCK FROM ALV BUFFER
  492. ;  ENTRY DE=OLD BLOCK NUMBER
  493. ;  EXIT  DE=NEW BLOCK NUMBER (0 IF NO FREE BLOCK)
  494. ;   HL COUNTS UP,DE COUNTS DOWN
  495. ;
  496. GETFRE:    LD    H,D            ; COPY OLD BLOCK TO HL
  497.     LD    L,E
  498. GETFR0:    LD    A,D            ; TEST DOWN COUNTER IS ZERO
  499.     OR    E
  500.     JR    Z,GETFR1        ; YES THEN JUMP
  501.     DEC    DE            ; DECREMEMT DOWN COUNTER
  502.     PUSH    HL            ; SAVE UP/DOWN COUNTER
  503.     PUSH    DE
  504.     CALL    GETBIT            ; GET BIT FROM ALV BUFFER
  505.     RRA                ; TEST IF ZERO
  506.     JR    NC,GETFR3        ; YES THEN FOUND EMPTY BLOCK
  507.     POP    DE            ; GET UP/DOWN COUNTER
  508.     POP    HL
  509. GETFR1:    LD    BC,(MAXLEN)        ; GET MAXIMUM ALV LENGTH-1 IN BC
  510.     OR    A            ; CLEAR CARRY
  511.     SBC    HL,BC            ; TEST HL>=LENGTH ALV-1
  512.     ADD    HL,BC            ; RESTORE HL (FLAGS ARE NOT AFFECTED)
  513.     JR    NC,GETFR2        ; END BUFFER THEN JUMP
  514.     INC    HL            ; INCREMENT UP COUNTER
  515.     PUSH    DE            ; SAVE DOWN/UP COUNTER
  516.     PUSH    HL
  517.     EX    DE,HL            ; SAVE UP COUNTER IN DE
  518.     CALL    GETBIT            ; GET BIT FROM ALV BUFFER
  519.     RRA                ; TEST IF ZERO
  520.     JR    NC,GETFR3        ; YES THEN FOUND EMPTY BLOCK
  521.     POP    HL            ; GET DOWN/UP COUNTER
  522.     POP    DE
  523.     JR    GETFR0            ; AND TEST NEXT BLOCK 
  524. GETFR2:    LD    A,D            ; TEST IF LAST BLOCK TESTED
  525.     OR    E
  526.     JR    NZ,GETFR0        ; NO THEN TEST NEXT BLOCK
  527.     RET                ; EXIT (DE=0)
  528. GETFR3:    SCF                ; SET BLOCK NUMBER USED
  529.     RLA                ; SAVE BIT
  530.     CALL    SETBT0            ; PUT BIT IN ALV BUFFER
  531.     POP    DE            ; GET CORRECT COUNTER
  532.     POP    HL            ; RESTORE STACK POINTER
  533.     RET                ; EXIT (DE=BLOCK NUMBER)
  534. ;
  535. ; SEARCH FOR FILE NAME
  536. ;  ENTRY: A : NUMBER OF BYTES TO SEARCH FOR
  537. ;
  538. SEARCH:    PUSH    AF
  539.     LD    HL,DIFF            ;Reset disk if it has changed
  540.     XOR    A
  541.     CP    (HL)
  542.     JR    Z,S1
  543.     CALL    CLRDSK            
  544. S1:    POP    AF
  545.     LD    (SEARNB),A        ; SAVE NUMBER OF BYTES
  546.     LD    A,0FFH            ; SET EXIT CODE TO 0FFH (NOT FOUND)
  547.     LD    (SEAREX),A
  548.     LD    (DCOPY),IX        ; COPY FCB POINTER TO RAM (SEARCH NEXT)
  549.     CALL    SETFCT            ; INITIATE FILE COUNTER
  550. ;Mod 0.1 had a bug in which the directory of a changed disk would not be
  551. ;read.  Adding CALL HOME forces a directory read--B.H.
  552. ;
  553.     CALL    HOME
  554. ;
  555. ; SEARCH NEXT FILE NAME
  556. ;
  557. SEARCN:    XOR    A            ; CHECK CHECKSUM DIRECTORY
  558.     CALL    RDDIR            ; GET FCB FROM DIRECTORY
  559.     CALL    TSTFCT            ; TEST IF PAST LAST ENTRY
  560.     JR    Z,SEARC8        ; YES THEN JUMP
  561.     LD    DE,(DCOPY)        ; GET FCB POINTER
  562.     LD    A,(DE)            ; GET FIRST BYTE
  563.     CP    0E5H            ; TEST IF SEARCHING EMPTY DIRECTORY
  564.     JR    Z,SEARC1        ; YES THEN JUMP
  565.     PUSH    DE            ; SAVE FCB POINTER
  566.     CALL    TSTLF            ; TEST LAST FILE ON THIS DRIVE
  567.     POP    DE            ; RESTORE FCB POINTER
  568.     JR    NC,SEARC8        ; YES THEN JUMP
  569. SEARC1:    CALL    CALDIR            ; GET ENTRY IN DIRECTORY
  570.     LD    A,(HL)            ; GET FIRST BYTE DIRECTORY ENTRY
  571.     CP    021H            ; TEST TIME STAMP
  572.     JR    Z,SEARCN        ; YES THEN GET NEXT DIRECTORY ENTRY
  573.     LD    A,(SEARNB)        ; GET NUMBER OF BYTES TO SEARCH FOR
  574.     LD    B,A            ; SAVE IT IN COUNTER
  575.     XOR    A            ; CLEAR ACCU
  576.     LD    (SEARQU),A        ; CLEAR QUESTION MARK DETECTED FLAG
  577.     LD    (SEARPU),A        ; CLEAR PUBLIC FILE FLAG
  578.     LD    C,A            ; CLEAR COUNTER
  579. SEARC2:    LD    A,B            ; TEST IF COUNTER IS ZERO
  580.     OR    A
  581.     JR    Z,SEARC9        ; YES THEN JUMP
  582.     LD    A,(DE)            ; GET BYTE FROM FCB
  583.     SUB    '?'            ; TEST IF QUESTION MARK
  584.     JR    Z,SEARC6        ; YES THEN JUMP
  585.     LD    A,C            ; GET FCB COUNTER
  586.     OR    A            ; TEST FIRST BYTE
  587.     JR    NZ,SEARC3        ; NO THEN JUMP
  588.     LD    A,(FLAGS)        ; GET FLAG BYTE
  589.     BIT    0,A            ; TEST PUBLIC FILE ENABLE
  590.     JR    Z,SEARC3        ; NO THEN JUMP
  591.     INC    HL            ; GET POINTER TO PUBLIC BIT
  592.     INC    HL
  593.     BIT    7,(HL)            ; TEST PUBLIC BIT DIRECTORY
  594.     DEC    HL            ; RESTORE POINTER
  595.     DEC    HL
  596.     JR    Z,SEARC3        ; NO PUBLIC FILE THEN JUMP
  597.     LD    A,(DE)            ; GET FIRST BYTE FCB
  598.     CP    0E5H            ; TEST IF SEARCHING EMPTY DIRECTORY
  599.     JR    Z,SEARC3        ; YES THEN JUMP
  600.     XOR    (HL)            ; TEST FCB=DIRECTORY ENTRY
  601.     AND    07FH            ; MASK IT
  602.     JR    Z,SEARC5        ; YES THEN JUMP
  603.     AND    0E0H            ; MASK USER NUMBER
  604.     JR    NZ,SEARC3        ; NOT THE SAME THEN JUMP
  605.     DEC    A            ; A=0FFH
  606.     LD    (SEARPU),A        ; SET PUBLIC FILE FOUND
  607.     JR    SEARC5            ; JUMP FOUND
  608. SEARC3:    LD    A,C            ; GET FCB COUNTER
  609.     CP    13            ; TEST IF USER CODE
  610.     JR    Z,SEARC5        ; YES THEN NO TEST
  611.     CP    12            ; TEST IF EXTENT NUMBER
  612.     LD    A,(DE)            ; GET BYTE FROM FCB
  613.     JR    Z,SEARC7        ; JUMP IF EXTENT NUMBER
  614.     XOR    (HL)            ; TEST BYTE FCB=BYTE DIRECTORY ENTRY
  615.     AND    07FH            ; MASK IT
  616. SEARC4:    JR    NZ,SEARCN        ; NOT THE SAME THEN GET NEXT ENTRY
  617. SEARC5:    INC    DE            ; INCREMENT POINTER FCB
  618.     INC    HL            ; INCREMENT POINTER DIRECTORY ENTRY
  619.     INC    C            ; INCREMENT COUNTER
  620.     DEC    B            ; DECREMENT COUNTER
  621.     JR    SEARC2            ; TEST NEXT BYTE
  622. SEARC6:    DEC    A            ; SET QUESTION MARK FOUND FLAG
  623.     LD    (SEARQU),A        
  624.     JR    SEARC5            ; JUMP FOUND
  625. SEARC7:    PUSH    BC            ; SAVE COUNTERS
  626.     XOR    (HL)            ; TEST EXTENTS
  627.     LD    B,A            ; SAVE IT
  628.     LD    A,(NEXTND)        ; GET EXTENT MASK
  629.     CPL                ; COMPLEMENT IT
  630.     AND    01FH            ; MASK IT
  631.     AND    B            ; MASK EXTENTS
  632.     POP    BC            ; RETORE COUNTERS
  633.     JR    SEARC4            ; AND TEST RESULT
  634. SEARC8:    CALL    SETFCT            ; ERROR SET FILE COUNTER
  635.     LD    A,0FFH            ; AND SET EXIT CODE
  636.     LD    (PEXIT),A
  637.     RET                ; RETURN TO CALLER
  638. SEARC9:    LD    A,(SEARQU)        ; GET QUESTION MARK FOUND FLAG
  639.     LD    B,A            ; SAVE IT
  640.     LD    A,(SEARPU)        ; GET PUBLIC FILE FLAG
  641.     AND    B            ; TEST IF PUBLIC FILE AND QUESTION MARK
  642.     JR    NZ,SEARC4        ; YES THEN SEARCH FOR NEXT ENTRY
  643.     CALL    SETLF            ; UPDATE LAST FILE COUNT (EMPTY FCB)
  644.     LD    A,(FILCNT)        ; GET FILE COUNTER
  645.     AND    3            ; MASK IT
  646.     LD    (PEXIT),A        ; AND SET EXIT CODE
  647.     XOR    A            ; CLEAR EXIT CODE SEARCH
  648.     LD    (SEAREX),A
  649.     RET                ; AND RETURN TO CALLER
  650. ;
  651. ;DELETE FILE
  652. ;
  653. DELETE:    CALL    CHKRO            ; CHECK DISK R/O
  654.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  655.     CALL    SEARCH            ; SEARCH FILE
  656. DEL0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  657.     RET    Z            ; NOT THEN EXIT
  658.     CALL    CHKFRO            ; CHECK FILE R/O
  659.     CALL    CALDIR            ; GET ENTRY POINT DIRECTORY
  660.     LD    (HL),0E5H        ; REMOVE FILE
  661.     LD    C,0            ; REMOVE BITS ALV BUFFER
  662.     CALL    FILLBB 
  663.     CALL    WRFCB1            ; WRITE DIRECTORY BUFFER ON DISK
  664.     CALL    SEARCN            ; SEARCH NEXT ENTRY
  665.     JR    DEL0            ; AND TEST IT
  666. ;
  667. ; RENAME FILE
  668. ;
  669. RENAM:    CALL    CHKRO            ; CHECK DISK R/O
  670.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  671.     CALL    SEARCH            ; SEARCH FILE
  672. RENAM0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  673.     RET    Z            ; NOT THEN EXIT
  674.     CALL    CHKFRO            ; CHECK FILE R/O
  675.     LD    BC,12*256+16        ; COPY FCB+16 TO DIRECTORY+0 12 TIMES
  676.     CALL    WRFCB            ; AND WRITE DIRECTORY ON DISK
  677.     CALL    SEARCN            ; SEARCH NEXT FILE
  678.     JR    RENAM0            ; AND TEST IT
  679. ;
  680. ; CHANGE STATUS FILE
  681. ;
  682. CSTAT:    CALL    CHKRO            ; CHECK DISK R/O
  683.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  684.     CALL    SEARCH            ; SEARCH FILE
  685. CSTAT0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  686.     RET    Z            ; NOT THEN EXIT
  687.     LD    BC,12*256+0        ; COPY FCB+0 TO DIRECTORY+0 12 TIMES
  688.     CALL    WRFCB            ; AND WRITE DIRECTORY TO DISK
  689.     CALL    SEARCN            ; SEARCH NEXT FILE
  690.     JR    CSTAT0            ; AND TEST IT
  691. ;
  692. ; COMPUTE FILE SIZE
  693. ;
  694. FILSZ:    LD    BC,0            ; RESET FILE SIZE LENGTH
  695.     LD    D,C
  696.     CALL    LDRRC            ; SAVE IT IN FCB+33,34,35
  697.     LD    A,12            ; NUMBER OF BYTES TO SEARCH FOR
  698.     CALL    SEARCH            ; SEARCH FILE
  699. FILSZ0:    CALL    TSTFCT            ; TEST IF FILE FOUND
  700.     RET    Z            ; NOT THEN EXIT
  701.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  702.     EX    DE,HL            ; COPY TO DE
  703.     LD    HL,15            ; OFFSET TO NEXT RECORD
  704.     CALL    CALRRC            ; CALCULATE RANDOM RECORD COUNT
  705.     LD    A,D            ; TEST LSB < (IX+33)
  706.     SUB    (IX+33)
  707.     LD    A,C            ; TEST ISB < (IX+34)
  708.     SBC    A,(IX+34)
  709.     LD    A,B            ; TEST MSB < (IX+35)
  710.     SBC    A,(IX+35)
  711.     CALL    NC,LDRRC        ; WRITE NEW MAXIMUM
  712.     CALL    SEARCN            ; SEARCH NEXT FILE
  713.     JR    FILSZ0            ; AND TEST IT
  714. ;
  715. ; WRITE FCB ON DISK
  716. ;
  717. WRFCB:    CALL    CALDIR            ; GET DIRECTORY ENTRY
  718.     PUSH    HL            ; SAVE POINTER
  719.     LD    A,(HL)            ; GET USER CODE
  720.     EX    DE,HL            ; COPY TO DE
  721.     PUSH    IX            ; SAVE FCB ENTRY
  722.     POP    HL            ; GET IT IN HL
  723.     PUSH    BC            ; SAVE BC
  724.     LD    B,0            ; RESET B FOR ADD
  725.     ADD    HL,BC            ; ADD OFFSET FCB
  726.     POP    BC            ; RESTORE BC
  727.     LD    C,B            ; GET NUMBER OF BYTES TO MOVE
  728.     LD    B,0            ; RESET B FOR LDIR
  729.     LDIR                ; MOVE BYTES
  730.     POP    HL            ; GET POINTER USER CODE
  731.     LD    (HL),A            ; RESTORE IT
  732. WRFCB1:    CALL    STDIR            ; CALCULATE SECTOR/TRACK DIRECTORY
  733.     JP    WRITDR            ; WRITE DIRECTORY ON DISK
  734. ;
  735. ; FIND FILE
  736. ;
  737. FINDF:    LD    A,15            ; NUMBER OF BYTES TO SEARCH FOR 
  738.     CALL    SEARCH            ; SEARCH FILE
  739.     CALL    TSTFCT            ; TEST IF FILE PRESENT
  740.     RET    NZ            ; YES THEN EXIT
  741.     LD    A,(RDWR)        ; TEST IF WRITE FUNCTION
  742.     OR    A            
  743.     RET    NZ            ; YES THEN EXIT
  744.     LD    A,(SEARQU)        ; TEST IF QUESTION MARK USED
  745.     OR    A
  746.     RET    NZ            ; YES THEN EXIT
  747.     LD    HL,(PATH)        ; GET PATH ADDRESS
  748.     LD    A,H            ; TEST IF ZERO (NO PATH)
  749.     OR    L
  750.     RET    Z            ; YES THEN EXIT
  751. FINDF0:    LD    A,(HL)            ; GET FIRST ENTRY PATH NAME
  752.     INC    HL            ; INCREMENT POINTER
  753.     OR    A            ; TEST IF LAST ENTRY
  754.     JP    Z,SEARC8        ; YES THEN ERROR EXIT 
  755.     AND    07FH            ; MASK DRIVE NUMBER
  756.     CP    '$'            ; TEST IF CURRENT DRIVE
  757.     JR    NZ,FINDF1        ; NO THEN JUMP
  758.     LD    A,(DRIVE)        ; GET CURRENT DRIVE
  759.     INC    A            ; INCREMENT DRIVE NUMBER
  760. FINDF1:    DEC    A            ; DECREMENT DRIVE NUMBER
  761.     PUSH    HL            ; SAVE PATH POINTER
  762.     CALL    SELDK            ; SELECT DRIVE
  763.     POP    HL            ; RESTORE PATH POINTER
  764.     LD    A,(HL)            ; GET USER NUMBER
  765.     INC    HL            ; ADVANCE POINTER
  766.     AND    07FH            ; MASK USER NUMBER
  767.     CP    '$'            ; TEST IF CURRENT USER
  768.     JR    NZ,FINDF2        ; NO THEN JUMP
  769.     LD    A,(USER)        ; GET CURRENT USER
  770. FINDF2:    AND    01FH            ; MASK USER NUMBER
  771.     LD    B,A            ; SAVE IT
  772.     LD    A,(IX+0)        ; GET FCB BYTE 0
  773.     AND    0E0H            ; REMOVE USER NUMBER
  774.     OR    B            ; ADD NEW USER NUMBER
  775.     LD    (IX+0),A        ; AND SAVE IT
  776.     PUSH    HL            ; SAVE PATH POINTER
  777.     LD    A,15            ; SET NUMBER OF BYTES TO SEARCH FOR
  778.     CALL    SEARCH            ; SEARCH FILE 
  779.     CALL    TSTFCT            ; TEST IF FILE PRESENT
  780.     POP    HL            ; RESTORE PATH POINTER
  781.     JR    Z,FINDF0        ; NO THEN TEST NEXT PATH ENTRY
  782.     PUSH    HL            ; SAVE PATH POINTER
  783.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  784.     LD    DE,10            ; ADD OFFSET SYSTEM BIT
  785.     ADD    HL,DE
  786.     BIT    7,(HL)            ; TEST SYSTEM FILE
  787.     POP    HL            ; RESTORE PATH POINTER
  788.     JR    Z,FINDF0        ; NO SYSTEM FILE THEN TEST NEXT PATH
  789.                     ;  ENTRY
  790.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  791.     INC    A            ; INCREMENT DRIVE NUMBER
  792.     LD    (FCB0),A        ; SAVE IT IN EXIT FCB0
  793.     RET                ; AND RETURN TO CALLER
  794. ;
  795. ; OPEN FILE COMMAND
  796. ;
  797. CMND15:    
  798.     CALL    SELDRV            ; SELECT DRIVE FROM FCB
  799.     LD    (IX+14),0        ; CLEAR FCB+14
  800. ;
  801. ; OPEN FILE
  802. ;
  803. OPENF:    CALL    FINDF            ; FIND FILE (USE PATH NAME)
  804.     CALL    TSTFCT            ; TEST FILE FOUND
  805.     RET    Z            ; NO THEN EXIT
  806. OPENF0:    LD    A,(IX+12)        ; GET EXTENT NUMBER FROM FCB
  807.     PUSH    AF            ; SAVE IT
  808.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  809.     PUSH    IX            ; SAVE FCB ENTRY
  810.     POP    DE            ; GET IN IN DE
  811.     LD    BC,32            ; NUMBER OF BYTES TO MOVE
  812.     LDIR                ; MOVE DIRECTORY TO FCB
  813.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  814.     LD    B,(IX+12)        ; GET EXTENT NUMBER
  815.     LD    C,(IX+15)        ; GET NEXT RECORD NUMBER
  816.     POP    AF            ; GET OLD EXTENT NUMBER
  817.     LD    (IX+12),A        ; SAVE IT
  818.     CP    B            ; COMPARE OLD AND NEW EXTENT NUMBER
  819.     JR    Z,OPENF1        ; SAME THEN JUMP
  820.     LD    C,0            ; SET NEXT RECORD COUNT TO 0
  821.     JR    NC,OPENF1        ; OLD EXTENT >= NEW EXTENT THEN JUMP
  822.     LD    C,80H            ; SET NEXT RECORD COUNT TO MAXIMUM
  823. OPENF1:    LD    (IX+15),C        ; SAVE NEXT RECORD COUNT
  824.     RET                ; AND RETURN TO CALLER
  825. ;
  826. ; CLOSE FILE COMMAND
  827. ;
  828. CMND16:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  829. ;
  830. ; CLOSE FILE
  831. ;
  832. CLOSE:    BIT    7,(IX+14)        ; TEST FCB/FILE MODIFIED
  833.     RET    NZ            ; NOT THEN NO CLOSE REQUIRED
  834.     CALL    CHKRO            ; TEST DISK R/O
  835.     LD    A,15            ; NUMBER OF BYTES TO SEARCH FOR
  836.     CALL    SEARCH            ; SEARCH FILE
  837.     CALL    TSTFCT            ; TEST FILE PRESENT
  838.     RET    Z            ; NO THEN EXIT
  839.     CALL    CHKFRO            ; CHECK FILE R/O
  840.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  841.     LD    BC,16            ; OFFSET TO DM BLOCK 
  842.     ADD    HL,BC            ; ADD OFFSET
  843.     EX    DE,HL            ; SAVE HL IN DE
  844.     PUSH    IX            ; SAVE FCB POINTER
  845.     POP    HL            ; GET IT IN HL
  846.     ADD    HL,BC            ; ADD OFFSET
  847.     LD    A,(MAXLEN+1)        ; TEST NUMBER OF BLOCK >= 256
  848.     OR    A            
  849.     JR    Z,CLOSE0        ; NO THEN JUMP
  850.     DEC    B            ; SET FLAG
  851. CLOSE0:    CALL    COPYDM            ; COPY AND TEST BLOCKS
  852.     EX    DE,HL            ; EXCHANGE COPY DIRECTION
  853.     CALL    COPYDM            ; COPY AND TEST BLOCKS
  854.     EX    DE,HL            ; EXCHANGE COPY DIRECTION
  855.     JR    NZ,CLOSE4        ; BLOCK NOT THE SAME THEN ERROR
  856.     INC    HL            ; INCREMENT POINTER FCB
  857.     INC    DE            ; INCREMENT POINTER DIRECTORY
  858.     BIT    0,B            ; TEST NUMBER OF BLOCK >= 256
  859.     JR    Z,CLOSE1        ; NO THEN JUMP
  860.     INC    HL            ; INCREMENT POINTER FCB
  861.     INC    DE            ; INCREMENT POINTER DIRECTORY
  862.     DEC    C            ; DECREMENT COUNTER
  863. CLOSE1:    DEC    C            ; DECREMENT COUNTER
  864.     JR    NZ,CLOSE0        ; NOT READY THEN JUMP
  865.     LD    HL,-20            ; ADD -20 TO GET EXTENT NUMBER
  866.     ADD    HL,DE            ; HL CONTAINS POINTER TO EXTENT NUMBER
  867.     LD    A,(IX+12)        ; GET EXTENT NUMBER FCB
  868.     CP    (HL)            ; COMPARE WITH EXTENT NUMBER DIRECTORY
  869.     JR    C,CLOSE3        ; FCB < DIRECTORY THEN JUMP
  870.     LD    (HL),A            ; SAVE EXTENT NUMBER IN DIRECTORY
  871.     INC    HL            ; GET POINTER TO NEXT RECORD
  872.     INC    HL
  873.     INC    HL
  874.     LD    A,(IX+15)        ; GET NEXT RECORD FCB
  875. ;
  876. ; THESE LINES HAVE TO BE REMOVED TO LET SUBMIT WORK CORRECTLY
  877. ;
  878. ;    JR    NZ,CLOSE2        ; EXTENTS NOT EQUAL THEN JUMP
  879. ;    CP    (HL)            ; TEST FCB < DIRECTORY
  880. ;    JR    C,CLOSE3        ; IF SO THEN JUMP
  881. ;
  882. CLOSE2:    LD    (HL),A            ; SAVE NEXT RECORD IN DIRECTORY
  883. CLOSE3:    
  884.     IF    DOTIME
  885.     LD    E,5            ; SET LAST UPDATE DATE/TIME
  886.     CALL    STIME            ; UPDATE TIME
  887.     ENDIF
  888.     JP    WRFCB1            ; WRITE FCB ON DISK
  889. CLOSE4:    LD    A,0FFH            ; FLAG ERROR
  890.     LD    (PEXIT),A 
  891.     RET                ; AND RETURN TO CALLER
  892. ;
  893. ; COPY AND TEST DISK MAP
  894. ;  ENTRY : HL : POINTER TO FIRST FCB
  895. ;          DE : POINTER TO SECOND FCB
  896. ;          B  : 000H LESS THEN 256 BLOCKS
  897. ;               0FFH MORE OR EQUAL TO 256 BLOCKS
  898. ;  EXIT  : ZERO : 1 BLOCKS ARE THE SAME
  899. ;                 0 BLOCKS ARE NOT THE SAME
  900. ;
  901. COPYDM:    LD    A,(HL)            ; GET BYTE FIRST FCB
  902.     BIT    0,B            ; TEST NUMBER OF BLOCKS >=256
  903.     JR    Z,COPYD0        ; NO THEN JUMP
  904.     INC    HL            ; INCREMENT POINTER
  905.     OR    (HL)            ; TEST BYTE =0
  906.     DEC    HL            ; DECREMENT POINTER
  907. COPYD0:    OR    A            ; TEST BLOCK NUMBER IS ZERO
  908.     JR    NZ,COPYD1        ; NO THEN COMPARE BLOCKS
  909.     LD    A,(DE)            ; COPY BLOCK FROM OTHER FCB IN EMPTY 
  910.                     ; LOCATION
  911.     LD    (HL),A 
  912.     BIT    0,B            ; TEST NUMBER OF BLOCKS >=256
  913.     RET    Z            ; NO THEN EXIT
  914.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBERS
  915.     INC    DE
  916.     LD    A,(DE)            ; COPY BLOCK FROM OTHER FCB IN EMPTY 
  917.                     ; LOCATION
  918.     LD    (HL),A
  919.     JR    COPYD2            ; JUMP TRICK TO SAVE SPACE
  920. COPYD1:    LD    A,(DE)            ; GET BLOCK NUMBER FIRST FCB
  921.     SUB    (HL)            ; TEST IF THE SAME
  922.     RET    NZ            ; NOT THEN RETURN
  923.     OR    B            ; TEST IF >=256 BLOCKS
  924.     RET    Z            ; NO THEN RETURN
  925.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBERS
  926.     INC    DE
  927. COPYD2:    LD    A,(DE)            ; GET BLOCK NUMBER FIRST FCB
  928.     SUB    (HL)            ; TEST IF THE SAME
  929.     DEC    HL            ; DECREMENT BLOCK FCB POINTERS
  930.     DEC    DE
  931.     RET                ; AND EXIT TO CALLER
  932. ;
  933. ; MAKE FILE COMMAND
  934. ;
  935. CMND22:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  936.     LD    (IX+14),0        ; CLEAR FCB+14
  937. ;
  938. ; MAKE FILE
  939. ;
  940. MAKE:
  941.     CALL    CHKRO            ; CHECK DRIVE R/O
  942.     LD    A,(IX+0)        ; GET FIRST BYTE FCB
  943.     PUSH    AF            ; SAVE IT
  944.     LD    (IX+0),0E5H        ; SET FIRST BYTE TO EMPTY FILE
  945.     LD    A,1            ; SEARCH FOR 1 BYTE
  946.     CALL    SEARCH            ; SEARCH EMPTY FILE
  947.     POP    AF            ; GET FIRST BYTE FCB
  948.     LD    (IX+0),A        ; RESTORE IT
  949.     CALL    TSTFCT            ; TEST EMPTY FILE FOUND
  950.     RET    Z            ; NO THEN RETURN ERROR
  951.     XOR    A            ; CLEAR FCB+13
  952.     LD    (IX+13),A
  953.     PUSH    IX            ; SAVE FCB POINTER
  954.     POP    HL            ; GET IT BACK IN HL
  955.     LD    DE,15            ; PREPARE OFFSET
  956.     ADD    HL,DE            ; ADD IT
  957.     LD    B,17            ; SET LOOP COUNTER
  958. MAKE0:    LD    (HL),A            ; CLEAR FCB+15 UNP TO FCB+31
  959.     INC    HL            ; INCREMENT POINTER
  960.     DJNZ    MAKE0            ; AND CLEAR ALL BYTES
  961.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  962.     LD    A,(IX+0)        ; GET FIRST BYTE FCB
  963.     LD    (HL),A            ; SAVE IT IN DIRECTORY (WRITE FCB 
  964.                     ; NEEDS THIS)
  965.     IF    DOTIME
  966.     LD    E,1            ; SET CREATION DATE/TIME
  967.     CALL    STIME            ; UPDATE TIME IN DIRECTORY 
  968.     LD    E,5            ; SET LAST UPDATE DATE/TIME
  969.     CALL    STIME            ; UPDATE TIME IN DIRECTORY
  970.     ENDIF
  971. ;
  972.     LD    BC,32*256+0        ; COPY FCB+0 TO DIRECTOTY+0 32 TIMES
  973.     CALL    WRFCB            ; WRITE FCB ON DISK
  974.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  975.     RET                ; AND RETURN TO CALLER
  976. ;
  977. ; OPEN NEXT EXTENT
  978. ;
  979. OPENEX:    BIT    7,(IX+14)        ; TEST IF FCB/FILE MODIFIED (WRITE)
  980.     JR    NZ,OPENX2        ; NOT THEN JUMP
  981.     CALL    CLOSE            ; CLOSE CURRENT FCB
  982.     LD    A,(PEXIT)        ; GET EXIT CODE
  983.     INC    A            ; TEST IF ERROR
  984.     RET    Z            ; YES THEN EXIT
  985.     CALL    CALNEX            ; CALCULATE NEXT EXTENT
  986.     JR    C,OPENX3        ; ERROR THEN JUMP
  987.     JR    NZ,OPENX5        ; FCB PRESENT FROM CLOSE THEN JUMP
  988. OPENX0:    LD    A,15            ; SEARCH FIRST 15 BYTES
  989.     CALL    SEARCH            ; SEARCH FOR FILE
  990. OPENX1:    CALL    TSTFCT            ; TEST IF FILE FOUND
  991.     JR    NZ,OPENX5        ; YES THEN JUMP
  992.     LD    A,(RDWR)        ; TEST READ/WRITE FLAG
  993.     OR    A            ; TEST IF READ
  994.     JR    Z,OPENX3        ; YES THEN ERROR
  995.     CALL    MAKE            ; MAKE NEW EXTENT IF WRITE
  996.     CALL    TSTFCT            ; TEST IF SUCCESFULL
  997.     JR    NZ,OPENX6        ; YES THEN EXIT
  998.     JR    OPENX3            ; NO THEN ERROR
  999. OPENX2:    CALL    CALNEX            ; CALCULATE NEXT EXTENT
  1000.     JR    C,OPENX3        ; ERROR THEN JUMP
  1001.     BIT    7,(IX+10)        ; TEST SYSTEM FILE BIT
  1002.     JR    Z,OPENX0        ; NO SYSTEM FILE THEN JUMP
  1003.     CALL    FINDF            ; SEARCH PATH FOR FILE
  1004.     JR    OPENX1            ; USE SAME ROUTINE
  1005. OPENX3:    SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED 
  1006.     LD    A,0FFH            ; SET EXIT CODE
  1007. OPENX4:    LD    (PEXIT),A        
  1008.     RET                ; AND RETURN TO CALLER
  1009. OPENX5:    CALL    OPENF0            ; OPEN FILE
  1010. OPENX6:    XOR    A            ; AND CLEAR EXIT CODE
  1011.     JR    OPENX4            ; USE SAME ROUTINE 
  1012. ;
  1013. ; CALCULATE NEXT EXTENT
  1014. ;  EXIT: CARRY=1 => OVERFLOW DETECTED
  1015. ;        ZERO =1 => SEARCH NEXT EXTENT
  1016. ;     ZERO =0 => NEXT EXTENT PRESENT (CLOSE)
  1017. ;
  1018. CALNEX:    LD    B,(IX+12)        ; GET EXTENT NUMBER
  1019.     LD    C,(IX+14)        ; GET FCB+14
  1020.     BIT    6,C            ; TEST ERROR BIT RANDOM RECORD
  1021.     SCF                ; SET ERROR FLAG
  1022.     RET    NZ            ; NON ZERO THEN ERROR EXIT
  1023.     INC    B            ; INCREMENT EXTENT NUMBER
  1024.     LD    A,B            ; GET EXTENT NUMBER
  1025.     AND    01FH            ; MASK IT
  1026.     LD    B,A            ; SAVE IT IN B
  1027.     JR    NZ,CALNX0        ; NON ZERO THEN JUMP
  1028.     INC    C            ; INCREMENT FCB+14
  1029.     LD    A,C            ; GET IT IN A
  1030.     AND    03FH            ; MASK IT
  1031.     LD    C,A            ; SAVE IT IN C
  1032.     SCF                ; SET ERROR FLAG
  1033.     RET    Z            ; AND RETURN IF FILE OVERFLOW
  1034.     XOR    A            ; CLEAR ZERO FLAG (NOT SAME EXTENT)
  1035.     JR    CALNX1            ; AND SAVE EXTENT NUMBER AND FCB+14
  1036. CALNX0:    LD    A,(NEXTND)        ; GET NEXT EXTENT MASK
  1037.     AND    B            ; TEST IF SAME EXTENT (CLOSE)
  1038. CALNX1:    LD    (IX+12),B        ; SAVE EXTENT NUMBER
  1039.     LD    (IX+14),C        ; SAVE FCB+14
  1040.     RET                ; AND RETURN TO CALLER
  1041. ;
  1042. ; READ RANDOM RECORD COMMAND
  1043. ;
  1044. CMND33:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1045. ;
  1046. ; READ RANDOM SECTOR
  1047. ;
  1048. RDRAN:    XOR    A            ; SET READ/WRITE FLAG
  1049.     CALL    LDFCB            ; LOAD RANDOM RECORD IN FCB
  1050.     JR    Z,READS            ; NO ERROR THEN READ SECTOR
  1051.     RET                ; RETURN ERROR 
  1052. ;
  1053. ; READ SEQUENTIAL
  1054. ;
  1055. CMND20:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1056. ;
  1057. ; READ SECTOR
  1058. ;
  1059. READS:    XOR    A            ; SET READ/WRITE FLAG
  1060.     LD    (RDWR),A        ; SAVE IT
  1061.     LD    A,(IX+32)        ; GET RECORD COUNTER
  1062.     CP    080H            ; TEST IF LAST RECORD THIS EXTENT
  1063.     JR    NC,READS1        ; YES THEN OPEN NEXT EXTENT
  1064.     CP    (IX+15)            ; TEST IF GREATER THEN CURRENT RECORD
  1065.     JR    C,READS2        ; NO THEN GET RECORD
  1066. READS0:    LD    A,1            ; SET END OF FILE FLAG
  1067.     LD    (PEXIT),A        ; SAVE IT
  1068.     RET                ; AND RETURN TO CALLER
  1069. READS1:    CALL    OPENEX            ; OPEN NEXT EXTENT
  1070.     LD    A,(PEXIT)        ; GET EXIT CODE
  1071.     OR    A
  1072.     JR    NZ,READS0        ; YES THEN END OF FILE
  1073.     LD    (IX+32),0        ; CLEAR RECORD COUNTER
  1074. READS2:    CALL    GETDM            ; GET BLOCK NUMBER FROM DM IN FCB
  1075.     LD    A,D            ; TEST BLOCK NUMBER = 0
  1076.     OR    E
  1077.     JR    Z,READS0        ; YES THEN END FILE
  1078.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  1079.     CALL    CALST            ; CALCULATE SECTOR/TRACK NUMBER
  1080.     CALL    READR            ; READ DATA
  1081.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  1082.     CP    20            ; TEST IF READ SEQUENTIAL
  1083.     RET    NZ            ; NO THEN RETURN
  1084.     INC    (IX+32)            ; INCREMENT NEXT RECORD COUNTER
  1085.     RET                ; AND RETURN TO CALLER
  1086. ;
  1087. ; WRITE RANDOM SECTOR WITH ZERO FILL COMMAND
  1088. ;
  1089. CMND40:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1090. ;
  1091. ; WRITE RANDOM SECTOR WITH ZERO FILL
  1092. ;
  1093. WRRANZ:    LD    A,0FFH            ; SET READ/WRITE FLAG
  1094.     CALL    LDFCB            ; LOAD FCB FROM RANDOM RECORD
  1095.     JR    Z,WRITES        ; NO ERROR THEN WRITE RECORD
  1096.     RET                ; RETURN ERROR
  1097. ;
  1098. ; WRITE RANDOM RECORD COMMAND
  1099. ;
  1100. CMND34:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1101. ;
  1102. ; WRITE RANDOM SECTOR
  1103. ;
  1104. WRRAN:    LD    A,0FFH            ; SET READ/WRITE FLAG
  1105.     CALL    LDFCB            ; LOAD FCB FROM RANDOM RECORD
  1106.     JR    Z,WRITES        ; NO ERROR THEN WRITE RECORD
  1107.     RET                ; RETURN ERROR
  1108. ;
  1109. ; WRITE SEQUENTIAL
  1110. ;
  1111. CMND21:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1112. ;
  1113. ; WRITE SECTOR
  1114. ;
  1115. WRITES:    LD    A,0FFH            ; SET READ/WRITE FLAG
  1116.     LD    (RDWR),A        ; AND SAVE IT
  1117.     CALL    CHKRO            ; CHECK DISK R/O
  1118.     PUSH    IX            ; SAVE FCB POINTER
  1119.     POP    HL            ; GET IT BACK IN HL
  1120.     CALL    CHKFR0            ; CHECK FILE R/O
  1121.     LD    A,(IX+32)        ; GET RECORD COUNT
  1122.     CP    080H            ; TEST IF END THIS EXTENT
  1123.     JR    C,WRITS0        ; YES THEN OPEN NEXT EXTENT
  1124.     CALL    OPENEX            ; OPEN NEXT EXTENT
  1125.     LD    A,(PEXIT)        ; GET ERROR CODE
  1126.     OR    A        
  1127.     JP    NZ,WRITS9        ; ERROR THEN DIRECTORY FULL ERROR
  1128.     LD    (IX+32),0        ; CLEAR RECORD COUNTER
  1129. WRITS0:    CALL    GETDM            ; GET BLOCK NUMBER FROM FCB
  1130.     LD    A,D            ; TEST IF BLOCK NUMBER = 0
  1131.     OR    E
  1132.     JR    NZ,WRITS5        ; NO THEN WRITE SECTOR
  1133.     PUSH    HL            ; SAVE POINTER TO BLOCK NUMBER
  1134.     LD    A,C            ; TEST FIRST BLOCK NUMBER IN EXTENT
  1135.     OR    A
  1136.     JR    Z,WRITS1        ; YES THEN JUMP
  1137.     DEC    A            ; DECREMENT POINTER TO BLOCK NUMBER
  1138.     CALL    GETDM4            ; GET PREVIOUS BLOCKNUMBER
  1139. WRITS1:    CALL    GETFRE            ; GET NEAREST FREE BLOCK
  1140.     POP    HL            ; GET POINTER TO BLOCK NUMBER
  1141.     LD    A,D            ; TEST IF BLOCKNUMBER = 0
  1142.     OR    E
  1143.     JR    Z,WRITS8        ; YES THEN DISK FULL ERROR
  1144.     RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED
  1145.     LD    (HL),E            ; SAVE BLOCKNUMBER
  1146.     LD    A,(MAXLEN+1)        ; GET NUMBER OF BLOCKS
  1147.     OR    A            ; TEST IF <256
  1148.     JR    Z,WRITS2        ; YES THEN JUMP
  1149.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBER
  1150.     LD    (HL),D            ; SAVE MSB BLOCK NUMBER
  1151. WRITS2:    LD    C,2            ; SET WRITE NEW BLOCK FLAG
  1152.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  1153.     SUB    40            ; TEST IF WRITE RR WITH ZERO FILL
  1154.     JR    NZ,WRITS6        ; NO THEN JUMP
  1155.     PUSH    DE            ; SAVE BLOCKNUMBER
  1156.      LD    HL,DIRBUF        ; USE DIRECTORY BUFFER FOR ZERO FILL
  1157.     LD    B,128            ; 128 BYTES TO CLEAR
  1158. WRITS3:    LD    (HL),A            ; CLEAR DIRECTORY BUFFER
  1159.     INC    HL            ; INCREMENT POINTER
  1160.     DJNZ    WRITS3            ; CLEAR ALL BYTES
  1161.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  1162.     LD    A,(NMASK)        ; GET SECTOR MASK
  1163.     LD    B,A            ; COPY IT
  1164.     INC    B            ; INCREMENT IT TO GET NUMBER OF WRITES
  1165.     CPL                ; COMPLEMENT SECTOR MASK
  1166.     AND    E            ; MASK SECTOR NUMBER
  1167.     LD    E,A            ; AND SAVE IT
  1168.     LD    C,2            ; SET WRITE NEW BLOCK FLAG
  1169. WRITS4:    PUSH    HL            ; SAVE REGISTERS
  1170.     PUSH    DE
  1171.     PUSH    BC
  1172.     CALL    CALST            ; CALCULATE SECTOR/TRACK
  1173.     CALL    DMADIR            ; SET DMA DIRECTORY BUFFER
  1174.     POP    BC            ; GET WRITE NEW BLOCK FLAG
  1175.     PUSH    BC            ; SAVE IT AGAIN
  1176.     CALL    WRITER            ; WRITE RECORD ON DISK
  1177.     POP    BC            ; RESTORE REGISTERS
  1178.     POP    DE
  1179.     POP    HL
  1180.     LD    C,0            ; CLEAR WRITE NEW BLOCK FLAG
  1181.     INC    E            ; INCREMENT SECTOR NUMBER
  1182.     DJNZ    WRITS4            ; WRITE ALL BLOCKS
  1183.     CALL    STDMA            ; SET USER DMA ADDRESS
  1184.     POP    DE            ; GET BLOCK NUMBER
  1185. WRITS5:    LD    C,0            ; CLEAR WRITE NEW BLOCK FLAG 
  1186. WRITS6:    RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED FLAG
  1187.     PUSH    BC            ; SAVE IT
  1188.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  1189.     CALL    CALST            ; CALCULATE SECTOR/TRACK
  1190.     POP    BC            ; GET WRITE NEW BLOCK FLAG
  1191.     CALL    WRITER            ; WRITE RECORD ON DISK
  1192.     LD    A,(IX+32)        ; GET RECORD COUNTER
  1193.     CP    (IX+15)            ; COMPARE WITH NEXT RECORD
  1194.     JR    C,WRITS7        ; IF LESS THEN JUMP
  1195.     INC    A            ; INCREMENT RECORD COUNT 
  1196.     LD    (IX+15),A        ; SAVE IT ON NEXT RECORD POSITION
  1197.     RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED FLAG
  1198. WRITS7:    LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  1199.     CP    21            ; TEST WRITE SEQUENTIAL
  1200.     RET    NZ            ; NOT THEN RETURN
  1201.     INC    (IX+32)            ; INCREMENT RECORD COUNT
  1202.     RET                ; AND RETURN TO CALLER
  1203. WRITS8:    LD    A,2            ; SET DISK FULL ERROR
  1204.     LD    (PEXIT),A
  1205.     RET                ; AND RETURN TO CALLER
  1206. WRITS9:    LD    A,1            ; SET DIRECTORY FULL FLAG
  1207.     LD    (PEXIT),A
  1208.     RET                ; AND RETURN TO CALLER
  1209. ;
  1210. ; LOAD FCB FOR RANDOM READ/WRITE
  1211. ;  EXIT : ZERO FLAG : 1 NO ERROR
  1212. ;                     0 ERROR OCCURED
  1213. ;
  1214. LDFCB:    LD    (RDWR),A        ; SAVE READ/WRITE FLAG
  1215.     LD    A,(IX+33)        ; GET FIRST BYTE RANDOM RECORD
  1216.     LD    D,A            ; SAVE IT IN D
  1217.     RES    7,D            ; RESET MSB TO GET NEXT RECORD
  1218.     RLA                ; SHIFT MSB IN CARRY
  1219.     LD    A,(IX+34)        ; LOAD NEXT BYTE RANDOM RECORD
  1220.     RLA                ; SHIFT CARRY
  1221.     PUSH    AF            ; SAVE IT
  1222.     AND    01FH            ; MASK NEXT EXTENT
  1223.     LD    C,A            ; SAVE IT IN C
  1224.     POP    AF            ; GET BYTE
  1225.     RLA                ; SHIFT 4 TIMES
  1226.     RLA
  1227.     RLA
  1228.     RLA
  1229.     AND    0FH            ; MASK IT
  1230.     LD    B,A            ; SAVE FCB+14
  1231.     LD    A,(IX+35)        ; GET NEXT BYTE RANDOM RECORD
  1232.     LD    E,6            ; SET RANDOM RECORD TO LARGE FLAG
  1233.     CP    4            ; TEST RANDOM RECORD TO LARGE 
  1234.     JR    NC,LDFCB8        ; YES THEN ERROR
  1235.     RLCA                ; SHIFT 4 TIMES
  1236.     RLCA
  1237.     RLCA
  1238.     RLCA
  1239.     ADD    A,B            ; ADD BYTE
  1240.     LD    B,A            ; SAVE FCB+14 IN B
  1241.     LD    (IX+32),D        ; SET NEXT RECORD COUNT
  1242.     LD    D,(IX+14)        ; GET FCB+14
  1243.     BIT    6,D            ; TEST ERROR RANDOM RECORD
  1244.     JR    NZ,LDFCB0        ; YES THEN JUMP
  1245.     LD    A,C            ; GET NEW EXTENT NUMBER
  1246.     CP    (IX+12)            ; COMPARE WITH FCB
  1247.     JR    NZ,LDFCB0        ; NOT EQUAL THEN OPEN NEXT EXTENT
  1248.     LD    A,B            ; GET NEW FCB+14
  1249.     XOR    (IX+14)            ; COMPARE WITH FCB+14
  1250.     AND    03FH            ; MASK IT
  1251.     JR    Z,LDFCB6        ; EQUAL THEN RETURN
  1252. LDFCB0:    BIT    7,D            ; TEST FCB MODIFIED (WRITE)
  1253.     JR    NZ,LDFCB1        ; NO THEN JUMP
  1254.     PUSH    DE            ; SAVE REGISTERS
  1255.     PUSH    BC
  1256.     CALL    CLOSE            ; CLOSE EXTENT
  1257.     POP    BC            ; RESTORE REGISTERS
  1258.     POP    DE
  1259.     LD    E,3            ; SET CLOSE ERROR
  1260.     LD    A,(PEXIT)        ; GET EXIT CODE
  1261.     INC    A
  1262.     JR    Z,LDFCB7        ; ERROR THEN EXIT
  1263. LDFCB1:    LD    (IX+12),C        ; SAVE NEW EXTENT NUMBER
  1264.     LD    (IX+14),B        ; SAVE NEW FCB+14
  1265.     BIT    7,D            ; TEST FCB MODIFIED (PREVIOUS FCB)
  1266.     JR    NZ,LDFCB3        ; NO THEN JUMP
  1267. LDFCB2:    LD    A,15            ; SET NUMBER OF BYTES TO SEARCH FOR
  1268.     CALL    SEARCH            ; SEARCH NEXT FCB
  1269.     JR    LDFCB4            ; JUMP
  1270. LDFCB3:    BIT    7,(IX+10)        ; TEST IF SYSTEM FILE
  1271.     JR    Z,LDFCB2        ; NO USE SEARCH
  1272.     CALL    FINDF            ; OPEN FILE (USE PATH NAME)
  1273. LDFCB4:    LD    A,(PEXIT)        ; GET ERROR CODE
  1274.     INC    A
  1275.     JR    NZ,LDFCB5        ; NO ERROR THEN EXIT
  1276.     LD    A,(RDWR)        ; GET READ/WRITE FLAG
  1277.     LD    E,4            ; SET READ EMPTY RECORD
  1278.     INC    A
  1279.     JR    NZ,LDFCB7        ; READ THEN ERROR
  1280.     CALL    MAKE            ; MAKE MEW FCB
  1281.     LD    E,5            ; SET MAKE ERROR
  1282.     LD    A,(PEXIT)        ; GET ERROR CODE
  1283.     INC    A
  1284.     JR    Z,LDFCB7        ; ERROR THEN EXIT
  1285.     JR    LDFCB6            ; NO ERROR EXIT (ZERO SET)
  1286. LDFCB5:    CALL    OPENF0            ; OPEN FILE
  1287. LDFCB6:    XOR    A            ; SET ZERO FLAG AND CLEAR ERROR CODE
  1288.     LD    (PEXIT),A
  1289.     RET                ; AND RETURN TO CALLER
  1290. LDFCB7:    LD    (IX+14),0C0H        ; SET RANDOM RECORD ERROR
  1291. LDFCB8:    LD    A,E            ; GET ERROR CODE
  1292.     LD    (PEXIT),A        ; AND SAVE IT
  1293.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  1294.     OR    A            ; CLEAR ZERO FLAG
  1295.     RET                ; AND RETURN TO CALLER
  1296. ;
  1297. ; CALCULATE RANDOM RECORD
  1298. ;  ENTRY HL=OFFSET IN FCB
  1299. ;        DE=FCB POINTER
  1300. ;  EXIT  D=LSB RANDOM RECORD
  1301. ;        C=ISB RANDOM RECORD
  1302. ;        B=MSB RANDOM RECORD
  1303. ;
  1304. CALRRC:    ADD    HL,DE            ; POINTER TO FCB+15 OR FCB+32
  1305.     LD    A,(HL)            ; GET BYTE
  1306.     LD    HL,12            ; OFFSET TO EXTENT NUMBER
  1307.     ADD    HL,DE            ; GET POINTER TO EXTENT BYTE
  1308.     LD    D,A            ; SAVE FIRST BYTE
  1309.     LD    A,(HL)            ; GET EXTENT BYTE
  1310.     AND    01FH            ; MASK IT
  1311.     RL    D            ; SHIFT MSB IN CARRY
  1312.     ADC    A,0            ; ADD CARRY
  1313.     RRA                ; SHIFT 1 TIME (16 BITS)
  1314.     RR    D
  1315.     LD    C,A            ; SAVE ISB
  1316.     INC    HL            ; INCREMENT TO FCB+14
  1317.     INC    HL
  1318.     LD    A,(HL)            ; GET FCB+14
  1319.     RRCA                ; SHIFT 4 TIMES
  1320.     RRCA
  1321.     RRCA
  1322.     RRCA
  1323.     PUSH    AF            ; SAVE IT
  1324.     AND    03H            ; MASK MSB
  1325.     LD    B,A            ; SAVE IT
  1326.     POP    AF            ; GET LSB
  1327.     AND    0F0H            ; MASK IT
  1328.     ADD    A,C            ; ADD WITH ISB
  1329.     LD    C,A            ; SAVE ISB
  1330.     RET    NC            ; NO CARRY THEN RETURN
  1331.     INC    B            ; INCREMENT MSB
  1332.     RET                ; AND RETURN TO CALLER
  1333. ;
  1334. CLRDSK:    LD    HL,0            ; Disk reset routine
  1335.     LD    (LOGIN),HL
  1336.     CALL    INITDR
  1337.     XOR    A            ;Clear disk changed flag
  1338.     LD    (DIFF),A
  1339.     LD    A,(SUBFLG)
  1340.     JP    CMD25A
  1341. ;
  1342. ; SET TIME AND DATE
  1343. ;  ENTRY: E : 1 : SET CREATION TIME/DATE
  1344. ;             5 : SET LAST UPDATE TIME/DATE
  1345. ;  TIME RETURN POINTER IN HL
  1346. ;   HL+0 : LOW  BYTE DATE SINCE JAN,1,1978
  1347. ;   HL+1 : HIGH BYTE DATE SINCE JAN,1,1978
  1348. ;   HL+2 : HOURS   (BCD)
  1349. ;   HL+3 : MINUTES (BCD)
  1350. ;   HL+4 : SECONDS (BCD) (NOT USED IN TIME STAMP)
  1351. ;    
  1352.     IF    DOTIME
  1353. STIME:    LD    HL,(DIRBUF)        ; GET DIRECTORY ENTRY
  1354.     LD    BC,060H            ; OFFSET ENTRY POINT TIME/DATE STAMP
  1355.     ADD    HL,BC            ; ADD OFFSET
  1356.     LD    A,(HL)            ; GET BYTE
  1357.     SUB    021H            ; TEST IF TIME STAMP PRESENT
  1358.     RET    NZ            ; NO THEN RETURN
  1359.     LD    D,A            ; CLEAR D
  1360.     ADD    HL,DE            ; ADD ENTRY (UPDATE/CREATE)
  1361.     LD    A,(SECPNT)        ; GET SECTOR POINTER
  1362.     RRCA                ; SHIFT 2 TIMES
  1363.     RRCA
  1364.     LD    E,A            ; SAVE IT
  1365.     RRCA                ; SHIFT 2 TIMES
  1366.     RRCA
  1367.     ADD    A,E            ; ADD IT (A=0,10,20)
  1368.     LD    E,A            ; SAVE IN E
  1369.     ADD    HL,DE            ; ADD OFFSET
  1370.     PUSH    HL            ; SAVE RESULT
  1371.     LD    C,0            ; RETURN POINTER IN HL
  1372.                     ; C=FF MEANS SET DATE POINTED TO BY HL
  1373.     CALL    BTIME            ; RETURN POINTER IN HL
  1374.     POP    DE            ; GET POINTER
  1375.     LD    BC,4            ; SET 4 BYTES
  1376.     LDIR                ; COPY 4 BYTES
  1377.     RET                ; AND RETURN TO CALLER
  1378. ;
  1379. ; GET TIME
  1380. ;
  1381. GETTIM:    PUSH    DE            ; SAVE ADDRESS TO PUT TIME 
  1382.     LD    C,0            ; GET TIME ADDRESS
  1383.     CALL    BTIME            ; EXECUTE P2BIOS CALL
  1384.     POP    DE            ; RESTORE ADDRESS TO PUT TIME
  1385.     LD    BC,5            ; 5 BYTES TO MOVE
  1386.     LDIR                ; STORE THE TIME
  1387.     RET                ; AND RETURN TO CALLER
  1388. ;
  1389. ; SET TIME
  1390. ;
  1391. SETTIM:    EX    DE,HL            ; GET ADDRESS TIME IN HL 
  1392.     LD    C,0FFH            ; SET TIME ADDRESS
  1393.                     ; AND FALL THROUGH TO P2BIOS CALL 
  1394. ;
  1395. ; EXECUTE P2BIOS TIME ROUTINE
  1396. ;
  1397. BTIME:    PUSH    HL            ; SAVE VALUE IN HL
  1398.     LD    HL,(TIMEAD)        ; GET ADDRESS TIME ROUTINE
  1399.     EX    (SP),HL            ; PUT ADDRESS ON STACK AND RESTORE HL
  1400.     RET                ; EXECUTE TIME ROUTINE
  1401. ;
  1402.     ENDIF    
  1403. ;
  1404. ; P2DOS EXIT ROUTINE
  1405. ;
  1406. P2EXIT:    LD    A,(FLDRV)        ; TEST DRIVE SELECT USED FLAG
  1407.     OR    A            
  1408.     JR    Z,P2EXT0        ; NO THEN EXIT
  1409.     LD    A,(FCB0)        ; GET FCB BYTE 0
  1410.     LD    (IX+0),A        ; SAVE IT
  1411.     LD    A,(DRIVE)        ; GET OLD DRIVE NUMBER
  1412.     CALL    SELDK            ; SELECT DISK
  1413. P2EXT0:    PUSH    IX            ; SAVE IX
  1414.     POP    DE            ; RESTORE DE
  1415.     POP    IX            ; RESTORE IX
  1416.     LD    SP,(SPSAVE)        ; GET OLD SP
  1417.     LD    HL,(PEXIT)        ; GET EXIT CODE
  1418.     LD    A,(FUNCT)        ; GET FUNCTION CODE
  1419.     LD    C,A            ; RESTORE C
  1420.     LD    A,L            ; COPY FUNCTION CODE
  1421.     LD    B,H
  1422.     RET                ; AND RETURN TO CALLER
  1423. ;
  1424. ; RAM AREA
  1425. ;
  1426. TABCNT:    DB    0            ; TAB COUNTER
  1427. TABCX1:    DB    0            ; TEMPORARY TAB COUNTER (USED BY RDBUF)
  1428. FCONTP:    DB    0            ; LIST ENABLE FLAG (CONTROL P)
  1429. LASTCH:    DB    0            ; LAST CHARACTER
  1430. DELAY:    DB    0FFH            ; DELAY COUNTER
  1431. ;
  1432. TRANS:    DEFW    0            ; TRANSLATION VECTOR
  1433. TEMP0:    DEFW    0            ; NUMBER OF FILES ON DRIVE 
  1434. TEMP1:    DEFW    0            ; NOT USED 
  1435. TEMP2:    DEFW    0            ; NOT USED
  1436. DIRBUF:    DEFW    0            ; DIRECTORY BUFFER
  1437. IXP:    DEFW    0            ; DISK PARAMETER BLOCK
  1438. CSV:    DEFW    0            ; CHECK SUM POINTER
  1439. ALV:    DEFW    0            ; ALLOCATION VECTOR POINTER
  1440. ;
  1441. MAXSEC:    DEFW    0            ; MAXIMUM NUMBER OF SECTORS/TRACK
  1442. NBLOCK:    DB    0            ; NUMBER OF BLOCKS
  1443. NMASK:    DB    0            ; MASK NUMBER OF BLOCKS
  1444. NEXTND:    DB    0            ; EXTENT MASK
  1445. MAXLEN:    DEFW    0            ; MAXIMUM BLOCK NUMBER-1
  1446. NFILES:    DEFW    0            ; MAXIMUM NUMBER OF FILES-1
  1447. NDIR0:    DB    0            ; FIRST TWO ENTRIES ALV BUFFER
  1448. NDIR1:    DB    0
  1449. NCHECK:    DEFW    0            ; NUMBER OF CHECKSUM ENTRUIES
  1450. NFTRK:    DEFW    0            ; FIRST TRACK NUMBER
  1451. ;
  1452. DSKRO:    DEFW    0            ; DISK R/O VECTOR
  1453. LOGIN:    DEFW    0            ; LOGIN VECTOR
  1454. DMA:    DEFW    080H            ; DMA ADDRESS
  1455. ;
  1456. FUNCT:    DB    0            ; FUNCTION NUMBER
  1457. PEXIT:    DEFW    0            ; EXIT CODE
  1458. FLDRV:    DB    0            ; DRIVE SELECT USED FLAG
  1459. RDWR:    DB    0            ; READ/WRITE FLAG
  1460. ;
  1461. FCB0:    DB    0            ; FCB BYTE 0
  1462. USER:    DB    0            ; USER NUMBER
  1463. DRIVE:    DB    0            ; DRIVE NUMBER
  1464. DEFDRV:    DB    0            ; DEFAULT DRIVE NUMBER
  1465. RECDIR:    DEFW    0            ; RECORD DIRECTORY (CHECKSUM)
  1466. FILCNT:    DEFW    0            ; FILE COUNTER
  1467. SECPNT:    DB    0            ; SECTOR POINTER
  1468. SUBFLG:    DB    0            ; SUBMIT FLAG (RESET DISK COMMAND)
  1469. ;
  1470. DCOPY:    DEFW    0            ; COPY ADDRESS FCB
  1471. SEAREX:    DB    0            ; EXIT CODE SEARCH
  1472. SEARNB:    DB    0            ; SEARCH NUMBER OF BYTES
  1473. SEARQU:    DB    0            ; SEARCH QUESTION MARK USED
  1474. SEARPU:    DB    0            ; SEARCH PUBLIC FILE
  1475. ;next two flags added by B.H.
  1476. DIFF:    DB    0            ; disk changed flag
  1477. RETFLG:    DB    0            ; allows recovery from read/write errors 
  1478. ;
  1479. SPSAVE:    DEFW    0            ; STACK POINTER LOCATION
  1480.     DEFS    62            ; 62 BYTE STACK
  1481. P2DOSS:                    ; P2DOS STACK
  1482. DOSSTOP    EQU    $
  1483. ;
  1484.     IF    Z80MR
  1485.     IF    ((DOSSTOP-DOSSTRT).GT.3584)
  1486.     *Bdos too large
  1487.     ENDIF
  1488.     ELSE
  1489.     IF    ((DOSSTOP-DOSSTRT) GT 3584)
  1490.     *Bdos too large!!*
  1491.     ENDIF
  1492.     ENDIF
  1493. ;
  1494. P-DOSSTRT).GT.3584)
  1495.     *Bdos too large
  1496.     ENDIF
  1497.     ELSE
  1498.     IF    ((