home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol042 / hd-bios.z80 < prev    next >
Encoding:
Text File  |  1984-04-29  |  29.3 KB  |  1,256 lines

  1. ;------THIS IS A BIOS FOR CPM 2.2 USEING A HARD DISK & 2 FLOPPY DISKS----------
  2. ;
  3. ;THE FLOPPY'S CAN BE EITHER SINGLE OR DOUBLE DENSITY THE BIOS WILL FIGURE IT
  4. ;OUT AUTOMATICALLY. IT IS SETUP AT THE MOMENT FOR ONE SEGATE ST-506 DRIVE &
  5. ;ONLY 2 8" DRIVES CONTROLLED BY THE 1791 CHIP. THIS BIOS IS VERY HARDWARE
  6. ;DEPENDENT AND WOULD REQUIRE SOME REWORKING FOR OTHERE S-100 BOARDS
  7. ;
  8. ;THE S100 BOARDS ARE THE VERSAFLOPPY II AND THE XCOMP HARD DISK CONTROLLER
  9. ; (BOTH OF THESE ARE FIRST CLASS BORDS IN MY OPINION)
  10. ;
  11. ;    AUTHOR:    JOHN J. MONAHAN        (201)779-0635        8/6/81
  12. ;
  13. ;NOTE THIS BIOS IS ~2.5K LONG SO ONE COMPLETE TRACK OF THE 506 DRIVE IS REQ TO
  14. ;HOLD THE CP/M SYSTEM (IE 32 256 BYTE SECTORS). ALSO REMEMBER DUREING A SAVE OF
  15. ;A REBUILT MEMORY IMAGE (TO USE FOR EXAMPLE IN SYSGEN), SAVE 38 PAGES OF RAM.
  16. ;YOU WILL ALSO NEED TO WRITE A SYSGEN PROGRAM TO PUT THIS BIOS ON THE HARD DISK
  17. ;A BOOT (IN ROM) TO READ IN THE CPM LOADER (SECTOR 1) AND THE LOADER ITSELF.
  18. ;THESE PROGRAMS ARE SUPPLIED BY XCOMP. 
  19. ;
  20. ZAPPLE    EQU  0F000H        ;SYSTEM MONITOR
  21. MSIZE    EQU  60            ;MEMORY SIZE IN KBYTES.
  22. CPMBASE    EQU  (MSIZE-22)*1024      ;BIAS FOR CPM LARGER THAN 17K.(NOTE I ALLOW AN 
  23.                 ;EXTRA 1K TO MAKE ROOM FOR EXTRA CODE REQ.
  24. CCP    EQU  CPMBASE+3400H    ;START OF CPM
  25. BDOS    EQU  CCP+806H        ;LINK TO BDOS
  26. BIOS    EQU  CCP+1600H        ;START OF BIOS
  27. ;
  28. NSECT:    EQU    (BIOS-CCP)/128    ;NUMBER SECTORS TO WARM BOOT
  29. IOBYT:    EQU    3             ;I/O SYSTEM CONFIGURATION
  30. CDISK:    EQU    4             ;CURRENT DISK ADDRESS (USED BY CPM)
  31. BUFF:    EQU    80H             ;FCB BUFFER
  32. VSA:    EQU    8             ;SEEK VERIFY START ADDRESS
  33. VCA:    EQU    1BH             ;SEEK VERIFY COMPARE ADDRESS
  34. ;
  35. ;------- HARD DISK PARAMETERS --------------------------------------
  36. ;
  37. MAXSEC:    EQU    32             ;NUMBER OF SECTORS PER TRACK ON HARD DISK
  38. MAXHED:    EQU    4             ;NUMBER OF HEADS ON HARD DISK
  39. MAXCYL:    EQU    153             ;NUMBER OF CYLINDERS/HEAD (ST-506)
  40. BLKSIZ:    EQU    2048             ;NUMBER OF BYTES PER BLOCK FOR HARD DISK
  41. CPMSPT:    EQU    2*MAXSEC         ;NUMBER OF CPM SECTORS PER TRACK FOR HARD DISK
  42. HSKCMD:    EQU    3             ;SEEK COMMAND FOR HARD DISK CONTROLLER
  43. NOPC:    EQU    40H             ;NO PRE-COMPENSATION
  44. LOWRT:    EQU    80H             ;LOW WRITE CURRENT
  45. READY:    EQU    1             ;HARD DISK DRIVE READY
  46. WRTFLT:    EQU    2             ;HARD DISK WRITE FAULT
  47. TK00:    EQU    4             ;HARD DISK TRACK ZERO
  48. RAWINDX:EQU    20H             ;HARD DISK RAW INDEX
  49. BANK0:    EQU    0             ;BANK 0 SELECT ON XCOMP CONTROLLER
  50. BANK1:    EQU    1             ;BANK 1 SELECT
  51. DBENB:    EQU    2             ;DATA BUFFER ENABLE
  52. CBENB:    EQU    4             ;COMPARE BUFFER ENABLE
  53. START:    EQU    8             ;START COMMAND FOR XCOMP CONTROLLER
  54. CBASE:    EQU    70H             ;BASE ADR OF THE XCOMP CONTROLLER PORTS
  55. DRCSR:    EQU    CBASE             ;DRIVE COMMAND/STATUS
  56. EXTCMD:    EQU    CBASE+1             ;EXTENDED COMMNAND REGISTER
  57. LOSC:    EQU    CBASE+2             ;SEEK COUNT, LSB
  58. HISC:    EQU    CBASE+3             ;SEEK COUNT, MSB
  59. CTCSR:    EQU    CBASE+4             ;CONTROLLER COMMAND/STATUS
  60. CTBFR:    EQU    CBASE+5             ;CONTROLLER BUFFER ADDRESS
  61. CTDP:    EQU    CBASE+6             ;CONTROLLER DATA PORT
  62. ;
  63. ;------    FLOPPY DISK PARAMETERS ---------------------------------
  64. ;
  65. X    EQU    60H        ;BASE ADDRESS OF PORTS FOR 1791
  66. RSET    EQU    X+0        ;CONTROLLER RESET ADDRESS
  67. SELECT    EQU    X+3        ;DRIVE SELECT PORT
  68. STATUS    EQU    X+4        ;STATUS PORT
  69. TRACK    EQU    X+5        ;TRACK PORT
  70. SECTOR    EQU    X+6        ;SECTOR PORT
  71. DATA    EQU    X+7        ;DATA PORT
  72. CMD    EQU    X+4        ;COMMAND PORT
  73. RDACMD    EQU    0C0H        ;READ ADDRESS CODE
  74. RDCMD    EQU    088H        ;READ SECTOR CODE
  75. WRCMD    EQU    0A8H        ;WRITE SECTOR CODE
  76. WRTCMD    EQU    0F4H        ;WRITE TRACK CODE
  77. RSCMD    EQU    009H        ;RESTORE COMMAND
  78. SKNCMD    EQU    019H        ;SEEK NO VERIFY
  79. SKCMD    EQU    1DH        ;SEEK WITH VERIFY
  80. STDSDT    EQU    26        ;STANDARD 8" 26 SECTORS/TRACK
  81. STDDDT    EQU    50        ;STANDARD DD 8" 50 SECTORS/TRACK
  82. NBYTES    EQU    128        ;BYTES/SECTOR 
  83. NTRKS    EQU    77        ;TRACKS/DISK
  84. ;
  85. UNIT    EQU    40H        ;STORE FOR FLOPPY NEW UNIT BYTE
  86. ERMASK    EQU    41H        ;FLOPPY ERROR MASK
  87. ERSTAT    EQU    42H        ;FLOPPY ERROR FLAG STORE
  88. CMDSV    EQU    43H        ;COMMAND SAVE 
  89. SPSV    EQU    44H        ;SP SAVE 
  90. TEMP2    EQU    46H        ;2 BYTE TEMP RECORD
  91. COUNT    EQU    48H        ;SECTORS/TRACK STORE
  92. UNITCK    EQU    49H        ;OLD FLOPPY UNIT BYTE
  93. RSEEK    EQU    4AH        ;NBR OF RESEEKS
  94. RTRY    EQU    4BH        ;NBR OF RTRYS
  95. ADRIVE    EQU    4CH        ;STORE OF A: DRIVE DENSITY ETC TYPE
  96. BDRIVE    EQU    4DH        ;STORE OF B: DRIVE TYPE
  97. IDSV    EQU    50H        ;6 BYTES (USED FOR TRACK ID COMMAND)
  98. ;
  99. ;   ASCII CHARACTERS
  100. ;
  101. CR:    EQU    0DH         ;CARRIAGE RETURN
  102. LF:    EQU    0AH         ;LINE FEED
  103. BELL:    EQU    7         ;DING
  104. ;
  105. ;
  106.     ORG    BIOS
  107. ;
  108. ;    ---JUMP TABLE---
  109. ;
  110. ;
  111.     JP    BOOT         ;  0 - COLD BOOT
  112. WBX:    JP    WBOOT         ;  1 - WARM BOOT
  113.     JP    ZAPPLE+12H   ;  2 - CONSOLE STATUS REQUEST
  114. ZCI:    JP    ZAPPLE+03H   ;  3 - CONSOLE INPUT
  115. ZCO:    JP    ZAPPLE+09H   ;  4 - CONSOLE OUTPUT
  116. ZLO:    JP    ZAPPLE+0FH   ;  5 - LIST OUTPUT
  117.     JP    ZAPPLE+0CH   ;  6 - PUNCH OUTPUT
  118.     JP    ZAPPLE+06H   ;  7 - READER INPUT
  119.     JP    HOME         ;  8 - TRACK ZERO SEEK
  120.     JP    SETDR         ;  9 - SET DRIVE #
  121.     JP    SETTK         ; 10 - SET TRACK ADR
  122.     JP    SETSEC         ; 11 - SET SECTOR ADR
  123.     JP    SETDMA         ; 12 - SET BUFFER ADDRESS
  124.     JP    READ         ; 13 - READ A SECTOR
  125.     JP    WRITE         ; 14 - WRITE A SECTOR
  126. ZLISTS:    JP    ZAPPLE+27H   ; 15 - LIST OUTPUT READY TEST
  127.     JP    SXR         ; 16 - SECTOR XLATE ROUTINE
  128. ;
  129. ;    ======================
  130. ;    ** DISK DEFINITIONS **
  131. ;    ======================
  132. ;
  133. DPHDR:    DEFW    0,0             ;SEAGATE ST-506 DRIVE (DRIVE A:)
  134.     DEFW    0,0
  135.     DEFW    DIRBUF,HDBLK
  136.     DEFW    LAST,HALL0    ;LAST & FIRST LOCATIONS FOR BIT-MAP
  137. ;
  138.     DEFW    XLT0,0        ;FLOPPY 8" SD (DRIVE B:)
  139.     DEFW    0,0
  140.     DEFW    DIRBUF,DPB0
  141.     DEFW    CSV0,ALV0
  142. ;
  143.     DEFW    XLT0,0        ;FLOPPY 8" SD (DRIVE C:)
  144.     DEFW    0,0
  145.     DEFW    DIRBUF,DPB0
  146.     DEFW    CSV1,ALV1
  147. ;
  148.     DEFW    XLT1,0        ;FLOPPY 8" DOUBLE DEN (FOR CPM = D:)
  149.     DEFW    0,0        ;(FOR HARDWARE DRIVE B: CF. ROM BIOS)
  150.     DEFW    DIRBUF,DPB1
  151.     DEFW    CSV2,ALV2
  152. ;
  153.     DEFW    XLT1,0        ;FLOPPY 8" DOUBLE DEN (FOR CPM = E:)
  154.     DEFW    0,0        ;(FOR HARDWARE DRIVE C: CT. ROM BIOS)
  155.     DEFW    DIRBUF,DPB1
  156.     DEFW    CSV3,ALV3
  157. ;
  158. ;    ---THE HARD DISK PARAMETER BLOCK IS SETUP AS FOLLOWS---
  159. ;
  160. ;    1. THE SEAGATE ST-506 IS CONFIGURED AS A SINGLE 5.0 MEGABYTE DRIVE.
  161. ;
  162. ;    2. THE CPM LOGICAL BLOCK SIZE IS 2048 BYTES.
  163. ;
  164. ;    3. THERE ARE 1024 DIRECTORY ENTRIES. THIS IS THE MOST
  165. ;       WE CAN GET WITH A BLOCK SIZE OF 2048.
  166. ;
  167. ;    4. THE FIRST TRACK IS RESERVED FOR THE SYSTEM. THIS WILL
  168. ;       ALLOW AN AGGREGATE CCP/BDOS/CBIOS SIZE OF 8 K-BYTES.
  169. ;
  170. ;
  171. HDBLK:    DEFW    64         ;SPT: (LOGICAL) SECTORS PER TRACK
  172.     DEFB    4         ;BSH: BLOCK SHIFT FACTOR
  173.     DEFB    15         ;BLM: BLOCK MASK
  174.     DEFB    0         ;EXM: NULL MASK
  175.     DEFW    2441         ;DSM: (DISK SIZE) - 1
  176.     DEFW    1023         ;DRM: (DIR SIZE) - 1
  177.     DEFB    0FFH         ;AL0: DIRECTORY ALLOCATION BITS, MSB
  178.     DEFB    0FFH         ;AL1:   * LSB
  179.     DEFW    0         ;CKS: CHECK SIZE
  180.     DEFW    2         ;OFF: TRACK OFFSET
  181. ;
  182. ;--- THE FLOPPYS CAN BE SD OR DD SO 2 LOGICAL DRIVE TYPES---
  183. ;
  184. ;        DRIVES B: & C:
  185. ;          (DISKDEF 0,1,26,6,1024,243,64,64,2)
  186. ;
  187. DPB0:      DW    26        ;SEC PER TRACK
  188.          DB    3        ;BLOCK SHIFT
  189.            DB    7        ;BLOCK MASK
  190.           DB    0        ;EXTNT MASK
  191.           DW    242        ;DISK SIZE-1
  192.           DW    63        ;DIRECTORY MAX
  193.           DB    192        ;ALLOC0
  194.            DB    0        ;ALLOC1
  195.          DW    16        ;CHECK SIZE
  196.          DW    2        ;OFFSET
  197. ;
  198. XLT0:    DB    1,7,13,19,25,5,11,17,23,3,9,15,21,2,8
  199.     DB    14,20,26,6,12,18,24,4,10,16,22
  200. ;
  201. ;    ----- DRIVE D: & E: ARE DOUBLE DENSITY----
  202. ;        (DISKDEF 2,1,50,0,2048,234,64,64,2)
  203. ;
  204. DPB1:      DW    50        ;SEC PER TRACK
  205.          DB    4        ;BLOCK SHIFT
  206.         DB    15        ;BLOCK MASK
  207.           DB    1        ;EXTNT MASK
  208.         DW    233        ;DISK SIZE-1
  209.         DW    63        ;DIRECTORY MAX
  210.          DB    128        ;ALLOC0
  211.          DB    0        ;ALLOC1
  212.          DW    16        ;CHECK SIZE
  213.           DW    2        ;OFFSET
  214. ;
  215. XLT1:    DB    1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
  216.     DB    20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
  217.     DB    37,38,39,40,41,42,43,44,45,46,47,48,49,50
  218. ;                
  219. ;
  220. ;        =====================
  221. ;        ** CBIOS FUNCTIONS **
  222. ;        =====================
  223. ;          ---COLD BOOT---
  224. ;
  225. ;
  226. BOOT:    LD    SP,BUFF             ;USE LOW MEMORY
  227.     LD    HL,FLAGS    ;CLEAR RAM STORAGE AREA
  228.     LD    B,FLGSIZ
  229.     XOR    A
  230. INIT1:    LD    (HL),A             ;CLEAR FLAGS & VARIABLES
  231.     INC    HL
  232.     DEC    B
  233.     JP    NZ,INIT1
  234.     LD    (CDISK),A        ;FOR USE BY CPM
  235.     LD    (IOBYT),A    ;CLEAR IOBYTE
  236.     DEC    A        ;PUT 0FFH IN FLOPPY A & B STORE 
  237.     LD    (ADRIVE),A
  238.     LD    (BDRIVE),A
  239.     JP    XIT          ;GOTO CPM
  240. ;
  241. ;    ---WARM BOOT---
  242. ;
  243. ;
  244. WBOOT:    LD    SP,BUFF
  245.     XOR    A
  246.     LD    (RRDSK),A     ;SLCT DRIVE ZERO
  247.     DEC    A
  248.     LD    (ADRIVE),A    ;PUT 0FFH IN FLOPPY A & B STORE
  249.     LD    (BDRIVE),A
  250.     CALL    XSTZ             ;SEEK TO TRACK ZERO
  251.     LD    HL,CCP             ;CPM LOAD ADR
  252.     LD    (DMADR),HL       ;SAVE IT
  253.     LD    C,2
  254.     CALL    SETSEC             ;SET SECTOR ADR
  255.     LD    A,NSECT             ; # SECTORS TO WARM BOOT
  256. WB1:    LD    (SECNT),A        ;SAVE THE SECTOR COUNT
  257.     CALL    HDREAD             ;READ A SECTOR FROM THE HARD DISK
  258.     OR    A
  259.     JP    Z,WB2             ;JIF READ OK
  260.     LD    HL,MSG1             ;  'CAN'T BOOT'
  261.     CALL    PRNT             ;PRINT ERROR MSG
  262.     JP    ZAPPLE
  263. WB2:    LD    HL,(DMADR)
  264.     LD    DE,128
  265.     ADD    HL,DE             ;BUMP DMA ADR
  266.     LD    (DMADR),HL
  267.     LD    HL,RRSEC
  268.     LD    C,(HL)
  269.     INC    C             ;INCR SECT ADR
  270.     CALL    SETSEC             ;SET NEW SECT ADR
  271.     LD    A,(SECNT)        ;A = SECTOR COUNT
  272.     DEC    A
  273.     JP    NZ,WB1             ;JIF MORE TO READ
  274. ;
  275. ;    ---EXIT TO CPM---
  276. ;
  277. XIT:    LD    HL,BUFF
  278.     LD    (DMADR),HL   ;INIT DMA ADR
  279.     LD    A,0C3H         ;JMP INST
  280.     LD    (0),A
  281.     LD    HL,WBX
  282.     LD    (1),HL         ;SET WARM BOOT LINK
  283.     LD    HL,BDOS
  284.     LD    (5),A
  285.     LD    (6),HL         ;SET BDOS LINK
  286.     LD    A,(CDISK)    ;CURRENT LOGGED-IN DISK & USER
  287.     LD    C,A
  288.     JP    CCP         ;GOTO CPM
  289. ;
  290. ;    ---SECTOR TRANSLATE ROUTINE---
  291. ;
  292. SXR:    EX    DE,HL         ;H/L = ADR OF XLATE TABLE
  293.     LD    A,L
  294.     OR    H         ;TEST TABLE ADR
  295.     JP    NZ,SXR1         ;JIF DO XLATE
  296.     ADD    HL,BC         ;DON'T XLATE -- USE SECT ADR AS IS
  297.     RET    
  298. ;
  299. SXR1:    ADD    HL,BC         ;INDEX INTO THE TABLE
  300.     LD    L,(HL)         ;L = XLATED SECTOR ADR
  301.     LD    H,0         ;H = 0 FOR 16-BIT VALUE
  302.     RET    
  303. ;
  304. ;    ---HOME---
  305. ;
  306. ;
  307. HOME:    LD    A,(RRDSK)        ;DRIVE #
  308.     CP    1        ;SET AT THE MOMENT FOR ONE HARD DISK
  309.     JP    C,XSTZ             ;JIF REZERO HARD DISK
  310.     CP    3        ;ALLOW TWO FLOPPYS
  311.     JP    C,FHOME        ;JIF REZERO FLOPPY
  312. SELERR:    LD    A,1             ;SET ERROR FLAG
  313.     RET    
  314. ;
  315. ;    ---READ---
  316. ;
  317. READ:    LD    A,(RRDSK)        ;DRIVE #
  318.     CP    1
  319.     JP    C,HDREAD         ;JIF READ FROM H/D
  320.     CP    3
  321.     JP    C,FREAD        ;JIF READ FROM F/D
  322.     JP    SELERR             ;ABORT, SELECT ERROR
  323. ;
  324. ;    ---WRITE---
  325. ;
  326. ;
  327. WRITE:    LD    A,(RRDSK)        ;DRIVE #
  328.     CP    1
  329.     JP    C,HDWRT             ;JIF WRITE ONTO H/D
  330.     CP    3
  331.     JP    C,FWRITE    ;JIF WRITE ONTO F/D
  332.     JP    SELERR             ;ABORT, SELECT ERROR
  333. ;
  334. ;    ---SET DRIVE NUMBER---
  335. ;
  336. SETDR:    LD    A,C             ;A = NEW DRIVE #
  337.     LD    (RRDSK),A        ;  SAVE IT
  338.     LD    HL,0
  339.     CP    3
  340.     RET    NC             ;RIF INVALID DRIVE # WITH [HL]=0
  341.     CP    1        ;IF NOT 1 MUST BE FLOPPYS
  342.     CALL    NC,FSELDSK    ;RETURNS WITH LOGICAL DRIVE OFFSET IN [A]
  343.     LD    L,A
  344.     ADD    HL,HL             ;SHIFT H/L LEFT 4
  345.     ADD    HL,HL             ;   (HL = HL*16)
  346.     ADD    HL,HL
  347.     ADD    HL,HL
  348.     LD    DE,DPHDR         ;DISK PARM HDR
  349.     ADD    HL,DE             ;H/L = DPHDR FOR SELECTED DRIVE
  350.     RET    
  351. ;
  352. ;    ---SET SECTOR ADR---
  353. ;
  354. SETSEC:    LD    A,C
  355.     LD    (RRSEC),A    ;SAVE SECTOR ADR
  356.                  ;SET REAL SECTOR ADR FOR THE H/D DRIVER
  357.     AND    NOT 1         ;CLEAR LOW ORDER BIT
  358.     RRCA             ;THERE ARE 2 CPM SECTORS PER H/D SECT
  359.     LD    (RSA),A         ;SAVE REAL SECTOR ADR
  360.     RET
  361. ;    
  362. ;    ---SET TRACK ADDRESS---
  363. ;
  364. ;
  365. SETTK:    LD    H,B
  366.     LD    L,C
  367.     LD    (RRTRK),HL   ;SAVE TRACK ADR
  368.     RET
  369. ;
  370. ;    ---SET DMA ADDRESS---
  371. ;
  372. ;
  373. SETDMA:    LD    H,B
  374.     LD    L,C
  375.     LD    (DMADR),HL   ;SAVE DMA ADR
  376.     RET    
  377. ;
  378. ;    ======================================
  379. ;    ** HARD DISK BLOCK/DEBLOCK ROUTINES **
  380. ;    ======================================
  381. ;
  382. ;    ---HARD DISK READ---
  383. ;
  384. HDREAD:    XOR    A
  385.     LD    (ERFLG),A    ;CLEAR THE ERROR FLAG
  386.     LD    A,(FLAGS)    ;SET READ OPERATION FLAG
  387.     SET    0,A     
  388.     BIT    2,A          ;WRITE IN PROGRESS ?
  389.     LD    (FLAGS),A
  390.     CALL    NZ,XWRT         ;YES, WRITE DATA BEFORE READ
  391.     LD    A,(FLAGS)
  392.     RES    2,A          ;RESET 'WIP' FLAG
  393.     LD    (FLAGS),A
  394.     CALL    TSTHST         ;HOST = REQ ?
  395.     JP    NZ,HDRD1     ;NO, READ A BLOCK
  396.     LD    A,(FLAGS)
  397.     BIT    1,A             ;PRIOR BLOCK READ ?
  398.     JP    NZ,HDRD2     ;YES, JUST EXTRACT DATA FROM BFR
  399. HDRD1:    CALL    SETHST         ;MAKE HOST=REQ
  400.     CALL    XREAD         ;READ A BLOCK
  401. HDRD2:    CALL    GETDMA         ;GET DMA ADR, SET POINTERS
  402.     IN    A,CTDP         ;PRIME DATA INPUT
  403.     INIR             ;BLOCK INPUT
  404.     LD    A,(FLAGS)
  405.     SET    1,A             ;SET READ-IN-PROGRESS FLAG
  406.     LD    (FLAGS),A
  407.     LD    A,(ERFLG)    ;ERROR FLAG
  408.     RET
  409. ;    
  410. ;    ---HARD DISK WRITE---
  411. ;
  412. ;
  413. HDWRT:    XOR    A
  414.     LD    (ERFLG),A    ;CLEAR THE ERROR FLAG
  415.     LD    A,(FLAGS)
  416.     RES    1,A             ;CLEAR READ-IN-PROGRESS FLAG
  417.     LD    (FLAGS),A
  418.     LD    A,C         ;A = WRITE MODE
  419.     DEC    A
  420.     JP    Z,WDIR         ;DO DIRECTORY WRITE
  421.     JP    M,WNORM         ;DO NORMAL WRITE
  422. ;
  423. ;   UNALLOCATED WRITE
  424. ;
  425. WUN:    LD    A,(FLAGS)
  426.     BIT    2,A             ;WRITE IN PROGRESS ?
  427.     CALL    NZ,XWRT         ;YES, WRITE DATA IN BFR
  428.                  ;SET UNALLOC RECORD PARAMETERS
  429.     LD    A,BLKSIZ/128
  430.     LD    (URCNT),A    ;SET UNALLOC RECORD COUNT
  431.     LD    HL,(RRDSK)
  432.     LD    (URDSK),HL   ;UPDATE DRIVE & SECTOR
  433.     LD    HL,(RRTRK)
  434.     LD    (URTRK),HL   ;UPDATE TRACK ADR
  435.     CALL    SETHST         ;SET HOST = REQ
  436.     CALL    BUMP         ;BUMP UNALC PARMS FOR NEXT PASS
  437.                  ;XFER DATA TO CTLR BFR
  438. WXFER:    LD    A,(FLAGS)
  439.     RES    0,A          ;CLEAR READ OPER FLAG
  440.     LD    (FLAGS),A
  441.     CALL    GETDMA         ;GET DMA ADR, SET FOR WRITE
  442.     OTIR             ;BLOCK OUTPUT
  443.     LD    A,(FLAGS)
  444.     SET    2,A             ;SET WRITE-IN-PROGRESS FLAG
  445.     LD    (FLAGS),A
  446.     LD    A,(ERFLG)    ;ERROR FLAG
  447.     RET    
  448. ;
  449. ;   NORMAL WRITE
  450. ;
  451. WNORM:    LD    A,(URCNT)    ;UNALC RECORD COUNT
  452.     OR    A
  453.     JP    Z,WALC         ;JIF DO ALLOC WRITE
  454.     LD    HL,URTRK
  455.     CALL    DSKCMP         ;UNALC DSK/TRK = REQ DSK/TRK ?
  456.     JP    NZ,WALC         ;NO, DO ALLOC WRITE
  457.     LD    A,(RRSEC)
  458.     CP    (HL)         ;UNALC SECT = REQ SECT ?
  459.     JP    NZ,WALC         ;NO, DO ALLOC WRITE
  460.     CALL    BUMP         ;BUMP UNALC PARMS FOR NEXT PASS
  461.     CALL    TSTHST         ;HOST = REQ ?
  462.     JP    Z,WN1         ;YES, CON'T TO FILL THE BFR
  463.     LD    A,(FLAGS)    
  464.     BIT    2,A             ;WRITE IN PROGRESS ?
  465.     CALL    NZ,XWRT         ;YES, WRITE OLD DATA ONTO DISK
  466.     CALL    SETHST         ;MAKE HOST = REQ
  467. ;
  468. WN1:    LD    A,(FLAGS)
  469.     BIT    0,A          ;INTERVENING READ ?
  470.     CALL    NZ,XREAD     ;YES, READ OLD UNALC DATA
  471.     JP    WXFER         ;MOVE DATA TO BFR, EXIT
  472. ;
  473. ;   ALLOCATED WRITE
  474. ;
  475. WALC:    XOR    A
  476.     LD    (URCNT),A    ;CLEAR UNALC RECORD COUNT
  477.     CALL    TSTHST         ;HOST = REQ ?
  478.     JP    Z,WXFER         ;YES -  MOVE DATA TO BFR, EXIT
  479.     LD    A,(FLAGS)
  480.     BIT    2,A             ;WRITE IN PROGRESS ?
  481.     CALL    NZ,XWRT         ;YES, WRITE OLD DATA ONTO DISK
  482.     CALL    SETHST         ;MAKE HOST = REQ
  483.     CALL    XREAD         ;READ IN ALLOCATED DATA
  484.     JP    WXFER         ;MOVE NEW DATA IN BFR, EXIT
  485. ;
  486. ;   DIRECTORY WRITE
  487. ;
  488. WDIR:    XOR    A
  489.     LD    (URCNT),A    ;CLEAR UNALC RECORD COUNT
  490.     LD    A,(FLAGS)
  491.     RES    0,A          ;RESET 'RDOP' FLAG
  492.     LD    (FLAGS),A
  493.     BIT    2,A             ;WRITE IN PROGRESS ?
  494.     CALL    NZ,XWRT         ;YES, WRITE OLD DATA ONTO THE DISK
  495.     LD    A,(FLAGS)
  496.     RES    2,A             ;CLEAR 'WIP' FLAG
  497.     LD    (FLAGS),A
  498.     CALL    SETHST         ;MAKE HOST = REQ
  499.     CALL    XREAD         ;READ DIR DATA
  500.     RET    NZ         ;RIF READ ERROR
  501.     CALL    GETDMA         ;GET DMA ADR, SET POINTERS
  502.     OTIR             ;BLOCK OUTPUT
  503.     JP    XWRT         ;WRITE DIR DATA, EXIT
  504. ;
  505. ;    ---TEST HOST---
  506. ;
  507. ;   DETERMINES IF THE HOST DISK ADDRESS IS
  508. ;   THE SAME AS THE REQUESTED DISK ADDRESS.
  509. ;
  510. ;
  511. TSTHST:    LD    HL,HHTRK
  512.     CALL    DSKCMP         ;TRACK & DRIVE THE SAME ?
  513.     RET    NZ         ;RIF NO
  514.     LD    A,(RSA)
  515.     CP    (HL)         ;SECTOR THE SAME ?
  516.     RET             ;IF A = 0 THEN THEY MATCH
  517. ;
  518. ;    ---SET HOST---
  519. ;
  520. ;   SETS THE HOST DISK ADDRESS TO BE THE
  521. ;   SAME AS THE REQUESTED DISK ADDRESS.
  522. ;
  523. ;
  524. SETHST:    LD    A,(RRDSK)
  525.     LD    (HHDSK),A    ;DRIVE #
  526.     LD    HL,(RRTRK)
  527.     LD    (HHTRK),HL   ;TRACK ADR
  528.     LD    A,(RSA)
  529.     LD    (HHSEC),A    ;SECTOR ADR
  530.     RET    
  531. ;
  532. ;    ---BUMP---
  533. ;
  534. ;   BUMPS PARAMETERS FOR UNALLOCATED WRITES.
  535. ;   PARMS ARE CHANGED FOR THE NEXT PASS THRU
  536. ;   THE CODE (NOT THE CURRENT PASS).
  537. ;
  538. BUMP:    LD    HL,URCNT     ;UNALC RECORD COUNT
  539.     DEC    (HL)         ;  DECR IT
  540.     DEC    HL         ;H/L = URSEC
  541.     INC    (HL)         ;  INCR IT
  542.     LD    A,(HL)
  543.     CP    CPMSPT         ;CPM SECTORS PER TRACK
  544.     RET    C         ;RIF STAY ON SAME TRACK
  545.                  ;OVERFLOW TO NEXT TRACK
  546.     LD    (HL),0         ;RESET SECTOR ADR
  547.     LD    HL,(URTRK)
  548.     INC    HL         ;INCR TRACK ADR
  549.     LD    (URTRK),HL
  550.     RET    
  551. ;
  552. ;    ---GET DMA ADDRESS---
  553. ;
  554. ;   SETS THE CONTROLLER BUFFER ADDRESS TO THE CORRECT
  555. ;   STARTING POINT. ALSO SETS B=128 & H/L=DMADR.
  556. ;
  557. ;
  558. GETDMA:    LD    HL,(DMADR)   ;DMA ADR
  559.     LD    C,CTDP         ;FOR BLOCK I/O
  560.     LD    B,128         ;B = COUNT
  561.     LD    A,DBENB
  562.     OUT    CTCSR,A         ;ENB DATA BFR
  563.     LD    A,(RRSEC)    ;REQUESTED SECTOR
  564.     RRCA    
  565.     LD    A,0
  566.     JP    NC,GET1         ;JIF USE 1ST HALF OF BFR
  567.     LD    A,B         ;   USE 2ND HALF OF BFR
  568. GET1:    OUT    CTBFR,A         ;SET CTLR DATA BFR ADR
  569.     RET    
  570. ;
  571. ;
  572. ;    ======================================
  573. ;    ** HARD DISK I/O & SUPPORT ROUTINES **
  574. ;    ======================================
  575. ;    ---READ A BLOCK---
  576. ;
  577. XREAD:    LD    HL,RTBL         ;READ CMD TBL
  578.     CALL    DORW         ;READ
  579. ;
  580. XR1:    LD    A,0
  581.     RET    Z         ;RIF READ/WRITE OK
  582.     INC    A
  583.     LD    (ERFLG),A    ;SET ERROR FLAG
  584.     RET    
  585. ;
  586. ;    ---WRITE A BLOCK---
  587. ;
  588. XWRT:    LD    HL,WTBL         ;WRITE CMD TBL
  589.     CALL    DORW         ;WRITE A SECTOR
  590.     JP    XR1         ;SET ERROR FLAG
  591. ;
  592. ;    ---EXECUTE READ/WRITE COMMANDS---
  593. ;
  594. DORW:    PUSH    HL         ;SAVE CMD TBL ADR
  595.     CALL    XSEK         ;SEEK TO NEW TRACK (IF REQUIRED)
  596.     POP    HL         ;RESTORE CMD TBL ADR
  597.     RET    NZ         ;RIF SEEK FAILED
  598.     CALL    XSEL         ;HEAD SELECT
  599. ;
  600. DO0:    LD    A,(HL)
  601.     LD    (RETRY),A    ;SET RETRY COUNT
  602.     INC    HL
  603.     LD    A,(HL)
  604.     OUT    CTCSR,A         ;ENB CMP BFR
  605.     INC    HL
  606.     LD    A,(HL)
  607.     OUT    CTBFR,A         ;SET CMP BFR ADR
  608.     INC    HL
  609.     LD    (CTA),HL     ;SAVE CMD TBL ADR
  610. ;
  611.     LD    HL,RTK         ;REAL TK ADR
  612.     LD    B,3
  613. DO1:    LD    A,(HL)
  614.     OUT    CTDP,A         ;PUT HDR INFO INTO CMP BFR
  615.     INC    HL
  616.     DEC    B
  617.     JP    NZ,DO1
  618.     LD    A,(HHSEC)
  619.     OUT    CTDP,A         ;SET SECT ADR FOR COMPARE
  620. ;
  621. DO2:    CALL    XRDY         ;DRIVE READY ?
  622.     RET    NZ         ;  RIF NO
  623.     LD    HL,(CTA)     ;CMD TBL ADR
  624.     LD    A,(HL)         ;A = CNTL BANK
  625.     INC    HL
  626.     LD    B,A
  627.     OUT    CTCSR,A         ;SLCT CNTL BANK
  628.     LD    A,(HL)
  629.     OUT    CTBFR,A         ;SET START ADR
  630.     INC    HL
  631.     LD    A,B
  632.     OR    START
  633.     OUT    CTCSR,A         ;START R/W CMD
  634. ;
  635. DO3:    CALL    WFD         ;WAIT FOR READ/WRITE TO FINISH
  636.     AND    (HL)         ;TEST CTLR STATUS (0=OK)
  637.     LD    B,A
  638.     IN    A,DRCSR         ;DRIVE STATUS
  639.     AND    WRTFLT
  640.     CALL    NZ,CLRDF     ;CIF CLEAR DRIVE FAULT
  641.     OR    B         ;SET/CLEAR ERROR FLAG (0=OK)
  642.     RET    Z         ;RIF READ/WRITE OK
  643.     LD    HL,RETRY
  644.     DEC    (HL)         ;DECR RETRY COUNT
  645.     JP    NZ,DO2         ;JIF RETRY READ/WRITE
  646. ;
  647. ;   SET ERROR FLAG
  648. ;
  649. SEF:    LD    A,1         ;A = ERROR FLAG
  650.     OR    A         ;SET 8080 FLAGS
  651.     RET             ;TAKE ERROR EXIT
  652. ;
  653. ;    ---WAIT FOR DONE---
  654. ;
  655. WFD:    IN    A,CTCSR         ;CTLR STATUS
  656.     RRCA    
  657.     JP    NC,WFD         ;WAIT FOR DONE
  658.     NOP             ;DELAY FOR H/W
  659.     IN    A,CTCSR         ;GET NON-CHANGING STATUS
  660.     LD    B,A    
  661.     XOR    A
  662.     OUT    CTCSR,A         ;STOP CTLR
  663.     LD    A,B
  664.     RET    
  665. ;
  666. ;    ---REZERO---
  667. ;
  668. XTKZ:    CALL    XRDY         ;DRIVE READY ?
  669.     RET    NZ         ;   RIF NO
  670.     LD    HL,0
  671.     LD    (CHDT),HL    ;SET CURRENT TRACK = 0
  672.     LD    B,0         ;SET RETRY COUNT = 256
  673. ;
  674. XTKZ1:    IN    A,DRCSR         ;DRIVE STATUS
  675.     AND    TK00         ;TRACK ZERO INDICATOR
  676.     XOR    TK00         ;  MAKE IT LO-TRUE
  677.     RET    Z         ;RIF AT TRACK ZERO
  678.     DEC    B         ;DECR RETRY CNT
  679.     JP    Z,SEF         ;JIF REZERO FAILED
  680.     XOR    A
  681.     OUT    HISC,A
  682.     INC    A
  683.     OUT    LOSC,A         ;SET SEEK COUNT = 1
  684.     OUT    EXTCMD,A     ;SET SEEK DIRECTION = OUT
  685.     LD    A,HSKCMD
  686.     OUT    DRCSR,A         ;START SEEK
  687.     CALL    WSC         ;WAIT FOR SEEK DONE
  688.     JP    XTKZ1
  689. ;
  690. ;    ---SEEK TO TRACK ZERO---
  691. ;
  692. XSTZ:    LD    A,(FLAGS)
  693.     BIT    2,A    
  694.     JP    NZ,XSTZ1     ;JIF WRITE IN PROGRESS
  695.     LD    (FLAGS),A    ;MAKE HOST INACTIVE
  696. XSTZ1:    LD    HL,0
  697.     LD    (RRTRK),HL   ;SET TK ADR = 0
  698.     XOR    A         ;SET FLAG = NO ERRORS
  699.     RET
  700. ;
  701. ;    ---SEEK---
  702. ;
  703. XSEK:    CALL    XRDY         ;DRIVE READY ?
  704.     RET    NZ         ;  RIF NO
  705.     LD    A,3
  706.     LD    (RETRY),A    ;SET RETRY COUNT
  707. ;
  708. XSEK1:    XOR    A
  709.     OUT    HISC,A         ;SET MSB OF SEEK COUNT = 0
  710.     LD    HL,(HHTRK)   ;REQUESTED TRACK
  711.     LD    B,2
  712.     CALL    DRS         ;SHIFT H/L RIGHT TWICE
  713.     LD    (RTK),HL     ;SAVE REAL TK ADR
  714.     LD    A,L
  715.     SUB    MAXCYL AND 0FFH
  716.     LD    A,H
  717.     SBC    MAXCYL SHR 8
  718.     JP    NC,SEF         ;JIF INVALID CYL ADR
  719.     LD    A,L         ;A = TARGET CYL ADR
  720.     LD    B,L         ;FOR LATER USE
  721.     LD    C,3         ;DIRECTION = INWARD
  722.     LD    HL,CHDT         ;CURR TK ADR
  723.     SUB    (HL)
  724.     RET    Z         ;RIF AT REQUESTED TK
  725.     LD    (HL),B         ;UPDATE CURR TK ADR
  726.     JP    NC,XSEK2     ;JIF SEEK INWARD
  727.     CPL    
  728.     INC    A         ;MAKE SEEK CNT POSITIVE
  729.     LD    C,1         ;MAKE DIRECTION = OUTWARD
  730. XSEK2:    OUT    LOSC,A         ;SET SEEK COUNT
  731.     LD    A,C
  732.     OUT    EXTCMD,A     ;SET DIRECTION OF SEEK
  733.     LD    A,HSKCMD
  734.     OUT    DRCSR,A         ;INITIATE SEEK
  735.     CALL    WSC         ;WAIT FOR SEEK DONE
  736.                  ;SEEK VERIFY
  737.     LD    A,CBENB
  738.     OUT    CTCSR,A         ;ENABLE BANK ZERO CMP BFR
  739.     LD    A,VCA
  740.     OUT    CTBFR,A         ;SET CMP BFR ADR
  741.     LD    A,(CHDT)
  742.     OUT    CTDP,A         ;SET CYL ADR, LSB
  743.     XOR    A
  744.     OUT    CTDP,A         ;SET CYL ADR, MSB
  745.     LD    A,VSA
  746.     OUT    CTBFR,A         ;SET M/CODE START ADR
  747.     LD    A,START
  748.     OUT    CTCSR,A         ;START VERIFY
  749.     CALL    WFD         ;WAIT FOR DONE
  750.     AND    0CH         ;TEST CTLR STATUS
  751.     RET    Z         ;RIF VERIFY OK
  752.                  ;VERIFY FAILED
  753.     CALL    XTKZ         ;RESTORE
  754.     LD    HL,RETRY
  755.     DEC    (HL)         ;DECR RETRY COUNT
  756.     JP    NZ,XSEK1     ;JIF RETRY SEEK
  757.     OR    1         ;SET FAIL FLAG
  758.     RET             ;ERROR EXIT
  759. ;
  760. ;    ---WAIT FOR SEEK COMPLETE---
  761. ;
  762. WSC:    IN    A,DRCSR         ;DRIVE STATUS
  763.     RLA    
  764.     JP    NC,WSC         ;WAIT FOR SEEK DONE
  765.     IN    A,DRCSR         ;DRIVE STATUS
  766.     AND    WRTFLT         ;TEST FOR DRIVE FAULT
  767.     RET    Z         ;RIF OK
  768. ;
  769. ;    ---CLEAR DRIVE FAULT---
  770. ;
  771. CLRDF:    XOR    A
  772.     OUT    EXTCMD,A     ;DE-SELECT THE DRIVE (FALL THRU TO 'XSEL' TO
  773.                  ;RE-SELECT THE DRIVE)
  774. ;
  775. ;    ---HEAD SELECT---
  776. ;
  777. XSEL:    LD    A,(HHTRK)    ;REQUESTED TRACK
  778.     AND    3         ;4 HEADS
  779.     LD    (RHD),A         ;SAVE REAL HEAD #
  780.     ADD    A         ;SHIFT HEAD # LEFT TWICE FOR H/W
  781.     ADD    A
  782.     OR    1         ;TO MAINTAIN DRIVE SLCT
  783.     LD    B,A
  784.     LD    A,(CHDT)     ;CURRENT CYLINDER ADR
  785.     CP    MAXCYL/2     ;HALF CYLINDER POINT ?
  786.     LD    A,0         ;PRE-COMP ST-506 ON ALL CYLS
  787.     JP    C,XSEL1         ;JIF 1ST HALF OF DISK
  788.     LD    A,LOWRT         ;LOW WRITE CURRENT
  789. XSEL1:    OR    B         ;B = HEAD SLCT INFO
  790.     OUT    EXTCMD,A     ;SELECT HEAD 0...3
  791.     RET    
  792. ;
  793. ;    ---DRIVE READY TEST---
  794. ;
  795. XRDY:    IN    A,DRCSR         ;DRIVE STATUS
  796.     AND    1         ;DRIVE READY BIT
  797.     XOR    1         ;INVERT IT
  798.     RET             ;IF A = 0, DRIVE RDY
  799. ;
  800. ;    ---COMMAND TABLES---
  801. ;   WRITE
  802. WTBL:    DEFB    5         ;RETRY COUNT
  803.     DEFB    5         ;CMP BFR ENB
  804.     DEFB    0E4H         ;CMP BFR ADR
  805.     DEFB    BANK1         ;CNTL BANK
  806.     DEFB    0D1H         ;START ADR
  807.     DEFB    0EH         ;STATUS MASK
  808. ;
  809. ;   READ
  810. RTBL:    DEFB    10         ;RETRY COUNT
  811.     DEFB    4         ;CMP BFR ENB
  812.     DEFB    0EAH         ;CMP BFR ADR
  813.     DEFB    BANK0         ;CNTL BANK
  814.     DEFB    0D7H         ;START ADDRESS
  815.     DEFB    0EH         ;STATUS MASK
  816. ;
  817. ;    ---DISK ADDRESS COMPARE---
  818. ;
  819. ;   COMPARES EITHER THE HOST DISK ADDRESS OR THE UNALLOCATED
  820. ;   DISK ADDRESS AGAINST THE REQUESTED DISK ADDRESS.
  821. ;
  822. DSKCMP:    LD    DE,RRTRK     ;REQUESTED TRACK
  823.     LD    B,3
  824. DC1:    LD    A,(DE)
  825.     CP    (HL)
  826.     RET    NZ         ;RIF ADRS NOT EQUAL
  827.     INC    HL
  828.     INC    DE
  829.     DEC    B
  830.     JP    NZ,DC1
  831.     RET    
  832. ;
  833. ;    ======================================
  834. ;         FLOPPY DISK ROUTINES
  835. ;    ======================================
  836. ;
  837. FHOME:    XOR    A        ;NO NEED TO DO ACTUAL HOME AT THIS STAGE
  838.     LD    (RRTRK),A    ;WILL ALWAYS BE < 0FF TRACKS ON FLOPPY
  839.     RET
  840. ;
  841. FSELDSK:DEC    A        ;FOR FLOPPY MAKE B:=A: (OR C:) 
  842.     LD    C,A        ;AND C:=B: (OR D:) FOR FLOPPY PARAMETERS
  843.     OR    A        ;IF REQUESTED DRIVE IS A: THEN [A] = 0
  844.     JP    NZ,BBBB        ;MUST BE B: DRIVE
  845.     LD    A,(ADRIVE)    ;IS IT FIRST TIME TO GET THIS DRIVE
  846.     CP    0FFH
  847.     CALL    Z,GETTYPE
  848.     LD    (ADRIVE),A    ;STORE DENSITY FLAG
  849.     JP    ALLOK
  850. BBBB:    LD    A,(BDRIVE)    ;IS IT FIRST TIME FOR THIS ONE
  851.     CP    0FFH
  852.     CALL    Z,GETTYPE
  853.     LD    (BDRIVE),A    ;STORE DENSITY FLAG
  854. ;
  855. ALLOK:    OR    C        ;MIX DRIVE TYPE WITH DRIVE#
  856.     LD    (UNIT),A    ;STORE IT FOR SECTOR R/W ROUTINES ETC
  857.     INC    A        ;ADD BACK WHAT WE SUBTRACTED ABOVE
  858.     BIT    6,A
  859.     RET    Z        ;RETURNS WITH TABLE OFFSET B:=B: & C:=C:
  860.                 ;FOR DOUBLE DENSITY DISKS WE MUST USE THE
  861.                 ;LOOKUP TABLE FOR DRIVES D: & E:
  862.     LD    A,00000011B    ;RETURNS FOR TABLE OFFSET B:=D: & C:=E:
  863.     ADD    C        ;FOR DOUBLE DENSITY DISKS
  864.     RET    
  865. ;
  866. GETTYPE:LD    A,C        ;FIND OUT TYPE OF DRIVE
  867.     CALL    UNITSL
  868.     JP    NZ,HB101    ;IF NZ PROBLEMS ABORT
  869.     LD    A,(UNIT)
  870.     AND    01000000B    ;GET DENSITY FLAG
  871.     RET
  872. ;
  873. ; THIS ROUTINE SETS UP THE FLOPPY DISK UNIT BYTE
  874. ; THE REQUIRED DRIVE IS IN [A]
  875. ;
  876. UNITSL:    LD    B,5
  877.     AND    0FH
  878.     OR    40H        ;COME UP DEFALT IN 8" DD
  879.     LD    (UNIT),A
  880.     LD    HL,(DMADR)
  881.     LD    (TEMP2),HL
  882.     CALL    USL1
  883.     LD    HL,(TEMP2)
  884.     LD    (DMADR),HL
  885.     LD    A,(UNIT)
  886.     RET    
  887. ;
  888. USL1:    PUSH    BC
  889.     PUSH    HL
  890.     LD    (SPSV),SP
  891.     POP    HL
  892.     CALL    DRVSET        ;SELECT DRIVE IN HARDWARE
  893.     CALL    IDRD        ;TRY READING TRACK ID
  894.     POP    BC
  895.     RET    Z        ;IF CORRECT DENSITY WILL BE Z
  896.     DEC    B        ;DECREASE 5.......0 IF Z THEN ERROR
  897.     JP    Z,SPECIAL
  898.     CALL    CHGTYP
  899.     JR    USL1
  900. ;
  901. SPECIAL:XOR    A        ;COULD BE LATER USED FOR SPECIAL SECTOR SIZE
  902.     DEC    A
  903.     RET            ;RET NZ SO SELDSK KNOWS THERE IS A PROBLEM
  904. ;
  905. CHGTYP:    LD    A,(UNIT)
  906.     ADD    01000000B    ;TOGGLE DENSITY BIT
  907.     AND    01111111B    ;CLEAR BIT 7
  908.     LD    (UNIT),A
  909.     RET
  910. ;
  911. ;    READ A SECTOR
  912. FREAD:    LD    BC,301H
  913. READBT:    LD    (RSEEK),BC
  914. READ1:    PUSH    BC
  915.     CALL    RDSC
  916.     POP    BC
  917.     RET    Z
  918.     CALL    FRETRY
  919.     JR    READ1  
  920. ;
  921. ;    WRITE A SECTOR
  922. FWRITE:    LD    BC,301H
  923. WRBT:    LD    (RSEEK),BC
  924. WRITE1:    PUSH    BC
  925.     CALL    WRSC    
  926.     POP    BC
  927.     RET    Z
  928.     CALL    RETRY
  929.     JR    WRITE1  
  930. ;
  931. FRETRY:    DJNZ    RETRY2  
  932.     LD    A,(RTRY)
  933.     LD    B,A
  934.     DEC    C
  935.     JP    P,RETRY1
  936.     POP    AF
  937.     XOR    A
  938.     INC    A
  939.     RET
  940. ;
  941. RETRY1:    PUSH    BC
  942.     CALL    HOME1
  943.     POP    BC
  944. RETRY2:    RET
  945. ;
  946. HOME1:    LD    (SPSV),SP
  947.     LD    A,RSCMD
  948.     CALL    SEEK4
  949.     XOR    A
  950.     RET
  951. ;
  952. ;    SELECT DRIVE IN HARDWARE
  953. ;
  954. DRVSET:LD    DE,UNIT
  955.     LD    A,(DE)
  956.     AND    0E0H
  957.     LD    C,A        ;STORE DRIVE TYPE IN [C]
  958.     LD    A,(DE)
  959.     AND    03
  960.     LD    B,A        ;STORE DRIVE # IN [B]
  961.     LD    A,1
  962.     JR    Z,DRVSEL  
  963. CKDRV1:    RLCA
  964.     DJNZ    CKDRV1  
  965. DRVSEL:    OR    C        ;COMBINE TYPE & DRIVE#
  966.     AND    7FH
  967.     LD    B,A        ;[B] CONTAINS INFO FOR HARDWARE
  968.     LD    A,STDSDT    ;SETUP FOR SD
  969.     LD    (COUNT),A    ;STORE AS 26 SECTORS/TRACK
  970.     LD    A,40H        ;WAS IT DD
  971. DRV1:    CP    C
  972.     JR    NZ,CKDRV
  973.     LD    A,STDDDT    ;SETUP FOR DD 
  974.     LD    (COUNT),A    ;SET TO 50 SECTORS/TRACK
  975. CKDRV:    LD    A,B        ;GET HARDWARE SELECT DATA
  976.     CPL            ;HARDWARE IS INVERTED
  977.     OUT    (SELECT),A
  978.     LD    A,(DE)
  979.     LD    (UNITCK),A
  980.     CALL    DELAY
  981. RDYCK:    IN    A,(STATUS)
  982.     AND    80H
  983.     JP    NZ,END2
  984.     RET
  985. ;
  986. ;    READ PRESENT DISK ADDRESS
  987. IDRD:    CALL    WAIT
  988.     LD    HL,IDSV
  989.     LD    BC,600H+DATA    ;READ 6 BYTES
  990.     LD    A,0F8H
  991.     LD    (ERMASK),A
  992.     CALL    SWEB
  993.     LD    A,RDACMD    ;DO THE ID READ
  994.     CALL    RDSCO
  995.     LD    A,(IDSV)
  996.     CP    NTRKS        ;IS IT REASONABLE
  997.     JP    NC,SEEK0
  998.     OUT    (TRACK),A    
  999.     XOR    A
  1000.     RET
  1001. ;
  1002. DELAY:    LD    A,40        ;DELAY ~32 MS (DOES NOT SEEM TO BE CRITICAL)
  1003. DELAY1:    LD    B,0
  1004. M0:    DJNZ    M0
  1005.     DEC    A
  1006.     JR    NZ,DELAY1  
  1007.     RET
  1008. ;
  1009. ;    READ SECTOR COMMAND
  1010. RDSC:    CALL    DRINIT
  1011.     LD    A,RDCMD
  1012. RDSCO:    LD    (CMDSV),A
  1013.     DI
  1014.     OUT    (CMD),A
  1015.     JR    M2
  1016. M2:    JR    MM2
  1017. MM2:    INIR
  1018.     EI
  1019.     JR    END
  1020. ;
  1021. ;
  1022. ;    WRITE SECTOR COMMAND
  1023. WRSC:    CALL    DRINIT
  1024.     LD    A,WRCMD
  1025.     LD    (CMDSV),A
  1026.     DI    
  1027.     OUT    (CMD),A
  1028.     JR    H2
  1029. H2:    JR    HM2
  1030. HM2:    OTIR
  1031.     EI
  1032. ;
  1033. ;    END  OF COMMAND
  1034. END:    CALL    WAIT
  1035.     IN    A,(STATUS)
  1036.     LD    D,A
  1037.     LD    A,(ERMASK)
  1038.     AND    D
  1039.     RET    Z
  1040. END1:    LD    A,D
  1041. END2:    LD    (ERSTAT),A
  1042.     CALL    DELAY
  1043.     OR    1
  1044.     LD    SP,(SPSV)
  1045.     CALL    UNITFX
  1046.     RET
  1047. ;
  1048. ;
  1049. ;    DRIVE INITIALIZATION
  1050. ;
  1051. DRINIT:    POP    HL
  1052.     LD    (SPSV),SP
  1053.     PUSH    HL
  1054.     LD    A,(UNIT)
  1055.     LD    D,A
  1056.     LD    A,(UNITCK)
  1057.     CP    D
  1058.     JR    Z,DINIT1  
  1059.     CALL    DRVSET
  1060.     CALL    IDRD
  1061. DINIT1:    CALL    SEEK
  1062.     LD    A,0FEH
  1063.     LD    (ERMASK),A
  1064. ;
  1065. TRINT:    LD    HL,(DMADR)    ;SETUP DMA ADDRESS AND BYTE COUNT
  1066.     LD    A,(RRSEC)
  1067.     OUT    (SECTOR),A
  1068.     LD    BC,NBYTES*100H+DATA
  1069. ;
  1070. SWEB:    IN    A,(SELECT)    ;ENABLE WAIT STATES
  1071.     AND    7FH
  1072.     OUT    (SELECT),A
  1073.     RET
  1074. ;
  1075. ;    SEEK TRACK
  1076. ;
  1077. SEEK:    CALL    RDYCK
  1078.     LD    C,NTRKS        ;MUST BE REASONABLE TRACK #
  1079.     LD    A,(RRTRK)    ;ALWAYS < 0FFH TRACKS FOR FLOPPY
  1080.     CP    C
  1081.     JR    C,SEEK1  
  1082. SEEK0:    LD    A,0FH
  1083.     JR    END2 
  1084. SEEK1:    LD    C,A
  1085.     IN    A,(TRACK)
  1086.     CP    C
  1087.     RET    Z        ;IF SAME TRACK NO NEED TO SEEK
  1088.     LD    A,SKCMD
  1089. SEEK4:    LD    (CMDSV),A
  1090.     LD    B,210
  1091. S0:    DJNZ    S0
  1092.     CALL    WAIT
  1093.     LD    A,(RRTRK)
  1094.     OUT    (DATA),A
  1095.     LD    A,80H
  1096.     LD    (ERMASK),A
  1097.     LD    A,(CMDSV)
  1098.     OUT    (CMD),A
  1099.     LD    B,10
  1100. D0:    DJNZ    D0
  1101.     CALL    END
  1102.     CALL    DELAY
  1103.     LD    A,(CMDSV)
  1104.     CP    RSCMD        ;NO NEED TO CHECK RESTORE COMMAND
  1105.     RET    Z
  1106.     IN    A,(STATUS)
  1107.     AND    10H
  1108.     JR    NZ,SEEK2
  1109.     IN    A,(TRACK)
  1110.     CP    C
  1111.     RET    Z
  1112. SEEK2:    LD    A,20H
  1113. END2JP:    JP    END2  
  1114. ;
  1115. WAIT:    LD    E,0
  1116.     PUSH    BC
  1117.     LD    C,2
  1118. WAIT2:    IN    A,(STATUS)
  1119.     AND    1
  1120.     JR    Z,DWAIT
  1121.     DJNZ    WAIT2  
  1122.     DEC    E
  1123.     JR    NZ,WAIT2
  1124.     DEC    C
  1125.     JR    NZ,WAIT2
  1126.     POP    BC  
  1127.     IN    A,(SELECT)        ;IF BY THIS TIME NOT READY FORCE
  1128.     OR    80H            ;A HARDWARE RESET
  1129.     OUT    (RSET),A
  1130. F0:    DJNZ    F0
  1131.     IN    A,(RSET)
  1132.     CALL    FRCINT
  1133.     LD    A,RSCMD
  1134.     CALL    SEEK4
  1135.     LD    A,0FEH
  1136.     JP    END2JP    
  1137. ;
  1138. ;    DISABLE WAIT STATES
  1139. DWAIT:    POP    BC            ;TO BALANCE THE ABOVE PUSH IN WAIT
  1140.     IN    A,(SELECT)
  1141.     OR    80H
  1142.     OUT    (SELECT),A
  1143.     RET
  1144. ;
  1145. ;
  1146. ;
  1147. ;    FORCE CHIP INTERUPT
  1148. FRCINT:    LD    A,0D0H
  1149.     OUT    (CMD),A
  1150.     LD    A,10
  1151. FRC1:    DEC    A
  1152.     JR    NZ,FRC1
  1153.     IN    A,(STATUS)
  1154.     RET
  1155. ;
  1156. UNITFX:    LD    A,0FFH
  1157.     LD    (UNITCK),A
  1158.     RET
  1159. ;
  1160. ;
  1161. ;    ======================================
  1162. ;    ** SUBROUTINES, MESSAGES, & STORAGE **
  1163. ;    ======================================
  1164. ;
  1165. ;    ---DOUBLE RIGHT SHIFT---
  1166. ;
  1167. ;   SHIFTS THE CONTENTS OF H/L RIGHT 'N' TIMES.
  1168. ;
  1169. DRS:    PUSH    AF         ;SAVE 'A'
  1170. DRS1:    LD    A,H         ;MSB
  1171.     OR    A         ;CLEAR CY
  1172.     RRA    
  1173.     LD    H,A
  1174.     LD    A,L         ;LSB
  1175.     RRA    
  1176.     LD    L,A
  1177.     DEC    B         ;B = SHIFT COUNT
  1178.     JP    NZ,DRS1
  1179.     POP    AF         ;RESTORE 'A'
  1180.     RET    
  1181. ;
  1182. ;    ---PRINT ROUTINE---
  1183. ;
  1184. ;
  1185. PRNT:    LD    A,(HL)         ;PRINT CHAR
  1186.     INC    HL         ;FOR NEXT CHAR
  1187.     OR    A
  1188.     RET    Z         ;RIF DONE
  1189.     LD    C,A
  1190.     CALL    ZCO         ;PRINT A CHAR
  1191.     JP    PRNT         ;DO NEXT CHAR
  1192. ;
  1193. ;
  1194. HB101:    LD    HL,0        ;ABORT BECAUSE CANNOT GET DISK TYPE
  1195.     POP    AF        ;DROP STACK BACK ONE LEVEL
  1196.     XOR    A
  1197.     LD    (CDISK),A    ;SO WARMSTART WILL COME UP ON A
  1198.     INC    A        ;JUST IN CASE
  1199.     RET
  1200. ;
  1201. ;    ---MESSAGES---
  1202. ;
  1203. MSG1:    DEFB    CR,LF,BELL
  1204.     DEFB    'Warm boot read error'
  1205.     DEFB    CR,LF,0
  1206. ;
  1207. ;    ---PROGRAM STORAGE---
  1208. ;
  1209. FLAGS:    DEFS    1         ;BIT FLAGS
  1210.                  ;BIT 0 SET FOR READ OPERATION
  1211.                  ;BIT 1 SET FOR READ IN PROGRESS
  1212.                  ;BIT 2 SET FOR WRITE IN PROGRESS
  1213. ;
  1214. RRTRK    DEFS    2         ;CP/M REQUESTED TRACK ADDRESS
  1215. RRDSK    DEFS    1         ;CP/M REQUESTED DRIVE #
  1216. RRSEC    DEFS    1         ;CP/M REQUESTED SECTOR
  1217. ;
  1218. URTRK:    DEFS    2         ;UNALLOCATED TRACK ADDRESS
  1219. URDSK:    DEFS    1         ;   DRIVE #
  1220. URSEC:    DEFS    1         ;   SECTOR ADDRESS
  1221. URCNT:    DEFS    1         ;   RECORD COUNT
  1222. ;
  1223. HHTRK:    DEFS    2         ;HOST (SHUGART) TRACK ADDRESS
  1224. HHDSK:    DEFS    1         ;   DRIVE #
  1225. HHSEC:    DEFS    1         ;   SECTOR ADDRESS
  1226. ;
  1227. RTK:    DEFS    2         ;REAL TRACK ADDRESS
  1228. RHD:    DEFS    1         ;  HEAD
  1229. RSA:    DEFS    1         ;  SECTOR
  1230. ;
  1231. SECNT:    DEFS    1         ;SECTOR COUNT (FOR WARM BOOT)
  1232. RETRY:    DEFS    1         ;RETRY COUNT
  1233. CTA:    DEFS    2         ;COMMAND TABLE ADDRESS
  1234. ERFLG:    DEFS    1         ;ERROR FLAG
  1235. DMADR:    DEFS    2         ;BUFFER (DMA) ADDRESS
  1236. WRTMODE:DEFS    1         ;WRITE MODE
  1237. CHDT:    DEFS    2         ;CURRENT HARD DISK TRACK
  1238. TEMP:    DEFS    2         ;TEMPORARY STORAGE
  1239. ;
  1240. FLGSIZ:    EQU    $-FLAGS         ;DEFINES SIZE OF VARIABLE STORAGE
  1241. ;
  1242. ;    ---BDOS STORAGE---
  1243. ;
  1244. DIRBUF:    DS    128         ;DIRECTORY ACCESS BUFFER
  1245. ALV0:    DS    31
  1246. CSV0:    DS    16
  1247. ALV1:    DS    31
  1248. CSV1:    DS    16
  1249. ALV2:    DS    30
  1250. CSV2:    DS    16
  1251. ALV3:    DS    30
  1252. CSV3:    DS    16
  1253. HALL0:    DS    306    ;BIT MAP FOR ST-506
  1254. LAST:    EQU    $
  1255. ;END
  1256.