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 / SUPRDOS2.LBR / DOS1.MZC / DOS1.MAC
Text File  |  2000-06-30  |  37KB  |  1,166 lines

  1.         TITLE    'SUPRBDOS Disk Operating System'
  2. ;
  3. ;******************************************************************************
  4. ;*                                          *
  5. ;*  P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 1.2          *
  6. ;*        No more control-C to change disks!                      *
  7. ;*  COPYRIGHT (C) 1985 BY:     H.A.J. TEN BRUGGE                  *
  8. ;*  ALL RIGHTS RESERVED         MOLENSTRAAT 33                      *
  9. ;*                  NL-7491 BD DELDEN                  *
  10. ;*                 THE NETHERLANDS                  *
  11. ;*                 TEL:..31-5407-1980                  *
  12. ;*  P2DOS WAS WRITTEN BY HERMAN TEN BRUGGE, WHO ASSUMES NO RESPONSIBILITY     *
  13. ;*  OR LIABILITY FOR ITS USE. P2DOS IS RELEASED TO THE PUBLIC DOMAIN FOR      *
  14. ;*  NON-COMMERCIAL USE ONLY.                              *
  15. ;*                                          *
  16. ;*  THE PULBLIC IS ENCOURAGED TO FREELY COPY AND USE THIS PROGRAM FOR         *
  17. ;*  NON-COMMERCIAL PURPOSES. ANY COMMERCIAL USE OF P2DOS IS PROHIBITED        *
  18. ;*  UNLESS APPROVED BY THE AUTHOR, H.A.J. TEN BRUGGE, IN WRITING.          *
  19. ;*                                              *     
  20. ;*  THIS IS MOD 0.2 TO THE RELEASE VERSION OF P2DOS                  *
  21. ;*                                          *
  22. ;******************************************************************************
  23. ;*  MOD 0.2 Revisions
  24. ;*  Renamed to SUPRBDOS
  25. ;*        By Benjamin Ho
  26. ;*               626 Emerson St.
  27. ;*                 Evanston, IL 60201
  28. ;*  Background:
  29. ;* 
  30. ;*  P2DOS MOD 0.1 was not a major improvement on the standard CP/M BDOS.
  31. ;*  While it added Public files, slightly more informative error messages, and
  32. ;*  time stamping support, it did not fix the major annoyances of the CP/M BDOS,
  33. ;*  namely the necessity of logging in new disks with Control-C, mystifying
  34. ;*  error messages, and a delete key that looked like it didn't delete.  
  35. ;*
  36. ;*  P2DOS MOD 0.2 is a major enhancement which liberates the CP/M user from all
  37. ;*  these annoyances.  It is compatible with all CP/M software except those
  38. ;*  that modify the BDOS.  Fortunately, that type of program is extremely rare.
  39. ;*
  40. ;*  P2DOS MOD 0.2 may be used with ZCPR3 to provide an extremely powerful
  41. ;*  100% CP/M 2.2 compatible operating system.  The resulting system is not
  42. ;*  subject to Digital Research's licensing agreement.  The only restriction
  43. ;*  is that it may be used for non-commerical use only, as stated by the
  44. ;*  authors of ZCPR3 and P2DOS.
  45. ;*
  46. ;*  Enjoy!
  47. ;*  9/2/86- 
  48. ;*        Added automatic login of changed disks--no more Control-C 
  49. ;*          when changing disks!  
  50. ;*        Removed P2DOS tie to ZCPR2.  Can now be used with ZCPR3 or 
  51. ;*            (ugh!) normal CP/M.  
  52. ;*        Improved error messages:  
  53. ;*          Disk Error on X: Read Error 
  54. ;*                             Write Error 
  55. ;*                           Non-existent drive 
  56. ;*                             File is Read-Only 
  57. ;*        Fixed delete key--now works like backspace.  No echoing characters 
  58. ;*        Allowed functions 13 and 37 to recognize changes between single and 
  59. ;*            double sided disks on machines which normally require a warm 
  60. ;*            boot when "sidedness" is changed.  Bios modification is needed 
  61. ;*            to support this feature 
  62. ;*        Fixed directory read bug.  Function 37 bug which plagued
  63. ;*            library utility program NULU 1.5 is fixed.                
  64. ;*        Choice of assembly by M80 and compatibles or public domain ZASM 
  65. ;*          System files are read/write, as in CP/M.  Changed from P2DOS 
  66. ;*           mod 0.1 in which system files were R/O
  67. ;*          Deleted P2DOS search path so the more flexible 
  68. ;*           ZCR3 search path could be used
  69. ;*          File split into 3 sections for easy of editing.
  70. ;******************************************************************************
  71. RAMLOW    EQU    00000H            ; START ADDRESS MEMORY
  72. DOSSTRT    EQU    $
  73. P2BIOS    EQU    DOSSTRT+0E00H
  74. ;
  75. ;
  76. ;  P 2 D O S --Z80 REPLACEMENT DISK OPERATING SYSTEM VERSION 1.1
  77. ;
  78. ;
  79. ; NEW FEATURES OF P2DOS ARE:
  80. ; - TEST CONSOLE STATUS AFTER 256 CHARACTERS OUTPUT. THIS MAKES IT POSSIBLE TO
  81. ;   EXIT A PROGRAM, AFTER YOU HIT ACCIDENTALY A KEY, BY TYPING ^S FOLLOWED BY ^C.  
  82. ;  - ERROR ROUTINES GIVE MORE INFORMATION.
  83. ;      P2DOS ERROR ON D: BAD SECTOR
  84. ;             SELECT
  85. ;             FILE R/O
  86. ;             R/O
  87. ;      FUNCTION =XXX (FILE =FILENAME.TYP)
  88. ;    AS YOU CAN SEE THE ERROR IS DISPLAYED WITH THE P2DOS FUNCTION CALL.
  89. ;    THE OPTION 'FILE =FILENAME.TYP' IS ONLY DISPLAYED IF THE P2DOS FUNCTION
  90. ;    USES A FILENAME. AFTER ALL ERRORS A WARM BOOT IS DONE.
  91. ;
  92. ; - PUBLIC FILES ARE SUPPORTED. YOU CAN ACCESS A PUBLIC FILE FROM ANY
  93. ;   USER NUMBER.  THIS MAKES IT POSSIBLE TO PUT FOR EXAMPLE ALL '.COM' IN 
  94. ;   A SPECIAL USER NUMBER AND MAKE ALL THOSE FILES PUBLIC. YOU CAN ACCESS ALL 
  95. ;   THE FILES FROM ANY USER NUMBER ON THE SAME DISK.
  96. ;   A PUBLIC FILE IS A FILE WITH BIT F2 (BIT 7 FROM FILENAME LETTER 2) SET TO
  97. ;   ONE. PUBLIC FILES CAN ONLY BE REFERENCED BY THERE EXACT NAME AND NOT BY WILD
  98. ;   CARD CHARACTERS. 
  99. ;
  100. ; - SEARCH PATH IS IMPLEMENTED JUST AS IN ZCPR2 TO FIND FILES ON OTHER DRIVES
  101. ;   AND IN OTHER USER AREAS. THE FILES MUST BE SYSTEM FILES AND MUST BE
  102. ;   REFERENCED BY THEIR EXACT NAME AS IN PUBLIC FILE NAMES ABOVE.
  103. ;
  104. ; - AUTOMATIC DATE AND TIME STAMP IS IMPLEMENTED. THE CREATION DATE AND TIME
  105. ;    IS SET WHEN THE FUNCTION MAKE IS EXECUTED. THE UPDATE DATE AND TIME IS
  106. ;    SET AS THE FILE IS CLOSED. TO LET THIS FEATURE WORK YOU NEED TO HAVE A 
  107. ;    REAL TIME CLOCK AND THE CORRECT P2BIOS DRIVER ROUTINE. YOU ALSO HAVE TO 
  108. ;    INITIALISE YOUR  DIRECTORY FOR TIME STAMPS.   
  109. ;  - FILE R/O ERROR MESSAGE OCCURS IF ONE OF THE FOLLOWING FILE TYPES IS ACTIVE:
  110. ;     PUBLIC FILE (F2)
  111. ;     FILE R/O    (T1)
  112. ;     SYSTEM FILE (T2)
  113. ;    THIS MEANS THAT A SYSTEM FILE OR PUBLIC FILE CANNOT BE ERASED ACCIDENTALY.
  114. ;
  115. ; - NEW FUNCTION GET TIME (200) IS IMPLEMENTED TO GET THE CORRECT DATE AND TIME.
  116. ;   ENTRY DE IS ADDRESS TO PUT TIME. THE DATE AND TIME RECORD HAS THE FOLLOWING
  117. ;   LAYOUT:
  118. ;    DATE:    DEFS    2    DATE = 1     (SU 01-JAN-1978)
  119. ;                DATE = 65535 (SU 05-JUN-2157)     
  120. ;    HOUR:    DEFS    1    HOUR IN BCD
  121. ;    MINUTE:    DEFS    1    MINUTE IN BCD
  122. ;    SECOND:    DEFS    1    SECOND IN BCD
  123. ;    FUNCTION WORKS ONLY IF CORRECT P2BIOS FUNCTION CALL IS INSTALLED.
  124. ;
  125. ; - NEW FUNCTION SET TIME (201) IS IMPLEMENTED TO SET THE CORRECT DATE AND TIME.
  126. ;   ENTRY DE IS ADDRESS NEW TIME. THE DATE AND TIME LAYOUT IS AS ABOVE.
  127. ;   FUNCTION WORKS ONLY IF CORRECT P2BIOS FUNCTION CALL IS INSTALLED.
  128. ;
  129. ;  - DISK SIZE CAN BE AS LARGE AS 65536*16K=1 048 576 K BYTE=1 G BYTE. 
  130. ;  - FILE SIZE CAN BE AS LARGE AS 32*64*16K=32 768K BYTE=32 M BYTE.  
  131. ;
  132. ; YOU CAN ENABLE/DISABLE THE FUNCTIONS MENTIONED ABOVE WITH THE FOLLOWING DATA
  133. ; AND ADDRESSES.
  134. ;
  135. ; - ENABLE PATH NAME BY PUTTING ADDRESS OF PATH IN P2DOS+11H. IF THIS VALUE IS
  136. ;   0000H NO PATH IS USED. THIS ADDRESS IS NORMALLY SET TO 0040H.
  137. ;
  138. ; - ENABLE P2DOS TIME AND DATE STAMPING BY PUTTING THE CORRECT P2BIOS ADDRESS
  139. ;   AT P2DOS+13H. THIS ADDRESS IS NORMALY SET TO THE P2BIOS CONSOLE STATUS 
  140. ;   FUNCTION. 
  141. ;
  142. ; - YOU CAN ENABLE THE 256 CHARACTER DELAY FUNCTION BY SETTING BIT 0 OF
  143. ;   ADDRESS P2DOS+15H. THIS BIT IS NORMALLY SET TO 1.
  144. ;
  145. ; - YOU CAN ENABLE PUBLIC FILES BY SETTING BIT 1 OF ADDRESS P2DOS+15H TO 1.
  146. ;   THIS BIT IS NORMALLY SET TO 1.
  147. ;
  148. ; ENTRY ADDRESSES P2BIOS
  149. ;
  150. ; FUNC    NAME    INPUT PARAMETERS    RETURNED VALUES
  151. ;  0    BOOT    NONE            NONE
  152. ;  1    WBOOT    NONE            NONE
  153. ;  2    CONST    NONE            A=0FFH IF READY
  154. ;                    A=000H IF NOT READY
  155. ;  3    CONIN    NONE            A=CONSOLE CHARACTER
  156. ;  4    CONOUT    C=CONSOLE CHARACTER    NONE
  157. ;  5    LIST    C=LIST CHARACTER    NONE
  158. ;  6    PUNCH    C=PUNCH CHARACTER    NONE
  159. ;  7    READER    NONE            A=READER CHARACTER
  160. ;  8    HOME    NONE            NONE
  161. ;  9    SELDSK    C=DRIVE NUMBER (0..15)    HL=DISK PARAMETER HEADER ADDRESS
  162. ;        E=INIT SELECT FLAG    HL=0000H IF INVALID DRIVE
  163. ; 10    SETTRK    BC=TRACK NUMBER        NONE
  164. ; 11    SETSEC    BC=SECTOR NUMBER    NONE
  165. ; 12    SETDMA    BC=DMA ADDRESS        NONE
  166. ; 13    READ    NONE            A=00H IF NO ERROR
  167. ;                    A=01H IF ERROR
  168. ; 14    WRITE    C=0 WRITE DATA        A=00H IF NO ERROR
  169. ;        C=1 WRITE DIRECTORY    A=01H IF ERROR
  170. ;        C=2 WRITE NEW DATA
  171. ; 15    LISTST    NONE            A=000H IF READY
  172. ;                    A=0FFH IF NOT READY
  173. ; 16    SECTRN    BC=LOGICAL SECTOR    HL=PHYSICAL SECTOR NUMBER
  174. ;            NUMBER
  175. ;        DE=TRANSLATION TABLE
  176. ;            ADDRESS
  177. ; XX    TIME    C=000H GET TIME        HL=POINTER TO TIME TABLE
  178. ;        C=0FFH UPDATE CLOCK        HL+0:DATE LSB SINCE 1,1,1978
  179. ;        HL=POINTER TO TIME        HL+1:DATE MSB
  180. ;            TABLE            HL+2:HOURS  (BCD)
  181. ;                        HL+3:MINUTES (BCD)
  182. ;                        HL+4:SECONDS (BCD)
  183. ;
  184. BOOT    EQU    P2BIOS+00000H        ; P2 SYSTEM COLD BOOT
  185. WBOOT    EQU    P2BIOS+00003H        ; P2 SYSTEM WARM BOOT
  186. CONST    EQU    P2BIOS+00006H        ; P2 SYSTEM CONSOLE STATUS
  187. CONIN    EQU    P2BIOS+00009H        ; P2 SYSTEM CONSOLE INPUT
  188. CONOUT    EQU    P2BIOS+0000CH        ; P2 SYSTEM CONSOLE OUTPUT
  189. LIST    EQU    P2BIOS+0000FH        ; P2 SYSTEM LIST OUTPUT
  190. PUNCH    EQU    P2BIOS+00012H        ; P2 SYSTEM PUNCH OUTPUT
  191. READER    EQU    P2BIOS+00015H        ; P2 SYSTEM READER INPUT
  192. HOME    EQU    P2BIOS+00018H        ; P2 SYSTEM HOME DISK
  193. SELDSK    EQU    P2BIOS+0001BH        ; P2 SYSTEM SELECT DISK
  194. SETTRK    EQU    P2BIOS+0001EH        ; P2 SYSTEM SELECT TRACK
  195. SETSEC    EQU    P2BIOS+00021H        ; P2 SYSTEM SELECT SECTOR
  196. SETDMA    EQU    P2BIOS+00024H        ; P2 SYSTEM SET DMA ADDRESS
  197. READ    EQU    P2BIOS+00027H        ; P2 SYSTEM READ 128 BYTES
  198. WRITE    EQU    P2BIOS+0002AH        ; P2 SYSTEM WRITE 128 BYTES
  199. LISTST    EQU    P2BIOS+0002DH        ; P2 SYSTEM LIST STATUS
  200. SECTRN    EQU    P2BIOS+00030H        ; P2 SYSTEM SECTOR TRANSLATION
  201. TIME    EQU    P2BIOS+00006H        ; P2 SYSTEM GET/SET TIME
  202.                     ; MUST BE CHANGED IF ROUTINE PRESENT
  203. ;
  204. ;
  205. ; INTERNAL DEFINITIONS
  206. ;
  207. CONTC    EQU    003H            ; KEY TO GENERATE WARM BOOT
  208. CONTE    EQU    005H            ; BREAK LINE
  209. CONTH    EQU    008H            ; BACKSPACE
  210. TAB    EQU    009H            ; TAB
  211. LF    EQU    00AH            ; LINE FEED
  212. CR    EQU    00DH            ; CARRIAGE RETURN
  213. CONTP    EQU    010H            ; SET/RESET PRINT FLAG
  214. CONTR    EQU    012H            ; REPEAT LINE
  215. CONTS    EQU    013H            ; STOP CONSOLE OUTPUT
  216. CONTU    EQU    015H            ; DELETE LINE
  217. CONTX    EQU    018H            ; DELETE LINE (BACKSPACES)
  218. DRVSEP    EQU    03AH            ; DRIVE SEPERATOR (:)
  219. RUBOUT    EQU    07FH            ; DELETE LAST CHAR
  220. ;
  221. MAXCMD    EQU    40            ; NUMBER OF VALID P2DOS COMMANDS
  222. ;
  223. ; START PROGRAM
  224. ;    
  225. P2DOS:
  226. ;
  227. VERS:    DB    000H            ; VERSION NUMBER NOT IMPLEMENTED
  228.     DB    000H            
  229.     DB    000H            
  230.     DB    000H
  231.     DB    000H
  232.     DB    000H
  233. ;
  234. ; START P2DOS
  235. ;
  236. START:    JP    ENTRY            ; JUMP TO ENTRY POINT P2DOS
  237. ;
  238. ; ERROR MESSAGES P2DOS
  239. ;
  240. ;Bad sector message changed to read/write messages-B.H.
  241. ;STBDSC:    DEFW    BADSEC            ; BAD SECTOR MESSAGE
  242. STSEL:    DEFW    SELERR            ; SELECT ERROR
  243. STRO:    DEFW    RDONLY            ; DRIVE READ ONLY
  244. SFILRO:    DEFW    FILRO            ; FILE READ ONLY
  245. SRDERR:    DEFW    RDERR            ; Read error message
  246. SWRTER:    DEFW    WRTERR            ; Write error message
  247. ;
  248. ; EXTERNAL PATH NAME
  249. ;
  250. ;PATH:    DEFW    RAMLOW+00040H        ; PATHNAME FOR OPEN FILE COMMAND
  251. ;Path not supported--B.H.
  252. PATH:    DEFW    RAMLOW+0000H
  253. ;
  254. ; TIME ADDRESS P2BIOS
  255. ;
  256.     IF    DOTIME
  257. TIMEAD:    DEFW    TIME            ; TIME ROUTINE ADDRESS FOR TIME
  258.                         ; AND DATE STAMPS
  259.     ELSE
  260. TIMEAD:    DEFW    CONST
  261.     ENDIF
  262. ;
  263. ; FLAGS FOR SPECIALS
  264. ; BIT 0: PUBLIC FILE ENABLE(1)/DISABLE(0)
  265. ; BIT 1: DELAY 256 CHARACTERS ACTIVE(1)/DISABLE(0)
  266. ;
  267. FLAGS:    DB    0FFH            ; FLAG BITE
  268. ;
  269. ; ENTRY POINT P2DOS COMMANDS
  270. ;
  271. ENTRY:    LD    A,C            ; GET FUNCTION NUMBER
  272.     LD    (FUNCT),A        ; SAVE IT FOR LATER USE
  273.     LD    HL,0            ; SET HL TO ZERO
  274.     LD    (PEXIT),HL        ; CLEAR EXIT CODE
  275.     XOR    A            ; CLEAR A
  276.     LD    (FLDRV),A        ; RESET DRIVE SELECT DONE FLAG
  277.     LD    (RDWR),A        ; RESET READ/WRITE FLAG
  278.     LD    (SPSAVE),SP        ; SAVE STACK POINTER
  279.     LD    SP,P2DOSS        ; GET INTERNAL STACK POINTER
  280.     PUSH    IX            ; SAVE INDEX REGISTER
  281.     PUSH    DE            ; SAVE PARAMETER REGISTER
  282.     POP    IX            ; GET IT BACK IN IX
  283.     LD    HL,P2EXIT        ; GET EXIT ADDRESS P2DOS
  284.     PUSH    HL            ; SAVE IT ON STACK TO RETURN FROM P2DOS
  285.     LD    A,C            ; GET FUNCTION CODE
  286. ;
  287.     IF    DOTIME
  288.     CP    200            ; TEST GET TIME
  289.     JP    Z,GETTIM        ; YES THEN GET TIME
  290.     CP    201            ; TEST SET TIME
  291.     JP    Z,SETTIM        ; YES THEN SET TIME
  292.     ENDIF
  293. ;
  294.     CP    MAXCMD+1        ; TEST GREATER THEN MAXCMD 
  295.     RET    NC            ; IF SO RETURN TO CALLER AND DO NOTHING
  296.     LD    HL,CTABLE        ; LOAD TABLE
  297.     LD    B,0            ; PREPARE 16 BIT ADD
  298.     ADD    HL,BC            ; ADD
  299.     ADD    HL,BC            ; ADD TWICE TO GET WORD VALUE
  300.     LD    A,(HL)            ; GET LSB
  301.     INC    HL            ; POINTER TO MSB
  302.     LD    H,(HL)            ; GET MSB
  303.     LD    L,A            ; SAVE LSB IN L 
  304.     JP    (HL)            ; JUMP TO ROUTINE
  305. ;
  306. ; COMMAND TABLE
  307. ;
  308. ;
  309. ; FUNC    NAME            INPUT PARAMETERS    RETURNED VALUES
  310. ;   0    BOOT            NONE            NONE
  311. ;   1    CONSOLE INPUT        NONE            A=CHARACTER
  312. ;   2    CONSOLE OUTPUT        E=CHARACTER        A=00H
  313. ;   3    READER INPUT        NONE            A=CHARACTER
  314. ;   4    PUNCH OUTPUT        E=CHARACTER        A=00H
  315. ;   5    LIST OUTPUT        E=CHARACTER        A=00H
  316. ;   6    DIRECT CONSOLE I/O    E=0FFH            A=INPUT CHARACTER
  317. ;                            A=00H IF NO CHARACTER 
  318. ;                                PRESENT
  319. ;                E=0FEH            A=CONSOLE STATUS
  320. ;                E=000H..0FDH        A=00H
  321. ;   7    GET I/O BYTE        NONE            A=I/O BYTE (RAMLOW+03H)
  322. ;   8    SET I/O BYTE        E=I/O BYTE        A=00H
  323. ;   9    PRINT STRING        DE=ADDRESS STRING    A=00H
  324. ;  10    READ CONSOLE BUFFER    DE=ADDRESS BUFFER    A=00H
  325. ;  11    GET CONSOLE STATUS    NONE            A=00H IF NO CHARACTER 
  326. ;                                PRESENT
  327. ;                            01H IF CHARACTER PRESENT
  328. ;  12    RETURN VERSION NUMBER    NONE            A=VERSION NUMBER (022H)
  329. ;  13    RESET DISK SYSTEM    NONE            A=00H NO $*.* FILE
  330. ;                            A=FFH $*.* FILE PRESENT
  331. ;  14    SELECT DISK        E=DISK NUMBER        A=00H
  332. ;  15    OPEN FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  333. ;  16    CLOSE FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  334. ;  17    SEARCH FOR FIRST    DE=ADDRESS FCB        A=DIRECTORY CODE
  335. ;  18    SEARCH FOR NEXT        DE=ADDRESS FCB        A=DIRECTORY CODE
  336. ;  19    DELETE FILE        DE=ADDRESS FCB        A=ERROR CODE
  337. ;  20    READ SEQUENTIAL        DE=ADDRESS FCB        A=READ/WRITE CODE
  338. ;  21    WRITE SEQUENTIAL    DE=ADDRESS FCB        A=READ/WRITE CODE
  339. ;  22    MAKE FILE        DE=ADDRESS FCB        A=DIRECTORY CODE
  340. ;  23    RENAME FILE        DE=ADDRESS FCB        A=ERROR CODE
  341. ;  24    RETURN LOGIN VECTOR    NONE            HL=LOGIN VECTOR
  342. ;  25    RETURN CURRENT DISK    NONE            A=CURRENT DISK
  343. ;  26    SET DMA ADDRESS        DE=DMA ADDRESS        A=00H
  344. ;  27    GET ALLOCATION ADDRESS    NONE            HL=ADDRESS ALLOCATION 
  345. ;                                VECTOR
  346. ;  28    WRITE PROTECT DISK    NONE            A=00H
  347. ;  29    GET R/O VECTOR        NONE            HL=R/O VECTOR
  348. ;  30    SET FILE ATTRIBUTES    DE=ADDRESS FCB        A=ERROR CODE
  349. ;  31    GET ADDRESS DPB        NONE            HL=ADDRESS DPB
  350. ;  32    SET/GET USER CODE    E=0FFH            A=USER NUMBER
  351. ;                E=USER NUMBER        A=00H
  352. ;  33    READ RANDOM        DE=ADDRESS FCB        A=READ/WRITE CODE
  353. ;  34    WRITE RANDOM        DE=ADDRESS FCB        A=READ/WRITE CODE
  354. ;  35    COMPUTE FILE SIZE    DE=ADDRESS FCB        A=ERROR CODE
  355. ;  36    SET RANDOM RECORD    DE=ADDRESS FCB        A=00H
  356. ;  37    RESET MULTIPLE DRIVE    DE=MASK            A=00H
  357. ;  38    NOT IMPLEMENTED        NONE            A=00H
  358. ;  39    NOT IMPLEMENTED        NONE            A=00H
  359. ;  40    WRITE RANDOM WITH    DE=ADDRESS FCB        A=READ/WRITE CODE
  360. ;     ZERO FILL
  361. ; 200    GET TIME        DE=ADDRESS TO PUT TIME    A=00H
  362. ; 201    SET TIME        DE=ADDRESS TIME        A=00H
  363. ;
  364. ; DIRECTORY CODE : A=00H,01H,02H,03H IF NO ERROR
  365. ;                  A=0FFH IF ERROR
  366. ; ERROR CODE     : A=00H IF NO ERROR
  367. ;                  A=0FFH IF ERROR
  368. ; READ/WRITE CODE: A=00H IF NO ERROR
  369. ;           A=01H READ  => END OF FILE
  370. ;             WRITE => DIRECTORY FULL
  371. ;           A=02H DISK FULL
  372. ;
  373. CTABLE:    DEFW    WBOOT            ; WARM BOOT 
  374.     DEFW    RDCON            ; CONSOLE INPUT
  375.     DEFW    BWRCON            ; CONSOLE OUTPUT
  376.     DEFW    RDRDR            ; READER INPUT
  377.     DEFW    WPUNCH            ; PUNCH OUTPUT
  378.     DEFW    WLIST            ; LIST OUTPUT
  379.     DEFW    DCIO            ; DIRECT CONSOLE I/O
  380.     DEFW    GIOST            ; GET I/O BYTE
  381.     DEFW    SIOST            ; SET I/O BYTE
  382.     DEFW    MESS            ; PRINT STRING
  383.     DEFW    RDBUF            ; READ CONSOLE BUFFER
  384.     DEFW    TSTCS            ; GET CONSOLE STATUS
  385.     DEFW    CMND12            ; RETURN VERSION NUMBER
  386.     DEFW    CMND13            ; RESET DISK SYSTEM
  387.     DEFW    CMND14            ; SELECT DISK
  388.     DEFW    CMND15            ; OPEN FILE
  389.     DEFW    CMND16            ; CLOSE FILE
  390.     DEFW    CMND17            ; SEARCH FOR FIRST
  391.     DEFW    CMND18            ; SEARCH FOR NEXT
  392.     DEFW    CMND19            ; DELETE FILE
  393.     DEFW    CMND20            ; READ SEQUENTIAL
  394.     DEFW    CMND21            ; WRITE SEQUENTIAL
  395.     DEFW    CMND22            ; MAKE FILE
  396.     DEFW    CMND23            ; RENAME FILE
  397.     DEFW    CMND24            ; RETURN LOGIN VECTOR
  398.     DEFW    CMND25            ; RETURN CURRENT DISK
  399.     DEFW    CMND26            ; SET DMA ADDRESS
  400.     DEFW    CMND27            ; GET ADDRESS ALLOCATION VECTOR
  401.     DEFW    CMND28            ; WRITE PROTECT DISK
  402.     DEFW    CMND29            ; GET R/O VECTOR
  403.     DEFW    CMND30            ; SET FILE ATTRIBUTES
  404.     DEFW    CMND31            ; GET ADDRESS DISK PARAMETER HEADER(DPH) 
  405.     DEFW    CMND32            ; GET/SET USER CODE
  406.     DEFW    CMND33            ; READ RANDOM
  407.     DEFW    CMND34            ; WRITE RANDOM
  408.     DEFW    CMND35            ; COMPUTE FILE SIZE
  409.     DEFW    CMND36            ; SET RANDOM RECORD
  410.     DEFW    CMND37            ; RESET MULTIPLE DRIVE
  411.     DEFW    DUMMY            ; NOT IMPLEMENTED 
  412.     DEFW    DUMMY            ; NOT IMPLEMENTED 
  413.     DEFW    CMND40            ; WRITE RANDOM WITH ZERO FILL
  414. ;
  415. ; I/O ROUTINES
  416. ;
  417. ; P2DOS CONSOLE INPUT
  418. ;
  419. ; READ CHARACTER FROM CONSOLE AND ECHO
  420. ;  IF CHAR=CR,LF,TAB,CONTH OR >=SPACE
  421. ;
  422. RDCON:    CALL    GETCH            ; GET CHARACTER
  423.     CALL    TSTCH            ; TEST IF CR,LF,TAB,CONTH OR >=SPACE
  424.     JR    C,EXIT            ; NO THEN EXIT
  425.     CALL    WRCON            ; ECHO CHARACTER
  426. EXIT:    LD    (PEXIT),A        ; RETURN CHARACTER 
  427. DUMMY:    RET                ; AND EXIT P2DOS
  428. ;
  429. ; P2DOS WRITE CONSOLE
  430. ;
  431. BWRCON:    LD    A,E            ; COPY CHARACTER
  432.     JR    WRCON            ; AND OUTPUT IT
  433. ;
  434. ; READ READER
  435. ;
  436. RDRDR:    CALL    READER            ; GET CHARACTER FROM READER
  437.     JR    EXIT            ; AND RETURN IT TO CALLER 
  438. ;
  439. ; WRITE PUNCH
  440. ;
  441. WPUNCH:    LD    C,E            ; COPY CHARACTER
  442.     JP    PUNCH            ; AND OUTPUT IT TO PUNCH DEVICE
  443. ;
  444. ; WRITE LIST
  445. ;
  446. WLIST:    LD    C,E            ; COPY CHARACTER
  447.     JP    LIST            ; AND OUTPUT IT TO LIST DEVICE
  448. ;
  449. ; DIRECT CONSOLE INPUT/OUTPUT
  450. ;
  451. DCIO:    LD    C,E            ; COPY CHARACTER
  452.     INC    E            ; TEST IF 0FFH
  453.     JR    Z,DCIO0            ; YES DO INPUT
  454.     INC    E            ; TEST IF 0FEH
  455.     JP    NZ,CONOUT        ; NO THEN OUTPUT CHARACTER
  456.     CALL    CONST            ; GET CONSOLE STATUS
  457.     JR    EXIT            ; AND RETURN IT TO CALLER
  458. DCIO0:    CALL    CONST            ; GET CONSOLE STATUS
  459.     OR    A            ; TEST IT
  460.     RET    Z            ; EXIT IF NO CHARACTER PRESENT
  461.     CALL    CONIN            ; GET CHARACTER
  462.     JR    EXIT            ; AND RETURN IT TO CALLER
  463. ;
  464. ; GET I/O STATUS BYTE
  465. ;
  466. GIOST:    LD    A,(RAMLOW+00003H)    ; GET I/O BYTE FROM RAM
  467.     JR    EXIT            ; AND RETURN IT TO CALLER
  468. ;
  469. ; SET I/O STATUS BYTE
  470. ;
  471. SIOST:    LD    A,E            ; COPY I/O BYTE
  472.     LD    (RAMLOW+00003H),A    ; AND SAVE IT IN RAM
  473.     RET                ; EXIT TO CALLER
  474. ;
  475. ; TEST CONSOLE STATUS
  476. ;
  477. TSTCS:    CALL    GCONST            ; GET CONSOLE STATUS
  478.     JR    EXIT            ; AND RETURN IT TO CALLER
  479. ;
  480. ; OUTPUT CHAR (CONTROL CHAR = ^CHAR)
  481. ;
  482. OUTCH:    CALL    TSTCH            ; TEST IT CR,LF,TAB,CONTH OR >=SPACE
  483.     JR    NC,WRCON        ; YES THEN JUMP
  484.     PUSH    AF            ; SAVE CHARACTER
  485.     LD    A,'^'            ; LOAD A WITH '^' 
  486.     CALL    WRCON            ; OUTPUT IT
  487.     POP    AF            ; GET CHARACTER BACK
  488.     PUSH    AF            ; SAVE IT AGAIN
  489.     ADD    A,'A'-1            ; ADD OFFSET
  490.     CALL    WRCON            ; OUTPUT IT
  491.     POP    AF            ; GET CHARACTER
  492.     RET                ; RETURN TO CALLER
  493. ;
  494. ; ECHO CR,LF
  495. ;
  496. CROUT:    LD    A,CR            ; A=CARRIAGE RETURN
  497.     CALL    WRCON            ; OUTPUT IT
  498.     LD    A,LF            ; A=LINE FEED
  499.                     ; FALL THROUGH TO OUTPUT ROUTINE
  500. ;
  501. ; WRITE CHARACTER ON CONSOLE
  502. ;
  503. WRCON:    CP    TAB            ; TEST IF TAB
  504.     JR    NZ,WRCON1        ; NO THEN JUMP
  505. WRCON0:    LD    A,' '            ; EXPAND TAB WITH SPACES
  506.     CALL    WRCON            ; WRITE SPACE
  507.     LD    A,(TABCNT)        ; GET TAB COUNT
  508.     AND    7            ; TEST IF DONE
  509.     JR    NZ,WRCON0        ; NO THEN REPEAT
  510.     LD    A,TAB            ; RETURN TAB
  511.     RET                ; RETURN TO CALLER
  512. WRCON1:    PUSH    AF            ; SAVE CHARACTER
  513.     CALL    GCONST            ; TEST STATUS AND CONTS/CONTC
  514.     POP    AF            ; GET CHARACTER BACK
  515.     PUSH    AF            ; SAVE IT AGAIN
  516.     LD    C,A            ; COPY IT
  517.     CALL    CONOUT            ; OUTPUT IT
  518.     POP    AF            ; GET CHARACTER BACK
  519.     PUSH    AF            ; SAVE IT AGAIN
  520.     LD    C,A            ; COPY IT
  521.     LD    A,(FCONTP)        ; GET PRINTER ECHO FLAG 
  522.     OR    A            ; TEST IT
  523.     CALL    NZ,LIST            ; NON ZERO => OUTPUT CHAR TO PRINTER
  524.     LD    A,(FLAGS)        ; GET FLAG BYTE
  525.     BIT    1,A            ; TEST DELAY 256 BYTES ACTIVE
  526.     JR    Z,WRCON2        ; NO THEN EXIT
  527.     LD    HL,DELAY        ; GET DELAY COUNTER
  528.     XOR    A            ; A=0 
  529.     OR    (HL)            ; TEST COUNTER=0
  530.     JR    Z,WRCON2        ; YES THEN EXIT
  531.     DEC    (HL)            ; ELSE DECREMENT COUNTER
  532. WRCON2:    POP    AF            ; RESTORE CHARACTER
  533.                     ; FALL THROUGH TO COUNT ROUTINE
  534. ;
  535. ; COUNT CHARACTERS IN LINE
  536. ;
  537. COUNTC:    LD    HL,TABCNT        ; GET POINTER TO TAB COUNTER
  538. ;Part of delete key fix--B.H.
  539. ;    CP    RUBOUT            ; TEST IF CHARACTER = RUBOUT
  540. ;    RET    Z            ; YES NO UPDATE TAB COUNTER
  541.     INC    (HL)            ; INCREMENT TAB COUNTER
  542.     CP    ' '            ; TEST IF CHAR >= ' '
  543.     RET    NC            ; YES, NORMAL CHARACTER THEN EXIT
  544.     DEC    (HL)            ; CONTROL CHARACTER, DECREMENT TAB COUNT
  545.     CP    CONTH            ; TEST BACKSPACE
  546.     JR    NZ,COUNT0        ; NO BACKSPACE THEN JUMP
  547.     DEC    (HL)            ; DECREMENT TAB COUNTER
  548.     RET                ; AND EXIT
  549.     CP    RUBOUT
  550.     JR    NZ,COUNT0
  551.     DEC    (HL)
  552.     RET
  553. COUNT0:    CP    CR            ; TEST CARRIAGE RETURN
  554.     JR    NZ,COUNT1        ; NO THEN JUMP
  555.     LD    (HL),0            ; RESET TAB COUNT
  556.     RET                ; AND EXIT
  557. COUNT1:    CP    TAB            ; TEST TAB CHARACTER
  558.     RET    NZ            ; NO THEN EXIT
  559.     PUSH    AF            ; SAVE CHARACTER
  560.     LD    A,(HL)            ; GET TAB COUNT
  561.     ADD    A,8            ; ADVANCE IT 8 POSITION
  562.     AND    0F8H            ; SET IT TO NEXT TAB POSITION
  563.     LD    (HL),A            ; SAVE IT
  564.     POP    AF            ; RESTORE CHARACTER 
  565.     RET                ; AND EXIT
  566. ;
  567. ; GET CHARACTER FROM CONSOLE
  568. ;
  569. GETCH:    LD    HL,LASTCH        ; GET POINTER TO LAST INPUT CHARACTER
  570.     LD    A,(HL)            ; GET CHARACTER
  571.     LD    (HL),0            ; RESET LAST CHARACTER
  572.     OR    A            ; TEST IF CHARACTER PRESENT
  573.     RET    NZ            ; RETURN IF SO
  574.     JP    CONIN            ; ELSE GET CHARACTER
  575. ;
  576. ; GET CONSOLE STATUS
  577. ;
  578. GCONST:    LD    A,(DELAY)        ; GET 256 BYTES DELAY
  579.     OR    A            ; TEST IT
  580.     JR    NZ,GCONS0        ; NON ZERO, DELAY STIL ACTIVE OR DISABLED
  581.     CALL    CONST            ; GET CONSOLE STATUS
  582.     AND    1            ; TEST IT
  583.     JR    NZ,GCONS1        ; NON ZERO THEN GET CHARACTER
  584. GCONS0:    LD    A,(LASTCH)        ; GET LAST CHARACTER
  585.     OR    A            ; TEST IT
  586.     JR    NZ,GCONS3        ; NON ZERO THEN CHARACTER PRESENT
  587.     CALL    CONST            ; GET CONSOLE STATUS
  588.     AND    1            ; TEST IT
  589.     RET    Z            ; RETURN IF NO CHARACTER PRESENT
  590. GCONS1:    CALL    CONIN            ; GET CHARACTER
  591.     CP    CONTS            ; TEST STOP CHARACTER
  592.     JR    NZ,GCONS2        ; NOT THEN EXIT CHARACTER
  593.     CALL    CONIN            ; GET NEXT CHARACTER
  594.     CP    CONTC            ; TEST IF USER WANTS TO EXIT
  595.     JP    Z,RAMLOW+00000H        ; YES THEN WARM BOOT
  596.     JR    GCONST            ; TEST AGAIN
  597. GCONS2:    LD    (LASTCH),A        ; SAVE CHARACTER
  598.     LD    A,0FFH            ; SET DELAY COUNTER
  599.     LD    (DELAY),A        ; AND SAVE IT
  600. GCONS3:    LD    A,1            ; CHARACTER PRESENT CODE
  601.     RET                ; RETURN TO CALLER
  602. ;
  603. ; TEST CHARACTER
  604. ;  EXIT CARRY=0: CR,LF,TAB,CONTH OR >=SPACE
  605. ;       CARRY=1: ALL OTHER CHARACTERS
  606. ;
  607. TSTCH:    CP    CR            ; TEST CARRIAGE RETURN
  608.     RET    Z            ; RETURN IF SO
  609.     CP    LF            ; TEST LINE FEED
  610.     RET    Z            ; RETURN IF SO
  611.     CP    TAB            ; TEST TAB
  612.     RET    Z            ; RETURN IF SO
  613.     CP    CONTH            ; TEST BACKSPACE
  614. ;Added next two lines as a part of delete key fix--B.H.
  615.     RET    Z            ; RETURN IF SO
  616.     CP    RUBOUT
  617.     RET    Z
  618.     CP    ' '            ; TEST >=SPACE
  619.     RET                ; RETURN TO CALLER
  620. ;
  621. ; WRITE BACKSPACE,SPACE,BACKCPACE
  622. ;
  623. WCONTH:    CALL    WCONT0            ; WRITE BACKSPACE
  624.     LD    C,' '            ; LOAD SPACE
  625.     CALL    CONOUT            ; AND OUTPUT IT
  626. WCONT0:    LD    C,CONTH            ; LOAD BACKSPACE
  627.     JP    CONOUT            ; AND OUTPUT IT
  628. ;
  629. ; OUTPUT MESSAGE
  630. ;
  631. MESS:    LD    A,(DE)            ; GET BYTE FROM BUFFER
  632.     CP    '$'            ; TEST LAST BYTE
  633.     RET    Z            ; YES, THEN RETURN TO CALLER
  634.     INC    DE            ; POINT TO NEXT BYTE
  635.     PUSH    DE            ; SAVE POINTER
  636.     CALL    WRCON            ; OUTPUT CHARACTER
  637.     POP    DE            ; RESTORE POINTER
  638.     JR    MESS            ; AND TEST AGAIN
  639. ;
  640. ; AGAIN PRINTS #,CR,LF AND ADVANCES TO TABCX1
  641. ;
  642. AGAIN:    LD    A,'#'            ; LOAD '#'
  643.     CALL    WRCON            ; OUTPUT IT
  644. AGAIN0:    CALL    CROUT            ; OUTPUT CARRIAGE RETURN/LINE FEED
  645. AGAIN1:    LD    HL,TABCNT        ; GET TAB COUNT POINTER
  646.     LD    A,(TABCX1)        ; GET POSITION FIRST CHARACTER LINE
  647.     CP    (HL)            ; CHECK IT
  648.     RET    Z            ; RETURN IF ON SAME POSITION
  649.     LD    A,' '            ; LOAD SPACE
  650.     CALL    WRCON            ; OUTPUT IT
  651.     JR    AGAIN1            ; AND TEST AGAIN
  652. ;
  653. ; DELETE CHAR
  654. ;  ENTRY : HL=START BUFFER-1
  655. ;          B =CHARACTER COUNTER (ALWAYS>0)
  656. ;
  657. DELCH:    DEC    B            ; DECREMENT CHARACTER COUNTER
  658.     LD    A,(TABCNT)        ; GET TAB COUNTER
  659.     PUSH    AF            ; SAVE IT
  660.     PUSH    BC            ; SAVE CHARACTER COUNTER
  661.     LD    A,(TABCX1)        ; GET POSITION FIRST CHARACTER LINE
  662.     LD    (TABCNT),A        ; SAVE IT IN TAB COUNTER
  663. DELCH0:    LD    A,B            ; COPY CHARACTER COUNTER
  664.     OR    A            ; TEST IF 0
  665.     JR    Z,DELCH2        ; YES THEN JUMP
  666.     DEC    B            ; DECREMENT IT
  667.     INC    HL            ; INCREMENT BUFFER POINTER
  668.     LD    A,(HL)            ; GET CHARACTER FROM BUFFER
  669.     PUSH    HL            ; SAVE BUFFER POINTER
  670.     CALL    TSTCH            ; TEST IF CR,LF,TAB,CONTH OR >=SP
  671.     JR    NC,DELCH1        ; YES THEN JUMP
  672.     RRA                ; ELSE MUST BE CONTROL CHARACTER
  673.     CALL    COUNTC            ; COUNT CONTROL CHARACTER TWICE
  674. DELCH1:    CALL    COUNTC            ; COUNT CHARACTER
  675.     POP    HL            ; GET BUFFER POINTER
  676.     JR    DELCH0            ; AND TEST AGAIN
  677. DELCH2:    POP    BC            ; RESTORE CHARACTER COUNTER
  678.     POP    AF            ; AND TAB COUNTER
  679.     PUSH    HL            ; SAVE BUFFER POINTER
  680.     PUSH    BC            ; AND CHARACTER COUNTER
  681.     LD    HL,TABCNT        ; GET TAB COUNTER POINTER
  682.     SUB    (HL)            ; CALCULATE DIFFERENCE
  683. DELCH3:    DEC    A            ; DECREMENT IT
  684.     CP    8            ; COMPARE WITH 8
  685.     JR    NC,DELCH4        ; JUMP IF >=8
  686.     PUSH    AF            ; SAVE DIFFERENCE
  687.     CALL    WCONTH            ; REMOVE CHARACTER END LINE
  688.     POP    AF            ; RESTORE COUNTER
  689.     JR    DELCH3            ; REMOVE MORE CHARACTERS
  690. DELCH4:    POP    BC            ; RESTORE CHARACTER COUNTER
  691.     POP    HL            ; RESTORE BUFFER POINTER
  692.     RET                ; AND RETURN TO CALLER 
  693. ;
  694. ; READ BUFFER
  695. ;
  696. RDBUF:    LD    A,(TABCNT)        ; GET CURRENT POSITION CURSOR
  697.     LD    (TABCX1),A        ; SAVE IT
  698. RDBUF0:    PUSH    IX            ; SAVE START ADDRESS BUFFER
  699.     POP    HL            ; GET IT IN HL
  700.     LD    C,(HL)            ; GET MAXIMUM LINE LENGTH
  701.     INC    HL            ; INCREMENT TO LINE LENGTH POSITION
  702.     LD    B,0            ; CLEAR LINE LENGTH COUNTER
  703.     PUSH    HL            ; SAVE START LINE - 1
  704. RDBUF1:    PUSH    HL            ; SAVE REGISTERS
  705.     PUSH    BC
  706. RDBUF2:    CALL    GETCH            ; GET CHARACTER
  707.     POP    BC            ; RESTORE REGISTERS
  708.     POP    HL
  709.     AND    07FH            ; MASK CHARACTER
  710.     CP    CONTE            ; TEST IF CONTE
  711.     JR    NZ,RDBUF3        ; NOT THEN JUMP 
  712.     PUSH    HL            ; SAVE REGISTERS
  713.     PUSH    BC
  714.     CALL    AGAIN0            ; MOVE CURSOR TO NEXT LINE
  715.     JR    RDBUF2            ; AND GET NEXT CHAR
  716. RDBUF3:    CP    CONTH            ; TEST BACKSPACE
  717.     JR    NZ,RDBUF4        ; NOT THEN JUMP
  718. DOBACK:    LD    A,B            ; TEST IF DELETING CHAR FROM EMPTY LINE
  719.     OR    A
  720.     JR    Z,RDBUF1        ; YES THEN GET NEXT CHAR
  721.     POP    HL            ; GET START LINE
  722.     PUSH    HL            ; AND SAVE IT AGAIN
  723.     CALL    DELCH            ; DELETE CHARACTER
  724.     JR    RDBUF1            ; GET NEXT CHARACTER
  725. RDBUF4:    CP    CONTP            ; TEST PRINT ENABLE/DISABLE
  726.     JR    NZ,RDBUF6        ; NOT THEN JUMP
  727.     LD    A,(FCONTP)        ; COMPLEMENT PRINT FLAG
  728.     CPL
  729.     LD    (FCONTP),A
  730. RDBUF5:    JR    RDBUF1            ; AND GET NEXT CHARACTER
  731. RDBUF6:    CP    CONTR            ; TEST REPEAT LINE
  732.     JR    NZ,RDBUFA        ; NOT THEN JUMP
  733.     PUSH    BC            ; SAVE REGISTERS
  734.     CALL    AGAIN            ; MOVE CURSOR TO NEXT LINE
  735.     POP    BC            ; RESTORE REGISTERS
  736.     POP    HL            ; GET START LINE
  737.     PUSH    HL            ; SAVE IT AGAIN
  738.     PUSH    BC            ; SAVE LINE COUNTER/MAXIMUM LINE LENGTH
  739. RDBUF7:    LD    A,B            ; TEST LAST CHARACTER ECHOED 
  740.     OR    A
  741.     JR    Z,RDBUF8        ; YES THEN JUMP
  742.     INC    HL            ; INCREMENT POINTER
  743.     LD    A,(HL)            ; GET CHARACTER
  744.     DEC    B            ; DECREMENT LINE COUNTER
  745.     PUSH    HL            ; SAVE REGISTERS
  746.     PUSH    BC
  747.     CALL    OUTCH            ; OUTPUT CHARACTER
  748.     POP    BC            ; RESTORE REGISTERS
  749.     POP    HL
  750.     JR    RDBUF7            ; AND TEST END LINE
  751. RDBUF8:    POP    BC            ; RESTORE LINE COUNTER/MAX LINE LENGTH
  752. RDBUF9:    JR    RDBUF5            ; AND GET NEXT CHAR
  753. RDBUFA:    CP    CONTU            ; TEST DELETE LINE
  754.     JR    NZ,RDBUFC        ; NOT THEN JUMP
  755.     POP    HL            ; GET START LINE
  756.     CALL    AGAIN            ; MOVE CURSOR TO NEXT LINE
  757. RDBUFB:    JR    RDBUF            ; AND START ROUTINE AGAIN
  758. RDBUFC:    CP    CONTX            ; TEST DELETE LINE
  759.     JR    NZ,RDBUFE        ; NOT THEN JUMP
  760. RDBUFD:    POP    HL            ; GET START LINE
  761.     LD    A,B            ; TEST IF LAST CHARACTER DELETED
  762.     OR    A
  763.     JR    Z,RDBUFB        ; YES START ROUTINE AGAIN
  764.     PUSH    HL            ; SAVE POINTER
  765.     CALL    DELCH            ; DELETE LAST CHARACTER LINE
  766.     JR    RDBUFD            ; TEST LAST CHARACTER DELETED
  767. RDBUFE:    CP    RUBOUT            ; TEST DELETE LAST CHARACTER
  768.     JR    NZ,RDBUFF        ; NOT THEN JUMP
  769.     JR    DOBACK            ; Part of delete key fix
  770. ;Remove code for echoing deleted character--B.H.
  771. ;    LD    A,B            ; TEST FIRST CHARACTER LINE
  772. ;    OR    A
  773. ;    JR    Z,RDBUF9        ; YES, DO NOT DELETE
  774. ;    LD    A,(HL)            ; GET LAST CHARACTER
  775. ;    DEC    HL            ; DECREMENT POINTER LINE
  776. ;    DEC    B            ; DECREMENT LINE COUNTER
  777. ;    JR    RDBUFG            ; ECHO LAST CHARACTER
  778. RDBUFF:    CP    CR            ; TEST CARRIAGE RETURN
  779.     JR    Z,RDBUFI        ; YES, THEN EXIT
  780.     CP    LF            ; TEST LINE FEED
  781.     JR    Z,RDBUFI        ; YES THEN EXIT
  782.     INC    HL            ; INCREMENT POINTER
  783.     LD    (HL),A            ; AND SAVE CHARACTER
  784.     INC    B            ; INCREMENT LINE COUNTER
  785. RDBUFG:    PUSH    HL            ; SAVE REGISTERS
  786.     PUSH    BC
  787.     CALL    OUTCH            ; ECHO CHARACTER
  788.     POP    BC            ; RESTORE REGISTERS
  789.     POP    HL
  790.     CP    CONTC            ; TEST WARM BOOT
  791.     LD    A,B            ; GET LINE COUNT
  792.     JR    NZ,RDBUFH        ; NO WARM BOOT THEN JUMP
  793.     CP    1            ; TEST CONTC IS FIRST CHARACTER LINE 
  794.     JP    Z,RAMLOW+00000H        ; YES THEN EXECUTE WARM BOOT
  795. RDBUFH:    CP    C            ; TEST LINE LENGTH=MAXIMUM LINE LENGTH
  796.     JR    NZ,RDBUF9        ; NOT THEN GET NEXT CHARACTER
  797. RDBUFI:    POP    HL            ; GET START LINE - 1
  798.     LD    (HL),B            ; SAVE LINE COUNTER
  799.     LD    A,CR            ; LOAD CARRIAGE RETURN
  800.     JP    WRCON            ; AND ECHO IT
  801. ;
  802. ;******************************************************************************
  803. ;*                                          *
  804. ;*     DISK FUNCTIONS                                  *
  805. ;*                                          *
  806. ;******************************************************************************
  807. ;
  808. ; RETURN VERSION NUMBER
  809. ;
  810. CMND12:    LD    A,22H            ; SET VERSION NUMBER
  811.     JR    CMD25A            ; AND EXIT
  812. ;
  813. ; RESET DISK SYSTEM
  814. ;
  815. CMND13:    
  816.     IF    RESDSK
  817. ;detect change between single and double sided disks if this function is
  818. ;supported.--B.H.
  819.     CALL    SETDSK        
  820.     ENDIF    
  821.     LD    HL,0            ; LOAD ZERO
  822.     LD    (LOGIN),HL        ; ALL DRIVES LOGED OUT
  823.     LD    (DSKRO),HL        ; ALL DRIVES READ/WRITE
  824.     LD    HL,RAMLOW+00080H    ; SET UP DMA ADDRESS
  825.     LD    (DMA),HL        ; AND SAVE IT
  826.     CALL    STDMA            ; DO P2BIOS CALL
  827.     XOR    A            ; SET DEFAULT DRIVE = 'A'
  828.     LD    (DEFDRV),A        ; SAVE IT
  829.     CALL    SELDK            ; SELECT DRIVE 'A'
  830.     LD    A,(SUBFLG)        ; GET SUBMIT FLAG
  831.     JR    CMD25A            ; EXIT
  832. ;
  833. ; SEARCH FOR FILE
  834. ;
  835. CMND17:    
  836.     CALL    SELDRV            ; SELECT DRIVE FROM FCB
  837.     LD    A,(IX+0)        ; GET DRIVE NUMBER FROM FCB
  838.     SUB    '?'            ; TEST IF '?'
  839.     JR    Z,CMD17B        ; IF SO ALL ENTRIES MATCH
  840.     LD    A,(IX+14)        ; GET SYSTEM BYTE
  841.     CP    '?'            ; TEST IF '?' 
  842.     JR    Z,CMD17A        ; YES, JUMP
  843.     LD    (IX+14),0        ; LOAD SYSTEM BYTE WITH ZERO
  844. CMD17A:    LD    A,15            ; TEST FIRST 15 ITEMS IN FCB
  845. CMD17B:    CALL    SEARCH            ; DO SEARCH
  846. CMD17C:    LD    HL,(DIRBUF)        ; COPY DIRECTORY BUFFER 
  847.     LD    DE,(DMA)        ; TO DMA ADDRESS
  848.     LD    BC,128            ; DIRECTORY=128 BYTES 
  849.     LDIR
  850.     RET                ; EXIT
  851. ;
  852. ; SEARCH FOR NEXT OCCURENCE FILE
  853. ;
  854. CMND18:    LD    IX,(DCOPY)        ; GET LAST FCB USED BY SEARCH
  855.     CALL    SELDRV            ; SELEXT DRIVE FROM FCB
  856.     CALL    SEARCN            ; SEARCH NEXT FILE MATCH
  857.     JR    CMD17C            ; AND COPY DIRECTORY TO DMA ADDRESS
  858. ;
  859. ; DELETE FILE
  860. ;
  861. CMND19:    
  862.     CALL    SELDRV            ; SELECT DRIVE FROM FCB
  863.     CALL    DELETE            ; DELETE FILE
  864. CMD19A:    LD    A,(SEAREX)        ; GET EXIT BYTE 00=FILE FOUND,0FFH NOT
  865.     JR    CMD25A            ; AND EXIT
  866. ;
  867. ; RENAME FILE
  868. ;
  869. CMND23:    
  870.     CALL    SELDRV            ; SELECT DRIVE FROM FCB
  871.     CALL    RENAM            ; RENAME FILE
  872.     JR    CMD19A            ; AND EXIT
  873. ;
  874. ; RETURN LOGIN VECTOR
  875. ;
  876. CMND24:    LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  877. CMD24A:    LD    (PEXIT),HL        ; SAVE IT
  878.     RET                ; AND EXIT
  879. ;
  880. ; RETURN CURRENT DRIVE
  881. ;
  882. CMND25:    LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  883. CMD25A:    JP    EXIT            ; AND EXIT
  884. ;
  885. ; RETURN ALV VECTOR
  886. ;
  887. CMND27:    LD    HL,(ALV)        ; GET ALLOCATION VECTOR
  888.     JR    CMD24A            ; AND EXIT
  889. ;
  890. ; RETURN DISK R/O VECTOR
  891. ;
  892. CMND29:    LD    HL,(DSKRO)        ; GET DISK R/O VECTOR
  893.     JR    CMD24A            ; AND EXIT
  894. ;
  895. ; CHANGE STATUS
  896. ;
  897. CMND30:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  898.     CALL    CSTAT            ; CHANGE STATUS
  899.     JR    CMD19A            ; AND EXIT
  900. ;
  901. ; RETURN DRIVE TABLE
  902. ;
  903. CMND31:    LD    HL,(IXP)        ; GET DRIVE TABLE
  904.     JR    CMD24A            ; AND EXIT
  905. ;
  906. ; SET/GET USER CODE
  907. ;
  908. CMND32:    LD    A,E            ; GET USER CODE
  909.     INC    A            ; TEST IF 0FFH
  910.     LD    A,(USER)        ; GET OLD USER CODE
  911.     JR    Z,CMD25A        ; IF 0FFH THEN EXIT
  912.     LD    A,E            ; GET NEW USER CODE
  913.     AND    01FH            ; MASK IT
  914.     LD    (USER),A        ; SAVE IT
  915.     RET                ; AND EXIT
  916. ;
  917. ; COMPUTE FILE SIZE COMMAND
  918. ;
  919. CMND35:    CALL    SELDRV            ; SELECT DRIVE FROM FCB
  920.     CALL    FILSZ            ; COMPUTE FILE SIZE
  921.     JR    CMD19A            ; AND EXIT
  922. ;
  923. ; SET RANDOM RECORD COUNT
  924. ;
  925. CMND36:    LD    HL,32            ; SET POINTER TO NEXT RECORD
  926.     CALL    CALRRC            ; CALCULATE RANDOM RECORD COUNT
  927. LDRRC:    LD    (IX+33),D        ; AND SAVE RANDOM RECORD COUNT
  928.     LD    (IX+34),C
  929.     LD    (IX+35),B
  930.     RET                ; AND EXIT
  931. ;
  932. ; RESET MULTIPLE LOGIN DRIVE
  933. ;
  934. CMND37:    
  935.     LD    A,E            ; GET MASK LSB
  936.     CPL                ; COMPLEMENT IT
  937.     LD    E,A 
  938.     LD    A,D            ; GET MASK MSB
  939.     CPL                ; COMPLEMENT IT
  940.     LD    D,A
  941.     LD    HL,(LOGIN)        ; GET LOGIN VECTOR
  942.     LD    A,E            ; MASK LOGIN VECTOR
  943.     AND    L            ; LSB
  944.     LD    L,A
  945.     LD    A,D            ; MASK LOGIN VECTOR
  946.     AND    H            ; MSB
  947.     LD    H,A
  948.     LD    (LOGIN),HL        ; SAVE LOGIN VECTOR
  949.     EX    DE,HL            ; USE LOGIN VECTOR AS MASK
  950.     LD    HL,(DSKRO)        ; GET DRIVE R/O VECTOR
  951.     LD    A,E            ; MASK DRIVE R/O VECTOR
  952.     AND    L            ; LSB
  953.     LD    L,A
  954.     LD    A,D            ; MASK DRIVE R/O VECTOR
  955.     AND    H            ; LSB
  956.     LD    H,A
  957.     LD    (DSKRO),HL        ; SAVE DRIVE R/O VECTOR
  958. ;
  959. DBL:    EXX
  960.     IF    RESDSK
  961.     CALL    SETDSK
  962.     ENDIF
  963.     CALL    CLRDSK
  964.     EXX
  965.     RET
  966. ;
  967. ;******************************************************************************
  968. ;*                                          *
  969. ;*     ERROR ROUTINES                                  *
  970. ;*                                          *
  971. ;******************************************************************************
  972. ;
  973. ; Bad sector error message replaced by read/write error messages--B.H.
  974. ; BAD SECTOR ERROR
  975. ;
  976. ;BADSEC:    LD    DE,MBADSC        ; LOAD BAD SECTOR MESSAGE
  977. ;    JR    DERROR            ; AND DISPLAY ERROR
  978. ;
  979. ; SELECT ERROR
  980. ;
  981. SELERR:    LD    DE,MSEL            ; LOAD SELECT ERROR MESSAGE
  982.     JR    DERROR            ; AND DIPLAY ERROR
  983. ;
  984. ; FILE READ ONLY ERROR
  985. ;
  986. FILRO:    LD    DE,MFILRO        ; LOAD FILE R/O MESSAGE
  987.     LD    A,0FFH            ; SET FILE R/O MESSAGE FLAG
  988.     JR    ERROR            ; AND DISPLAY ERROR
  989. ;
  990. ; Read Error Message--B.H.
  991. ;
  992. RDERR:    LD    DE,MRDERR
  993.     JR    DERROR
  994. ;
  995. ; Write Error Message--B.H.
  996. WRTERR:    LD    DE,MWRTER
  997.     JR    DERROR
  998. ;
  999. ; DRIVE READ ONLY ERROR
  1000. ;
  1001. RDONLY:    LD    DE,MRO            ; LOAD DRIVE R/O MESSAGE
  1002. DERROR:    XOR    A            ; SET NO FILE R/O MESSAGE
  1003. ;
  1004. ;
  1005. ; DISPLAY ERROR MESSAGE
  1006. ;
  1007. ; P2DOS ERROR ON D: ERROR MESSAGE
  1008. ; FUNCTION = NN  [FILE = FILENAME.TYP]
  1009. ;
  1010. ERROR:    LD    C,A            ; SAVE FILE R/O MESSAGE FLAG
  1011.     PUSH    BC
  1012.     PUSH    DE            ; SAVE ERROR MESSAGE POINTER
  1013.     CALL    CROUT            ; DIPLAY CR/LF
  1014.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  1015.     ADD    A,'A'            ; MAKE ASCII
  1016.     LD    (MDRIVE),A        ; SAVE IT
  1017.     LD    DE,MBERR        ; LOAD MESSAGE "P2DOS ERROR ON D:"
  1018.     CALL    MESS            ; DISPLAY MESSAGE
  1019.     POP    DE            ; GET ERROR MESSAGE POINTER
  1020.     CALL    MESS            ; DISPLAY MESSAGE
  1021.     CALL    CROUT            ; DISPLAY CR/LF
  1022.     LD    DE,MBFUNC        ; LOAD MESSAGE "FUNCTION ="
  1023.     CALL    MESS            ; DISPLAY MESSAGE
  1024.     LD    A,(FUNCT)        ; GET FUNCTION NUMBER
  1025.     PUSH    AF            ; SAVE IT
  1026.     LD    BC,100            ; DISPLAY NUMBER / 100
  1027.     CALL    NUM
  1028.     LD    C,10            ; DISPLAY NUMBER / 10
  1029.     CALL    NUM
  1030.     LD    BC,101H            ; ALWAYS DISPLAY NUMBER / 1
  1031.     CALL    NUM
  1032.     POP    AF            ; GET FUNCTION NUMBER
  1033.     POP    BC            ; GET FILE R/O FLAG
  1034.     CP    15            ; TEST IF FCB USED IN COMMAND
  1035.     JR    C,ERROR3
  1036.     CP    24
  1037.     JR    C,ERROR1
  1038.     CP    30
  1039.     JR    Z,ERROR1
  1040.     CP    33
  1041.     JR    C,ERROR3
  1042.     CP    37
  1043.     JR    C,ERROR1
  1044.     CP    40
  1045.     JR    NZ,ERROR3
  1046. ERROR1:    PUSH    IX            ; YES THEN DISPLAY "FILE ="
  1047.     SUB    19            ; TEST DELETE FILE FUNCTION
  1048.     JR    NZ,ERROR2        ; NOT THEN JUMP
  1049.     OR    C            ; TEST FILE R/O FLAG
  1050.     JR    Z,ERROR2        ; NO FILE R/O THEN JUMP
  1051.     CALL    CALDIR            ; GET FCB FROM DIRECTORY BUFFER
  1052.     EX    (SP),HL            ; SAVE IT
  1053. ERROR2:    LD    DE,MFILE        ; GET MESSAGE " FILE ="
  1054.     CALL    MESS            ; DISPLAY MESSAGE
  1055.     POP    HL            ; GET POINTER FCB
  1056.     LD    B,8            ; DISPLAY FISRT 8 CHARACTERS
  1057.     CALL    FILENM
  1058.     LD    A,'.'            ; LOAD '.'
  1059.     PUSH    HL            ; SAVE FCB POINTER
  1060.     CALL    WRCON            ; ECHO IT
  1061.     POP    HL            ; RESTORE FCB POINTER
  1062.     LD    B,3            ; DISPLAY LAST 3 CHARACTERS 
  1063.     CALL    FILENM
  1064. ERROR3:    CALL    GCONST            ; TEST IF CHARACTER PRESENT
  1065.     OR    A
  1066.     JR    Z,ERROR4        ; NO THEN JUMP
  1067.     CALL    GETCH            ; GET CHARACTER
  1068.     JR    ERROR3            ; AND TEST AGAIN
  1069. ERROR4:    CALL    GETCH            ; GET CHARACTER
  1070. ;P2DOS had a bug which did not allow the user to ignore a read/write error
  1071. ;by hitting a key other than Control-C. This is the fix.--B.H.
  1072.     PUSH    AF            ; Save it
  1073.     LD    A,(RETFLG)        ; Get RETFLG
  1074.     OR    A
  1075.     JR    Z,ERROR5
  1076.     POP    AF
  1077.     CP    CONTC
  1078.     RET    NZ
  1079. ERROR5:    JP    RAMLOW+00000H        ; AND DO WARM BOOT
  1080. ;
  1081. ; DISPLAY NUMBER
  1082. ;
  1083. NUM:    LD    D,0FFH            ; LOAD NUMBER -1
  1084. NUM1:    INC    D            ; INCREMENT NUMBER
  1085.     SUB    C            ; DIVIDE BY C
  1086.     JR    NC,NUM1            ; NOT FINISHED THEN LOOP
  1087.     ADD    A,C            ; RESTORE LAST VALUE
  1088.     PUSH    AF            ; SAVE IT
  1089.     LD    A,D            ; TEST IF "0"
  1090.     OR    B            ; AND IF LEADING ZERO
  1091.     JR    Z,NUM2            ; YES, THEN EXIT 
  1092.     LD    B,D            ; SET NO LEADING ZERO 
  1093.     LD    A,D            ; GET NUMBER
  1094.     ADD    A,'0'            ; MAKE ASCII
  1095.     PUSH    BC            ; SAVE REGISTERS
  1096.     CALL    WRCON            ; ECHO NUMBER
  1097.     POP    BC            ; RESTORE REGISTERS
  1098. NUM2:    POP    AF            ; RESTORE NUMBER
  1099.     RET                ; AND EXIT
  1100. ;
  1101. ; DISPLAY FILNAME.TYP
  1102. ;
  1103. FILENM:    INC    HL            ; INCREMENT POINTER FCB
  1104.     LD    A,(HL)            ; GET CHARACTER FROM FCB
  1105.     AND    07FH            ; MASK IT
  1106.     PUSH    HL            ; SAVE REGISTERS
  1107.     PUSH    BC
  1108.     CALL    WRCON            ; ECHO CHARACTER
  1109.     POP    BC            ; RESTORE REGISTERS
  1110.     POP    HL
  1111.     DJNZ    FILENM            ; REPEAT B TIMES
  1112.     RET                ; AND EXIT
  1113. ;
  1114. ; ERROR MESSAGES
  1115. ; Made more meaningful-B.H.
  1116. ;
  1117. ;Bad sector message replaced by read/write error messages
  1118. ;MBADSC:    DB    'Bad sector$'
  1119. ;
  1120. MSEL:    DB    'Non-existent drive$'
  1121. ;
  1122. MFILRO:    DB    'File is '
  1123. ;
  1124. MRO:    DB    'Read-Only$'
  1125. ;
  1126. MBERR:    DB    'Disk error on '
  1127. MDRIVE:    DB    0
  1128.     DB    DRVSEP
  1129.     DB    ' $'
  1130. ;
  1131. MBFUNC:    DB    'Function = $'
  1132. ;
  1133. MFILE:    DB    '; File = $'
  1134. ;
  1135. MRDERR:    DB    'Read error$'
  1136. ;
  1137. MWRTER:    DB    'Write error$'
  1138. ;
  1139. ; SELECT DISK FROM FCB
  1140. ;
  1141. SELDRV:    LD    A,0FFH            ; SET DISK SELECT DONE FLAG
  1142.     LD    (FLDRV),A
  1143.     LD    A,(DEFDRV)        ; GET CURRENT DRIVE
  1144.     LD    (DRIVE),A        ; SAVE IT IN MEMORY
  1145.     LD    E,A            ; SAVE IT IN REGISTER E
  1146.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  1147.     LD    (FCB0),A        ; SAVE IT
  1148.     CP    '?'            ; TEST IF '?'
  1149.     JR    Z,CMND14        ; YES, THEN SELECT DRIVE FROM REGISTER E
  1150.     AND    01FH            ; MASK DRIVE
  1151.     LD    A,E            ; TEST IF ZERO
  1152.     JR    Z,SELDR0        ; SELECT DRIVE FROM REGISTER E
  1153.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  1154.     DEC    A            ; DECREMENT DRIVE
  1155. SELDR0:    CALL    SELDK            ; SELECT DRIVE
  1156.     LD    A,(IX+0)        ; GET DRIVE FROM FCB
  1157.     AND    0E0H            ; REMOVE DRIVE BITS
  1158.     LD    B,A            ; SAVE REGISTER
  1159.     LD    A,(USER)        ; GET USER NUMBER
  1160.     OR    B            ; INSERT USER NUMBER IN FCB
  1161.     LD    (IX+0),A
  1162.     RET                ; AND EXIT
  1163.  
  1164. A            ; SAVE REGISTER
  1165.     LD    A,(USER)        ; GET USER NUMBER
  1166.     OR    B            ; INSERT USER