home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / suprbdos.lbr / DOS2.MZC / DOS2.MAC
Encoding:
Text File  |  1993-10-25  |  42.9 KB  |  1,486 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            ;Clear disk changed flag
  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:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  798.     LD    (IX+14),0        ; CLEAR FCB+14
  799. ;
  800. ; OPEN FILE
  801. ;
  802. OPENF:    CALL    FINDF            ; FIND FILE (USE PATH NAME)
  803.     CALL    TSTFCT            ; TEST FILE FOUND
  804.     RET    Z            ; NO THEN EXIT
  805. OPENF0:    LD    A,(IX+12)        ; GET EXTENT NUMBER FROM FCB
  806.     PUSH    AF            ; SAVE IT
  807.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  808.     PUSH    IX            ; SAVE FCB ENTRY
  809.     POP    DE            ; GET IN IN DE
  810.     LD    BC,32            ; NUMBER OF BYTES TO MOVE
  811.     LDIR                ; MOVE DIRECTORY TO FCB
  812.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  813.     LD    B,(IX+12)        ; GET EXTENT NUMBER
  814.     LD    C,(IX+15)        ; GET NEXT RECORD NUMBER
  815.     POP    AF            ; GET OLD EXTENT NUMBER
  816.     LD    (IX+12),A        ; SAVE IT
  817.     CP    B            ; COMPARE OLD AND NEW EXTENT NUMBER
  818.     JR    Z,OPENF1        ; SAME THEN JUMP
  819.     LD    C,0            ; SET NEXT RECORD COUNT TO 0
  820.     JR    NC,OPENF1        ; OLD EXTENT >= NEW EXTENT THEN JUMP
  821.     LD    C,80H            ; SET NEXT RECORD COUNT TO MAXIMUM
  822. OPENF1:    LD    (IX+15),C        ; SAVE NEXT RECORD COUNT
  823.     RET                ; AND RETURN TO CALLER
  824. ;
  825. ; CLOSE FILE COMMAND
  826. ;
  827. CMND16:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  828. ;
  829. ; CLOSE FILE
  830. ;
  831. CLOSE:    BIT    7,(IX+14)        ; TEST FCB/FILE MODIFIED
  832.     RET    NZ            ; NOT THEN NO CLOSE REQUIRED
  833.     CALL    CHKRO            ; TEST DISK R/O
  834.     LD    A,15            ; NUMBER OF BYTES TO SEARCH FOR
  835.     CALL    SEARCH            ; SEARCH FILE
  836.     CALL    TSTFCT            ; TEST FILE PRESENT
  837.     RET    Z            ; NO THEN EXIT
  838.     CALL    CHKFRO            ; CHECK FILE R/O
  839.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  840.     LD    BC,16            ; OFFSET TO DM BLOCK 
  841.     ADD    HL,BC            ; ADD OFFSET
  842.     EX    DE,HL            ; SAVE HL IN DE
  843.     PUSH    IX            ; SAVE FCB POINTER
  844.     POP    HL            ; GET IT IN HL
  845.     ADD    HL,BC            ; ADD OFFSET
  846.     LD    A,(MAXLEN+1)        ; TEST NUMBER OF BLOCK >= 256
  847.     OR    A            
  848.     JR    Z,CLOSE0        ; NO THEN JUMP
  849.     DEC    B            ; SET FLAG
  850. CLOSE0:    CALL    COPYDM            ; COPY AND TEST BLOCKS
  851.     EX    DE,HL            ; EXCHANGE COPY DIRECTION
  852.     CALL    COPYDM            ; COPY AND TEST BLOCKS
  853.     EX    DE,HL            ; EXCHANGE COPY DIRECTION
  854.     JR    NZ,CLOSE4        ; BLOCK NOT THE SAME THEN ERROR
  855.     INC    HL            ; INCREMENT POINTER FCB
  856.     INC    DE            ; INCREMENT POINTER DIRECTORY
  857.     BIT    0,B            ; TEST NUMBER OF BLOCK >= 256
  858.     JR    Z,CLOSE1        ; NO THEN JUMP
  859.     INC    HL            ; INCREMENT POINTER FCB
  860.     INC    DE            ; INCREMENT POINTER DIRECTORY
  861.     DEC    C            ; DECREMENT COUNTER
  862. CLOSE1:    DEC    C            ; DECREMENT COUNTER
  863.     JR    NZ,CLOSE0        ; NOT READY THEN JUMP
  864.     LD    HL,-20            ; ADD -20 TO GET EXTENT NUMBER
  865.     ADD    HL,DE            ; HL CONTAINS POINTER TO EXTENT NUMBER
  866.     LD    A,(IX+12)        ; GET EXTENT NUMBER FCB
  867.     CP    (HL)            ; COMPARE WITH EXTENT NUMBER DIRECTORY
  868.     JR    C,CLOSE3        ; FCB < DIRECTORY THEN JUMP
  869.     LD    (HL),A            ; SAVE EXTENT NUMBER IN DIRECTORY
  870.     INC    HL            ; GET POINTER TO NEXT RECORD
  871.     INC    HL
  872.     INC    HL
  873.     LD    A,(IX+15)        ; GET NEXT RECORD FCB
  874. ;
  875. ; THESE LINES HAVE TO BE REMOVED TO LET SUBMIT WORK CORRECTLY
  876. ;
  877. ;    JR    NZ,CLOSE2        ; EXTENTS NOT EQUAL THEN JUMP
  878. ;    CP    (HL)            ; TEST FCB < DIRECTORY
  879. ;    JR    C,CLOSE3        ; IF SO THEN JUMP
  880. ;
  881. CLOSE2:    LD    (HL),A            ; SAVE NEXT RECORD IN DIRECTORY
  882. CLOSE3:    
  883.     IF    DOTIME
  884.     LD    E,5            ; SET LAST UPDATE DATE/TIME
  885.     CALL    STIME            ; UPDATE TIME
  886.     ENDIF
  887.     JP    WRFCB1            ; WRITE FCB ON DISK
  888. CLOSE4:    LD    A,0FFH            ; FLAG ERROR
  889.     LD    (PEXIT),A 
  890.     RET                ; AND RETURN TO CALLER
  891. ;
  892. ; COPY AND TEST DISK MAP
  893. ;  ENTRY : HL : POINTER TO FIRST FCB
  894. ;          DE : POINTER TO SECOND FCB
  895. ;          B  : 000H LESS THEN 256 BLOCKS
  896. ;               0FFH MORE OR EQUAL TO 256 BLOCKS
  897. ;  EXIT  : ZERO : 1 BLOCKS ARE THE SAME
  898. ;                 0 BLOCKS ARE NOT THE SAME
  899. ;
  900. COPYDM:    LD    A,(HL)            ; GET BYTE FIRST FCB
  901.     BIT    0,B            ; TEST NUMBER OF BLOCKS >=256
  902.     JR    Z,COPYD0        ; NO THEN JUMP
  903.     INC    HL            ; INCREMENT POINTER
  904.     OR    (HL)            ; TEST BYTE =0
  905.     DEC    HL            ; DECREMENT POINTER
  906. COPYD0:    OR    A            ; TEST BLOCK NUMBER IS ZERO
  907.     JR    NZ,COPYD1        ; NO THEN COMPARE BLOCKS
  908.     LD    A,(DE)            ; COPY BLOCK FROM OTHER FCB IN EMPTY 
  909.                     ; LOCATION
  910.     LD    (HL),A 
  911.     BIT    0,B            ; TEST NUMBER OF BLOCKS >=256
  912.     RET    Z            ; NO THEN EXIT
  913.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBERS
  914.     INC    DE
  915.     LD    A,(DE)            ; COPY BLOCK FROM OTHER FCB IN EMPTY 
  916.                     ; LOCATION
  917.     LD    (HL),A
  918.     JR    COPYD2            ; JUMP TRICK TO SAVE SPACE
  919. COPYD1:    LD    A,(DE)            ; GET BLOCK NUMBER FIRST FCB
  920.     SUB    (HL)            ; TEST IF THE SAME
  921.     RET    NZ            ; NOT THEN RETURN
  922.     OR    B            ; TEST IF >=256 BLOCKS
  923.     RET    Z            ; NO THEN RETURN
  924.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBERS
  925.     INC    DE
  926. COPYD2:    LD    A,(DE)            ; GET BLOCK NUMBER FIRST FCB
  927.     SUB    (HL)            ; TEST IF THE SAME
  928.     DEC    HL            ; DECREMENT BLOCK FCB POINTERS
  929.     DEC    DE
  930.     RET                ; AND EXIT TO CALLER
  931. ;
  932. ; MAKE FILE COMMAND
  933. ;
  934. CMND22:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  935.     LD    (IX+14),0        ; CLEAR FCB+14
  936. ;
  937. ; MAKE FILE
  938. ;
  939. MAKE:    CALL    CHKRO            ; CHECK DRIVE R/O
  940.     LD    A,(IX+0)        ; GET FIRST BYTE FCB
  941.     PUSH    AF            ; SAVE IT
  942.     LD    (IX+0),0E5H        ; SET FIRST BYTE TO EMPTY FILE
  943.     LD    A,1            ; SEARCH FOR 1 BYTE
  944.     CALL    SEARCH            ; SEARCH EMTY FILE
  945.     POP    AF            ; GET FIRST BYTE FCB
  946.     LD    (IX+0),A        ; RESTORE IT
  947.     CALL    TSTFCT            ; TEST EMPTY FILE FOUND
  948.     RET    Z            ; NO THEN RETURN ERROR
  949.     XOR    A            ; CLEAR FCB+13
  950.     LD    (IX+13),A
  951.     PUSH    IX            ; SAVE FCB POINTER
  952.     POP    HL            ; GET IT BACK IN HL
  953.     LD    DE,15            ; PREPARE OFFSET
  954.     ADD    HL,DE            ; ADD IT
  955.     LD    B,17            ; SET LOOP COUNTER
  956. MAKE0:    LD    (HL),A            ; CLEAR FCB+15 UNP TO FCB+31
  957.     INC    HL            ; INCREMENT POINTER
  958.     DJNZ    MAKE0            ; AND CLEAR ALL BYTES
  959.     CALL    CALDIR            ; GET DIRECTORY ENTRY
  960.     LD    A,(IX+0)        ; GET FIRST BYTE FCB
  961.     LD    (HL),A            ; SAVE IT IN DIRECTORY (WRITE FCB 
  962.                     ;NEEDS THIS)
  963.     IF    DOTIME
  964.     LD    E,1            ; SET CREATION DATE/TIME
  965.     CALL    STIME            ; UPDATE TIME IN DIRECTORY 
  966.     LD    E,5            ; SET LAST UPDATE DATE/TIME
  967.     CALL    STIME            ; UPDATE TIME IN DIRECTORY
  968.     ENDIF
  969. ;
  970.     LD    BC,32*256+0        ; COPY FCB+0 TO DIRECTOTY+0 32 TIMES
  971.     CALL    WRFCB            ; WRITE FCB ON DISK
  972.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  973.     RET                ; AND RETURN TO CALLER
  974. ;
  975. ; OPEN NEXT EXTENT
  976. ;
  977. OPENEX:    BIT    7,(IX+14)        ; TEST IF FCB/FILE MODIFIED (WRITE)
  978.     JR    NZ,OPENX2        ; NOT THEN JUMP
  979.     CALL    CLOSE            ; CLOSE CURRENT FCB
  980.     LD    A,(PEXIT)        ; GET EXIT CODE
  981.     INC    A            ; TEST IF ERROR
  982.     RET    Z            ; YES THEN EXIT
  983.     CALL    CALNEX            ; CALCULATE NEXT EXTENT
  984.     JR    C,OPENX3        ; ERROR THEN JUMP
  985.     JR    NZ,OPENX5        ; FCB PRESENT FROM CLOSE THEN JUMP
  986. OPENX0:    LD    A,15            ; SEARCH FIRST 15 BYTES
  987.     CALL    SEARCH            ; SEARCH FOR FILE
  988. OPENX1:    CALL    TSTFCT            ; TEST IF FILE FOUND
  989.     JR    NZ,OPENX5        ; YES THEN JUMP
  990.     LD    A,(RDWR)        ; TEST READ/WRITE FLAG
  991.     OR    A            ; TEST IF READ
  992.     JR    Z,OPENX3        ; YES THEN ERROR
  993.     CALL    MAKE            ; MAKE NEW EXTENT IF WRITE
  994.     CALL    TSTFCT            ; TEST IF SUCCESFULL
  995.     JR    NZ,OPENX6        ; YES THEN EXIT
  996.     JR    OPENX3            ; NO THEN ERROR
  997. OPENX2:    CALL    CALNEX            ; CALCULATE NEXT EXTENT
  998.     JR    C,OPENX3        ; ERROR THEN JUMP
  999.     BIT    7,(IX+10)        ; TEST SYSTEM FILE BIT
  1000.     JR    Z,OPENX0        ; NO SYSTEM FILE THEN JUMP
  1001.     CALL    FINDF            ; SEARCH PATH FOR FILE
  1002.     JR    OPENX1            ; USE SAME ROUTINE
  1003. OPENX3:    SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED 
  1004.     LD    A,0FFH            ; SET EXIT CODE
  1005. OPENX4:    LD    (PEXIT),A        
  1006.     RET                ; AND RETURN TO CALLER
  1007. OPENX5:    CALL    OPENF0            ; OPEN FILE
  1008. OPENX6:    XOR    A            ; AND CLEAR EXIT CODE
  1009.     JR    OPENX4            ; USE SAME ROUTINE 
  1010. ;
  1011. ; CALCULATE NEXT EXTENT
  1012. ;  EXIT: CARRY=1 => OVERFLOW DETECTED
  1013. ;        ZERO =1 => SEARCH NEXT EXTENT
  1014. ;     ZERO =0 => NEXT EXTENT PRESENT (CLOSE)
  1015. ;
  1016. CALNEX:    LD    B,(IX+12)        ; GET EXTENT NUMBER
  1017.     LD    C,(IX+14)        ; GET FCB+14
  1018.     BIT    6,C            ; TEST ERROR BIT RANDOM RECORD
  1019.     SCF                ; SET ERROR FLAG
  1020.     RET    NZ            ; NON ZERO THEN ERROR EXIT
  1021.     INC    B            ; INCREMENT EXTENT NUMBER
  1022.     LD    A,B            ; GET EXTENT NUMBER
  1023.     AND    01FH            ; MASK IT
  1024.     LD    B,A            ; SAVE IT IN B
  1025.     JR    NZ,CALNX0        ; NON ZERO THEN JUMP
  1026.     INC    C            ; INCREMENT FCB+14
  1027.     LD    A,C            ; GET IT IN A
  1028.     AND    03FH            ; MASK IT
  1029.     LD    C,A            ; SAVE IT IN C
  1030.     SCF                ; SET ERROR FLAG
  1031.     RET    Z            ; AND RETURN IF FILE OVERFLOW
  1032.     XOR    A            ; CLEAR ZERO FLAG (NOT SAME EXTENT)
  1033.     JR    CALNX1            ; AND SAVE EXTENT NUMBER AND FCB+14
  1034. CALNX0:    LD    A,(NEXTND)        ; GET NEXT EXTENT MASK
  1035.     AND    B            ; TEST IF SAME EXTENT (CLOSE)
  1036. CALNX1:    LD    (IX+12),B        ; SAVE EXTENT NUMBER
  1037.     LD    (IX+14),C        ; SAVE FCB+14
  1038.     RET                ; AND RETURN TO CALLER
  1039. ;
  1040. ; READ RANDOM RECORD COMMAND
  1041. ;
  1042. CMND33:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1043. ;
  1044. ; READ RANDOM SECTOR
  1045. ;
  1046. RDRAN:    XOR    A            ; SET READ/WRITE FLAG
  1047.     CALL    LDFCB            ; LOAD RANDOM RECORD IN FCB
  1048.     JR    Z,READS            ; NO ERROR THEN READ SECTOR
  1049.     RET                ; RETURN ERROR 
  1050. ;
  1051. ; READ SEQUENTIAL
  1052. ;
  1053. CMND20:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1054. ;
  1055. ; READ SECTOR
  1056. ;
  1057. READS:    XOR    A            ; SET READ/WRITE FLAG
  1058.     LD    (RDWR),A        ; SAVE IT
  1059.     LD    A,(IX+32)        ; GET RECORD COUNTER
  1060.     CP    080H            ; TEST IF LAST RECORD THIS EXTENT
  1061.     JR    NC,READS1        ; YES THEN OPEN NEXT EXTENT
  1062.     CP    (IX+15)            ; TEST IF GREATER THEN CURRENT RECORD
  1063.     JR    C,READS2        ; NO THEN GET RECORD
  1064. READS0:    LD    A,1            ; SET END OF FILE FLAG
  1065.     LD    (PEXIT),A        ; SAVE IT
  1066.     RET                ; AND RETURN TO CALLER
  1067. READS1:    CALL    OPENEX            ; OPEN NEXT EXTENT
  1068.     LD    A,(PEXIT)        ; GET EXIT CODE
  1069.     OR    A
  1070.     JR    NZ,READS0        ; YES THEN END OF FILE
  1071.     LD    (IX+32),0        ; CLEAR RECORD COUNTER
  1072. READS2:    CALL    GETDM            ; GET BLOCK NUMBER FROM DM IN FCB
  1073.     LD    A,D            ; TEST BLOCK NUMBER = 0
  1074.     OR    E
  1075.     JR    Z,READS0        ; YES THEN END FILE
  1076.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  1077.     CALL    CALST            ; CALCULATE SECTOR/TRACK NUMBER
  1078.     CALL    READR            ; READ DATA
  1079.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  1080.     CP    20            ; TEST IF READ SEQUENTIAL
  1081.     RET    NZ            ; NO THEN RETURN
  1082.     INC    (IX+32)            ; INCREMENT NEXT RECORD COUNTER
  1083.     RET                ; AND RETURN TO CALLER
  1084. ;
  1085. ; WRITE RANDOM SECTOR WITH ZERO FILL COMMAND
  1086. ;
  1087. CMND40:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1088. ;
  1089. ; WRITE RANDOM SECTOR WITH ZERO FILL
  1090. ;
  1091. WRRANZ:    LD    A,0FFH            ; SET READ/WRITE FLAG
  1092.     CALL    LDFCB            ; LOAD FCB FROM RANDOM RECORD
  1093.     JR    Z,WRITES        ; NO ERROR THEN WRITE RECORD
  1094.     RET                ; RETURN ERROR
  1095. ;
  1096. ; WRITE RANDOM RECORD COMMAND
  1097. ;
  1098. CMND34:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1099. ;
  1100. ; WRITE RANDOM SECTOR
  1101. ;
  1102. WRRAN:    LD    A,0FFH            ; SET READ/WRITE FLAG
  1103.     CALL    LDFCB            ; LOAD FCB FROM RANDOM RECORD
  1104.     JR    Z,WRITES        ; NO ERROR THEN WRITE RECORD
  1105.     RET                ; RETURN ERROR
  1106. ;
  1107. ; WRITE SEQUENTIAL
  1108. ;
  1109. CMND21:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  1110. ;
  1111. ; WRITE SECTOR
  1112. ;
  1113. WRITES:    LD    A,0FFH            ; SET READ/WRITE FLAG
  1114.     LD    (RDWR),A        ; AND SAVE IT
  1115.     CALL    CHKRO            ; CHECK DISK R/O
  1116.     PUSH    IX            ; SAVE FCB POINTER
  1117.     POP    HL            ; GET IT BACK IN HL
  1118.     CALL    CHKFR0            ; CHECK FILE R/O
  1119.     LD    A,(IX+32)        ; GET RECORD COUNT
  1120.     CP    080H            ; TEST IF END THIS EXTENT
  1121.     JR    C,WRITS0        ; YES THEN OPEN NEXT EXTENT
  1122.     CALL    OPENEX            ; OPEN NEXT EXTENT
  1123.     LD    A,(PEXIT)        ; GET ERROR CODE
  1124.     OR    A        
  1125.     JP    NZ,WRITS9        ; ERROR THEN DIRECTORY FULL ERROR
  1126.     LD    (IX+32),0        ; CLEAR RECORD COUNTER
  1127. WRITS0:    CALL    GETDM            ; GET BLOCK NUMBER FROM FCB
  1128.     LD    A,D            ; TEST IF BLOCK NUMBER = 0
  1129.     OR    E
  1130.     JR    NZ,WRITS5        ; NO THEN WRITE SECTOR
  1131.     PUSH    HL            ; SAVE POINTER TO BLOCK NUMBER
  1132.     LD    A,C            ; TEST FIRST BLOCK NUMBER IN EXTENT
  1133.     OR    A
  1134.     JR    Z,WRITS1        ; YES THEN JUMP
  1135.     DEC    A            ; DECREMENT POINTER TO BLOCK NUMBER
  1136.     CALL    GETDM4            ; GET PREVIOUS BLOCKNUMBER
  1137. WRITS1:    CALL    GETFRE            ; GET NEAREST FREE BLOCK
  1138.     POP    HL            ; GET POINTER TO BLOCK NUMBER
  1139.     LD    A,D            ; TEST IF BLOCKNUMBER = 0
  1140.     OR    E
  1141.     JR    Z,WRITS8        ; YES THEN DISK FULL ERROR
  1142.     RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED
  1143.     LD    (HL),E            ; SAVE BLOCKNUMBER
  1144.     LD    A,(MAXLEN+1)        ; GET NUMBER OF BLOCKS
  1145.     OR    A            ; TEST IF <256
  1146.     JR    Z,WRITS2        ; YES THEN JUMP
  1147.     INC    HL            ; INCREMENT TO MSB BLOCK NUMBER
  1148.     LD    (HL),D            ; SAVE MSB BLOCK NUMBER
  1149. WRITS2:    LD    C,2            ; SET WRITE NEW BLOCK FLAG
  1150.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  1151.     SUB    40            ; TEST IF WRITE RR WITH ZERO FILL
  1152.     JR    NZ,WRITS6        ; NO THEN JUMP
  1153.     PUSH    DE            ; SAVE BLOCKNUMBER
  1154.      LD    HL,DIRBUF        ; USE DIRECTORY BUFFER FOR ZERO FILL
  1155.     LD    B,128            ; 128 BYTES TO CLEAR
  1156. WRITS3:    LD    (HL),A            ; CLEAR DIRECTORY BUFFER
  1157.     INC    HL            ; INCREMENT POINTER
  1158.     DJNZ    WRITS3            ; CLEAR ALL BYTES
  1159.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  1160.     LD    A,(NMASK)        ; GET SECTOR MASK
  1161.     LD    B,A            ; COPY IT
  1162.     INC    B            ; INCREMENT IT TO GET NUMBER OF WRITES
  1163.     CPL                ; COMPLEMENT SECTOR MASK
  1164.     AND    E            ; MASK SECTOR NUMBER
  1165.     LD    E,A            ; AND SAVE IT
  1166.     LD    C,2            ; SET WRITE NEW BLOCK FLAG
  1167. WRITS4:    PUSH    HL            ; SAVE REGISTERS
  1168.     PUSH    DE
  1169.     PUSH    BC
  1170.     CALL    CALST            ; CALCULATE SECTOR/TRACK
  1171.     CALL    DMADIR            ; SET DMA DIRECTORY BUFFER
  1172.     POP    BC            ; GET WRITE NEW BLOCK FLAG
  1173.     PUSH    BC            ; SAVE IT AGAIN
  1174.     CALL    WRITER            ; WRITE RECORD ON DISK
  1175.     POP    BC            ; RESTORE REGISTERS
  1176.     POP    DE
  1177.     POP    HL
  1178.     LD    C,0            ; CLEAR WRITE NEW BLOCK FLAG
  1179.     INC    E            ; INCREMENT SECTOR NUMBER
  1180.     DJNZ    WRITS4            ; WRITE ALL BLOCKS
  1181.     CALL    STDMA            ; SET USER DMA ADDRESS
  1182.     POP    DE            ; GET BLOCK NUMBER
  1183. WRITS5:    LD    C,0            ; CLEAR WRITE NEW BLOCK FLAG 
  1184. WRITS6:    RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED FLAG
  1185.     PUSH    BC            ; SAVE IT
  1186.     CALL    CALSEC            ; CALCULATE SECTOR NUMBER (128 BYTES)
  1187.     CALL    CALST            ; CALCULATE SECTOR/TRACK
  1188.     POP    BC            ; GET WRITE NEW BLOCK FLAG
  1189.     CALL    WRITER            ; WRITE RECORD ON DISK
  1190.     LD    A,(IX+32)        ; GET RECORD COUNTER
  1191.     CP    (IX+15)            ; COMPARE WITH NEXT RECORD
  1192.     JR    C,WRITS7        ; IF LESS THEN JUMP
  1193.     INC    A            ; INCREMENT RECORD COUNT 
  1194.     LD    (IX+15),A        ; SAVE IT ON NEXT RECORD POSITION
  1195.     RES    7,(IX+14)        ; RESET FCB/FILE MODIFIED FLAG
  1196. WRITS7:    LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  1197.     CP    21            ; TEST WRITE SEQUENTIAL
  1198.     RET    NZ            ; NOT THEN RETURN
  1199.     INC    (IX+32)            ; INCREMENT RECORD COUNT
  1200.     RET                ; AND RETURN TO CALLER
  1201. WRITS8:    LD    A,2            ; SET DISK FULL ERROR
  1202.     LD    (PEXIT),A
  1203.     RET                ; AND RETURN TO CALLER
  1204. WRITS9:    LD    A,1            ; SET DIRECTORY FULL FLAG
  1205.     LD    (PEXIT),A
  1206.     RET                ; AND RETURN TO CALLER
  1207. ;
  1208. ; LOAD FCB FOR RANDOM READ/WRITE
  1209. ;  EXIT : ZERO FLAG : 1 NO ERROR
  1210. ;                     0 ERROR OCCURED
  1211. ;
  1212. LDFCB:    LD    (RDWR),A        ; SAVE READ/WRITE FLAG
  1213.     LD    A,(IX+33)        ; GET FIRST BYTE RANDOM RECORD
  1214.     LD    D,A            ; SAVE IT IN D
  1215.     RES    7,D            ; RESET MSB TO GET NEXT RECORD
  1216.     RLA                ; SHIFT MSB IN CARRY
  1217.     LD    A,(IX+34)        ; LOAD NEXT BYTE RANDOM RECORD
  1218.     RLA                ; SHIFT CARRY
  1219.     PUSH    AF            ; SAVE IT
  1220.     AND    01FH            ; MASK NEXT EXTENT
  1221.     LD    C,A            ; SAVE IT IN C
  1222.     POP    AF            ; GET BYTE
  1223.     RLA                ; SHIFT 4 TIMES
  1224.     RLA
  1225.     RLA
  1226.     RLA
  1227.     AND    0FH            ; MASK IT
  1228.     LD    B,A            ; SAVE FCB+14
  1229.     LD    A,(IX+35)        ; GET NEXT BYTE RANDOM RECORD
  1230.     LD    E,6            ; SET RANDOM RECORD TO LARGE FLAG
  1231.     CP    4            ; TEST RANDOM RECORD TO LARGE 
  1232.     JR    NC,LDFCB8        ; YES THEN ERROR
  1233.     RLCA                ; SHIFT 4 TIMES
  1234.     RLCA
  1235.     RLCA
  1236.     RLCA
  1237.     ADD    A,B            ; ADD BYTE
  1238.     LD    B,A            ; SAVE FCB+14 IN B
  1239.     LD    (IX+32),D        ; SET NEXT RECORD COUNT
  1240.     LD    D,(IX+14)        ; GET FCB+14
  1241.     BIT    6,D            ; TEST ERROR RANDOM RECORD
  1242.     JR    NZ,LDFCB0        ; YES THEN JUMP
  1243.     LD    A,C            ; GET NEW EXTENT NUMBER
  1244.     CP    (IX+12)            ; COMPARE WITH FCB
  1245.     JR    NZ,LDFCB0        ; NOT EQUAL THEN OPEN NEXT EXTENT
  1246.     LD    A,B            ; GET NEW FCB+14
  1247.     XOR    (IX+14)            ; COMPARE WITH FCB+14
  1248.     AND    03FH            ; MASK IT
  1249.     JR    Z,LDFCB6        ; EQUAL THEN RETURN
  1250. LDFCB0:    BIT    7,D            ; TEST FCB MODIFIED (WRITE)
  1251.     JR    NZ,LDFCB1        ; NO THEN JUMP
  1252.     PUSH    DE            ; SAVE REGISTERS
  1253.     PUSH    BC
  1254.     CALL    CLOSE            ; CLOSE EXTENT
  1255.     POP    BC            ; RESTORE REGISTERS
  1256.     POP    DE
  1257.     LD    E,3            ; SET CLOSE ERROR
  1258.     LD    A,(PEXIT)        ; GET EXIT CODE
  1259.     INC    A
  1260.     JR    Z,LDFCB7        ; ERROR THEN EXIT
  1261. LDFCB1:    LD    (IX+12),C        ; SAVE NEW EXTENT NUMBER
  1262.     LD    (IX+14),B        ; SAVE NEW FCB+14
  1263.     BIT    7,D            ; TEST FCB MODIFIED (PREVIOUS FCB)
  1264.     JR    NZ,LDFCB3        ; NO THEN JUMP
  1265. LDFCB2:    LD    A,15            ; SET NUMBER OF BYTES TO SEARCH FOR
  1266.     CALL    SEARCH            ; SEARCH NEXT FCB
  1267.     JR    LDFCB4            ; JUMP
  1268. LDFCB3:    BIT    7,(IX+10)        ; TEST IF SYSTEM FILE
  1269.     JR    Z,LDFCB2        ; NO USE SEARCH
  1270.     CALL    FINDF            ; OPEN FILE (USE PATH NAME)
  1271. LDFCB4:    LD    A,(PEXIT)        ; GET ERROR CODE
  1272.     INC    A
  1273.     JR    NZ,LDFCB5        ; NO ERROR THEN EXIT
  1274.     LD    A,(RDWR)        ; GET READ/WRITE FLAG
  1275.     LD    E,4            ; SET READ EMPTY RECORD
  1276.     INC    A
  1277.     JR    NZ,LDFCB7        ; READ THEN ERROR
  1278.     CALL    MAKE            ; MAKE MEW FCB
  1279.     LD    E,5            ; SET MAKE ERROR
  1280.     LD    A,(PEXIT)        ; GET ERROR CODE
  1281.     INC    A
  1282.     JR    Z,LDFCB7        ; ERROR THEN EXIT
  1283.     JR    LDFCB6            ; NO ERROR EXIT (ZERO SET)
  1284. LDFCB5:    CALL    OPENF0            ; OPEN FILE
  1285. LDFCB6:    XOR    A            ; SET ZERO FLAG AND CLEAR ERROR CODE
  1286.     LD    (PEXIT),A
  1287.     RET                ; AND RETURN TO CALLER
  1288. LDFCB7:    LD    (IX+14),0C0H        ; SET RANDOM RECORD ERROR
  1289. LDFCB8:    LD    A,E            ; GET ERROR CODE
  1290.     LD    (PEXIT),A        ; AND SAVE IT
  1291.     SET    7,(IX+14)        ; SET FCB/FILE NOT MODIFIED
  1292.     OR    A            ; CLEAR ZERO FLAG
  1293.     RET                ; AND RETURN TO CALLER
  1294. ;
  1295. ; CALCULATE RANDOM RECORD
  1296. ;  ENTRY HL=OFFSET IN FCB
  1297. ;        DE=FCB POINTER
  1298. ;  EXIT  D=LSB RANDOM RECORD
  1299. ;        C=ISB RANDOM RECORD
  1300. ;        B=MSB RANDOM RECORD
  1301. ;
  1302. CALRRC:    ADD    HL,DE            ; POINTER TO FCB+15 OR FCB+32
  1303.     LD    A,(HL)            ; GET BYTE
  1304.     LD    HL,12            ; OFFSET TO EXTENT NUMBER
  1305.     ADD    HL,DE            ; GET POINTER TO EXTENT BYTE
  1306.     LD    D,A            ; SAVE FIRST BYTE
  1307.     LD    A,(HL)            ; GET EXTENT BYTE
  1308.     AND    01FH            ; MASK IT
  1309.     RL    D            ; SHIFT MSB IN CARRY
  1310.     ADC    A,0            ; ADD CARRY
  1311.     RRA                ; SHIFT 1 TIME (16 BITS)
  1312.     RR    D
  1313.     LD    C,A            ; SAVE ISB
  1314.     INC    HL            ; INCREMENT TO FCB+14
  1315.     INC    HL
  1316.     LD    A,(HL)            ; GET FCB+14
  1317.     RRCA                ; SHIFT 4 TIMES
  1318.     RRCA
  1319.     RRCA
  1320.     RRCA
  1321.     PUSH    AF            ; SAVE IT
  1322.     AND    03H            ; MASK MSB
  1323.     LD    B,A            ; SAVE IT
  1324.     POP    AF            ; GET LSB
  1325.     AND    0F0H            ; MASK IT
  1326.     ADD    A,C            ; ADD WITH ISB
  1327.     LD    C,A            ; SAVE ISB
  1328.     RET    NC            ; NO CARRY THEN RETURN
  1329.     INC    B            ; INCREMENT MSB
  1330.     RET                ; AND RETURN TO CALLER
  1331. ;
  1332. CLRDSK:    LD    HL,0            ; Disk reset routine
  1333.     LD    (LOGIN),HL
  1334.     CALL    INITDR
  1335.     XOR    A            ;Clear disk changed flag
  1336.     LD    (DIFF),A
  1337.     LD    A,(SUBFLG)
  1338.     JP    CMD25A
  1339. ;
  1340. ; SET TIME AND DATE
  1341. ;  ENTRY: E : 1 : SET CREATION TIME/DATE
  1342. ;             5 : SET LAST UPDATE TIME/DATE
  1343. ;  TIME RETURN POINTER IN HL
  1344. ;   HL+0 : LOW  BYTE DATE SINCE JAN,1,1978
  1345. ;   HL+1 : HIGH BYTE DATE SINCE JAN,1,1978
  1346. ;   HL+2 : HOURS   (BCD)
  1347. ;   HL+3 : MINUTES (BCD)
  1348. ;   HL+4 : SECONDS (BCD) (NOT USED IN TIME STAMP)
  1349. ;    
  1350.     IF    DOTIME
  1351. STIME:    LD    HL,(DIRBUF)        ; GET DIRECTORY ENTRY
  1352.     LD    BC,060H            ; OFFSET ENTRY POINT TIME/DATE STAMP
  1353.     ADD    HL,BC            ; ADD OFFSET
  1354.     LD    A,(HL)            ; GET BYTE
  1355.     SUB    021H            ; TEST IF TIME STAMP PRESENT
  1356.     RET    NZ            ; NO THEN RETURN
  1357.     LD    D,A            ; CLEAR D
  1358.     ADD    HL,DE            ; ADD ENTRY (UPDATE/CREATE)
  1359.     LD    A,(SECPNT)        ; GET SECTOR POINTER
  1360.     RRCA                ; SHIFT 2 TIMES
  1361.     RRCA
  1362.     LD    E,A            ; SAVE IT
  1363.     RRCA                ; SHIFT 2 TIMES
  1364.     RRCA
  1365.     ADD    A,E            ; ADD IT (A=0,10,20)
  1366.     LD    E,A            ; SAVE IN E
  1367.     ADD    HL,DE            ; ADD OFFSET
  1368.     PUSH    HL            ; SAVE RESULT
  1369.     LD    C,0            ; RETURN POINTER IN HL
  1370.                     ; C=FF MEANS SET DATE POINTED TO BY HL
  1371.     CALL    BTIME            ; RETURN POINTER IN HL
  1372.     POP    DE            ; GET POINTER
  1373.     LD    BC,4            ; SET 4 BYTES
  1374.     LDIR                ; COPY 4 BYTES
  1375.     RET                ; AND RETURN TO CALLER
  1376. ;
  1377. ; GET TIME
  1378. ;
  1379. GETTIM:    PUSH    DE            ; SAVE ADDRESS TO PUT TIME 
  1380.     LD    C,0            ; GET TIME ADDRESS
  1381.     CALL    BTIME            ; EXECUTE P2BIOS CALL
  1382.     POP    DE            ; RESTORE ADDRESS TO PUT TIME
  1383.     LD    BC,5            ; 5 BYTES TO MOVE
  1384.     LDIR                ; STORE THE TIME
  1385.     RET                ; AND RETURN TO CALLER
  1386. ;
  1387. ; SET TIME
  1388. ;
  1389. SETTIM:    EX    DE,HL            ; GET ADDRESS TIME IN HL 
  1390.     LD    C,0FFH            ; SET TIME ADDRESS
  1391.                     ; AND FALL THROUGH TO P2BIOS CALL 
  1392. ;
  1393. ; EXECUTE P2BIOS TIME ROUTINE
  1394. ;
  1395. BTIME:    PUSH    HL            ; SAVE VALUE IN HL
  1396.     LD    HL,(TIMEAD)        ; GET ADDRESS TIME ROUTINE
  1397.     EX    (SP),HL            ; PUT ADDRESS ON STACK AND RESTORE HL
  1398.     RET                ; EXECUTE TIME ROUTINE
  1399. ;
  1400.     ENDIF    
  1401. ;
  1402. ; P2DOS EXIT ROUTINE
  1403. ;
  1404. P2EXIT:    LD    A,(FLDRV)        ; TEST DRIVE SELECT USED FLAG
  1405.     OR    A            
  1406.     JR    Z,P2EXT0        ; NO THEN EXIT
  1407.     LD    A,(FCB0)        ; GET FCB BYTE 0
  1408.     LD    (IX+0),A        ; SAVE IT
  1409.     LD    A,(DRIVE)        ; GET OLD DRIVE NUMBER
  1410.     CALL    SELDK            ; SELECT DISK
  1411. P2EXT0:    PUSH    IX            ; SAVE IX
  1412.     POP    DE            ; RESTORE DE
  1413.     POP    IX            ; RESTORE IX
  1414.     LD    SP,(SPSAVE)        ; GET OLD SP
  1415.     LD    HL,(PEXIT)        ; GET EXIT CODE
  1416.     LD    A,(FUNCT)        ; GET FUNCTION CODE
  1417.     LD    C,A            ; RESTORE C
  1418.     LD    A,L            ; COPY FUNCTION CODE
  1419.     LD    B,H
  1420.     RET                ; AND RETURN TO CALLER
  1421. ;
  1422. ; RAM AREA
  1423. ;
  1424. TABCNT:    DB    0            ; TAB COUNTER
  1425. TABCX1:    DB    0            ; TEMPORARY TAB COUNTER (USED BY RDBUF)
  1426. FCONTP:    DB    0            ; LIST ENABLE FLAG (CONTROL P)
  1427. LASTCH:    DB    0            ; LAST CHARACTER
  1428. DELAY:    DB    0FFH            ; DELAY COUNTER
  1429. ;
  1430. TRANS:    DEFW    0            ; TRANSLATION VECTOR
  1431. TEMP0:    DEFW    0            ; NUMBER OF FILES ON DRIVE 
  1432. TEMP1:    DEFW    0            ; NOT USED 
  1433. TEMP2:    DEFW    0            ; NOT USED
  1434. DIRBUF:    DEFW    0            ; DIRECTORY BUFFER
  1435. IXP:    DEFW    0            ; DISK PARAMETER BLOCK
  1436. CSV:    DEFW    0            ; CHECK SUM POINTER
  1437. ALV:    DEFW    0            ; ALLOCATION VECTOR POINTER
  1438. ;
  1439. MAXSEC:    DEFW    0            ; MAXIMUM NUMBER OF SECTORS/TRACK
  1440. NBLOCK:    DB    0            ; NUMBER OF BLOCKS
  1441. NMASK:    DB    0            ; MASK NUMBER OF BLOCKS
  1442. NEXTND:    DB    0            ; EXTENT MASK
  1443. MAXLEN:    DEFW    0            ; MAXIMUM BLOCK NUMBER-1
  1444. NFILES:    DEFW    0            ; MAXIMUM NUMBER OF FILES-1
  1445. NDIR0:    DB    0            ; FIRST TWO ENTRIES ALV BUFFER
  1446. NDIR1:    DB    0
  1447. NCHECK:    DEFW    0            ; NUMBER OF CHECKSUM ENTRUIES
  1448. NFTRK:    DEFW    0            ; FIRST TRACK NUMBER
  1449. ;
  1450. DSKRO:    DEFW    0            ; DISK R/O VECTOR
  1451. LOGIN:    DEFW    0            ; LOGIN VECTOR
  1452. DMA:    DEFW    080H            ; DMA ADDRESS
  1453. ;
  1454. FUNCT:    DB    0            ; FUNCTION NUMBER
  1455. PEXIT:    DEFW    0            ; EXIT CODE
  1456. FLDRV:    DB    0            ; DRIVE SELECT USED FLAG
  1457. RDWR:    DB    0            ; READ/WRITE FLAG
  1458. ;
  1459. FCB0:    DB    0            ; FCB BYTE 0
  1460. USER:    DB    0            ; USER NUMBER
  1461. DRIVE:    DB    0            ; DRIVE NUMBER
  1462. DEFDRV:    DB    0            ; DEFAULT DRIVE NUMBER
  1463. RECDIR:    DEFW    0            ; RECORD DIRECTORY (CHECKSUM)
  1464. FILCNT:    DEFW    0            ; FILE COUNTER
  1465. SECPNT:    DB    0            ; SECTOR POINTER
  1466. SUBFLG:    DB    0            ; SUBMIT FLAG (RESET DISK COMMAND)
  1467. ;
  1468. DCOPY:    DEFW    0            ; COPY ADDRESS FCB
  1469. SEAREX:    DB    0            ; EXIT CODE SEARCH
  1470. SEARNB:    DB    0            ; SEARCH NUMBER OF BYTES
  1471. SEARQU:    DB    0            ; SEARCH QUESTION MARK USED
  1472. SEARPU:    DB    0            ; SEARCH PUBLIC FILE
  1473. ;next two flags added by B.H.
  1474. DIFF:    DB    0            ; disk changed flag
  1475. RETFLG:    DB    0            ; allows recovery from read/write errors 
  1476. ;
  1477. SPSAVE:    DEFW    0            ; STACK POINTER LOCATION
  1478.     DEFS    62            ; 62 BYTE STACK
  1479. P2DOSS:                    ; P2DOS STACK
  1480. DOSSTOP    EQU    $
  1481. ;
  1482.     IF    ((DOSSTOP-DOSSTRT) GT 3584)
  1483.     *Bdos too large!!*
  1484.     ENDIF
  1485. ;
  1486.