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 / CPM / BDOS / P2DOS23.LBR / P2DOS1.MZC / P2DOS1.MAC
Text File  |  2000-06-30  |  37KB  |  1,319 lines

  1. ;
  2. ; START PROGRAM
  3. ;    
  4. P2DOS:
  5. ;
  6. SERIAL:    DB    SERNO1            ; serial number
  7.     DB    SERNO2            
  8.     DB    SERNO3            
  9.     DB    SERNO4
  10.     DB    SERNO5
  11.     DB    SERNO6
  12. ;
  13. ; START P2DOS
  14. ;
  15. START:    JP    ENTRY            ; JUMP TO ENTRY POINT P2DOS
  16. ;
  17. ; ERROR MESSAGES P2DOS
  18. ;
  19. ;Bad sector message changed to read/write messages-B.H.
  20. STBDSC:    DEFW    BADSEC            ; split into read and write
  21. STSEL:    DEFW    SELERR            ; SELECT ERROR
  22. STRO:    DEFW    RDONLY            ; DRIVE READ ONLY
  23. SFILRO:    DEFW    FILRO            ; FILE READ ONLY
  24. ;
  25. ; BDOS Search Path Address
  26. ;
  27. PATH:                    ; keep same loc as in P2DOS
  28.     IF    PATHON
  29.     DEFW    RAMLOW+0040H
  30.     ELSE
  31.     DEFW    0000H
  32.     ENDIF
  33. ;
  34. ; TIME ADDRESS P2BIOS
  35. ;
  36. TIMEAD:
  37.     IF    DOTIME
  38.     DEFW    TIME            ; TIME ROUTINE ADDRESS FOR TIME
  39.                     ; AND DATE STAMPS
  40.     ELSE
  41.     DEFW    CONST
  42.     ENDIF
  43. ;
  44. ;
  45. ; FLAGS FOR SPECIALS
  46. ; BIT 0: PUBLIC FILE ENABLE(1)/DISABLE(0)
  47. ; BIT 1: DELAY 256 CHARACTERS ACTIVE(1)/DISABLE(0)
  48. ; BIT 2: WRITE PROTECT IGNORE ENABLED(1)/DISABLED(0)
  49. ;
  50. FLAGS:    DB    DEFFLG            ; FLAG BYTE
  51. ;
  52. ; ENTRY POINT P2DOS COMMANDS
  53. ;
  54. ENTRY:    LD    A,C            ; GET FUNCTION NUMBER
  55.     LD    (FUNCT),A        ; SAVE IT FOR LATER USE
  56.     LD    HL,0            ; SET HL TO ZERO
  57.     LD    (PEXIT),HL        ; CLEAR EXIT CODE
  58.     XOR    A            ; CLEAR A
  59.     LD    (FLDRV),A        ; RESET DRIVE SELECT DONE FLAG
  60.     LD    (RDWR),A        ; RESET READ/WRITE FLAG
  61.     LD    (SPSAVE),SP        ; SAVE STACK POINTER
  62.     LD    SP,P2DOSS        ; GET INTERNAL STACK POINTER
  63.     PUSH    IX            ; SAVE INDEX REGISTER
  64.     PUSH    DE            ; SAVE PARAMETER REGISTER
  65.     POP    IX            ; GET IT BACK IN IX
  66.     LD    HL,P2EXIT        ; GET EXIT ADDRESS P2DOS
  67.     PUSH    HL            ; SAVE IT ON STACK TO RETURN FROM P2DOS
  68.     LD    A,C            ; GET FUNCTION CODE
  69. ;
  70.     IF    DOTIME
  71.     CP    200            ; TEST GET TIME
  72.     JP    Z,GETTIM        ; YES THEN GET TIME
  73.     CP    201            ; TEST SET TIME
  74.     JP    Z,SETTIM        ; YES THEN SET TIME
  75.     ENDIF
  76. ;
  77.     CP    MAXCMD+1        ; TEST GREATER THEN MAXCMD 
  78.     RET    NC            ; IF SO RETURN TO CALLER AND DO NOTHING
  79.     LD    HL,CTABLE        ; LOAD TABLE
  80.     LD    B,0            ; PREPARE 16 BIT ADD
  81.     ADD    HL,BC            ; ADD
  82.     ADD    HL,BC            ; ADD TWICE TO GET WORD VALUE
  83.     LD    A,(HL)            ; GET LSB
  84.     INC    HL            ; POINTER TO MSB
  85.     LD    H,(HL)            ; GET MSB
  86.     LD    L,A            ; SAVE LSB IN L 
  87.     JP    (HL)            ; JUMP TO ROUTINE
  88. ;
  89. ; COMMAND TABLE
  90. ;
  91. ;
  92. ; FUNC    NAME            INPUT PARAMETERS    RETURNED VALUES
  93. ;   0    BOOT            NONE            NONE
  94. ;   1    CONSOLE INPUT        NONE            A=CHARACTER
  95. ;   2    CONSOLE OUTPUT        E=CHARACTER        A=00H
  96. ;   3    READER INPUT        NONE            A=CHARACTER
  97. ;   4    PUNCH OUTPUT        E=CHARACTER        A=00H
  98. ;   5    LIST OUTPUT        E=CHARACTER        A=00H
  99. ;   6    DIRECT CONSOLE I/O    E=0FFH            A=INPUT CHARACTER
  100. ;                            A=00H IF NO CHARACTER 
  101. ;                                PRESENT
  102. ;                E=0FEH            A=CONSOLE STATUS
  103. ;                E=000H..0FDH        A=00H
  104. ;   7    GET I/O BYTE        NONE            A=I/O BYTE (RAMLOW+03H)
  105. ;   8    SET I/O BYTE        E=I/O BYTE        A=00H
  106. ;   9    PRINT STRING        DE=ADDRESS STRING    A=00H
  107. ;  10    READ CONSOLE BUFFER    DE=ADDRESS BUFFER    A=00H
  108. ;  11    GET CONSOLE STATUS    NONE            A=00H IF NO CHARACTER 
  109. ;                                PRESENT
  110. ;                            01H IF CHARACTER PRESENT
  111. ;  12    RETURN VERSION NUMBER    NONE            A=VERSION NUMBER (022H)
  112. ;  13    RESET DISK SYSTEM    NONE            A=00H NO $*.* FILE
  113. ;                            A=FFH $*.* FILE PRESENT
  114. ;  14    SELECT DISK        E=DISK NUMBER        A=00H
  115. ;  15    OPEN FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  116. ;  16    CLOSE FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  117. ;  17    SEARCH FOR FIRST    DE=ADDRESS FCB        A=DIRECTORY CODE
  118. ;  18    SEARCH FOR NEXT        DE=ADDRESS FCB        A=DIRECTORY CODE
  119. ;  19    DELETE FILE        DE=ADDRESS FCB        A=ERROR CODE
  120. ;  20    READ SEQUENTIAL        DE=ADDRESS FCB        A=READ/WRITE CODE
  121. ;  21    WRITE SEQUENTIAL    DE=ADDRESS FCB        A=READ/WRITE CODE
  122. ;  22    MAKE FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  123. ;  23    RENAME FILE        DE=ADDRESS FCB        A=ERROR CODE
  124. ;  24    RETURN LOGIN VECTOR    NONE            HL=LOGIN VECTOR
  125. ;  25    RETURN CURRENT DISK    NONE            A=CURRENT DISK
  126. ;  26    SET DMA ADDRESS        DE=DMA ADDRESS        A=00H
  127. ;  27    GET ALLOCATION ADDRESS    NONE            HL=ADDRESS ALLOCATION 
  128. ;                                VECTOR
  129. ;  28    WRITE PROTECT DISK    NONE            A=00H
  130. ;  29    GET R/O VECTOR        NONE            HL=R/O VECTOR
  131. ;  30    SET FILE ATTRIBUTES    DE=ADDRESS FCB        A=ERROR CODE
  132. ;  31    GET ADDRESS DPB        NONE            HL=ADDRESS DPB
  133. ;  32    SET/GET USER CODE    E=0FFH            A=USER NUMBER
  134. ;                E=USER NUMBER        A=00H
  135. ;  33    READ RANDOM        DE=ADDRESS FCB        A=READ/WRITE CODE
  136. ;  34    WRITE RANDOM        DE=ADDRESS FCB        A=READ/WRITE CODE
  137. ;  35    COMPUTE FILE SIZE    DE=ADDRESS FCB        A=ERROR CODE
  138. ;  36    SET RANDOM RECORD    DE=ADDRESS FCB        A=00H
  139. ;  37    RESET MULTIPLE DRIVE    DE=MASK            A=00H NO $*.* FILE
  140. ;                            A=FFH $*.* FILE PRESENT
  141. ;  38    NOT IMPLEMENTED        NONE            A=00H
  142. ;  39    NOT IMPLEMENTED        NONE            A=00H
  143. ;  40    WRITE RANDOM WITH    DE=ADDRESS FCB        A=READ/WRITE CODE
  144. ;     ZERO FILL
  145. ; 200    GET TIME        DE=ADDRESS TO PUT TIME    A=00H
  146. ; 201    SET TIME        DE=ADDRESS TIME        A=00H
  147. ;
  148. ; DIRECTORY CODE : A=00H,01H,02H,03H IF NO ERROR
  149. ;                  A=0FFH IF ERROR
  150. ; ERROR CODE     : A=00H IF NO ERROR
  151. ;                  A=0FFH IF ERROR
  152. ; READ/WRITE CODE: A=00H IF NO ERROR
  153. ;           A=01H READ  => END OF FILE
  154. ;             WRITE => DIRECTORY FULL
  155. ;           A=02H DISK FULL
  156. ;           A=03H CLOSE ERROR DURING RANDOM RECORD READ/WRITE
  157. ;           A=04H READ EMPTY RECORD DURING RANDOM RECORD READ
  158. ;           A=05H DIRECTORY FULL DURING RANDOM RECORD WRITE
  159. ;           A=06H RANDOM RECORD TOO LARGE DURING RANDOM RECORD READ/WRITE
  160. ;
  161. ;
  162. CTABLE:    DEFW    WBOOT            ; WARM BOOT 
  163.     DEFW    RDCON            ; CONSOLE INPUT
  164.     DEFW    BWRCON            ; CONSOLE OUTPUT
  165.     DEFW    RDRDR            ; READER INPUT
  166.     DEFW    WPUNCH            ; PUNCH OUTPUT
  167.     DEFW    WLIST            ; LIST OUTPUT
  168.     DEFW    DCIO            ; DIRECT CONSOLE I/O
  169.     DEFW    GIOST            ; GET I/O BYTE
  170.     DEFW    SIOST            ; SET I/O BYTE
  171.     DEFW    MESS            ; PRINT STRING
  172.     DEFW    RDBUF            ; READ CONSOLE BUFFER
  173.     DEFW    TSTCS            ; GET CONSOLE STATUS
  174.     DEFW    CMND12            ; RETURN VERSION NUMBER
  175.     DEFW    CMND13            ; RESET DISK SYSTEM
  176.     DEFW    CMND14            ; SELECT DISK
  177.     DEFW    CMND15            ; OPEN FILE
  178.     DEFW    CMND16            ; CLOSE FILE
  179.     DEFW    CMND17            ; SEARCH FOR FIRST
  180.     DEFW    CMND18            ; SEARCH FOR NEXT
  181.     DEFW    CMND19            ; DELETE FILE
  182.     DEFW    CMND20            ; READ SEQUENTIAL
  183.     DEFW    CMND21            ; WRITE SEQUENTIAL
  184.     DEFW    CMND22            ; MAKE FILE
  185.     DEFW    CMND23            ; RENAME FILE
  186.     DEFW    CMND24            ; RETURN LOGIN VECTOR
  187.     DEFW    CMND25            ; RETURN CURRENT DISK
  188.     DEFW    CMND26            ; SET DMA ADDRESS
  189.     DEFW    CMND27            ; GET ADDRESS ALLOCATION VECTOR
  190.     DEFW    CMND28            ; WRITE PROTECT DISK
  191.     DEFW    CMND29            ; GET R/O VECTOR
  192.     DEFW    CMND30            ; SET FILE ATTRIBUTES
  193.     DEFW    CMND31            ; GET ADDRESS DISK PARAMETER HEADER(DPH) 
  194.     DEFW    CMND32            ; GET/SET USER CODE
  195.     DEFW    CMND33            ; READ RANDOM
  196.     DEFW    CMND34            ; WRITE RANDOM
  197.     DEFW    CMND35            ; COMPUTE FILE SIZE
  198.     DEFW    CMND36            ; SET RANDOM RECORD
  199.     DEFW    CMND37            ; RESET MULTIPLE DRIVE
  200.     DEFW    DUMMY            ; NOT IMPLEMENTED 
  201.     DEFW    DUMMY            ; NOT IMPLEMENTED 
  202.     DEFW    CMND40            ; WRITE RANDOM WITH ZERO FILL
  203. ;
  204. ; I/O ROUTINES
  205. ;
  206. ; P2DOS CONSOLE INPUT
  207. ;
  208. ; READ CHARACTER FROM CONSOLE AND ECHO
  209. ;  IF CHAR=CR,LF,TAB,CONTH OR >=SPACE
  210. ;
  211. RDCON:    CALL    GETCH            ; GET CHARACTER
  212.     CALL    TSTCH            ; TEST IF CR,LF,TAB,CONTH OR >=SPACE
  213.     CALL    NC,WRCON        ; ECHO CHARACTER
  214. EXIT:    LD    (PEXIT),A        ; RETURN CHARACTER 
  215. DUMMY:    RET                ; AND EXIT P2DOS
  216. ;
  217. ; P2DOS WRITE CONSOLE
  218. ;
  219. BWRCON:    LD    A,E            ; COPY CHARACTER
  220.     JR    WRCON            ; AND OUTPUT IT
  221. ;
  222. ; READ READER
  223. ;
  224. RDRDR:    CALL    READER            ; GET CHARACTER FROM READER
  225.     JR    EXIT            ; AND RETURN IT TO CALLER 
  226. ;
  227. ; WRITE PUNCH
  228. ;
  229. WPUNCH:    LD    C,E            ; COPY CHARACTER
  230.     JP    PUNCH            ; AND OUTPUT IT TO PUNCH DEVICE
  231. ;
  232. ; WRITE LIST
  233. ;
  234. WLIST:    LD    C,E            ; COPY CHARACTER
  235.     JP    LIST            ; AND OUTPUT IT TO LIST DEVICE
  236. ;
  237. ; DIRECT CONSOLE INPUT/OUTPUT
  238. ;
  239. DCIO:    LD    C,E            ; COPY CHARACTER
  240.     INC    E            ; TEST IF 0FFH
  241.     JR    Z,DCIO0            ; YES DO INPUT
  242.     INC    E            ; TEST IF 0FEH
  243.     JP    NZ,CONOUT        ; NO THEN OUTPUT CHARACTER
  244.     CALL    CONST            ; GET CONSOLE STATUS
  245.     JR    EXIT            ; AND RETURN IT TO CALLER
  246. DCIO0:    CALL    CONST            ; GET CONSOLE STATUS
  247.     OR    A            ; TEST IT
  248.     RET    Z            ; EXIT IF NO CHARACTER PRESENT
  249.     CALL    CONIN            ; GET CHARACTER
  250.     JR    EXIT            ; AND RETURN IT TO CALLER
  251. ;
  252. ; GET I/O STATUS BYTE
  253. ;
  254. GIOST:    LD    A,(RAMLOW+00003H)    ; GET I/O BYTE FROM RAM
  255.     JR    EXIT            ; AND RETURN IT TO CALLER
  256. ;
  257. ; SET I/O STATUS BYTE
  258. ;
  259. SIOST:    LD    A,E            ; COPY I/O BYTE
  260.     LD    (RAMLOW+00003H),A    ; AND SAVE IT IN RAM
  261.     RET                ; EXIT TO CALLER
  262. ;
  263. ; TEST CONSOLE STATUS
  264. ;
  265. TSTCS:    CALL    GCONST            ; GET CONSOLE STATUS
  266.     JR    EXIT            ; AND RETURN IT TO CALLER
  267. ;
  268. ; OUTPUT CHAR (CONTROL CHAR = ^CHAR)
  269. ;
  270. OUTCH:    CALL    TSTCH            ; TEST IT CR,LF,TAB,CONTH OR >=SPACE
  271.     JR    NC,WRCON        ; YES THEN JUMP
  272.     PUSH    AF            ; SAVE CHARACTER
  273.     LD    A,'^'            ; LOAD A WITH '^' 
  274.     CALL    WRCON            ; OUTPUT IT
  275.     POP    AF            ; GET CHARACTER BACK
  276.     PUSH    AF            ; SAVE IT AGAIN
  277.     ADD    A,'A'-1            ; ADD OFFSET
  278.     CALL    WRCON            ; OUTPUT IT
  279.     POP    AF            ; GET CHARACTER
  280.     RET                ; RETURN TO CALLER
  281. ;
  282. ; ECHO CR,LF
  283. ;
  284. CROUT:    LD    A,CR            ; A=CARRIAGE RETURN
  285.     CALL    WRCON            ; OUTPUT IT
  286.     LD    A,LF            ; A=LINE FEED
  287.                     ; FALL THROUGH TO OUTPUT ROUTINE
  288. ;
  289. ; WRITE CHARACTER ON CONSOLE
  290. ;
  291. WRCON:    CP    TAB            ; TEST IF TAB
  292.     JR    NZ,WRCON1        ; NO THEN JUMP
  293. WRCON0:    LD    A,' '            ; EXPAND TAB WITH SPACES
  294.     CALL    WRCON            ; WRITE SPACE
  295.     LD    A,(TABCNT)        ; GET TAB COUNT
  296.     AND    7            ; TEST IF DONE
  297.     JR    NZ,WRCON0        ; NO THEN REPEAT
  298.     LD    A,TAB            ; RETURN TAB
  299.     RET                ; RETURN TO CALLER
  300. WRCON1:    PUSH    AF            ; SAVE CHARACTER
  301.     CALL    GCONST            ; TEST STATUS AND CONTS/CONTC
  302.     POP    AF            ; GET CHARACTER BACK
  303.     PUSH    AF            ; SAVE IT AGAIN
  304.     LD    C,A            ; COPY IT
  305.     CALL    CONOUT            ; OUTPUT IT
  306.     POP    AF            ; GET CHARACTER BACK
  307.     PUSH    AF            ; SAVE IT AGAIN
  308.     LD    C,A            ; COPY IT
  309.     LD    A,(FCONTP)        ; GET PRINTER ECHO FLAG 
  310.     OR    A            ; TEST IT
  311.     CALL    NZ,LIST            ; NON ZERO => OUTPUT CHAR TO PRINTER
  312.     LD    A,(FLAGS)        ; GET FLAG BYTE
  313.     BIT    1,A            ; TEST DELAY 256 BYTES ACTIVE
  314.     JR    Z,WRCON2        ; NO THEN EXIT
  315.     LD    HL,DELAY        ; GET DELAY COUNTER
  316.     XOR    A            ; A=0 
  317.     OR    (HL)            ; TEST COUNTER=0
  318.     JR    Z,WRCON2        ; YES THEN EXIT
  319.     DEC    (HL)            ; ELSE DECREMENT COUNTER
  320. WRCON2:    POP    AF            ; RESTORE CHARACTER
  321.                     ; FALL THROUGH TO COUNT ROUTINE
  322. ;
  323. ; COUNT CHARACTERS IN LINE
  324. ;
  325. COUNTC:    LD    HL,TABCNT        ; GET POINTER TO TAB COUNTER
  326.     CP    RUBOUT            ; TEST IF CHARACTER = RUBOUT
  327.     RET    Z            ; YES NO UPDATE TAB COUNTER
  328.     INC    (HL)            ; INCREMENT TAB COUNTER
  329.     CP    ' '            ; TEST IF CHAR >= ' '
  330.     RET    NC            ; YES, NORMAL CHARACTER THEN EXIT
  331.     DEC    (HL)            ; CONTROL CHARACTER, DECREMENT TAB COUNT
  332.     CP    CONTH            ; TEST BACKSPACE
  333.     JR    NZ,COUNT0        ; NO BACKSPACE THEN JUMP
  334.     DEC    (HL)            ; DECREMENT TAB COUNTER
  335.     RET                ; AND EXIT
  336. COUNT0:    CP    CR            ; TEST CARRIAGE RETURN
  337.     JR    NZ,COUNT1        ; NO THEN JUMP
  338.     LD    (HL),0            ; RESET TAB COUNT
  339.     RET                ; AND EXIT
  340. COUNT1:    CP    TAB            ; TEST TAB CHARACTER
  341.     RET    NZ            ; NO THEN EXIT
  342.     PUSH    AF            ; SAVE CHARACTER
  343.     LD    A,(HL)            ; GET TAB COUNT
  344.     ADD    A,8            ; ADVANCE IT 8 POSITION
  345.     AND    0F8H            ; SET IT TO NEXT TAB POSITION
  346.     LD    (HL),A            ; SAVE IT
  347.     POP    AF            ; RESTORE CHARACTER 
  348.     RET                ; AND EXIT
  349. ;
  350. ; GET CHARACTER FROM CONSOLE
  351. ;
  352. GETCH:    LD    HL,LASTCH        ; GET POINTER TO LAST INPUT CHARACTER
  353.     LD    A,(HL)            ; GET CHARACTER
  354.     LD    (HL),0            ; RESET LAST CHARACTER
  355.     OR    A            ; TEST IF CHARACTER PRESENT
  356.     RET    NZ            ; RETURN IF SO
  357.     JP    CONIN            ; ELSE GET CHARACTER
  358. ;
  359. ; GET CONSOLE STATUS
  360. ;
  361. GCONST:    LD    A,(DELAY)        ; GET 256 BYTES DELAY
  362.     OR    A            ; TEST IT
  363.     JR    NZ,GCONS0        ; NON ZERO, DELAY STILL ACTIVE OR DISABLED
  364.     CALL    CONST            ; GET CONSOLE STATUS
  365.     OR    A            ; TEST IT
  366.     JR    NZ,GCONS1        ; NON ZERO THEN GET CHARACTER
  367. GCONS0:    LD    A,(LASTCH)        ; GET LAST CHARACTER
  368.     OR    A            ; TEST IT
  369.     JR    NZ,GCONS3        ; NON ZERO THEN CHARACTER PRESENT
  370.     CALL    CONST            ; GET CONSOLE STATUS
  371.     OR    A            ; TEST IT
  372.     RET    Z            ; RETURN IF NO CHARACTER PRESENT
  373. GCONS1:    CALL    CONIN            ; GET CHARACTER
  374.     CP    CONTS            ; TEST STOP CHARACTER
  375.     JR    NZ,GCONS2        ; NOT THEN EXIT CHARACTER
  376. GCONS4:    CALL    CONIN            ; GET NEXT CHARACTER
  377.     CP    CONTC            ; TEST IF USER WANTS TO EXIT
  378.     JP    Z,RAMLOW+00000H        ; YES THEN WARM BOOT
  379. ;
  380.     IF    XONOFF
  381.     CP    CONTQ            ; ^Q to turn on console output?
  382.     JR    NZ,GCONS4        ; no, igore character
  383.     ELSE
  384.     IF    NOXOFF
  385.     CP    CONTS            ; another ^S?
  386.     JR    Z,GCONS4        ; yes, don't restart console output
  387.     ENDIF
  388.     ENDIF
  389. ;
  390.     JR    GCONST            ; TEST AGAIN
  391. GCONS2:    LD    (LASTCH),A        ; SAVE CHARACTER
  392.     LD    A,0FFH            ; SET DELAY COUNTER
  393.     LD    (DELAY),A        ; AND SAVE IT
  394. GCONS3:    LD    A,1            ; CHARACTER PRESENT CODE
  395.     RET                ; RETURN TO CALLER
  396. ;
  397. ; TEST CHARACTER
  398. ;  EXIT CARRY=0: CR,LF,TAB,CONTH OR >=SPACE
  399. ;       CARRY=1: ALL OTHER CHARACTERS
  400. ;
  401. TSTCH:    CP    CR            ; TEST CARRIAGE RETURN
  402.     RET    Z            ; RETURN IF SO
  403.     CP    LF            ; TEST LINE FEED
  404.     RET    Z            ; RETURN IF SO
  405.     CP    TAB            ; TEST TAB
  406.     RET    Z            ; RETURN IF SO
  407.     CP    CONTH            ; TEST BACKSPACE
  408.     RET    Z            ; RETURN IF SO
  409.     CP    ' '            ; TEST >=SPACE
  410.     RET                ; RETURN TO CALLER
  411. ;
  412. ; WRITE BACKSPACE,SPACE,BACKCPACE
  413. ;
  414. WCONTH:    CALL    WCONT0            ; WRITE BACKSPACE
  415.     LD    C,' '            ; LOAD SPACE
  416.     CALL    CONOUT            ; AND OUTPUT IT
  417. WCONT0:    LD    C,CONTH            ; LOAD BACKSPACE
  418.     JP    CONOUT            ; AND OUTPUT IT
  419. ;
  420. ; OUTPUT MESSAGE
  421. ;
  422. MESS:    LD    A,(DE)            ; GET BYTE FROM BUFFER
  423.     CP    '$'            ; TEST LAST BYTE
  424.     RET    Z            ; YES, THEN RETURN TO CALLER
  425.     INC    DE            ; POINT TO NEXT BYTE
  426.     PUSH    DE            ; SAVE POINTER
  427.     CALL    WRCON            ; OUTPUT CHARACTER
  428.     POP    DE            ; RESTORE POINTER
  429.     JR    MESS            ; AND TEST AGAIN
  430. ;
  431. ; AGAIN PRINTS #,CR,LF AND ADVANCES TO TABCX1
  432. ;
  433. AGAIN:    LD    A,'#'            ; LOAD '#'
  434.     CALL    WRCON            ; OUTPUT IT
  435. AGAIN0:    CALL    CROUT            ; OUTPUT CARRIAGE RETURN/LINE FEED
  436. AGAIN1:    LD    HL,TABCNT        ; GET TAB COUNT POINTER
  437.     LD    A,(TABCX1)        ; GET POSITION FIRST CHARACTER LINE
  438.     CP    (HL)            ; CHECK IT
  439.     RET    Z            ; RETURN IF ON SAME POSITION
  440.     LD    A,' '            ; LOAD SPACE
  441.     CALL    WRCON            ; OUTPUT IT
  442.     JR    AGAIN1            ; AND TEST AGAIN
  443. ;
  444. ; DELETE CHAR
  445. ;  ENTRY : HL=START BUFFER-1
  446. ;          B =CHARACTER COUNTER (ALWAYS>0)
  447. ;
  448. DELCH:    DEC    B            ; DECREMENT CHARACTER COUNTER
  449.     LD    A,(TABCNT)        ; GET TAB COUNTER
  450.     PUSH    AF            ; SAVE IT
  451.     PUSH    BC            ; SAVE CHARACTER COUNTER
  452.     LD    A,(TABCX1)        ; GET POSITION FIRST CHARACTER LINE
  453.     LD    (TABCNT),A        ; SAVE IT IN TAB COUNTER
  454. DELCH0:    LD    A,B            ; COPY CHARACTER COUNTER
  455.     OR    A            ; TEST IF 0
  456.     JR    Z,DELCH2        ; YES THEN JUMP
  457.     DEC    B            ; DECREMENT IT
  458.     INC    HL            ; INCREMENT BUFFER POINTER
  459.     LD    A,(HL)            ; GET CHARACTER FROM BUFFER
  460.     PUSH    HL            ; SAVE BUFFER POINTER
  461.     CALL    TSTCH            ; TEST IF CR,LF,TAB,CONTH OR >=SP
  462.     JR    NC,DELCH1        ; YES THEN JUMP
  463.     RRA                ; ELSE MUST BE CONTROL CHARACTER
  464.     CALL    COUNTC            ; COUNT CONTROL CHARACTER TWICE
  465. DELCH1:    CALL    COUNTC            ; COUNT CHARACTER
  466.     POP    HL            ; GET BUFFER POINTER
  467.     JR    DELCH0            ; AND TEST AGAIN
  468. DELCH2:    POP    BC            ; RESTORE CHARACTER COUNTER
  469.     POP    AF            ; AND TAB COUNTER
  470.     PUSH    HL            ; SAVE BUFFER POINTER
  471.     PUSH    BC            ; AND CHARACTER COUNTER
  472.     LD    HL,TABCNT        ; GET TAB COUNTER POINTER
  473.     SUB    (HL)            ; CALCULATE DIFFERENCE
  474. DELCH3:    DEC    A            ; DECREMENT IT
  475.     CP    8            ; COMPARE WITH 8
  476.     JR    NC,DELCH4        ; JUMP IF >=8
  477.     PUSH    AF            ; SAVE DIFFERENCE
  478.     CALL    WCONTH            ; REMOVE CHARACTER END LINE
  479.     POP    AF            ; RESTORE COUNTER
  480.     JR    DELCH3            ; REMOVE MORE CHARACTERS
  481. DELCH4:    POP    BC            ; RESTORE CHARACTER COUNTER
  482.     POP    HL            ; RESTORE BUFFER POINTER
  483.     RET                ; AND RETURN TO CALLER 
  484. ;
  485. ; READ BUFFER
  486. ;
  487. RDBUF:    LD    A,(TABCNT)        ; GET CURRENT POSITION CURSOR
  488.     LD    (TABCX1),A        ; SAVE IT
  489. RDBUF0:    PUSH    IX            ; SAVE START ADDRESS BUFFER
  490.     POP    HL            ; GET IT IN HL
  491.     LD    C,(HL)            ; GET MAXIMUM LINE LENGTH
  492.     INC    HL            ; INCREMENT TO LINE LENGTH POSITION
  493.     LD    B,0            ; CLEAR LINE LENGTH COUNTER
  494.     PUSH    HL            ; SAVE START LINE - 1
  495. RDBUF1:    PUSH    HL            ; SAVE REGISTERS
  496.     PUSH    BC
  497. RDBUF2:    CALL    GETCH            ; GET CHARACTER
  498.     POP    BC            ; RESTORE REGISTERS
  499.     POP    HL
  500.     AND    07FH            ; MASK CHARACTER
  501.     CP    CONTE            ; TEST IF CONTE
  502.     JR    NZ,RDBUF3        ; NOT THEN JUMP 
  503.     PUSH    HL            ; SAVE REGISTERS
  504.     PUSH    BC
  505.     CALL    AGAIN0            ; MOVE CURSOR TO NEXT LINE
  506.     JR    RDBUF2            ; AND GET NEXT CHAR
  507. RDBUF3:    CP    CONTH            ; TEST BACKSPACE
  508.     JR    NZ,RDBUF4        ; NOT THEN JUMP
  509. DOBACK:    LD    A,B            ; TEST IF DELETING CHAR FROM EMPTY LINE
  510.     OR    A
  511.     JR    Z,RDBUF1        ; YES THEN GET NEXT CHAR
  512.     POP    HL            ; GET START LINE
  513.     PUSH    HL            ; AND SAVE IT AGAIN
  514.     CALL    DELCH            ; DELETE CHARACTER
  515.     JR    RDBUF1            ; GET NEXT CHARACTER
  516. RDBUF4:    CP    CONTP            ; TEST PRINT ENABLE/DISABLE
  517.     JR    NZ,RDBUF6        ; NOT THEN JUMP
  518.     LD    A,(FCONTP)        ; COMPLEMENT PRINT FLAG
  519.     CPL
  520.     LD    (FCONTP),A
  521. RDBUF5:    JR    RDBUF1            ; AND GET NEXT CHARACTER
  522. RDBUF6:    CP    CONTR            ; TEST REPEAT LINE
  523.     JR    NZ,RDBUFA        ; NOT THEN JUMP
  524.     PUSH    BC            ; SAVE REGISTERS
  525.     CALL    AGAIN            ; MOVE CURSOR TO NEXT LINE
  526.     POP    BC            ; RESTORE REGISTERS
  527.     POP    HL            ; GET START LINE
  528.     PUSH    HL            ; SAVE IT AGAIN
  529.     PUSH    BC            ; SAVE LINE COUNTER/MAXIMUM LINE LENGTH
  530. RDBUF7:    LD    A,B            ; TEST LAST CHARACTER ECHOED 
  531.     OR    A
  532.     JR    Z,RDBUF8        ; YES THEN JUMP
  533.     INC    HL            ; INCREMENT POINTER
  534.     LD    A,(HL)            ; GET CHARACTER
  535.     DEC    B            ; DECREMENT LINE COUNTER
  536.     PUSH    HL            ; SAVE REGISTERS
  537.     PUSH    BC
  538.     CALL    OUTCH            ; OUTPUT CHARACTER
  539.     POP    BC            ; RESTORE REGISTERS
  540.     POP    HL
  541.     JR    RDBUF7            ; AND TEST END LINE
  542. RDBUF8:    POP    BC            ; RESTORE LINE COUNTER/MAX LINE LENGTH
  543. RDBUF9:    JR    RDBUF5            ; AND GET NEXT CHAR
  544. RDBUFA:    CP    CONTU            ; TEST DELETE LINE
  545.     JR    NZ,RDBUFC        ; NOT THEN JUMP
  546.     POP    HL            ; GET START LINE
  547.     CALL    AGAIN            ; MOVE CURSOR TO NEXT LINE
  548. RDBUFB:    JR    RDBUF            ; AND START ROUTINE AGAIN
  549. RDBUFC:    CP    CONTX            ; TEST DELETE LINE
  550.     JR    NZ,RDBUFE        ; NOT THEN JUMP
  551. RDBUFD:    POP    HL            ; GET START LINE
  552.     LD    A,B            ; TEST IF LAST CHARACTER DELETED
  553.     OR    A
  554.     JR    Z,RDBUFB        ; YES START ROUTINE AGAIN
  555.     PUSH    HL            ; SAVE POINTER
  556.     CALL    DELCH            ; DELETE LAST CHARACTER LINE
  557.     JR    RDBUFD            ; TEST LAST CHARACTER DELETED
  558. RDBUFE:    CP    RUBOUT            ; TEST DELETE LAST CHARACTER
  559.     JR    Z,DOBACK        ; Part of delete key fix
  560. ;Remove code for echoing deleted character--B.H.
  561. ;    LD    A,B            ; TEST FIRST CHARACTER LINE
  562. ;    OR    A
  563. ;    JR    Z,RDBUF9        ; YES, DO NOT DELETE
  564. ;    LD    A,(HL)            ; GET LAST CHARACTER
  565. ;    DEC    HL            ; DECREMENT POINTER LINE
  566. ;    DEC    B            ; DECREMENT LINE COUNTER
  567. ;    JR    RDBUFG            ; ECHO LAST CHARACTER
  568.     CP    CR            ; TEST CARRIAGE RETURN
  569.     JR    Z,RDBUFI        ; YES, THEN EXIT
  570.     CP    LF            ; TEST LINE FEED
  571.     JR    Z,RDBUFI        ; YES THEN EXIT
  572.     INC    HL            ; INCREMENT POINTER
  573.     LD    (HL),A            ; AND SAVE CHARACTER
  574.     INC    B            ; INCREMENT LINE COUNTER
  575. RDBUFG:    PUSH    HL            ; SAVE REGISTERS
  576.     PUSH    BC
  577.     CALL    OUTCH            ; ECHO CHARACTER
  578.     POP    BC            ; RESTORE REGISTERS
  579.     POP    HL
  580.     CP    CONTC            ; TEST WARM BOOT
  581.     LD    A,B            ; GET LINE COUNT
  582.     JR    NZ,RDBUFH        ; NO WARM BOOT THEN JUMP
  583.     CP    1            ; TEST CONTC IS FIRST CHARACTER LINE 
  584.     JP    Z,RAMLOW+00000H        ; YES THEN EXECUTE WARM BOOT
  585. RDBUFH:    CP    C            ; TEST LINE LENGTH=MAXIMUM LINE LENGTH
  586.     JR    NZ,RDBUF9        ; NOT THEN GET NEXT CHARACTER
  587. RDBUFI:    POP    HL            ; GET START LINE - 1
  588.     LD    (HL),B            ; SAVE LINE COUNTER
  589.     LD    A,CR            ; LOAD CARRIAGE RETURN
  590.     JP    WRCON            ; AND ECHO IT
  591. ;
  592. ;******************************************************************************
  593. ;*                                          *
  594. ;*     DISK FUNCTIONS                                  *
  595. ;*                                          *
  596. ;******************************************************************************
  597. ;
  598. ; RETURN VERSION NUMBER
  599. ;
  600. CMND12:    LD    A,22H            ; SET VERSION NUMBER
  601.     JR    CMD25A            ; AND EXIT
  602. ;
  603. ; RESET DISK SYSTEM
  604. ;
  605. CMND13:    
  606.     IF    RESDSK
  607. ;detect change between single and double sided disks if this function is
  608. ;supported.--B.H.
  609.     CALL    SETDSK        
  610.     ENDIF    
  611.     LD    HL,0            ; LOAD ZERO
  612.     LD    (LOGIN),HL        ; ALL DRIVES LOGED OUT
  613.     LD    (DSKRO),HL        ; ALL DRIVES READ/WRITE
  614.     LD    HL,RAMLOW+00080H    ; SET UP DMA ADDRESS
  615.     LD    (DMA),HL        ; AND SAVE IT
  616.     CALL    STDMA            ; DO P2BIOS CALL
  617.     XOR    A            ; SET DEFAULT DRIVE = 'A'
  618.     LD    (DEFDRV),A        ; SAVE IT
  619.     CALL    SELDK            ; SELECT DRIVE
  620.     LD    A,(SUBFLG)        ; GET SUBMIT FLAG
  621.     JR    CMD25A            ; EXIT
  622. ;
  623. ; SEARCH FOR FILE
  624. ;
  625. CMND17:    
  626.     CALL    SELDRV            ; SELECT DRIVE FROM FCB
  627.     LD    A,(IX+0)        ; GET DRIVE NUMBER FROM FCB
  628.     SUB    '?'            ; TEST IF '?'
  629.     JR    Z,CMD17B        ; IF SO ALL ENTRIES MATCH
  630.     LD    A,(IX+14)        ; GET SYSTEM BYTE
  631.     CP    '?'            ; TEST IF '?' 
  632.     JR    Z,CMD17A        ; YES, JUMP
  633.     LD    (IX+14),0        ; LOAD SYSTEM BYTE WITH ZERO
  634. CMD17A:    LD    A,15            ; TEST FIRST 15 ITEMS IN FCB
  635. CMD17B:    CALL    SEARCH            ; DO SEARCH
  636. CMD17C:    LD    HL,(DIRBUF)        ; COPY DIRECTORY BUFFER 
  637.     LD    DE,(DMA)        ; TO DMA ADDRESS
  638.     LD    BC,128            ; DIRECTORY=128 BYTES 
  639.     LDIR
  640.     RET                ; EXIT
  641. ;
  642. ; SEARCH FOR NEXT OCCURENCE FILE
  643. ;
  644. CMND18:    LD    IX,(DCOPY)        ; GET LAST FCB USED BY SEARCH
  645.     CALL    SELDRV            ; SELEXT DRIVE FROM FCB
  646.     CALL    SEARCN            ; SEARCH NEXT FILE MATCH
  647.     JR    CMD17C            ; AND COPY DIRECTORY TO DMA ADDRESS
  648. ;
  649. ; DELETE FILE
  650. ;
  651. CMND19:    
  652.     CALL    SELDRV            ; SELECT DRIVE FROM FCB
  653.     CALL    DELETE            ; DELETE FILE
  654. CMD19A:    LD    A,(SEAREX)        ; GET EXIT BYTE 00=FILE FOUND,0FFH NOT
  655.     JR    CMD25A            ; AND EXIT
  656. ;
  657. ; RENAME FILE
  658. ;
  659. CMND23:    
  660.     CALL    SELDRV            ; SELECT DRIVE FROM FCB
  661.     CALL    RENAM            ; RENAME FILE
  662.     JR    CMD19A            ; AND EXIT
  663. ;
  664. ; RETURN LOGIN VECTOR
  665. ;
  666. CMND24:    LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  667. CMD24A:    LD    (PEXIT),HL        ; SAVE IT
  668.     RET                ; AND EXIT
  669. ;
  670. ; RETURN CURRENT DRIVE
  671. ;
  672. CMND25:    LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  673. CMD25A:    JP    EXIT            ; AND EXIT
  674. ;
  675. ; RETURN ALV VECTOR
  676. ;
  677. CMND27:    LD    HL,(ALV)        ; GET ALLOCATION VECTOR
  678.     JR    CMD24A            ; AND EXIT
  679. ;
  680. ; RETURN DISK R/O VECTOR
  681. ;
  682. CMND29:    LD    HL,(DSKRO)        ; GET DISK R/O VECTOR
  683.     JR    CMD24A            ; AND EXIT
  684. ;
  685. ; CHANGE STATUS
  686. ;
  687. CMND30:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  688.     CALL    CSTAT            ; CHANGE STATUS
  689.     JR    CMD19A            ; AND EXIT
  690. ;
  691. ; RETURN DRIVE TABLE
  692. ;
  693. CMND31:    LD    HL,(IXP)        ; GET DRIVE TABLE
  694.     JR    CMD24A            ; AND EXIT
  695. ;
  696. ; SET/GET USER CODE
  697. ;
  698. CMND32:    LD    A,E            ; GET USER CODE
  699.     INC    A            ; TEST IF 0FFH
  700.     LD    A,(USER)        ; GET OLD USER CODE
  701.     JR    Z,CMD25A        ; IF 0FFH THEN EXIT
  702.     LD    A,E            ; GET NEW USER CODE
  703.     AND    01FH            ; MASK IT
  704.     LD    (USER),A        ; SAVE IT
  705.     RET                ; AND EXIT
  706. ;
  707. ; COMPUTE FILE SIZE COMMAND
  708. ;
  709. CMND35:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  710.     CALL    FILSZ            ; COMPUTE FILE SIZE
  711.     JR    CMD19A            ; AND EXIT
  712. ;
  713. ; SET RANDOM RECORD COUNT
  714. ;
  715. CMND36:    LD    HL,32            ; SET POINTER TO NEXT RECORD
  716.     CALL    CALRRC            ; CALCULATE RANDOM RECORD COUNT
  717. LDRRC:    LD    (IX+33),D        ; AND SAVE RANDOM RECORD COUNT
  718.     LD    (IX+34),C
  719.     LD    (IX+35),B
  720.     RET                ; AND EXIT
  721. ;
  722. ; RESET MULTIPLE LOGIN DRIVE
  723. ;
  724. CMND37:    
  725.     LD    A,E            ; GET MASK LSB
  726.     CPL                ; COMPLEMENT IT
  727.     LD    E,A 
  728.     LD    A,D            ; GET MASK MSB
  729.     CPL                ; COMPLEMENT IT
  730.     LD    D,A
  731.     LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  732.     LD    A,E            ; MASK LOGIN VECTOR
  733.     AND    L            ; LSB
  734.     LD    L,A
  735.     LD    A,D            ; MASK LOGIN VECTOR
  736.     AND    H            ; MSB
  737.     LD    H,A
  738.     LD    (LOGIN),HL        ; SAVE LOGIN VECTOR
  739.     EX    DE,HL            ; USE LOGIN VECTOR AS MASK
  740.     LD    HL,(DSKRO)        ; GET DRIVE R/O VECTOR
  741.     LD    A,E            ; MASK DRIVE R/O VECTOR
  742.     AND    L            ; LSB
  743.     LD    L,A
  744.     LD    A,D            ; MASK DRIVE R/O VECTOR
  745.     AND    H            ; LSB
  746.     LD    H,A
  747.     LD    (DSKRO),HL        ; SAVE DRIVE R/O VECTOR
  748.     LD    A,(DEFDRV)        ; log in default drive if needed
  749.     CALL    SELDK
  750.     XOR    A            ; flag success
  751.     JP    EXIT            ; and return
  752. ;
  753. ;******************************************************************************
  754. ;*                                          *
  755. ;*     ERROR ROUTINES                                  *
  756. ;*                                          *
  757. ;******************************************************************************
  758. ;
  759. ; Bad sector error message separated into read/write error messages--B.H.
  760. ; BAD SECTOR ERROR
  761. ;
  762. BADSEC:    JP    (HL)            ; go to RDERR or WRTERR routine
  763. ;
  764. ; SELECT ERROR
  765. ;
  766. SELERR:    LD    DE,MSEL            ; LOAD SELECT ERROR MESSAGE
  767.     JR    WERROR            ; AND DISPLAY ERROR
  768. ;
  769. ; FILE READ ONLY ERROR
  770. ;
  771. FILRO:    LD    DE,MFILRO        ; LOAD FILE R/O MESSAGE
  772.     LD    BC,0FFFFH        ; SET FILE R/O and ignore MESSAGE FLAG
  773.     JR    ERROR            ; AND DISPLAY ERROR
  774. ;
  775. ; Read Error Message--B.H.
  776. ;
  777. RDERR:    LD    DE,MRDERR
  778.     JR    WERROR
  779. ;
  780. ; Write Error Message--B.H.
  781. WRTERR:    LD    DE,MWRTER
  782. WERROR:    LD    B,00H            ; set not ok to ignore
  783.     JR    DERROR
  784. ;
  785. ; DRIVE READ ONLY ERROR
  786. ;
  787. RDONLY:    LD    DE,MRO            ; LOAD DRIVE R/O MESSAGE
  788.     LD    B,0FFH            ; set ok to ignore
  789. DERROR:    LD    C,0            ; SET NO FILE R/O MESSAGE
  790. ;
  791. ;
  792. ; DISPLAY ERROR MESSAGE
  793. ;
  794. ; P2DOS ERROR ON D: ERROR MESSAGE
  795. ; FUNCTION = NN  [FILE = FILENAME.TYP]
  796. ;
  797. ERROR:    PUSH    BC            ; SAVE FILE R/O and IGNORE FLAG
  798.     PUSH    DE            ; SAVE ERROR MESSAGE POINTER
  799.     CALL    CROUT            ; DISPLAY CR/LF
  800.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  801.     ADD    A,'A'            ; MAKE ASCII
  802.     LD    (MDRIVE),A        ; SAVE IT
  803.     LD    DE,MBERR        ; LOAD MESSAGE "Disk error on "
  804.     CALL    MESS            ; DISPLAY MESSAGE
  805.     POP    DE            ; GET ERROR MESSAGE POINTER
  806.     CALL    MESS            ; DISPLAY MESSAGE
  807.     CALL    CROUT            ; DISPLAY CR/LF
  808.     LD    DE,MBFUNC        ; LOAD MESSAGE "FUNCTION ="
  809.     CALL    MESS            ; DISPLAY MESSAGE
  810.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  811.     PUSH    AF            ; SAVE IT
  812.     LD    BC,100            ; DISPLAY NUMBER / 100
  813.     CALL    NUM
  814.     LD    C,10            ; DISPLAY NUMBER / 10
  815.     CALL    NUM
  816.     LD    BC,101H            ; ALWAYS DISPLAY NUMBER / 1
  817.     CALL    NUM
  818.     POP    AF            ; GET FUNCTION NUMBER
  819.     POP    BC            ; GET FILE R/O FLAG
  820.     PUSH    BC
  821.     CP    15            ; TEST IF FCB USED IN COMMAND
  822.     JR    C,ERROR3
  823.     CP    24
  824.     JR    C,ERROR1
  825.     CP    30
  826.     JR    Z,ERROR1
  827.     CP    33
  828.     JR    C,ERROR3
  829.     CP    37
  830.     JR    C,ERROR1
  831.     CP    40
  832.     JR    NZ,ERROR3
  833. ERROR1:    PUSH    IX            ; YES THEN DISPLAY "FILE ="
  834.     SUB    19            ; TEST DELETE FILE FUNCTION
  835.     JR    NZ,ERROR2        ; NOT THEN JUMP
  836.     OR    C            ; TEST FILE R/O FLAG
  837.     JR    Z,ERROR2        ; NO FILE R/O THEN JUMP
  838.     CALL    CALDIR            ; GET FCB FROM DIRECTORY BUFFER
  839.     EX    (SP),HL            ; SAVE IT
  840. ERROR2:    LD    DE,MFILE        ; GET MESSAGE " FILE ="
  841.     CALL    MESS            ; DISPLAY MESSAGE
  842.     POP    HL            ; GET POINTER FCB
  843.     LD    B,8            ; DISPLAY FISRT 8 CHARACTERS
  844.     CALL    FILENM
  845.     LD    A,'.'            ; LOAD '.'
  846.     PUSH    HL            ; SAVE FCB POINTER
  847.     CALL    WRCON            ; ECHO IT
  848.     POP    HL            ; RESTORE FCB POINTER
  849.     LD    B,3            ; DISPLAY LAST 3 CHARACTERS 
  850.     CALL    FILENM
  851. ERROR3:    CALL    GCONST            ; TEST IF CHARACTER PRESENT
  852.     OR    A
  853.     JR    Z,ERROR4        ; NO THEN JUMP
  854.     CALL    GETCH            ; GET CHARACTER
  855.     JR    ERROR3            ; AND TEST AGAIN
  856. ERROR4:    CALL    GETCH            ; GET CHARACTER
  857. ;P2DOS had a bug which did not allow the user to ignore a read/write error
  858. ;by hitting a key other than Control-C. This is the fix.--B.H.
  859. ;
  860. ;further modified to accept only a single ignore character
  861. ;
  862.     POP    BC            ; get back ignore flag
  863.     CP    CONTC            ; warm boot?
  864.     JR    Z,ERROR5        ; yes
  865.     AND    B            ; possible to ignore (r/o error?)
  866.     JR    Z,ERROR5        ; no
  867.     LD    HL,FLAGS        ; ignore enabled?
  868.     BIT    2,(HL)
  869. ERROR5:    JP    Z,RAMLOW+00000H        ; no
  870.     CP    IGNORE            ; ignore?
  871.     RET    Z            ; yes
  872.     PUSH    BC            ; save ignore flag
  873.     JR    ERROR4
  874. ;
  875. ; DISPLAY NUMBER
  876. ;
  877. NUM:    LD    D,0FFH            ; LOAD NUMBER -1
  878. NUM1:    INC    D            ; INCREMENT NUMBER
  879.     SUB    C            ; DIVIDE BY C
  880.     JR    NC,NUM1            ; NOT FINISHED THEN LOOP
  881.     ADD    A,C            ; RESTORE LAST VALUE
  882.     PUSH    AF            ; SAVE IT
  883.     LD    A,D            ; TEST IF "0"
  884.     OR    B            ; AND IF LEADING ZERO
  885.     JR    Z,NUM2            ; YES, THEN EXIT 
  886.     LD    B,D            ; SET NO LEADING ZERO 
  887.     LD    A,D            ; GET NUMBER
  888.     ADD    A,'0'            ; MAKE ASCII
  889.     PUSH    BC            ; SAVE REGISTERS
  890.     CALL    WRCON            ; ECHO NUMBER
  891.     POP    BC            ; RESTORE REGISTERS
  892. NUM2:    POP    AF            ; RESTORE NUMBER
  893.     RET                ; AND EXIT
  894. ;
  895. ; DISPLAY FILNAME.TYP
  896. ;
  897. FILENM:    INC    HL            ; INCREMENT POINTER FCB
  898.     LD    A,(HL)            ; GET CHARACTER FROM FCB
  899.     AND    07FH            ; MASK IT
  900.     PUSH    HL            ; SAVE REGISTERS
  901.     PUSH    BC
  902.     CALL    WRCON            ; ECHO CHARACTER
  903.     POP    BC            ; RESTORE REGISTERS
  904.     POP    HL
  905.     DJNZ    FILENM            ; REPEAT B TIMES
  906.     RET                ; AND EXIT
  907. ;
  908. ; ERROR MESSAGES
  909. ; Made more meaningful-B.H.
  910. ;
  911. ;Bad sector message replaced by read/write error messages
  912. ;MBADSC:    DB    'Bad sector$'
  913. ;
  914. MSEL:    DB    'Non-existent drive$'
  915. ;
  916. MFILRO:    DB    'File is '
  917. ;
  918. MRO:    DB    'Read-Only$'
  919. ;
  920. MBERR:    DB    'Disk error on '
  921. MDRIVE:    DB    0
  922.     DB    DRVSEP
  923.     DB    ' $'
  924. ;
  925. MBFUNC:    DB    'Function = $'
  926. ;
  927. MFILE:    DB    '; File = $'
  928. ;
  929. MRDERR:    DB    'Read error$'
  930. ;
  931. MWRTER:    DB    'Write error$'
  932. ;
  933. ; SELECT DISK FROM FCB
  934. ;
  935. SELDRV:    LD    A,0FFH            ; SET DISK SELECT DONE FLAG
  936.     LD    (FLDRV),A
  937.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  938.     LD    (DRIVE),A        ; SAVE IT IN MEMORY
  939.     LD    E,A            ; SAVE IT IN REGISTER E
  940.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  941.     LD    (FCB0),A        ; SAVE IT
  942.     CP    '?'            ; TEST IF '?'
  943.     JR    Z,CMND14        ; YES, THEN SELECT DRIVE FROM REGISTER E
  944.     AND    01FH            ; MASK DRIVE
  945.     LD    A,E            ; TEST IF ZERO
  946.     JR    Z,SELDR0        ; SELECT DRIVE FROM REGISTER E
  947.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  948.     DEC    A            ; DECREMENT DRIVE
  949. SELDR0:    CALL    SELDK            ; SELECT DRIVE
  950.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  951.     AND    0E0H            ; REMOVE DRIVE BITS
  952.     LD    B,A            ; SAVE REGISTER
  953.     LD    A,(USER)        ; GET USER NUMBER
  954.     OR    B            ; INSERT USER NUMBER IN FCB
  955.     LD    (IX+0),A
  956.     RET                ; AND EXIT
  957. ;       
  958. ; SELECT DISK
  959. ;
  960. CMND14:    LD    A,E            ; COPY DRIVE NUMBER
  961. ;
  962. ; SELECT DISK
  963. ;
  964. SELDK:    AND    0FH            ; MASK DRIVE NUMBER
  965.     LD    B,A            ; SAVE COUNTER
  966.     LD    DE,(LOGIN)        ; GET LOGIN VECTOR
  967.     OR    A            ; TEST DRIVE 'A'
  968.     JR    Z,SELDK1        ; YES THEN JUMP
  969. SELDK0:    RR    D            ; SHIFT LOGIN VECTOR
  970.     RR    E            ; UNTIL BIT 0 REGISTER E
  971.     DJNZ    SELDK0            ; IS CURRENT DRIVE
  972. SELDK1:    LD    HL,DEFDRV        ; GET POINTER LAST DRIVE
  973.     BIT    0,E            ; TEST IF DRIVE LOGGED IN
  974.     JR    Z,SELDK2        ; NO, LOGIN DRIVE
  975.     CP    (HL)            ; TEST SAME DRIVE
  976.     RET    Z            ; YES THEN EXIT
  977. SELDK2:    LD    (HL),A            ; SAVE NEW CURRENT DRIVE
  978.     PUSH    DE            ; SAVE DRIVE LOGGED IN FLAG
  979.     LD    C,A            ; COPY DRIVE NUMBER
  980.     CALL    SELDSK            ; DO P2BIOS SELECT 
  981.     LD    A,H            ; TEST IF ERROR 
  982.     OR    L
  983.     JR    NZ,SELDK3        ; DRIVE NUMBER LEGAL
  984.     LD    HL,(STSEL)        ; load error message address
  985.     JP    (HL)            ; go to error routine
  986. SELDK3:    LD    E,(HL)            ; GET LSB TRANSLATION VECTOR
  987.     INC    HL            ; INCREMENT POINTER
  988.     LD    D,(HL)            ; GET MSB TRANSLATION VECTOR
  989.     INC    HL            ; INCREMENT POINTER
  990.     LD    (TRANS),DE        ; SAVE TRANSLATION VECTOR
  991.     LD    (TEMP0),HL        ; SAVE ADDRESS TEMP0
  992.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  993.     INC    HL
  994.     LD    (TEMP1),HL        ; SAVE ADDRESS TEMP1
  995.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  996.     INC    HL
  997.     LD    (TEMP2),HL        ; SAVE ADDRESS TEMP2
  998.     INC    HL            ; INCREMENT TO NEXT ADDRESS
  999.     INC    HL
  1000.     LD    DE,DIRBUF        ; LOAD DIRBUF POINTER
  1001.     LD    BC,8            ; COPY 8 BYTES
  1002.     LDIR
  1003.     LD    HL,(IXP)        ; GET DRIVE PARAMETER ADDRESS
  1004.     LD    C,15            ; COPY 15 BYTES
  1005.     LDIR
  1006.     POP    DE            ; GET DRIVE LOGGED IN FLAG
  1007.     BIT    0,E            ; TEST IT
  1008.     RET    NZ            ; DRIVE LOGGED IN SO RETURN
  1009.     LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  1010.     CALL    SDRVB            ; SET DRIVE BIT IN LOGIN VECTOR
  1011.     LD    (LOGIN),HL        ; SAVE LOGIN VECTOR
  1012. ;
  1013. ; INIT DRIVE
  1014. ;  CLEAR ALV BIT BUFFER AFTER DRIVE RESET
  1015. ;
  1016. INITDR:    LD    DE,(MAXLEN)        ; GET LENGTH ALV BUFFER-1 (BITS)
  1017.     LD    A,3            ; DIVIDE BY 8
  1018. INITD0:    SRL    D            ; TO GET BYTES
  1019.     RR    E
  1020.     DEC    A
  1021.     JR    NZ,INITD0
  1022.     LD    HL,(ALV)        ; GET POINTER ALV BUFFER
  1023.     PUSH    HL
  1024. INITD1:    INC    HL            ; zero n-1 bytes (skip first)
  1025.     LD    (HL),0            ; CLEAR 8 BITS
  1026.     DEC    DE            ; DECREMENT COUNTER
  1027.     LD    A,D            ; TEST IF COUNTER ZERO
  1028.     OR    E
  1029.     JR    NZ,INITD1        ; NOT THEN JUMP
  1030.     POP    HL            ; GET ALV POINTER
  1031.     LD    DE,(NDIR0)        ; now, GET FIRST TWO BYTES ALV BUFFER 
  1032.     LD    (HL),E            ; SAVE LSB
  1033.     INC    HL            ; INCREMENT POINTER
  1034.     LD    (HL),D            ; SAVE MSB
  1035.     LD    HL,(TEMP0)        ; CLEAR NUMBER OF FILES
  1036.     LD    (HL),A            ; CLEAR LSB
  1037.     INC    HL            ; INCREMENT POINTER
  1038.     LD    (HL),A            ; CLEAR MSB
  1039.     LD    (SUBFLG),A        ; CLEAR SUBMIT FLAG (RESET DISK COMMAND)
  1040.     LD    (DIFF),A        ; clear disk changed flag
  1041.     CALL    SETFCT            ; SET FILE COUNT
  1042. INITD2:    LD    A,0FFH            ; UPDATE DIRECTORY CHECKSUM
  1043.     CALL    RDDIR            ; READ FCB'S FROM DIRECTORY
  1044.     CALL    TSTFCT            ; TEST LAST FCB
  1045.     RET    Z            ; YES THEN EXIT
  1046.     CALL    CALDIR            ; CALCULATE ENTRY POINT FCB
  1047.     LD    A,(HL)            ; GET FIRST BYTE FCB
  1048.     CP    0E5H            ; TEST EMPTY DIRECTORY ENTRY
  1049.     JR    Z,INITD2        ; YES THEN GET NEXT FCB
  1050.     CP    021H            ; TEST TIME STAMP
  1051.     JR    Z,INITD2        ; YES THEN GET NEXT FCB
  1052.     LD    A,(USER)        ; GET USER NUMBER
  1053.     CP    (HL)            ; TEST IF USER IS SAME
  1054.     JR    NZ,INITD3        ; NO THEN JUMP
  1055.     INC    HL            ; POINT TO FILE NAME
  1056.     LD    A,(HL)            ; GET FIRST CHAR FILENAME
  1057.     SUB    '$'            ; TEST IF '$'
  1058.     JR    NZ,INITD3        ; NOT THEN JUMP
  1059.     DEC    A            ; LOAD A WITH 0FFH
  1060.     LD    (SUBFLG),A        ; SAVE IT IN SUBFLG 
  1061. INITD3:    LD    C,1            ; SET BIT IN ALV BUFFER
  1062.     CALL    FILLBB            ; SET BITS FROM FCB IN ALV BUFFER
  1063.     CALL    SETLF            ; UPDATE LAST FILE COUNT
  1064.     JR    INITD2            ; AND GET NEXT FCB
  1065. ;
  1066. ; SET DRIVE BIT IN HL
  1067. ;
  1068. SDRVB:    EX    DE,HL            ; COPY HL=>DE 
  1069.     LD    HL,1            ; GET MASK DRIVE "A"
  1070.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  1071.     OR    A            ; TEST IF DRIVE "A"
  1072.     JR    Z,SDRVB1        ; YES THEN DONE
  1073. SDRVB0:    ADD    HL,HL            ; GET NEXT MASK
  1074.     DEC    A            ; DECREMENT DRIVE COUNTER
  1075.     JR    NZ,SDRVB0        ; AND TEST IF DONE
  1076. SDRVB1:    LD    A,D            ; HL=HL OR DE
  1077.     OR    H
  1078.     LD    H,A
  1079.     LD    A,E
  1080.     OR    L
  1081.     LD    L,A
  1082.     RET                ; EXIT
  1083. ;
  1084. ; CALCULATE SECTOR/TRACK DIRECTORY
  1085. ;
  1086. STDIR:    LD    HL,(FILCNT)        ; GET FCB COUNTER DIRECTORY
  1087.     SRL    H            ; DIVIDE BY 4
  1088.     RR    L            ; (4 FCB'S / SECTOR)
  1089.     SRL    H
  1090.     RR    L
  1091.     LD    (RECDIR),HL        ; SAVE VALUE (USED BY CHECKSUM)
  1092.     EX    DE,HL            ; COPY IT TO DE
  1093.     LD    HL,0            ; CLEAR HL
  1094. ;
  1095. ; CALCULATE SECTOR/TRACK
  1096. ;  ENTRY: HL,DE=SECTOR NUMBER (128 BYTE SECTOR)
  1097. ;  RESULT SET TRACK  =HL,DE  /  MAXSEC
  1098. ;         SET SECTOR =HL,DE MOD MAXSEC
  1099. ;
  1100. CALST:    LD    BC,(MAXSEC)        ; GET SECTORS/TRACK
  1101.     LD    A,17            ; SET UP LOOP COUNTER
  1102. CALST0:    OR    A            ; TEST HL>=BC
  1103.     SBC    HL,BC
  1104.     CCF
  1105.     JR    C,CALST1        ; YES THEN JUMP
  1106.     ADD    HL,BC            ; NO THEN RETORE HL
  1107.     OR    A            ; AND CLEAR CARRY
  1108. CALST1:    RL    E            ; SHIFT RESULT IN DE
  1109.     RL    D
  1110.     DEC    A            ; TEST LAST BIT DONE
  1111.     JR    Z,CALST2        ; YES THEN EXIT
  1112.     RL    L            ; SHIFT NEXT BIT IN HL
  1113.     RL    H
  1114.     JR    CALST0            ; CONTINUE
  1115. CALST2:    PUSH    HL            ; SAVE SECTOR NUMBER
  1116.     LD    HL,(NFTRK)        ; GET FIRST TRACK
  1117.     ADD    HL,DE            ; ADD TRACK NUMBER
  1118.     LD    B,H            ; COPY IT TO BC
  1119.     LD    C,L
  1120.     CALL    SETTRK            ; P2BIOS CALL SET TRACK
  1121.     POP    BC            ; RESTORE SECTOR NUMBER
  1122.     LD    DE,(TRANS)        ; GET TRANSLATION TABLE ADDRESS
  1123.     CALL    SECTRN            ; P2BIOS CALL SECTOR TRANSLATION 
  1124.     LD    B,H            ; COPY RESULT TO BC
  1125.     LD    C,L
  1126.     JP    SETSEC            ; P2BIOS CALL SET SECTOR
  1127. ;
  1128. ; GET DISK MAP BLOCK NUMBER FROM FCB
  1129. ;  EXIT HL=ADDRESS FCB
  1130. ;       DE=DM
  1131. ;       BC=OFFSET IN DM
  1132. ;
  1133. GETDM:    LD    C,(IX+32)        ; GET NEXT RECORD
  1134.     LD    A,(NBLOCK)        ; GET NUMBER OF BLOCKS
  1135.     LD    B,A            ; SAVE IT 
  1136. GETDM0:    SRL    C            ; SHIFT NEXT RECORD 
  1137.     DJNZ    GETDM0            ; NUMBER OF BLOCKS TIMES
  1138. GETDM1:    CPL                ; COMPLEMENT NUMBER OF BLOCKS
  1139.     ADD    A,9            ; ADD 9
  1140.     LD    B,A            ; B=8-NUMBER OF BLOCKS
  1141.     LD    A,(NEXTND)        ; GET EXTENT MASK
  1142.     AND    (IX+12)            ; MASK WITH EXTENT
  1143.     RRCA                ; ROTATE ONE RIGHT
  1144. GETDM2:    RLCA                ; ROTATE ONE LEFT
  1145.     DJNZ    GETDM2            ; 8-NUMBER OF BLOCKS TIMES
  1146. GETDM3:    ADD    A,C            ; ADD THE TWO VALUES TO GET ENTRY FCB
  1147. GETDM4:    PUSH    IX            ; GET FCB ADDRESS
  1148.     POP    HL
  1149.     LD    C,16            ; ADD OFFSET 16 TO POINT TO DM
  1150.     ADD    HL,BC
  1151.     LD    C,A            ; ADD ENTRY FCB
  1152.     ADD    HL,BC
  1153.     LD    A,(MAXLEN+1)        ; TEST 8 BITS/16 BITS FCB ENTRY
  1154.     OR    A            ; 16 bits => jump
  1155.     LD    E,(HL)            ; GET 8 BIT VALUE
  1156.     LD    D,A            ; MAKE MSB ZERO (if a=0)
  1157.     RET    Z            ; AND EXIT
  1158.     ADD    HL,BC            ; else,    ADD TWICE (16 BIT VALUES)
  1159.     LD    E,(HL)            ; GET LSB
  1160.     INC    HL            ; INCREMENT POINTER
  1161.     LD    D,(HL)            ; GET MSB
  1162.     DEC    HL            ; DECREMENT POINTER
  1163.     RET                ; AND EXIT
  1164. ;
  1165. ; CALCULATE SECTOR NUMBER 
  1166. ;  ENTRY: DE=BLOCK NUMBER FROM FCB
  1167. ;
  1168. CALSEC:    LD    HL,0            ; CLEAR MSB SECTOR NUMBER
  1169.     LD    A,(NBLOCK)        ; GET LOOP COUNTER
  1170.     LD    B,A            ; SAVE IT IN B
  1171. CALSC0:    SLA    E            ; SHIFT L,D,E 
  1172.     RL    D
  1173.     RL    L
  1174.     DJNZ    CALSC0            ; B TIMES
  1175. CALSC1:    LD    A,(NMASK)        ; GET SECTOR MASK
  1176.     AND    (IX+32)            ; AND WHIT NEXT RECORD
  1177.     OR    E            ; SET UP LSB SECTOR NUMBER
  1178.     LD    E,A
  1179.     RET                ; AND EXIT
  1180. ;
  1181. ; CALCULATE DIRBUF ENTRY POINT
  1182. ;
  1183. CALDIR:    LD    HL,(DIRBUF)        ; GET START ADDRESS DIRBUF
  1184.     LD    A,(SECPNT)        ; GET SECTOR POINTER
  1185.     ADD    A,L            ; ADD L=L+A
  1186.     LD    L,A
  1187.     RET    NC            ; NO CARRY EXIT
  1188.     INC    H            ; INCREMENT H
  1189.     RET                ; AND EXIT
  1190. ;
  1191. ; INIT FILE COUNT
  1192. ;
  1193. SETFCT:    LD    HL,-1            ; SET UP FILE COUNT
  1194.     LD    (FILCNT),HL        ; SAVE IT
  1195.     RET                ; AND EXIT
  1196. ;
  1197. ; TEST FILE COUNT
  1198. ;
  1199. TSTFCT:    LD    HL,(FILCNT)        ; TEST FILE COUNT=0FFFFH
  1200.     LD    A,H            ; GET MSB 
  1201.     AND    L            ; AND LSB
  1202.     INC    A            ; TEST IF RESULT=0FFH
  1203.     RET                ; AND EXIT
  1204. ;
  1205. ; SET LAST FILE
  1206. ;
  1207. SETLF:    CALL    TSTLF            ; TEST LAST FILE
  1208.     RET    C            ; NO THEN EXIT
  1209.     INC    DE            ; INCREMENT LAST FILE
  1210.     LD    (HL),D            ; SAVE IT IN TEMP0
  1211.     DEC    HL
  1212.     LD    (HL),E
  1213.     RET                ; AND EXIT
  1214. ;
  1215. ; TEST LAST FILE
  1216. ;
  1217. TSTLF:    LD    HL,(TEMP0)        ; GET POINTER TO LAST FILE 
  1218.     LD    DE,(FILCNT)        ; GET FILE COUNTER
  1219.     LD    A,E            ; SUBTRACT DE-(HL)
  1220.     SUB    (HL)
  1221.     INC    HL
  1222.     LD    A,D
  1223.     SBC    A,(HL)
  1224.     RET                ; EXIT
  1225. ;
  1226. ; GET NEXT FCB FROM DRIVE
  1227. ; ENTRY A=0 CHECK CHECKSUM, A=0FFH UPDATE CHECKSUM
  1228. ;
  1229. RDDIR:    LD    C,A            ; SAVE CHECKSUM FLAG
  1230.     LD    HL,(FILCNT)        ; GET FILE COUNTER
  1231.     INC    HL            ; INCREMENT IT
  1232.     LD    (FILCNT),HL        ; AND SAVE IT
  1233.     LD    DE,(NFILES)        ; GET MAXIMUM NUMBER OF FILES
  1234.     OR    A            ; CLEAR CARRY
  1235.     SBC    HL,DE            ; TEST IF LAST FILE
  1236.     ADD    HL,DE
  1237.     JR    Z,RDDIR0        ; NO JUMP
  1238.     JR    NC,SETFCT        ; YES SET FILE COUNT TO 0FFFFH
  1239. RDDIR0:    LD    A,L            ; GET FILE COUNT LSB
  1240.     ADD    A,A            ; *32 
  1241.     ADD    A,A
  1242.     ADD    A,A
  1243.     ADD    A,A
  1244.     ADD    A,A
  1245.     AND    060H            ; MASK IT
  1246.     LD    (SECPNT),A        ; SAVE IT FOR LATER USE
  1247.     RET    NZ            ; RETURN IF NOT FISRT FCB SECTOR
  1248.     PUSH    BC            ; SAVE CHECKSUM FLAG
  1249.     CALL    STDIR            ; CALCULATE SECTOR/TRACK DIRECTORY
  1250.     CALL    READDR            ; READ SECTOR DIRECTORY
  1251.     POP    BC            ; RESTORE CHECKSUM FLAG
  1252. ;
  1253. ; UPDATE/CHECK CHECKSUM DIRECTORY
  1254. ; ENTRY C=0 CHECK CHECKSUM, C=0FFH UPDATE CHECKSUM
  1255. ;
  1256. CHKDIR:    LD    HL,(NCHECK)        ; GET NUMBER OF CHECKED RECORDS
  1257.     LD    DE,(RECDIR)        ; GET CURRENT RECORD
  1258.     OR    A            ; CLEAR CARRY
  1259.     SBC    HL,DE            ; TEST CURRENT RECORD 
  1260.     RET    Z            ; EXIT IF ZERO
  1261.     RET    C            ; EXIT IF GREATER THEN NCHECK
  1262.     LD    HL,(DIRBUF)        ; GET DIRBUF
  1263.     LD    B,128            ; SET UP COUNTER
  1264.     XOR    A            ; CLEAR CHECKSUM
  1265. CHKDR0:    ADD    A,(HL)            ; ADD CHECKSUM
  1266.     INC    HL            ; INCREMENT POINTER
  1267.     DJNZ    CHKDR0            ; 128 TIMES
  1268.     LD    HL,(CSV)        ; GET POINTER CHECKSUM DIRECTORY
  1269.     ADD    HL,DE            ; ADD CURRENT RECORD
  1270.     INC    C            ; TEST CHECKSUM FLAG
  1271.     JR    Z,CHKDR1        ; 0FFH=> UPDATE CHECKSUM
  1272.     CP    (HL)            ; TEST CHECKSUM
  1273.     RET    Z            ; EXIT IF OK
  1274. ;Automatic disk logging--instead of setting read/only flag when disk is
  1275. ;changed, a disk changed flag is set.  The disk is reset when the SEARCH
  1276. ;routine is called.
  1277. ;    JP    SETWPD
  1278.     LD    A,TRUE            ; set disk changed flag
  1279.     LD    (DIFF),A
  1280.     JP    SETFN            ; set number of files
  1281. CHKDR1:    LD    (HL),A            ; UPDATE CHECKSUM
  1282.     RET                ; AND EXIT
  1283. ;
  1284. ; READ SECTOR FROM DRIVE
  1285. ;
  1286. ;
  1287. ;Readr and Writer modified to give separate error messages--B.H.
  1288. READR:    CALL    READ            ; P2BIOS CALL READ SECTOR
  1289.     LD    HL,RDERR
  1290.     JR    WRITE0
  1291. ;
  1292. ; WRITE SECTOR ON DRIVE
  1293. ;
  1294. WRITER:    CALL    WRITE            ; P2BIOS CALL WRITE SECTOR
  1295.     LD    HL,WRTERR
  1296. WRITE0:    OR    A            ; TEST EXIT CODE
  1297.     RET    Z            ; EXIT IF OK
  1298.     PUSH    HL            ; go to "bad sector" routine
  1299.     LD    HL,(STBDSC)
  1300.     EX    (SP),HL
  1301.     RET                ; P2DOS ERROR ON D: BAD SECTOR
  1302. ;
  1303. ; READ DIRECTORY FROM DRIVE
  1304. ;
  1305. READDR:    CALL    DMADIR            ; SET UP DMA DIRECTORY
  1306.     CALL    READR            ; READ RECORD
  1307.     JR    STDMA            ; SET UP DMA USER
  1308. ;
  1309. ; WRITE DIRECTORY ON DRIVE
  1310. ;
  1311. WRITDR:    LD    C,0FFH            ; UPDATE CHECKSUM DIRECTORY
  1312.     CALL    CHKDIR
  1313.     CALL    DMADIR            ; SET UP DMA DIRECTORY 
  1314.     LD    C,1            ; WRITE DIRECTORY FLAG
  1315.     CALL    WRITER            ; WRITE RECORD
  1316.     JR    STDMA            ; SET UP DMA USER
  1317.  
  1318.  
  1319.