home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpmug / cpmug082.ark / NBIOS56.ASM < prev    next >
Assembly Source File  |  1984-04-29  |  56KB  |  2,199 lines

  1.     TITLE    'BIOS - NORTH STAR DD CP/M 2.2 OF 02/21/82'
  2. ;    PAGE    44
  3. ;
  4. ; These routines copyright (c) 1980, 1981, 1982 by Steve Bogolub,
  5. ; 2338 S. Scoville Ave., Berwyn, IL 60402.  Jade Double D (tm)
  6. ; disk handlers contributed to the public domain for use on Jade
  7. ; equipment by special permission of Jade Computer Products.
  8. ; This software may be used freely for non-commercial purposes
  9. ; only, and may not be sold.
  10. ;
  11. ;  THIS BIOS CONTAINS ROUTINES TO SUPPORT THE
  12. ; FOLLOWING HARDWARE:
  13. ;
  14. ; DISK:    NORTH STAR MDS-AD2 DOUBLE DENSITY 5.25"
  15. ;    FLOPPY DISK UNITS 1 AND 2 AS CP/M DRIVES
  16. ;    A: AND B:
  17. ;
  18. ;    JADE DOUBLE D REV C 8" FLOPPY DISK UNITS
  19. ;    0 AND 1 AS CP/M DRIVES C: AND D:
  20. ;
  21. ; SERIAL I/O:    HORIZON LEFT (LOW) SERIAL I/O PORT AS
  22. ;        CP/M DEVICE CRT:
  23. ;
  24. ;    QT IO+ BLOCK D (RIGHT) USART AS CP/M DEVICE
  25. ;    UC1:, INIT'ED TO 19.2K BAUD RATE
  26. ;
  27. ;    QT IO+ BLOCK C (LEFT) USART AS CP/M DEVICE
  28. ;    TTY:, INIT'ED TO 300 BAUD RATE
  29. ;
  30. ;    HORIZON RIGHT (HIGH) SERIAL I/O PORT AS
  31. ;    CP/M DEVICE LPT:, WHICH IS SUPPORTED AS
  32. ;    A MODEL 40 TELETYPE WITH THE SIMPLIFIED
  33. ;    (HANDSHAKE) EIA INTERFACE, AND IS GENNED-IN
  34. ;    AS THE LIST DEVICE.
  35. ;
  36. ;  THE GENNED-IN CONSOLE IS DETERMINED BY SOLICITING
  37. ; A SPACE CODE (20H) FROM CRT:, TTY:, AND UC1:. IF
  38. ; NO SPACE CODE IS RECEIVED AFTER ABOUT EIGHT SECONDS
  39. ; (AT 4 MHZ), CRT: IS ASSUMED TO BE THE CONSOLE. IF
  40. ; A SPACE IS READ FROM ONE OF THE DEVICES, THAT DEVICE
  41. ; IS ASSUMED TO BE THE CONSOLE.
  42. ;
  43. ;  LIST DEVICE UL1: PRINTS ON THE CURRENT CON: DEVICE.
  44. ; IF TTY: IS THE LIST DEVICE, DTR MUST BE HIGH, PROVIDING
  45. ; A SERIAL PRINTER PORT. BAT: IS NOT SUPPORTED, AND IS
  46. ; SET TO LPT: FOR OUTPUT AND CRT: FOR INPUT.
  47. ;
  48. ;  SINCE THIS BIOS IS SO LARGE, MOVCPM SHOULD BE
  49. ; RUN FOR TWO LESS THAN THE DESIRED SYSTEM SIZE
  50. ; IN K, I.E. SPECIFY 30 FOR A 32K SYSTEM.
  51. ;
  52. ;   ***   IMPORTANT BOOTSTRAP INFO   ***
  53. ;
  54. ;  THIS BIOS IS INTENDED TO RUN IN THE LAST
  55. ; 3.5K OF MEMORY. THE LAST .5K IS SET ASIDE
  56. ; FOR A NORTH STAR SECTOR DEBLOCKING BUFFER.
  57. ; THE FIRST 3K IS GENNED-IN BIOS CODE, AND
  58. ; IS EXPECTED TO RESIDE ON TRACK 0 OF NORTH
  59. ; STAR DISK UNIT 1 (A:) IN SECTORS 5-9, AND
  60. ; 4. THE NORTH STAR BOOT PROM READS IN SECTOR
  61. ; 4 INTO CONSECUTIVE PAGES OF MEMORY, STARTING
  62. ; WITH THE PAGE NUMBER SPECIFIED BY THE FIRST
  63. ; BYTE OF SECTOR DATA, THEN JUMPS TO THAT
  64. ; ADDRESS + 10 (0AH). THIS BIOS IS SET UP TO
  65. ; USE THAT METHOD TO COLD BOOT ITSELF. CODE
  66. ; AT THAT ADDRESS READS THE LAST FIVE SECTORS
  67. ; OF TRACK ZERO INTO MEMORY AT ADDRESS "BIOS",
  68. ; THEN JUMPS TO THE BIOS COLD START ADDRESS.
  69. ; THE BIOS COLD BOOT EXPECTS THE JADE DOUBLE D
  70. ; CONTROL CODE ("NDCM") TO RESIDE ON SECTORS
  71. ; ONE AND TWO OF TRACK ZERO, AND LOADS THOSE
  72. ; SECTORS FROM THE DISK INTO THE JADE DD MEMORY,
  73. ; THEN RESETS AND STARTS UP THE JADE DD RESIDENT
  74. ; Z80. THE BIOS WARM BOOT EXPECTS THE CCP/BDOS
  75. ; CODE TO RESIDE ON TRACKS 0-9 OF TRACK ONE
  76. ; (IN OTHER WORDS, THE WHOLE TRACK), AND THE
  77. ; LAST SECTOR IS EXPECTED TO BE ON TRACK ZERO,
  78. ; SECTOR 3. TRACK ZERO, SECTOR ZERO IS RESERVED
  79. ; FOR LIFEBOAT-COMPATIBLE ID INFO AND FUTURE
  80. ; ADDITIONS. THE MODIFIED VERSION OF SYSGEN
  81. ; NAMED "NSGEN" IS SET UP TO TRANSFER CP/M TO
  82. ; AND FROM DISK IN THIS REQUIRED MANNER.
  83. ;
  84. ;  WE USE THE Z80 INSTRUCTION "LD A,I" ON ENTRY
  85. ; TO THE DISK READ AND WRITE ROUTINES TO GET
  86. ; THE STATUS OF THE INTERRUPT FLIP/FLOP, SINCE
  87. ; WE MUST DISABLE INTERRUPTS WHILE THE NORTH
  88. ; STAR DISK READS OR WRITES ARE PERFORMED.
  89. ; USING THE Z80 STATUS, WE CAN RE-ENABLE
  90. ; INTERRUPTS AFTER WE LEAVE. THIS CHECK IS
  91. ; DONE BY THE ROUTINES "INTDI" AND "INDEN",
  92. ; AND CAN EASILY BE REMOVED IF WE EVER GO
  93. ; TO A NON-Z80 CPU (NEVER, I HOPE).
  94. ;
  95. LDAI    EQU    057EDH        ;Z80 "LD A,I" BYTE-SWAPPED
  96.                 ; FOR "DW" USE
  97. ;
  98. ;  DISK OPERATING SYSTEM ADDRESSES
  99. ;
  100. NKSYS    EQU    56        ;SYS SIZE IN K BYTES
  101. KBYTE    EQU    1024        ;1K BYTE SIZE
  102. CPMSZ    EQU    NKSYS*KBYTE    ;TOP SYSTEM ADDRESS
  103. CPMBS    EQU    CPMSZ-(22*KBYTE);CP/M BIAS VALUE
  104. CCP    EQU    CPMBS+3400H    ;ADDRESS OF CCP
  105. BDOS    EQU    CPMBS+3C00H    ;ADDRESS OF BDOS
  106. BIOS    EQU    CPMBS+4A00H    ;ADDRESS OF BIOS
  107. BIOSR    EQU    1F80H-BIOS+400H    ;DDT LOAD OFFSET
  108.             ;(LEAVES ROOM FOR NDCM)
  109. IOBYTE    EQU    0003H        ;IOBYTE ADDRESS
  110. DEFDSK    EQU    0004H        ;DEFAULT DISK FOR CCP
  111. SECSZ    EQU    128        ;BYTES PER SECTOR
  112. HSTSIZ    EQU    512        ;BYTES PER N* SECTOR
  113. NDRVS    EQU    4        ;# DRIVES IN SYSTEM
  114. ;
  115. ;  BDOS CONSTANTS ON ENTRY TO WRITE
  116. ;
  117. WRALL    EQU    0        ;WRITE TO ALLOCATED
  118. WRDIR    EQU    1        ;WRITE TO DIRECTORY
  119. WRUAL    EQU    2        ;WRITE TO UNALLOCATED
  120. ;
  121. ;  NORTH STAR MEMORY MAPPED I/O ADDRESSES
  122. ;
  123. NSROM    EQU    0E800H        ;COLD BOOT ROM ADDRESS
  124. WDATA    EQU    0E900H        ;WRITE DATA. DATA IS
  125.                 ; LOW 8 ADRESS BITS.
  126. CORDER    EQU    0EA00H        ;CONTROLLER ORDER
  127. CCMND    EQU    0EB00H        ;CONTROLLER COMMAND
  128. ;
  129. ;  DOUBLE D HARDWARE PARAMETERS
  130. ;
  131. DPORT    EQU    043H        ;DOUBLE D PORT ADDRESS
  132. DBASE    EQU    0E000H        ;DOUBLE D WINDOW MEM BASE ADDR
  133. DSHLT    EQU    001H        ;STATUS PORT INDICATOR
  134. ;
  135. ;  DOUBLE D HARDWARE COMMANDS
  136. ;
  137. DCSIN    EQU    001H        ;SWITCH DD BANK 0 INTO SYS
  138. DCMB0    EQU    001H        ;SELECT DD BANK 0
  139. DCMB1    EQU    003H        ;SELECT DD BANK 1
  140. DCSOT    EQU    000H        ;SWITCH DD MEM OUT OF SYS
  141. DCINT    EQU    002H        ;ISSUE DD Z80A INTERRUPT
  142. DCBGN    EQU    080H        ;RESET DD Z80A AND EXECUTE
  143. ;
  144. ;  DISK CONTROLLER MODULE LINKAGE (DCM - VER 2.2)
  145. ;
  146. ;  -- COMMAND BLOCK DEFINED
  147. ;
  148. DDCBT    EQU    0370H        ;COMMAND BYTE    (BANK 0)
  149. DDDRV    EQU    0371H        ;DRIVE NUMBER    (BANK 0)
  150. DDTRK    EQU    0372H        ;TRACK NUMBER    (BANK 0)
  151. DDSEC    EQU    0373H        ;SECTOR NUMBER    (BANK 0)
  152. DDSTS    EQU    0377H        ;COMMAND STATUS    (BANK 0)
  153. DDBBF    EQU    0000H        ;1024 SECTOR BUFFER (BANK 1)
  154. DDFBF    EQU    0300H        ;FORMAT BUFFER    (BANK 1)
  155. FMTSZ    EQU    0100H        ;FORMAT BUFF SIZE
  156. DDDPB    EQU    0020H        ;ID SEC DPB    (BANK 1)
  157. DDDDF    EQU    DDDPB+0011H    ;ID SEC FLAGS    (BANK 1)
  158. ;
  159. ;  -- DCM COMMANDS
  160. ;
  161. DCLOG    EQU    000H        ;LOG ON DISKETTE
  162. DCRDS    EQU    001H        ;READ SECTOR
  163. DCWRS    EQU    002H        ;WRITE SECTOR
  164. DCFMT    EQU    003H        ;FORMAT TRACK
  165. DCIDL    EQU    007H        ;STAY IDLE
  166. ;
  167. ;  CONSOLE DEFINITIONS
  168. ;
  169. MOTHR    EQU    000H        ;HORIZON MOTHERBOARD BASE
  170. CRT    EQU    MOTHR+2        ;HORIZON LEFT SERIAL BASE
  171. ;
  172. QTIO    EQU    0A0H        ;QT IO+ BOARD BASE
  173. QTCTRL    EQU    QTIO+03H    ;QT CONTROL PORT
  174. QTBAUD    EQU    QTIO+01H    ;QT BAUD RATE PORT
  175. TTY    EQU    QTIO+08H    ;QT LEFT SERIAL BASE
  176. UC1    EQU    QTIO+0CH    ;QT RIGHT SERIAL BASE
  177. ;
  178. CR    EQU    0DH        ;ASCII CARRIAGE RETURN
  179. LF    EQU    0AH        ;ASCII LINE FEED
  180. SPACE    EQU    20H        ;ASCII SPACE
  181. ;
  182. ;  PRINTER DEFINITIONS
  183. ;
  184. LPD    EQU    MOTHR+4        ;DATA OUT
  185. LPC    EQU    LPD+1        ;STATUS
  186. LPIO    EQU    MOTHR+6        ;CHAIN CONTROL WORD
  187. CHAIN    EQU    10H        ;CHAIN RUNNING BIT IN LPIO
  188. FF    EQU    0CH        ;ASCII FORM FEED
  189. ;
  190. ;
  191. ;  BIOS JUMP VECTOR TABLE
  192. ;
  193.     ORG    BIOS        ;START OF BIOS CODE
  194. ;
  195.     JMP    NSROM        ;COLD BOOT FROM ROM
  196.     JMP    WARM        ;RELOAD CCP/BDOS
  197. ;
  198. ;  USE VECTORS FOR INTERNAL CALLS ON CONSOLE ROUTINES
  199. ; INSTEAD OF CALLING THE ROUTINES DIRECTLY SO THAT
  200. ; BIOS ERROR I/O CAN BE HANDLED BY "BYE" AND OTHER
  201. ; VECTOR-PATCHING PROGRAMS.
  202. ;
  203. BCNSCK:    JMP    CNSCK        ;GET CONSOLE STATUS
  204. BCNSIN:    JMP    CNSIN        ;CONSOLE INPUT
  205. BCNSOT:    JMP    CNSOT        ;CONSOLE OUTPUT
  206. ;
  207.     JMP    LIST        ;PRINTER OUTPUT
  208.     JMP    PUNCH        ;PUNCH OUTPUT
  209.     JMP    READER        ;READER INPUT
  210.     JMP    HOME        ;HOME SELECTED DRIVE
  211.     JMP    SELDSK        ;SELECT DISK DRIVE
  212.     JMP    SETTRK        ;SET TRACK NUMBER
  213.     JMP    SETSEC        ;SET SECTOR NUMBER
  214.     JMP    SETDMA        ;SET TRANSFER ADDRESS
  215.     JMP    DISKRD        ;PERFORM DISK READ
  216.     JMP    DISKWR        ;PERFORM DISK WRITE
  217.     JMP    LISTST        ;RETURN LIST STAT
  218.     JMP    SECTRN        ;TRANSLATE SECTOR
  219.     JMP    FORMAT        ;FORMAT A JADE DD TRACK
  220. ;
  221. ;  INIT - COLD START ENTRY ** DIRECTORY BUFFER OVERLAY **
  222. ;
  223. DIRBF    EQU    $        ;BUFFER BEGINNING
  224. ;
  225. ;  SCRATCH RAM FOR BDOS OVERLAY
  226. ;
  227. D0ALL    EQU    DIRBF+SECSZ    ;OVERLAY ALLOCATE AND CHECK
  228. D0CHK    EQU    D0ALL+23    ; BUFFERS HERE TOO
  229. D1ALL    EQU    D0CHK+16
  230. D1CHK    EQU    D1ALL+23
  231. D2ALL    EQU    D1CHK+16    ;NOTE THAT THE JADE DISKS
  232. D2CHK    EQU    D2ALL+39    ; (C: AND D:) MAY NEED
  233. D3ALL    EQU    D2CHK+32    ; MUCH MORE ALLOC AND
  234. D3CHK    EQU    D3ALL+39    ; CHECK SPACE THAN N*
  235. ;
  236. ENDOV    EQU    D3CHK+32    ;END OF OVERLAY AREA
  237. ;
  238. ;  THE INIT ROUTINE IS ACTUALLY A CONTINUATION OF THE
  239. ; COLD BOOT BEGUN DOWN AT "BOOT".
  240. ;
  241. INIT:    LXI    SP,HSTBUF+HSTSIZ ;SET SP TO SCRATCH AREA
  242.     LXI    H,CCP        ;WHERE TO START CP/M
  243.     PUSH    H
  244.     XRA    A        ;INIT HORIZON MOTHERBOARD
  245.     OUT    MOTHR+6
  246.     STA    COLDB        ;BIOS NOW IN MEMORY
  247.     MVI    A,0B1H        ;INIT QT IO+ BOARD
  248.     OUT    QTCTRL
  249.     MVI    A,01FH        ;INIT UC1: TO 19.2K BAUD
  250.     OUT    QTBAUD
  251.     MVI    A,005H        ;INIT TTY: TO 300 BAUD
  252.     OUT    QTBAUD
  253.     CALL    DELAY        ;DELAY FOR 8251'S
  254.     MVI    A,0AEH        ;INIT SERIAL PORTS
  255.     OUT    CRT+1        ;OUTPUT DUMMY MODE TO INSURE
  256.     OUT    TTY+1
  257.     OUT    UC1+1
  258.     OUT    LPC
  259.     CALL    DELAY
  260.     MVI    A,040H        ; CMD EXPECTED, THEN OUTPUT
  261.     OUT    CRT+1        ; RESET CMD
  262.     OUT    TTY+1
  263.     OUT    UC1+1
  264.     OUT    LPC
  265.     CALL    DELAY
  266.     MVI    A,04EH        ;MODE: 1 STOP BIT, 16X CLK,
  267.     OUT    CRT+1        ; 8 DATA BITS, NO PARITY
  268.     OUT    TTY+1
  269.     OUT    UC1+1
  270.     OUT    LPC
  271.     CALL    DELAY
  272.     MVI    A,037H        ;CMD: RTS, ER, RXEN, DTR, TXEN
  273.     OUT    CRT+1
  274.     OUT    TTY+1
  275.     OUT    UC1+1
  276.     CALL    DELAY
  277.     CALL    LGOOSE        ;FINISH INIT OF MODEL 40
  278.     IN    CRT        ;FLUSH RECEIVER INPUTS
  279.     IN    TTY
  280.     IN    UC1
  281. ;
  282. ;  WAIT APPROX 8 SECONDS FOR OPERATOR TO STRIKE
  283. ; THE SPACE BAR ON CRT:, UC1:, OR TTY: TO DETERMINE
  284. ; CONSOLE. IF NO SPACE RECEIVED, DEFAULT TO CRT:.
  285. ;
  286.     LXI    H,0        ;SET UP WAIT
  287.     MVI    B,2        ; FOR ABOUT 8 SECS
  288. ;
  289. ICHK:    CALL    CRTCHK        ;CHECK CRT:
  290.     JZ    ICHK5        ;PASS IF NOTHING
  291.     IN    CRT        ; ELSE READ CHAR
  292.     ANI    07FH        ;STRIP PARITY
  293.     CPI    SPACE        ;IS IT SPACE?
  294.     JNZ    ICHK5        ;TOSS IF NOT
  295.     JMP    ICHK20        ;IF SO, CON:=CRT:
  296. ;
  297. ICHK5:    CALL    TTYCHK        ;CHECK TTY:
  298.     JZ    ICHK10
  299.     IN    TTY
  300.     ANI    07FH
  301.     CPI    SPACE
  302.     JNZ    ICHK10
  303.     MVI    A,00B        ;CON:=TTY:
  304.     JMP    ICHK25        ;GO SET IT
  305. ;
  306. ICHK10:    CALL    UC1CHK        ;CHECK UC1:
  307.     JZ    ICHK15
  308.     IN    UC1
  309.     ANI    07FH
  310.     CPI    SPACE
  311.     JNZ    ICHK15
  312.     MVI    A,11B        ;CON:=UC1:
  313.     JMP    ICHK25        ;GO SET IT
  314. ;
  315. ICHK15:    DCX    H        ;COUNT DOWN
  316.     MOV    A,H
  317.     ORA    L
  318.     JNZ    ICHK
  319.     DCR    B
  320.     JNZ    ICHK
  321. ;
  322. ICHK20:    MVI    A,01B        ;TIME UP, SET CON:=CRT:
  323. ;
  324. ICHK25:    ADI    80H        ;DEFAULT LST:=LPT:
  325.     STA    IOBYTE        ;SET INITIAL I/O BYTE
  326.     LXI    H,MSGSO        ;SIGN-ON MSG ADDRESS
  327.     CALL    MSGOT        ;ISSUE MESSAGE
  328. ;
  329. ;  MUST NOW LOAD UP THE JADE DOUBLE D CONTROL CODE
  330. ; OFF THE DISK AND START UP THE DOUBLE D.
  331. ;
  332.     MVI    A,DCSIN        ;REQUEST BANK ZERO
  333.     OUT    DPORT
  334.     MVI    A,1        ;CODE STARTS ON SEC 1
  335.     STA    HSTSEC        ;WE KNOW HSTTRK STILL 0
  336.     IN    DPORT        ;INPUT DD BOARD STATUS
  337.     ANI    0EH        ;MASK FOR ADDRESS SWITCHES
  338.     RLC            ;POSITION BITS
  339.     ORI    DBASE SHR 8    ;OR IN BASE ADDRESS
  340.     MOV    H,A        ;FORM WINDOW ADDRESS IN HL
  341.     MVI    L,0
  342.     SHLD    DADDR        ;SAVE ADDRESS FOR ALL JADE I/O
  343.     SHLD    HSTADR        ;SET NS I/O ADDR TO DD MEM
  344.     CALL    WSETUP        ;KICK MOTORS AND SEEK TRK
  345.     CALL    WRMRD        ;READ SECTOR AND CHECK ERR
  346.     MVI    A,2        ;CODE EXTENDS INTO SEC 2
  347.     STA    HSTSEC
  348.     LXI    D,512
  349.     LHLD    DADDR
  350.     DAD    D
  351.     SHLD    HSTADR
  352.     CALL    WRMRD
  353.     MVI    A,DCBGN        ;NOW START UP DD Z80
  354.     OUT    DPORT
  355. ;
  356.     JMP    CPMLD        ;GO PERFORM WARM BOOT FUNCS
  357. ;
  358. ;  THIS DELAY SUBROUTINE IS USED TO HELP US OUT ON
  359. ; TIMING WHEN RESETTING THE 8251 CONSOLE SERIAL DEVICE.
  360. ;
  361. DELAY:    LXI    B,600H
  362. DEL5:    DCX    B
  363.     MOV    A,B
  364.     ORA    C
  365.     JNZ    DEL5
  366.     RET
  367. ;
  368. MSGSO:    DB    CR,LF,'North Star / '
  369.     DB    'Jade DD '
  370.     DB    (NKSYS/10)+'0',(NKSYS MOD 10)+'0'
  371.     DB    'K CP/M 2.2 of 02/21/82',CR,LF+80H
  372. ;
  373.     IF    ($-ENDOV) SHR 15
  374.     ORG    ENDOV        ;FILL OUT OVERLAY SIZE
  375.     ENDIF
  376. ;
  377. ;  SELECT DRIVE - LOGON
  378. ;
  379. SELDSK:    LXI    H,0        ;ERROR RETURN CODE
  380.     MOV    A,C        ;PUT DRIVE # IN A
  381.     CPI    NDRVS        ;CHECK IF LEGAL DRIVE
  382.     RNC            ;NO CARRY IF ILLEGAL
  383.     STA    SEKDSK        ;STORE DRIVE NUMBER
  384.     MOV    B,E        ;SAVE LOGON REQ REG
  385.     MOV    L,C        ;L = DISK NUMBER
  386.     MVI    H,0        ;ZERO H REG
  387.     DAD    H        ; *2
  388.     DAD    H        ; *4
  389.     DAD    H        ; *8
  390.     DAD    H        ; *16 (SIZE OF HEADER)
  391.     LXI    D,D0DPH        ;DRIVE 0 DPH
  392.     DAD    D        ;HL = DRIVE N DPH
  393.     SHLD    DTPTR        ;STORE DRIVE TBL PTR
  394. ;
  395. ;  LOG-ON - SET DISK PARAMETER BLOCK
  396. ;
  397. ;  -- CHECK IF LOG-ON REQUESTED
  398. ;
  399.     XRA    A
  400.     STA    LOGFLG        ;ASSUME NO JADE LOGON
  401.     MOV    A,B        ;CHECK LOG REQUEST
  402.     ANI    001H        ;LOG ON BIT TEST
  403.     JNZ    NOLOG        ;PASS IF NO REQUEST
  404.     CALL    HFLUSH        ;MAKE SURE HOST BUF
  405.     JNZ    LOGERR        ; AVAILABLE, OUT ON ERR
  406. ;
  407. ;  SEE IF DISK IS JADE OR NORTH STAR.
  408. ;
  409.     LDA    SEKDSK        ;GET DISK #
  410.     CPI    2
  411.     JNC    LOGJAD        ;IF JADE, GO ELSEWHERE
  412. ;
  413. ;  LOG ON NORTH STAR BY READING ID SECTOR, THEN DECIDE
  414. ; WHICH TABLE TO USE BASED ON SINGLE OR DOUBLE DENSITY.
  415. ; IF DOUBLE DENSITY, LOOK FOR LIFEBOAT 2.X FLAG BYTE
  416. ; AT OFFSET 05CH IN THE SECTOR, AND USE LIFEBOAT 2.X
  417. ; DPB IF THAT BYTE CONTAINS 0B0H. IF NOT, ASSUME OUR
  418. ; NORMAL LIFEBOAT 1.4-COMPATIBLE DPB FOR DOUBLE DENSITY.
  419. ;
  420.     STA    HSTDSK        ;GOING TO ACCESS THIS DISK
  421.     XRA    A
  422.     STA    HSTTRK        ;TRACK ZERO
  423.     STA    HSTSEC        ;N* SECTOR ZERO
  424.     CALL    INTDI        ;INTERRUPTS OFF
  425.     CALL    READHST        ;READ THE SECTOR
  426.     CALL    INTEN        ;INTERRUPTS RESTORED
  427.     LDA    ERFLAG        ;CHECK FOR READ ERROR
  428.     ORA    A
  429.     JNZ    LOGERR        ;LOG-ON ERROR IF SO
  430.     LDA    NSDENS        ;IF OK, GET DENSITY FLAG
  431.     LXI    B,TRAN5S    ;ASSUME SINGLE DENSITY,
  432.     LXI    D,DPBNSS    ; EVEN THO USUALLY WRONG
  433.     ORA    A        ;CHECK
  434.     JNZ    LOGNSD        ;GO ON IF RIGHT
  435.     LXI    B,TRAN5D    ;DOUBLE DENS, COMMON XLATE
  436.     LXI    D,DPBNSD    ; BUT ASSUME OUR 1.4 DPB
  437.     LDA    HSTBUF+05CH    ;GET LIFEBOAT FLAG BYTE
  438.     CPI    0B0H        ;IS IT LIFEBOAT 2.X FLAG?
  439.     JNZ    LOGNSD        ;KEEP OUR DPB IF NOT
  440.     LXI    D,DPBNSL    ;GO TO LIFEBOAT 2.X IF NOT
  441. ;
  442. LOGNSD:    LHLD    DTPTR        ;LOAD DRIVE TBL PTR
  443.     MOV    M,C        ;SET TRANSLATE TABLE ADDR
  444.     INX    H
  445.     MOV    M,B
  446.     LXI    B,9        ;PT TO DPB ADDR
  447.     DAD    B
  448.     MOV    M,E        ;SET DPB ADDR
  449.     INX    H
  450.     MOV    M,D
  451.     JMP    NOLOG        ;GO COMPLETE LOGON NOW
  452. ;
  453. ;  -- READ JADE IDENTITY SECTOR
  454. ;
  455. LOGJAD:    STA    LOGFLG        ;LOGGING ON JADE DISK
  456.     MVI    A,DCSIN        ;SWITCH DD INTO SYS
  457.     OUT    DPORT        ;ISSUE HARDWARE CMND
  458.     MVI    A,DCLOG        ;LOAD DCM LOG-ON CMND
  459.     CALL    DSKEX        ;PERFORM DISK OP
  460.     JZ    LOGCK        ;PASS IF OK
  461.     CALL    DSKER        ;ERROR, BAD LOG ON
  462. ;
  463. LOGERR:    LXI    H,0
  464.     RET
  465. ;
  466. ;  -- CHECK FOR JADE ID
  467. ;
  468. LOGCK:    MVI    A,DCMB1        ;SELECT BANK 1
  469.     OUT    DPORT        ; BECAUSE BUFFER IS THERE
  470.     LHLD    DADDR        ;GET DD BUFFER ADDR IN HL
  471.     LXI    D,JADEID    ;DE PNTS TO BIOS ID
  472.     MVI    B,IDSZE        ;SET LABEL SIZE
  473. LOGID:    LDAX    D        ;GET LABEL CHARACTER
  474.     CMP    M        ;DOES ID SECTOR MATCH?
  475.     JNZ    LG3740        ;ASSUME 3740 IF NOT
  476.     INX    H        ;ADVANCE PTRS
  477.     INX    D
  478.     DCR    B
  479.     JNZ    LOGID        ;GO BACK IF MORE TO MATCH
  480. ;
  481. ;  -- DISKETTE CONTAINS ID
  482. ;
  483.     CALL    TRNONE        ;ASSUME DDENS
  484.     CALL    DPBAD        ;GET DPB ADDR IN DE
  485.     LXI    B,DDDPB        ;GET ID DPB ADDR IN HL
  486.     LHLD    DADDR
  487.     DAD    B
  488.     LXI    B,DPBSZ        ;DPB SIZE IN BYTES
  489.     CALL    BLOCK        ;MOVE INTO DPB
  490.     LXI    B,DDDDF        ;CALC ADDR OF ID FLAGS
  491.     LHLD    DADDR
  492.     DAD    B
  493.     MOV    A,M        ;GET ID FLAGS IN ACC
  494.     PUSH    PSW        ;SAVE FLAGS
  495.     ANI    0F0H        ;STRIP LOW FLAGS
  496.     RAR            ;MOVE SECTOR SHIFT BIT
  497.     RAR            ; FLAG RIGHT
  498.     RAR
  499.     DCX    D        ;PT INTO DPB ADD-ON
  500.     STAX    D        ;SAVE SECTOR SHIFT
  501.     ORA    A        ;IS THERE A SHIFT?
  502.     CNZ    TR1024        ;USE 1024 BYTES/SECTOR
  503.                 ; XLATE TABLE IF SO
  504.     POP    PSW        ;GET ORIG FLAGS AGAIN
  505.     ANI    04H        ;TEST DATA DENSITY
  506.     CZ    TR3740        ;IF ZERO USE 3740 TRN
  507. ;
  508. ;  SET UP DEBLOCKING VARIABLES FROM DPB VALUES
  509. ;
  510. NOLOG:    CALL    DPBAD        ;GET DPB ADDR
  511.     XCHG            ; IN HL
  512.     MOV    A,M        ;SET UP DEBLOCK
  513.     STA    CPMSPT        ; SECTORS PER TRACK
  514.     INX    H        ;GET TO GROUP MASK
  515.     INX    H
  516.     INX    H
  517.     MOV    A,M        ;GET IT
  518.     INR    A        ;CALC # BLOCKS/GROUP
  519.     STA    UNAVAL        ; AND SAVE THAT
  520.     LXI    D,12
  521.     DAD    D        ;PT TO SECTOR SHIFT
  522.     MOV    A,M        ; BIT FLAG
  523.     ORA    A        ;HAVE WE GOT ONE?
  524.     JZ    NOSHF        ;PASS IF NOT
  525.     MVI    B,0FFH        ;INIT SHIFT COUNT
  526. ;
  527. CALCSH:    INR    B        ;COUNT UP A SHIFT
  528.     RAR            ;SEE IF DONE
  529.     JNC    CALCSH        ;GO BACK IF NOT YET
  530.     MOV    A,B        ;SHIFT COUNT TO ACC
  531. ;
  532. NOSHF:    STA    SECSHF        ;STORE SHIFT COUNT
  533.     MOV    A,M        ;RELOAD BIT FLAG
  534.     DCR    A        ;FORM SECTOR MASK
  535.     STA    SECMSK        ; AND SET IT
  536.     LHLD    DTPTR        ;RELOAD PTR
  537.     LDA    LOGFLG        ;WAS JADE LOGGED ON?
  538.     ORA    A        ;FLAG NON-ZERO IF SO,
  539.     JNZ    DSKOK        ; GO HANDLE DCM MORE
  540.     RET            ;IF NOT, DONE, RET ZERO
  541. ;
  542. ;  -- ASSUME 3740 DISKETTE
  543. ;
  544. LG3740:    CALL    TR3740        ;SET SECTOR TRANSLATE
  545.     CALL    DPBAD        ;SET REGISTER DE
  546.     LXI    B,DPBSZ        ;DPB SIZE IN BYTES
  547.     LXI    H,DPB8        ;ADDRESS OF BLK IMAGE
  548.     CALL    BLOCK        ;MOVE INTO DPB
  549.     JMP    NOLOG        ;GO SET UP (CLEAR) THE
  550.                 ; DEBLOCK VARIABLES
  551. ;
  552. ;  -- SET 3740 SECTOR TRANSLATION
  553. ;
  554. TR3740:    LXI    D,TRAN8        ;SECTOR TRAN TBL ADDR
  555. ;
  556. TRCOM:    LHLD    DTPTR        ;ADDR DISK PARA HDER
  557.     MOV    M,E
  558.     INX    H
  559.     MOV    M,D
  560.     RET
  561. ;
  562. ;  -- SET 1024 BYTES/SECTOR TRANSLATION
  563. ;
  564. TR1024:    LXI    D,TRN124    ;SECTOR TRAN TBL ADDR
  565.     JMP    TRCOM        ;GO SET IT
  566. ;
  567. ;  -- SET NO SECTOR TRANSLATION
  568. ;
  569. TRNONE:    XRA    A        ;ZERO A REG
  570.     LHLD    DTPTR
  571.     MOV    M,A
  572.     INX    H
  573.     MOV    M,A
  574.     RET
  575. ;
  576. ;  -- GET DRIVE PARA BLK ADDR
  577. ;
  578. DPBAD:    LHLD    DTPTR        ;ADDR DISK PARA HDED
  579.     LXI    D,10        ;DPB TBL PNTR OFFSET
  580.     DAD    D        ;NOW AT DPB PNTR
  581.     MOV    E,M        ;LOAD INTO DE
  582.     INX    H
  583.     MOV    D,M
  584.     RET            ;RETURN TO LOG USER
  585. ;
  586. ;  HOME DRIVE
  587. ;
  588. HOME:    MVI    C,0        ;SET TRACK TO ZERO TO HOME
  589.     LDA    HSTWRT        ;CHECK FOR PENDING WRITE
  590.     ORA    A
  591.     JNZ    SETTRK
  592.     STA    HSTACT        ;CLEAR HOST ACTIVE IF NOT
  593. ;
  594. ;  SET TRACK
  595. ;
  596. SETTRK:    MOV    A,C        ;MOVE TRACK NUMBER
  597.     STA    SEKTRK        ; THEN SAVE IT
  598.     RET            ;RETURN TO CALLER
  599. ;
  600. ;  SET SECTOR
  601. ;
  602. SETSEC:    MOV    A,C        ;MOVE SECTOR NUMBER
  603.     STA    SEKSEC        ; THEN SAVE IT
  604.     RET            ;RETURN TO CALLER
  605. ;
  606. ;  SET TRANSFER ADDRESS
  607. ;
  608. SETDMA:    MOV    H,B        ;MOVE ADDR TO HL
  609.     MOV    L,C
  610.     SHLD    DMAADR        ; THEN SAVE IT
  611.     RET            ;RETURN TO CALLER
  612. ;
  613. ;  SECTOR TRANSLATION
  614. ;
  615. SECTRN:    MOV    A,E        ;IS THERE A TABLE?
  616.     ORA    D
  617.     JZ    JTRAN        ;JADE SPECIAL XLATE IF NOT
  618.     XCHG            ;MAP OFF TABLE IF SO
  619.     DAD    B
  620.     MOV    L,M
  621.     MVI    H,0
  622.     RET
  623. ;
  624. JTRAN:    MOV    H,B        ;JADE XLATE OFF BY ONE
  625.     MOV    L,C        ; SO FIX FOR CALLER
  626.     INX    H
  627.     RET            ; THEN DONE
  628. ;
  629. ;  IOBYTE IS SUPPORTED FOR CONSOLE AND LIST DEVICE
  630. ;
  631. ;  CONSOLE STATUS
  632. ;
  633. CNSCK:    CALL    CONS        ;GET HARDWARE STATUS
  634.     RZ            ;IF NO CHAR READY, RETURN 0
  635.     MVI    A,0FFH        ; ELSE RETURN 0FFH
  636.     RET
  637. ;
  638. CONS:    LDA    IOBYTE        ;GET IOBYTE
  639.     CALL    ROUTE        ;DISPATCH TO STATUS ROUTINE
  640.     DW    TTYCHK        ;TTY:
  641.     DW    CRTCHK        ;CRT:
  642.     DW    CRTCHK        ;BAT: (RDR: NOT SUPPORTED)
  643.     DW    UC1CHK        ;UC1:
  644. ;
  645. ;  CONSOLE INPUT
  646. ;
  647. CNSIN:    CALL    CONS        ;GET HARDWARE STATUS
  648.     JZ    CNSIN        ;WAIT FOR CHAR READY
  649.     CALL    CONIN        ; THEN GET CHAR
  650.     ANI    07FH        ;STRIP PARITY
  651.     RET            ; AND RETURN IN ACC
  652. ;
  653. CONIN:    LDA    IOBYTE
  654.     CALL    ROUTE        ;DISPATCH TO INPUT ROUTINE
  655.     DW    TTYIN        ;TTY:
  656.     DW    CRTIN        ;CRT:
  657.     DW    CRTIN        ;BAT: NOT SUPPORTED, USE CRT:
  658.     DW    UC1IN        ;UC1:
  659. ;
  660. ;  HXBOT DISPLAYS HEXIDECIMAL EQUIV OF ACC CONTENTS.
  661. ;
  662. HXBOT:    PUSH    PSW        ;SAVE CHAR
  663.     RRC            ;SWAP NIBBLES
  664.     RRC
  665.     RRC
  666.     RRC
  667.     CALL    HXNOT        ;OUTPUT HIGH NIBBLE
  668.     POP    PSW        ; THEN LOW NIBBLE
  669. HXNOT:    ANI    0FH        ;STRIP HIGH NIBBLE
  670.     ADI    90H        ;CVT TO ASCII DECIMAL
  671.     DAA
  672.     ACI    40H
  673.     DAA
  674.     MOV    C,A        ;CHAR TO C
  675.     JMP    BCNSOT        ;THRU VECTOR TO CNSOT
  676. ;
  677. ;  CONSOLE OUTPUT
  678. ;
  679. CNSOT:    LDA    IOBYTE
  680.     CALL    ROUTE        ;DISPATCH TO OUTPUT ROUTINE
  681.     DW    TTYOT        ;TTY:
  682.     DW    CRTOT        ;CRT:
  683.     DW    LPTOT        ;BAT: NOT SUPPORTED, USE LPT:
  684.     DW    UC1OT        ;UC1:
  685. ;
  686. ;  READER INPUT
  687. ;
  688. READER:    EQU    CNSIN        ;SAME AS CONSOLE INPUT
  689. ;
  690. ;  PUNCH OUTPUT
  691. ;
  692. PUNCH:    EQU    CNSOT        ;SAME AS CONSOLE OUTPUT
  693. ;
  694. ;  LIST STATUS
  695. ;
  696. LISTST:    XRA    A        ;SAY IT'S READY
  697.     DCR    A
  698.     RET
  699. ;
  700. ;  LIST OUTPUT
  701. ;
  702. LIST:    LDA    IOBYTE
  703.     RLC            ;ROTATE LST: BITS TO LOW
  704.     RLC            ; BIT POSITIONS
  705.     CALL    ROUTE        ;DISPATCH TO LIST ROUTINE
  706.     DW    TTYOTS        ;TTY: WITH DTR FOR
  707.                 ; SERIAL PRINTERS
  708.     DW    CRTOT        ;CRT:
  709.     DW    LPTOT        ;LPT:
  710.     DW    CNSOT        ;UL1: USES CURRENT CON:
  711. ;
  712. ;  THE ROUTING ROUTINE
  713. ;
  714. ROUTE:    RLC            ;DOUBLE FOR WORD OFFSET
  715.     ANI    06H        ;STRIP UNUSED BITS
  716.     XTHL            ;GET DISPATCH TABLE ADDR
  717.     ADD    L        ;ADD OFFSET TO GET
  718.     MOV    L,A        ; TO CORRECT VECTOR
  719.     JNC    ROUTE5
  720.     INR    H
  721. ROUTE5:    MOV    A,M        ;PULL VECTOR
  722.     INX    H
  723.     MOV    H,M
  724.     MOV    L,A
  725.     XTHL            ;STACK VECTOR, RESTORE HL
  726.     RET            ; THEN OFF TO ROUTINE
  727. ;
  728. ;  HORIZON TTY: ROUTINES
  729. ;
  730. TTYCHK:    IN    TTY+1        ;GET PORT STATUS
  731.     ANI    2        ;CHECK RECEIVER
  732.     RET            ;RET NON-ZERO IF READY
  733. ;
  734. TTYIN:    IN    TTY        ;GET PORT DATA
  735.     RET
  736. ;
  737. TTYOT:    IN    TTY+1        ;GET PORT STATUS
  738.     RRC            ;XMIT BUFFER EMPTY?
  739.     JNC    TTYOT        ;IF NOT, WAIT TIL IS
  740. ;
  741. ;  HERE FROM TTYOTS BELOW TO OUTPUT CHAR FROM C
  742. ;
  743. TTYOTC:    MOV    A,C        ; THEN OUTPUT CHAR FROM C
  744.     OUT    TTY
  745.     RET
  746. ;
  747. ;  SERIAL PRINTER ROUTINE.  WAIT FOR DTR HIGH, XMIT
  748. ; BUFFER EMPTY, AND XMITTER READY BEFORE SENDING NEXT
  749. ; CHAR.  THIS ROUTINE HAS BEEN TESTED WITH THE EPSON
  750. ; MX-80 WITH 2K SERIAL BUFFER, WHICH SHOULD BE
  751. ; TYPICAL OF SERIAL PRINTERS.
  752. ;
  753. TTYOTS:    IN    TTY+1
  754.     ANI    85H
  755.     CPI    85H        ;NEED ALL 3 BITS HIGH
  756.     JNZ    TTYOTS
  757.     JMP    TTYOTC        ;NOW OUTPUT
  758. ;
  759. ;  HORIZON CRT: ROUTINES. SAME AS TTY:, BUT DIFF PORT
  760. ;
  761. CRTCHK:    IN    CRT+1        ;GET PORT STATUS
  762.     ANI    2        ;CHECK RECEIVER
  763.     RET            ;RET NON-ZERO IF READY
  764. ;
  765. CRTIN:    IN    CRT        ;GET PORT DATA
  766.     RET
  767. ;
  768. CRTOT:    IN    CRT+1        ;GET PORT STATUS
  769.     RRC            ;XMIT BUFFER EMPTY?
  770.     JNC    CRTOT        ;IF NOT, WAIT TIL IS
  771.     MOV    A,C        ; THEN OUTPUT CHAR FROM C
  772.     OUT    CRT
  773.     RET
  774. ;
  775. ;  UC1 CONSOLE SERIAL ROUTINES
  776. ;
  777. UC1CHK:    IN    UC1+1        ;GET PORT STATUS
  778.     ANI    02H        ;CHECK RECEIVER
  779.     RET            ;RET NON-ZERO IF READY
  780. ;
  781. UC1IN:    IN    UC1        ;GET PORT DATA
  782.     RET
  783. ;
  784. UC1OT:    IN    UC1+1        ;GET PORT STATUS
  785.     RRC            ;XMIT BUFFER EMPTY?
  786.     JNC    UC1OT        ;IF NOT, WAIT TIL IS
  787.     MOV    A,C        ; THEN OUTPUT CHAR FROM C
  788.     OUT    UC1
  789.     RET
  790. ;
  791. ;  LIST CHAR OUT TO MODEL 40 LINE PRINTER
  792. ;
  793. LPTOT:    PUSH    H        ;SAVE HL
  794.     PUSH    B        ;SAVE CHAR TO OUTPUT
  795.     IN    LPIO        ;SEE IF M40 CHAIN RUNNING
  796.     ANI    CHAIN
  797.     JZ    LOUT7        ;SKIP RE-INIT IF SO
  798. ;
  799. LOUT5:    CALL    LGOOSE        ;GOOSE PRINTER
  800. ;
  801. LOUT7:    LXI    H,0        ;LOAD UP FOR NICE LONG DELAY
  802.     MVI    B,8
  803. ;
  804. LOUT10:    DCX    H        ;COUNT DOWN
  805.     MOV    A,H        ;SEE IF ZERO YET
  806.     ORA    L
  807.     JNZ    LOUT20        ;PASS IF NOT
  808.     DCR    B        ;COUNT OFF HIGHER BITS
  809.     JNZ    LOUT20        ;PASS IF NOT ZERO YET
  810. ;
  811. LOUT15:    MVI    A,'P'        ;DISK P: NOT READY, FOR PRINTER
  812.     CALL    PNTRDY        ;REPORT, AND RETURN IF NO CTRL-C
  813.     JMP    LOUT5        ;NOW GO RE-INIT THE PRINTER
  814. ;
  815. LOUT20:    IN    LPIO        ;CHECK FOR CHAIN NOT RUNNING
  816.     ANI    CHAIN
  817.     JNZ    LOUT10        ;COUNT DOWN TIMEOUT IF SO
  818.     IN    LPC        ;GET 8251 STATUS
  819.     ANI    85H        ;STRIP OUT REQ NXT CHAR, XMIT
  820.     CPI    85H        ; BUF RDY, AND XMIT EMPTY,
  821.                 ; THEN CHECK THEM
  822.     JNZ    LOUT10        ;ALL 3 MUST BE UP TO SEND
  823. ;
  824. ;  PRINTER NOW READY. OUTPUT CHAR.
  825. ;
  826.     POP    B        ;RESTORE CHAR TO C
  827.     MOV    A,C        ; AND GET IT TO ACC
  828.     ANI    7FH        ;STRIP PARITY
  829.     OUT    LPD        ;OUTPUT THE CHAR
  830.     CPI    FF        ;WAS CHAR FORM FEED?
  831.     JNZ    LOUT35        ;PASS IF NOT
  832.     MVI    L,6        ;MUST FOLLOW WITH NULLS IF SO
  833. ;
  834. LOUT30:    IN    LPC        ;WAIT FOR BUFFER READY
  835.     RRC
  836.     JNC    LOUT30
  837.     XRA    A        ; THEN OUTPUT NULL
  838.     OUT    LPD
  839.     DCR    L        ; AND COUNT IT OFF
  840.     JNZ    LOUT30        ;GO BACK IF MORE TO DO
  841. ;
  842. LOUT35:    MOV    A,C        ;RESTORE CHAR TO ACC
  843.     POP    H        ;RESTORE HL
  844.     RET            ; AND RETURN
  845. ;
  846. ;  TOGGLE DTR FOR PRINTER TO GOOSE IT INTO STARTING CHAIN UP
  847. ;
  848. LGOOSE:    MVI    A,035H        ;RAISE DTR
  849.     OUT    LPC
  850.     CALL    LWAIT        ;DELAY
  851.     MVI    A,037H        ;NOW DROP DTR TO TOGGLE
  852.     OUT    LPC
  853. LWAIT:    XRA    A        ;DELAY
  854. LPIL:    XTHL
  855.     XTHL
  856.     XTHL
  857.     XTHL
  858.     DCR    A
  859.     JNZ    LPIL
  860.     RET
  861. ;
  862. ;  DEBLOCKING DISK WRITE
  863. ;
  864. DISKWR:    CALL    INTDI        ;MASK INTERRUPTS
  865.     CALL    DSKWR        ;DO THE WRITE
  866.     JMP    INTEN        ;GO RESTORE INTS
  867. ;
  868. ;  DEBLOCKING DISK READ.  NOTE THAT ON DEBLOCKING READ
  869. ; AND WRITE, THE CALLER SECTOR NUMBERS RANGE FROM 1-XX
  870. ; DECIMAL. THIS IS FOR COMPATIBILITY WITH 8" FORMATS
  871. ; THAT ARE 1-ORIGIN. WE ADJUST FOR THIS THROUGHOUT THE
  872. ; DEBLOCKING ROUTINES BY SUBTRACTING 1 FROM SEKSEC
  873. ; BEFORE WE USE IT. VARIABLES TO CONTROL DEBLOCKING
  874. ; ARE SET UP FOR US WHEN DISK IS SELECTED.
  875. ;
  876. DISKRD:    CALL    INTDI        ;DISABLE INTERRUPTS
  877.     CALL    DSKRD        ;DO THE I/O
  878. ;
  879. INTEN:    PUSH    PSW        ;SAVE DISK I/O ERROR CODE
  880.     LHLD    ENTPSW        ;GET ENTRY PSW TO TEST
  881.     PUSH    H
  882.     POP    PSW
  883.     JPO    INTEN5        ;PASS IF INTS OFF WHEN ENTERED
  884.     EI            ; ELSE RE-ENABLE INTS
  885. ;
  886. INTEN5:    POP    PSW        ;RESTORE DISK I/O ERROR CODE
  887.     RET            ; THEN RETURN TO CALLER
  888. ;
  889. INTDI:    MVI    A,7FH        ;CHECK FOR RUNNING ON
  890.     INR    A        ; 8080 OR Z80
  891.     JPO    NOTZ80        ;CAN'T GET INT STATE ON 8080
  892.     DW    LDAI        ;GET INT STATE INTO
  893.     PUSH    PSW        ; PARITY FLAG, THEN
  894.     POP    H        ; SAVE PSW IN MEMORY
  895.     SHLD    ENTPSW
  896. ;
  897. NOTZ80:    DI            ;ALLOW NO INTERRUPTS
  898.     RET            ; DURING THE I/O XFER
  899. ;
  900. DSKRD:    LDA    SECSHF        ;SEE IF DEBLOCKING
  901.     ORA    A
  902.     JZ    JADERD        ;MUST BE JADE IF NOT
  903.     LDA    SEKDSK        ;IF SO, SEE IF JADE ANYWAY
  904.     CPI    2
  905.     JC    NOTJR        ;PASS IF NOT, N* READ
  906.     LDA    SEKTRK        ;IF SO, IS TRACK 0 OR 1?
  907.     CPI    2
  908.     JC    JADERD        ;NORMAL SECTOR SIZE IF SO
  909. ;
  910. NOTJR:    MVI    A,WRUAL
  911.     STA    WRTYPE        ;TREAT AS UNALLOC
  912.     STA    READOP        ;READ OPERATION
  913.     JMP    ALLOC        ;GO END UNALLOC SECTORS
  914.                 ; AND FORCE READ
  915. ;
  916. DSKWR:    LDA    SECSHF        ;SEE IF DEBLOCKING
  917.     ORA    A
  918.     JZ    JADEWR        ;MUST BE JADE IF NOT
  919.     LDA    SEKDSK        ;IF SO, SEE IF JADE ANYWAY
  920.     CPI    2
  921.     JC    NOTJW        ;PASS IF NOT, N* WRITE
  922.     LDA    SEKTRK        ;IF SO, IS TRACK 0 OR 1?
  923.     CPI    2
  924.     JC    JADEWR        ;NORMAL SECTOR SIZE IF SO
  925. ;
  926. NOTJW:    XRA    A
  927.     STA    READOP        ;NOT A READ OPERATION
  928.     MOV    A,C        ;WRITE TYPE IN C
  929.     STA    WRTYPE
  930.     CPI    WRUAL        ;WRITE UNALLOCATED?
  931.     JNZ    CHKUNA        ;CHECK FOR UNALLOC
  932. ;
  933. ;  WRITE TO UNALLOCATED, SET PARAMETERS
  934. ;
  935.     LDA    UNAVAL        ;NEXT UNALLOC RECS
  936.     STA    UNACNT
  937.     LHLD    SEKDSK        ;PICK UP SEKDSK AND SEKTRK
  938.     SHLD    UNADSK        ;UNADSK=SEKDSK, UNATRK=SEKTRK
  939.     LDA    SEKSEC
  940.     STA    UNASEC        ;UNASEC = SEKSEC
  941. ;
  942. ;  CHECK FOR WRITE TO UNALLOCATED SECTOR
  943. ;
  944. CHKUNA:    LDA    UNACNT        ;ANY UNALLOC REMAIN?
  945.     ORA    A
  946.     JZ    ALLOC        ;SKIP IF NOT
  947. ;
  948. ;  MORE UNALLOCATED RECORDS REMAIN
  949. ;
  950.     DCR    A        ;UNACNT = UNACNT - 1
  951.     STA    UNACNT
  952.     LDA    SEKDSK        ;SAME DISK?
  953.     LXI    H,UNADSK
  954.     CMP    M        ;SEKDSK = UNADSK?
  955.     JNZ    ALLOC        ;SKIP IF NOT
  956. ;
  957. ;  DISKS ARE THE SAME, CHECK TRACKS
  958. ;
  959.     LDA    SEKTRK
  960.     LXI    H,UNATRK
  961.     CMP    M        ;SEKTRK = UNATRK?
  962.     JNZ    ALLOC        ;SKIP IF NOT
  963. ;
  964. ;  TRACKS ARE THE SAME, CHECK SECTORS
  965. ;
  966.     LDA    SEKSEC
  967.     LXI    H,UNASEC
  968.     CMP    M        ;SEKSEC = UNASEC?
  969.     JNZ    ALLOC        ;SKIP IF NOT
  970. ;
  971. ;  MATCH, MOVE TO NEXT SECTOR FOR FUTURE REF
  972. ;
  973.     INR    M        ;UNASEC = UNASEC+1
  974.     LDA    CPMSPT        ;CHECK FOR END OF TRACK
  975.     CMP    M
  976.     JNC    NOOVF        ;SKIP IF STILL ON TRACK
  977. ;
  978. ;  OVERFLOW TO NEXT TRACK
  979. ;
  980.     MVI    M,1        ;UNASEC = 1
  981.     LXI    H,UNATRK
  982.     INR    M        ;UNATRK = UNATRK+1
  983. ;
  984. ;  MATCH FOUND, MARK AS UNNECESSARY READ
  985. ;
  986. NOOVF:    XRA    A
  987.     STA    RSFLAG        ;RSFLAG = 0
  988.     JMP    RWOPER        ;GO DO WRITE
  989. ;
  990. ;  NOT AN UNALLOCATED RECORD, REQUIRES PRE-READ
  991. ;
  992. ALLOC:    XRA    A
  993.     STA    UNACNT        ;UNACNT = 0
  994.     INR    A
  995.     STA    RSFLAG        ;RSFLAG = 1
  996. ;
  997. ;  COMMON CODE FOR READ AND WRITE FOLLOWS
  998. ;
  999. RWOPER:    XRA    A
  1000.     STA    ERFLAG        ;NO ERRORS (YET)
  1001.     LDA    SECSHF        ;GET SECTOR SHIFT COUNT
  1002.     MOV    B,A        ; IN COUNT REG
  1003.     LDA    SEKSEC        ;COMPUTE HOST SECTOR
  1004.     DCR    A        ;ADJUST FOR 1-ORIGIN
  1005. ;
  1006. RWOPSH:    ORA    A        ;CARRY = 0
  1007.     RAR            ;SHIFT RIGHT
  1008.     DCR    B        ;COUNT OFF A SHIFT
  1009.     JNZ    RWOPSH        ;LOOP IF MORE
  1010.     STA    SEKHST        ;HOST SECTOR TO SEEK
  1011. ;
  1012. ;  ACTIVE HOST SECTOR?
  1013. ;
  1014.     LXI    H,HSTACT    ;HOST ACTIVE FLAG
  1015.     MOV    A,M
  1016.     MVI    M,1        ;ALWAYS BECOMES 1
  1017.     ORA    A        ;WAS IT ALREADY?
  1018.     JZ    FILHST        ;FILL HOST IF NOT
  1019. ;
  1020. ;  HOST BUFFER ACTIVE, SAME AS SEEK BUFFER?
  1021. ;
  1022.     LDA    SEKDSK
  1023.     LXI    H,HSTDSK    ;SAME DISK?
  1024.     CMP    M        ;SEKDSK = HSTDSK?
  1025.     JNZ    NOMATCH
  1026. ;
  1027. ;  SAME DISK, CHECK TRACK
  1028. ;
  1029.     LDA    SEKTRK
  1030.     LXI    H,HSTTRK
  1031.     CMP    M        ;SEKTRK = HSTTRK?
  1032.     JNZ    NOMATCH
  1033. ;
  1034. ;  SAME DISK AND TRACK, CHECK SECTOR
  1035. ;
  1036.     LDA    SEKHST
  1037.     LXI    H,HSTSEC
  1038.     CMP    M        ;SEKHST = HSTSEC?
  1039.     JZ    MATCH        ;SKIP IF MATCH
  1040. ;
  1041. ;  MUST FLUSH HOST BUFFER FOR NEW SECTOR
  1042. ;
  1043. NOMATCH: LDA    HSTWRT        ;HOST WRITTEN?
  1044.     ORA    A
  1045.     CNZ    WRITEHST    ;CLEAR HOST BUFFER
  1046.     LDA    ERFLAG        ;CHECK FOR ERROR
  1047.     ORA    A
  1048.     RNZ            ;RETURN ERROR IF SO
  1049. ;
  1050. FILHST:    LHLD    SEKDSK        ;MAY HAVE TO FILL HOST BUFFER
  1051.     SHLD    HSTDSK        ;HSTDSK=SEKDSK,HSTTRK=SEKTRK
  1052.     LDA    SEKHST
  1053.     STA    HSTSEC
  1054.     XRA    A
  1055.     STA    HSTWRT        ;NO PENDING WRITE
  1056.     LDA    RSFLAG        ;NEED TO READ?
  1057.     ORA    A
  1058.     JZ    MATCH        ;NO IF FLAG ZERO
  1059.     LDA    HSTDSK        ;SEE WHICH DISK
  1060.     CPI    2        ;IF C: OR D:, JADE
  1061.     JNC    NOTNSR        ;BRANCH IF JADE
  1062.     CALL    READHST        ;IF A: OR B:, READ N*
  1063.     LDA    ERFLAG        ;CHECK FOR ERRORS
  1064.     ORA    A
  1065.     RNZ            ;NO MORE IF SO
  1066.     CALL    GNSDEN        ;CHECK DENSITY
  1067.     LXI    H,NSDENS
  1068.     CMP    M        ;IS DENSITY RIGHT?
  1069.     JZ    MATCH        ;OK IF SO
  1070.     LXI    H,SDEMSG    ;ERROR IF NOT
  1071.     CALL    DSKERR        ;REPORT IT
  1072.     MVI    A,5
  1073.     STA    ERFLAG
  1074.     RET            ;RET NZ ACC TO CALLER
  1075. ;
  1076. NOTNSR:    CALL    JHREAD        ;READ JADE DISK
  1077.     LDA    ERFLAG        ;READ ERROR?
  1078.     ORA    A
  1079.     RNZ            ;LEAVE BUF ALONE IF SO
  1080. ;
  1081. ;  COPY DATA TO OR FROM BUFFER
  1082. ;
  1083. MATCH:    LDA    SECMSK        ;GET MASK
  1084.     MOV    H,A        ; INTO TEMP REG
  1085.     LDA    SEKSEC        ;MASK SECTOR BUFFER NUMBER
  1086.     DCR    A        ;ADJUST FOR 1-ORIGIN
  1087.     ANA    H        ;LEAST SIGNIF BITS
  1088.     RAR            ;GET VALUE SHIFTED
  1089.     MOV    H,A        ; LEFT 7 IN HL
  1090.     MVI    A,0
  1091.     RAR
  1092.     MOV    L,A
  1093. ;
  1094. ;  HL CONTAINS RELATIVE HOST BUFFER ADDRESS
  1095. ;
  1096.     LXI    D,HSTBUF    ;ASSUME USING N* BUFFER
  1097.     LDA    HSTDSK        ;CHECK DISK SELECTED
  1098.     CPI    2
  1099.     JC    NJBUF        ;RIGHT IF NOT JADE DISK
  1100.     MVI    A,DCMB1        ;USING JADE BUFFER,
  1101.     OUT    DPORT        ; SWITCH BANK ONE IN
  1102.     XCHG            ;PUT OFFSET IN DE NOW
  1103.     LHLD    DADDR        ;PT HL AT BUFFER
  1104. ;
  1105. NJBUF:    DAD    D        ;HL = HOST ADDRESS
  1106.     XCHG            ;NOW IN DE
  1107.     LHLD    DMAADR        ;GET/PUT CP/M DATA
  1108.     MVI    C,SECSZ        ;LENGTH OF MOVE
  1109.     LDA    READOP        ;WHICH WAY?
  1110.     ORA    A
  1111.     JNZ    RWMOVE        ;SKIP IF READ
  1112. ;
  1113. ;  WRITE OPERATION, MARK AND SWITCH DIRECTION
  1114. ;
  1115.     INR    A        ;ACC KNOWN ZERO ABOVE
  1116.     STA    HSTWRT        ;HSTWRT = 1
  1117.     XCHG            ;SOURCE/DEST SWAP
  1118. ;
  1119. RWMOVE:    LDAX    D        ;SOURCE CHARACTER
  1120.     INX    D
  1121.     MOV    M,A        ;TO DEST
  1122.     INX    H
  1123.     DCR    C        ;LOOP 128 TIMES
  1124.     JNZ    RWMOVE
  1125.     LDA    HSTDSK        ;IS THIS JADE DISK?
  1126.     CPI    2
  1127.     CNC    DSKOUT        ;FIX MEM STATUS IF SO
  1128. ;
  1129. ;  DATA HAS BEEN MOVED TO/FROM HOST BUFFER
  1130. ;
  1131.     LDA    WRTYPE        ;WRITE TYPE
  1132.     CPI    WRDIR        ;TO DIRECTORY?
  1133.     MVI    A,0        ;NO ERROR AT THIS PT
  1134.     RNZ            ;RET IF NOT DIR WRITE
  1135. ;
  1136. ;  CLEAR HOST BUFFER FOR DIRECTORY WRITE
  1137. ;
  1138.     CALL    WRITEHST
  1139.     LDA    ERFLAG
  1140.     RET
  1141. ;
  1142. ;  WRITEHST PERFORMS THE PHYSICAL WRITE TO THE
  1143. ; NORTH STAR DISK. ON ENTRY, DRIVE IS IN HSTDSK,
  1144. ; TRACK IS IN HSTTRK, SECTOR IS IN HSTSEC. ON
  1145. ; EXIT, ERROR FLAG IS IN ERFLAG (ZERO IF NONE).
  1146. ;
  1147. ;  IT IS ASSUMED INTERRUPTS ARE DISABLED AT
  1148. ; THIS POINT. IF NOT, I/O MAY BE DISRUPTED.
  1149. ;
  1150. WRITEHST:            ;WRITE HOST
  1151.     XRA    A        ;BUFFER WILL BE CLEARED
  1152.     STA    HSTWRT
  1153.     LDA    HSTDSK        ;SEE IF N* DISK SELECTED
  1154.     CPI    2
  1155.     JNC    JHWRIT        ;IF NOT, DO JADE WRITE
  1156.     CALL    GNSDEN        ;GET DENSITY BASED ON ID
  1157.     STA    NSCNT        ;SET WRITE BYTE COUNT
  1158.     CALL    SETUP        ;SELECT DRIVE AND
  1159.                 ; SEEK TO TRACK
  1160.     LDA    ERFLAG        ;CHECK FOR ERRORS
  1161.     ORA    A
  1162.     RNZ            ;INDEX PULSE NOT FOUND IS FATAL
  1163.     CALL    POSEC        ;POSITION TO SECTOR
  1164.     JNZ    SNFERR        ;OUT ON ERROR
  1165.     LDA    CCMND+20H    ;GET B-STATUS
  1166.     ANI    02H        ;IS DISK WRITE-PROTECTED?
  1167.     MVI    A,6        ;ASSUME SO, ERROR CODE 6
  1168.     STA    ERFLAG
  1169.     JNZ    WPERR        ;WRITE ALWAYS FAILS IF SO
  1170.     LHLD    HSTADR        ;GET ADDRESS TO WRITE FROM
  1171.     MVI    B,31        ;ASSUME DOUBLE DENSITY
  1172.     MVI    E,2
  1173.     LDA    NSCNT        ;CHECK
  1174.     MOV    C,A        ;SAVE COUNT FOR LATER
  1175.     ORA    A
  1176.     JZ    WRIT5        ;GO ON IF COUNTS RIGHT
  1177.     MVI    B,15        ;CORRECT FOR SINGLE DENS
  1178.     DCR    E
  1179. ;
  1180. WRIT5:    LDA    CCMND+16H    ;INITIATE SECTOR WRITE
  1181. ;
  1182. WRIT10:    LDA    CCMND+15H    ;KEEP MOTORS RUNNING, GET A-STAT
  1183.     ANI    08H        ;MUST LOOP UNTIL 96 USEC WINDOW
  1184.     JNZ    WRIT10        ; PAST, SO LOOP WHILE WI TRUE
  1185. ;
  1186. ;  NOW WRITE THE 31 OR 15 BYTES OF LEADING ZEROES ON THE SECTOR
  1187. ;
  1188. WRIT15:    LDA    WDATA+00H    ;WRITE A BYTE OF ZEROES
  1189.     NOP            ;KILL TIME
  1190.     MVI    D,WDATA SHR 8    ;KILL TIME BY LOADING D FOR LATER
  1191.     DCR    B        ;COUNT OFF A ZERO BYTE
  1192.     JNZ    WRIT15        ;DO THEM ALL
  1193. ;
  1194. ;  FOLLOW WITH ONE OR TWO SYNCH BYTES
  1195. ;
  1196. WRIT17:    LDA    WDATA+0FBH    ;WRITE A SYNCH BYTE
  1197.     DCR    E        ;CHECK FOR 2ND NEEDED
  1198.     JNZ    WRIT17        ;GO BACK IF SO
  1199. ;
  1200. ;  NOW WRITE OUT 256 OR 512 BYTES. DO THIS TWO AT A
  1201. ; TIME SO WE CAN USE A SINGLE PRECISION COUNTER. B IS
  1202. ; ZERO FROM ABOVE TO INIT THE CRC BYTE.
  1203. ;
  1204. WRIT20:    MOV    A,M        ;GET NEXT BYTE TO OUTPUT
  1205.     MOV    E,A        ; IN OUTPUT REG
  1206.     XRA    B        ;ADD INTO CHECKSUM
  1207.     RLC
  1208.     MOV    B,A        ;LEAVE CHECKSUM IN B
  1209.     LDAX    D        ;WRITE DATA BYTE TO DISK
  1210.     INX    H        ;BOP BUF PTR
  1211.     MOV    A,M        ;REPEAT FOR NEXT BYTE
  1212.     MOV    E,A
  1213.     XRA    B
  1214.     RLC
  1215.     MOV    B,A
  1216.     LDAX    D
  1217.     INX    H
  1218.     DCR    C        ;COUNT OFF LAST PAIR OF BYTES
  1219.     JNZ    WRIT20        ;GO BACK IF MORE TO WRITE
  1220.     MOV    E,B        ;IF NOT, TIME TO WRITE CHECKSUM
  1221.     INX    B        ;KILL TIME
  1222.     LDAX    D        ; THEN WRITE THE BYTE
  1223.     XRA    A        ;DONE, INDICATE NO ERROR
  1224.     STA    ERFLAG
  1225.     RET            ;RETURN TO CALLER
  1226. ;
  1227. WPERR:    LXI    H,WPEMSG    ;WRITE PROTECT ERROR
  1228.     JMP    DSKERR        ;TELL OPERATOR ON WAY OUT
  1229. ;
  1230. ;  GNSDEN IS CALLED BY N* I/O ROUTINES TO DETERMINE THE
  1231. ; DENSITY OF THE CURRENT BLOCK BASED ON THE DENSITY OF
  1232. ; THE ID BLOCK. THAT IS DETERMINED BY TAKING ADVANTAGE
  1233. ; OF THE FACT THAT THE HOST DISK HAS NO TRANSLATE TABLE
  1234. ; IF SINGLE DENSITY.
  1235. ;
  1236. GNSDEN:    LXI    H,D0DPH        ;ASSUME A:
  1237.     LDA    HSTDSK        ;NOW CHECK
  1238.     ORA    A
  1239.     JZ    GNSDA        ;GO ON IF SO
  1240.     LXI    H,D1DPH        ;B: IF NOT
  1241. GNSDA:    MOV    A,M        ;SEE IF GOT XLATE TABLE
  1242.     INX    H
  1243.     ORA    M        ;IF NOT, SINGLE DENSITY
  1244.     MVI    A,80H        ;ASSUME SINGLE
  1245.     RZ            ;DONE IF RIGHT
  1246.     XRA    A        ;CORRECT IF DOUBLE DENSITY
  1247.     RET
  1248. ;
  1249. ;  DISK I/O ROUTINES FOR JADE DOUBLE D CONTROLLER
  1250. ;
  1251. ;  JADE HOST WRITE FOR FLUSHING BIG SECTOR BUFFER.
  1252. ; LIKE JADE HOST READ, THESE ROUTINES ARE CALLED BY
  1253. ; SECTOR DEBLOCKING I/O ROUTINES TO HANDLE JADE DISKS
  1254. ; WITH DATA SECTORS OF LARGER THAN 128 BYTES/SECTOR.
  1255. ;
  1256. JHWRIT:    MVI    B,DCWRS        ;WRITE OP
  1257.     JMP    JHOP
  1258. ;
  1259. ;  JADE HOST READ FOR FILLING BIG SECTOR BUFFER
  1260. ;
  1261. JHREAD:    MVI    B,DCRDS        ;READ OP
  1262. ;
  1263. JHOP:    LDA    HSTDSK        ;SET UP DISK TO USE
  1264.     SUI    2        ;OFFSET FOR 2ND CTRLR
  1265.     STA    BTDSK
  1266.     LDA    HSTTRK        ;THIS TRACK
  1267.     STA    BTTRK
  1268.     LDA    HSTSEC        ;THIS SECTOR
  1269.     INR    A        ;ADJUST FOR 1-ORIGIN
  1270.     STA    BTSEC
  1271.     MVI    A,DCSIN        ;SWITCH IN JADE MEM
  1272.     OUT    DPORT
  1273.     MOV    A,B        ;SET READ OR WRITE
  1274.     STA    BTCMD
  1275.     CALL    DSKEXR        ;DO THE OPERATION
  1276.     JZ    DSKOK        ;IF OK, GO THERE
  1277.     JMP    DSKER        ;IF ERROR, GO REPORT
  1278. ;
  1279. ;  READ A JADE DISK SECTOR ROUTINE. LIKE JADE DISK
  1280. ; WRITE, THIS ROUTINE IS CALLED TO DO A NORMAL, NON-
  1281. ; DEBLOCKING SECTOR I/O TO A DISK WITH 128-BYTE SECTORS.
  1282. ;
  1283. JADERD:    CALL    JFLUSH        ;FLUSH JADE BUF MAYBE
  1284.     RNZ            ;OUT ON ERROR
  1285.     MVI    A,DCSIN        ;SWITCH DD INTO SYS
  1286.     OUT    DPORT
  1287.     MVI    A,DCRDS        ;READ SECTOR COMMAND
  1288.     CALL    DSKEX        ;PERFORM OPERATION
  1289.     JNZ    DSKER        ;ERROR EXIT
  1290.     LHLD    DMAADR        ;LOAD USER BUF ADDRESS
  1291.     XCHG
  1292.     LHLD    DADDR        ;GET SECTOR BUF ADDR IN HL
  1293.     LXI    B,SECSZ        ;LOAD SECTOR SIZE
  1294.     MVI    A,DCMB1        ;BUFFER IS IN BANK ONE
  1295.     OUT    DPORT
  1296.     CALL    BLOCK        ;BLOCK MOVE ROUTINE
  1297.     JMP    DSKOK        ;NORMAL RETURN
  1298. ;
  1299. ;  WRITE A JADE DISK SECTOR
  1300. ;
  1301. JADEWR:    CALL    JFLUSH        ;FLUSH JADE BUF MAYBE
  1302.     RNZ            ;OUT ON ERROR
  1303.     MVI    A,DCMB1        ;SWITCH DD BANK ONE IN
  1304.     OUT    DPORT
  1305.     LHLD    DADDR        ;LOAD BUFFER ADDR
  1306.     XCHG            ;GET IT IN DE
  1307.     LHLD    DMAADR        ;LOAD USER BUF ADDRESS
  1308.     LXI    B,SECSZ        ;LOAD SECTOR SIZE
  1309.     CALL    BLOCK        ;BLOCK MOVE ROUTINE
  1310.     MVI    A,DCMB0        ;DSKEX NEEDS BANK 0
  1311.     OUT    DPORT        ; SO SWITCH IT IN
  1312.     MVI    A,DCWRS        ;LOAD WRITE SEC COMMAND
  1313.     CALL    DSKEX        ;CALL DISK EXEC
  1314.     JNZ    DSKER        ;IF ERROR, JUMP, ELSE
  1315.                 ; FALL INTO DSKOK
  1316. ;
  1317. ;  JADE DISK READ/WRITE/FORMAT EXITS
  1318. ;
  1319. DSKOK:    XRA    A        ;ZERO PSW
  1320.     JMP    DSKOUT
  1321. ;
  1322. DSKER:    PUSH    PSW        ;SAVE ERROR CODE
  1323.     LXI    H,JIOMSG    ;PT TO LEADER
  1324.     CALL    MSGOT        ;OUTPUT MESSAGE
  1325.     POP    PSW
  1326.     CALL    HXBOT        ;FORMAT AND OUTPUT HEX CODE
  1327.     LDA    BTTRK        ;IT HAPPENED ON THIS TRK
  1328.     STA    HSTTRK
  1329.     LDA    BTSEC        ; AND THIS SECTOR
  1330.     STA    ERSEC
  1331.     LDA    BTDSK        ; WITH THIS DISK
  1332.     ADI    2        ;OFFSET FOR C:
  1333.     CALL    JAERR        ;CALL COMMON CODE TO DO REST
  1334. ;
  1335. FMTER:    XRA    A        ;SIGNAL ERROR TO CALLER
  1336.     DCR    A        ; WITH NON-ZERO STATUS
  1337. ;
  1338. DSKOUT:    PUSH    PSW        ;SAVE RETURN STATUS
  1339.     PUSH    H        ; AND OTHER REGS
  1340.     PUSH    D
  1341.     LHLD    DADDR        ;PT TO DD MEM
  1342.     LXI    D,DDCBT        ;CALC DCM CMD BUF ADDR
  1343.     DAD    D
  1344.     MVI    A,DCMB0        ;CALL FOR BANK ZERO
  1345.     OUT    DPORT
  1346.     MVI    M,DCIDL        ;MAKE SURE DCM STAYS IDLE
  1347.     MVI    A,DCSOT        ;SWITCH OUT DD MEM
  1348.     OUT    DPORT
  1349.     POP    D        ;RESTORE REGS NOW
  1350.     POP    H
  1351.     POP    PSW        ;GET RETURN PSW
  1352.     RET            ;RET ZERO OR NON-ZERO
  1353. ;
  1354. ;  JFLUSH IS CALLED BY NORMAL JADE SECTOR ROUTINES TO
  1355. ; MAKE SURE THE JADE BUFFER IS NOT IN USE WHEN A
  1356. ; NORMAL READ, WRITE, OR FORMAT OPERATION NEEDS
  1357. ; THE BUFFER.
  1358. ;
  1359. JFLUSH:    XRA    A        ;NO ERROR YET
  1360.     STA    ERFLAG
  1361.     LDA    HSTDSK        ;IF N* DISK,
  1362.     CPI    2
  1363.     JC    NOJFL        ; NOT USING OUR BUFFER
  1364. ;
  1365. ;  COME HERE FROM SELDSK TO CLEAR ALL PENDING HOST WRITES
  1366. ;
  1367. HFLUSH:    LDA    HSTWRT        ;SEE IF BUFFER NEEDS FLUSH
  1368.     STA    ERFLAG        ;NO ERROR IF NOT
  1369.     ORA    A
  1370.     CNZ    WRITEHST    ;FLUSH IF SO, IF JADE
  1371.                 ; WILL USE BUFFER
  1372.     XRA    A
  1373.     STA    HSTACT        ;TOSS READ CONTENTS
  1374.     STA    UNACNT        ;BUFFER LEAVING, NEED
  1375.                 ; PRE-READ ON NEXT UNALLOC
  1376. ;
  1377. NOJFL:    LDA    ERFLAG        ;SET UP ERROR STATUS
  1378.     ORA    A
  1379.     RET
  1380. ;
  1381. ;  FORMAT A JADE DISK TRACK ROUTINE
  1382. ;
  1383. FORMAT:    LDA    SEKDSK        ;ONLY FORMAT JADE DISK
  1384.     CPI    2
  1385.     JC    FMTER        ;ERROR IF ANY OTHER
  1386.     CALL    JFLUSH        ;FLUSH JADE BUF MAYBE
  1387.     RNZ            ;OUT ON ERROR
  1388.     MVI    A,DCMB1        ;SWITCH DD BANK ONE
  1389.     OUT    DPORT        ; INTO SYS
  1390.     LXI    B,FMTSZ        ;FORMAT PROG SIZE
  1391.     LXI    D,DDFBF        ;CALC FORMAT BUF ADDR
  1392.     LHLD    DADDR
  1393.     DAD    D
  1394.     XCHG            ;GET IT IN DE
  1395.     LHLD    DMAADR        ;FORMAT PROGRAM ADDR
  1396.     CALL    BLOCK        ;BLOCK MOVE ROUTINE
  1397.     MVI    A,DCMB0        ;RESELECT DD BANK 0
  1398.     OUT    DPORT
  1399.     MVI    A,DCFMT        ;LOAD FORMAT TRK CMND
  1400.     CALL    DSKEX        ;CALL DISK EXEC
  1401.     JMP    DSKOK        ;GO RETURN STATUS TO CALLER
  1402. ;
  1403. ;  DOUBLE D EXECUTION SUBROUTINE
  1404. ;
  1405. DSKEX:    STA    BTCMD        ;STORE DCM COMMAND
  1406.     LDA    SEKDSK        ;MAP DISK TO JADE DD #
  1407.     SUI    2
  1408.     STA    BTDSK        ; AND STORE JADE DISK #
  1409.     LDA    SEKTRK        ;SET TRACK #
  1410.     STA    BTTRK
  1411.     LDA    SEKSEC        ; AND SECTOR #
  1412.     STA    BTSEC
  1413. ;
  1414. ;  HERE ON RETRY AFTER DISK NOT READY
  1415. ;
  1416. DSKEXR:    LXI    B,7        ;# BYTES TO MOVE
  1417.     LXI    D,DDCBT        ;CALC DCM COMMAND BUF ADDR
  1418.     LHLD    DADDR
  1419.     DAD    D
  1420.     XCHG            ;GET IT IN DE
  1421.     LXI    H,BTCMD        ;BIOS COMMAND BLOCK
  1422.     CALL    BLOCK        ;PERFORM BLOCK MOVE
  1423.     MVI    A,DCINT        ;INTERRUPT DD
  1424.     OUT    DPORT
  1425.     XCHG            ;EXCHANGE SRC/DST
  1426. DSKWT:    IN    DPORT        ;READ DD STATUS
  1427.     ANI    DSHLT        ;TEST HALT* FLAG
  1428.     JNZ    DSKWT        ;WAIT UNTIL DD HALTED
  1429.     MVI    A,DCSIN        ;SWITCH DD INTO SYS
  1430.     OUT    DPORT
  1431.     MOV    A,M        ;GET DD STATUS BYTE
  1432.     STAX    D        ;SAVE IN MEM
  1433.     STA    ERFLAG        ;SET ERFLAG FOR JHOP
  1434.     ANA    A        ;TEST FOR ERRORS
  1435.     RP            ;RETURN TO CALLER IF DISK READY
  1436.     CALL    NOTRDY        ;IF NOT READY, REPORT
  1437.     JMP    DSKEXR        ;IF CAME BACK, RETRY
  1438. ;
  1439. ;  BLOCK - BLOCK MOVE  (Z80 LDIR REGISTER USAGE)
  1440. ;
  1441. BLOCK:    MOV    A,M        ;GET BYTE
  1442.     STAX    D        ;STORE IT
  1443.     INX    H        ;BOP PTRS
  1444.     INX    D
  1445.     DCX    B        ;COUNT OFF BYTE
  1446.     MOV    A,B        ;CHECK FOR DONE
  1447.     ORA    C
  1448.     JNZ    BLOCK        ;GO BACK IF NOT
  1449.     RET
  1450. ;
  1451. ;
  1452. ;  HERE TO REPORT DISK NOT READY. TELL CONSOLE WHICH
  1453. ; DISK IT WAS, THEN SOLICIT REPLY. IF CTRL-C, WARM
  1454. ; BOOT TO A:, ELSE RETURN TO CALLER.
  1455. ;
  1456. NOTRDY:    LDA    SEKDSK        ;STUFF DISK
  1457.     ADI    'A'
  1458. ;
  1459. ;  ENTER HERE TO REPORT LINE PRINTER NOT READY
  1460. ;
  1461. PNTRDY:    STA    NRD        ; INTO MSG
  1462.     LXI    H,NRDMSG
  1463.     CALL    MSGOT        ;REPORT TO OPERATOR
  1464.     CALL    BCNSIN        ;GET REPLY
  1465.     SUI    3        ;IS ANSWER CTRL-C?
  1466.     RNZ            ;RETURN TO CALLER IF NOT
  1467.     STA    DEFDSK        ;SELECT A: IF SO,
  1468.                 ; THEN WARM BOOT IT
  1469. ;
  1470. ;  WARM BOOT ENTRY. LOAD CCP/BDOS AND INITIALIZE
  1471. ;
  1472. WARM:    DI            ;NO PROCESSOR INTS DURING BOOT
  1473.     LDA    DEFDSK        ;GET CURRENT DEFAULT DISK
  1474.     MOV    B,A        ;SAVE IT
  1475.     ANI    0F0H        ;GET USER #
  1476.     MOV    C,A        ;SAVE THAT
  1477.     MOV    A,B
  1478.     ANI    00FH        ;ISOLATE DISK #
  1479.     CPI    NDRVS        ;IS IT LEGAL?
  1480.     JC    WRMOK        ;GO ON IF SO
  1481.     XRA    A        ;BACK TO DRIVE ZERO IF NOT
  1482.     MOV    C,A        ;USER # PROB BAD TOO
  1483. WRMOK:    ORA    C        ;COMBINE WITH USER #
  1484.     STA    DFIMG        ;PUT TO BASE PAGE IMAGE
  1485.     LXI    SP,HSTBUF+HSTSIZ ;SET SP TO SCRATCH RAM
  1486.     LXI    H,CCP+3        ;CP/M WARM START ADDR
  1487.     PUSH    H
  1488. ;
  1489. ;  MERGE HERE FROM COLD BOOT
  1490. ;
  1491. CPMLD:    LDA    IOBYTE        ;GET CURRENT IOBYTE
  1492.     STA    IOIMG        ; INTO BASE PAGE IMAGE
  1493.     LXI    B,8        ;MOVE ZERO PAGE STUFF
  1494.     LXI    D,0        ; DOWN TO ZERO
  1495.     LXI    H,BSIMG
  1496.     CALL    BLOCK
  1497.     LXI    H,05959H    ;FORCE HOME OF N* DRIVES
  1498.     SHLD    NSTRK        ; A, B
  1499.     MOV    A,H        ;MAKE SURE NEW DISK SELECTED
  1500.     STA    CURDSK
  1501.     XRA    A        ;DRIVE ZERO VALUE
  1502.     STA    HSTDSK
  1503.     STA    HSTACT        ;HOST BUFFER INACTIVE
  1504.     STA    HSTWRT        ;NO HOST WRITE PENDING
  1505.     STA    UNACNT        ;CLEAR UNALLOC COUNT
  1506.     LXI    H,CCP        ;CP/M CCP ADDRESS
  1507.     SHLD    HSTADR        ;READ INTO THERE
  1508.     INR    A        ;GET 1 IN ACC
  1509.     STA    HSTTRK        ;READ FROM TRACK ONE
  1510.     CALL    WSETUP        ;KICK MOTORS AND SEEK TRK
  1511.     XRA    A        ;SECTOR ZERO
  1512. ;
  1513. ;  READ ALL TEN SECTORS FROM TRACK ONE THEN ONE SECTOR
  1514. ; FROM TRACK ZERO (SECTOR 3).
  1515. ;
  1516. WREAD:    STA    HSTSEC        ;SET CURRENT SECTOR TO READ
  1517.     CALL    WRMRD        ;READ SECTOR AND CHK STATUS
  1518.     LXI    D,HSTSIZ    ;SECTOR SIZE
  1519.     LHLD    HSTADR        ;CALC NEW ADDRESS
  1520.     DAD    D
  1521.     SHLD    HSTADR
  1522.     LDA    HSTSEC        ;BOP SECTOR #
  1523.     INR    A
  1524.     CPI    10        ;OFF END OF TRACK ONE?
  1525.     JNZ    WREAD        ;GO GET NEXT SECTOR IF NOT
  1526.     XRA    A        ;TO TRACK ZERO,
  1527.     STA    HSTTRK
  1528.     CALL    WSETUP
  1529.     MVI    A,3        ; SECTOR 3 IF SO
  1530.     STA    HSTSEC
  1531.     CALL    WRMRD        ;READ THE LAST SECTOR
  1532.     LXI    H,HSTBUF    ;NOW READ AND WRITE
  1533.     SHLD    HSTADR        ; USING DEBLOCK BUFFER
  1534.     LDA    DFIMG        ;RETRIEVE LAST USED DRIVE
  1535.     MOV    C,A        ; FOR BDOS
  1536.     RET            ; THEN GO TO CP/M
  1537. ;
  1538. WSETUP:    CALL    SETUP        ;KICK MOTORS AND SEEK TRK
  1539.     JMP    WECHK
  1540. ;
  1541. WRMRD:    CALL    READNS        ;READ HOST SECTOR
  1542. WECHK:    LDA    ERFLAG        ;CHECK FOR ERROR
  1543.     ORA    A
  1544.     RZ            ;RETURN IF NONE
  1545.     LXI    H,MSGLE        ;GET ERROR MESSAGE
  1546.     CALL    MSGOT        ;TYPE IT
  1547.     HLT            ; THEN GIVE UP
  1548. ;
  1549. ;  MSGOT DISPLAYS STRING OF CHARS PT'ED AT BY HL ON
  1550. ; CONSOLE, UNTIL CHAR WITH PARITY BIT SET IS OUTPUT.
  1551. ;
  1552. MSGOT:    PUSH    PSW        ;SAVE CALLER FLAGS
  1553. MSGL:    MOV    C,M        ;LOAD CHAR
  1554.     PUSH    H        ;SAVE HL
  1555.     CALL    BCNSOT        ;OUTPUT CHAR IN C
  1556.     POP    H        ;RESTORE HL
  1557.     MOV    A,M        ;GET CHAR BACK TO LOOK AT
  1558.     INX    H        ;LEAVE PTR ON NEXT CHAR
  1559.     RAL            ;IS HIGH BIT ON?
  1560.     JNC    MSGL        ;GO BACK IF NOT
  1561.     POP    PSW        ; ELSE RESTORE FLAGS
  1562.     RET            ; AND RETURN
  1563. ;
  1564. ;  DISK ERROR MESSAGES
  1565. ;
  1566. WPEMSG:    DB    'Protec','t'+80H
  1567. SDEMSG:    DB    'Densit','y'+80H
  1568. RERMSG:    DB    'CR','C'+80H
  1569. SYEMSG:    DB    'Syn','c'+80H
  1570. NIPMSG:    DB    'Inde','x'+80H
  1571. SNFMSG:    DB    'Secto','r'+80H
  1572. JIOMSG:    DB    CR,LF,'Jade DD',' '+80H
  1573. ;
  1574. ERRMSG:    DB    ' err '
  1575. ASCDSK:    DB    ' : trk',' '+80H
  1576. SECMSG:    DB    ' sec',' '+80H
  1577. NRDMSG:    DB    CR,LF,'Disk '
  1578. NRD:    DB    ' : not ready',' '+80H
  1579. CRLF:    DB    CR,LF+80H
  1580. ;
  1581. MSGLE:    DB    CR,LF,'Boot er','r'+80H
  1582. ;
  1583. ;  JADE ID LABEL DEFINITIONS
  1584. ;
  1585. JADEID:    DB    'Jade DD '    ;ID LABEL
  1586. IDSZE    EQU    $-JADEID    ;LABEL SIZE
  1587. ;
  1588. ;  NORTH STAR DD SECTOR TRANSLATE TABLE. AFTER
  1589. ; DEBLOCKING, WORKS OUT TO SKEW FACTOR OF 5.
  1590. ;
  1591. TRAN5D:    DB    01,02,03,04
  1592.     DB    21,22,23,24
  1593.     DB    05,06,07,08
  1594.     DB    25,26,27,28
  1595.     DB    09,10,11,12
  1596.     DB    29,30,31,32
  1597.     DB    13,14,15,16
  1598.     DB    33,34,35,36
  1599.     DB    17,18,19,20
  1600.     DB    37,38,39,40
  1601. ;
  1602. ;  NORTH STAR DD DISK PARAMETER BLOCK. THIS IS OUR
  1603. ; NORMAL DPB, AND IS COMPATIBLE WITH LIFEBOAT CP/M 1.4
  1604. ; DISKS.
  1605. ;
  1606. DPBNSD:    DW    40    ;SECTORS PER TRACK
  1607.     DB    3    ;BLOCK SHIFT FACTOR
  1608.     DB    07H    ;BLOCK MASK
  1609.     DB    0    ;EXM MASK
  1610.     DW    165-1    ;DISK SIZE - 1
  1611.     DW    63    ;DIRECTORY MAX
  1612.     DB    11000000B ;ALLOC 0
  1613.     DB    0    ;ALLOC 1
  1614.     DW    16    ;CHECK SIZE
  1615.     DW    2    ;TRACK OFFSET
  1616. ;
  1617. ;  THE NEXT BYTE IS ONE WE HAVE ADDED SPECIFICALLY
  1618. ; FOR THIS BIOS TO CONVENIENCE OUR DEBLOCKING ROUTINES.
  1619. ; IT IS A SECTOR SHIFT MASK, AND EACH DISK PARAMETER
  1620. ; BLOCK HAS ONE IN THIS POSITION. THE ALLOWABLE VALUES
  1621. ; ARE AS FOLLOWS:
  1622. ;
  1623. ;    1000B        ;1024 BYTES/SECTOR
  1624. ;    0100B        ; 512 BYTES/SECTOR
  1625. ;    0010B        ; 256 BYTES/SECTOR
  1626. ;    0000B        ; 128 BYTES/SECTOR
  1627. ;
  1628. ;  FOR THE NORTH STAR DD DISKS, 512 IS HARD-CODED. FOR
  1629. ; THE NORTH STAR SD DISKS, 256 IS HARD-CODED. FOR
  1630. ; JADE DISKS, THE VALUE IS READ IN FROM THE ID SECTOR.
  1631. ; IF THE ID LOOKS BOGUS, THE STANDARD 8" DPB IS USED,
  1632. ; WHICH HAS 128 CANNED-IN.
  1633. ;
  1634.     DB    0100B    ;512 BYTES/SECTOR
  1635. ;
  1636. ;  NORTH STAR DD DISK PARAMETER BLOCK, SET UP
  1637. ; FOR COMPATIBILITY WITH LIFEBOAT CP/M 2.X
  1638. ; FORMAT DISKS.
  1639. ;
  1640. DPBNSL:    DW    40    ;SECTORS PER TRACK
  1641.     DB    4    ;BLOCK SHIFT FACTOR
  1642.     DB    0FH    ;BLOCK MASK
  1643.     DB    1    ;EXM MASK
  1644.     DW    82-1    ;DISK SIZE - 1
  1645.     DW    63    ;DIRECTORY MAX
  1646.     DB    10000000B ;ALLOC 0
  1647.     DB    0    ;ALLOC 1
  1648.     DW    16    ;CHECK SIZE
  1649.     DW    2    ;TRACK OFFSET
  1650.     DB    0100B    ;512 BYTES/SECTOR
  1651. ;
  1652. ;  THERE IS NO NORTH STAR SINGLE DENSITY TRANSLATE
  1653. ; TABLE.
  1654. ;
  1655. TRAN5S:    EQU    0    ;TELL SECTRN TO JUST ADD 1
  1656. ;
  1657. ;  NORTH STAR SD DISK PARAMETER BLOCK
  1658. ;
  1659. DPBNSS:    DW    20    ;SECTORS PER TRACK
  1660.     DB    3    ;BLOCK SHIFT FACTOR
  1661.     DB    07H    ;BLOCK MASK
  1662.     DB    0    ;EXM MASK
  1663.     DW    80-1    ;DISK SIZE - 1
  1664.     DW    63    ;DIRECTORY MAX
  1665.     DB    11000000B ;ALLOC 0
  1666.     DB    0    ;ALLOC 1
  1667.     DW    16    ;CHECK SIZE
  1668.     DW    3    ;TRACK OFFSET
  1669.     DB    0010B    ;256 BYTES/SECTOR
  1670. ;
  1671. ;  STANDARD 8" SECTOR TRANSLATE TABLE
  1672. ;
  1673. TRAN8:    DB    1,7,13,19,25,5,11,17,23
  1674.     DB    3,9,15,21,2,8,14,20,26
  1675.     DB    6,12,18,24,4,10,16,22
  1676. ;
  1677. ;  STANDARD 8" DISK PARAMETER BLOCK
  1678. ;
  1679. DPB8:    DW    26
  1680.     DB    3
  1681.     DB    7
  1682.     DB    0
  1683.     DW    242
  1684.     DW    63
  1685.     DB    0C0H
  1686.     DB    0
  1687.     DW    16
  1688.     DW    2
  1689. ;
  1690.     DB    0000B    ;128 BYTES/SECTOR
  1691. ;
  1692. ;  1024 BYTES/SECTOR TRANSLATE TABLE
  1693. ;
  1694. TRN124:    DB    1,2,3,4,5,6,7,8
  1695.     DB    25,26,27,28,29,30,31,32
  1696.     DB    49,50,51,52,53,54,55,56
  1697.     DB    9,10,11,12,13,14,15,16
  1698.     DB    33,34,35,36,37,38,39,40
  1699.     DB    57,58,59,60,61,62,63,64
  1700.     DB    17,18,19,20,21,22,23,24
  1701.     DB    41,42,43,44,45,46,47,48
  1702. ;
  1703. ;  DRIVE PARAMETER HEADER AREA
  1704. ;
  1705. ;  DRIVES A: AND B: ARE NORTH STAR 5"
  1706. ;
  1707. D0DPH:    DW    0    ;SECTOR TRAN TBL SET BY SELDSK
  1708.     DW    0    ;SCRATCH
  1709.     DW    0    ;SCRATCH
  1710.     DW    0    ;SCRATCH
  1711.     DW    DIRBF    ;DIRECTORY BUFFER
  1712.     DW    0    ;DRIVE PARAM BLK SET BY SELDSK
  1713.     DW    D0CHK    ;DRIVE CHANGE BLK
  1714.     DW    D0ALL    ;DRIVE ALLOCATION
  1715. ;
  1716. D1DPH:    DW    0,0,0,0,DIRBF,0,D1CHK,D1ALL
  1717. ;
  1718. ;  DRIVES C: AND D: ARE JADE 8" SHUGART
  1719. ;
  1720. D2DPH:    DW    0,0,0,0,DIRBF,D2DPB,D2CHK,D2ALL
  1721. ;
  1722. D3DPH:    DW    0,0,0,0,DIRBF,D3DPB,D3CHK,D3ALL
  1723. ;
  1724. ;  ZERO PAGE IMAGE -- BLOCK MOVED TO BASE PAGE
  1725. ;
  1726. BSIMG:    JMP    BIOS+03H    ;WARM BOOT VECTOR
  1727. IOIMG:    DS    1        ;IOBYTE SET BY CPMLD
  1728. DFIMG:    DB    0        ;DEFAULT DISK -- ZERO
  1729.                 ; AFTER COLD BOOT
  1730.     JMP    BDOS+06H    ;BDOS CALL VECTOR
  1731. ;
  1732. ;  BIOS VARIABLE STORAGE
  1733. ;
  1734. SEKDSK:    DB    0    ;DRIVE NUMBER
  1735. SEKTRK:    DS    1    ;TRACK NUMBER (MUST IMM FOLLOW
  1736.             ; SEKDSK FOR LHLD)
  1737. SEKSEC:    DS    1    ;SECTOR NUMBER
  1738. SEKHST:    DS    1    ;SEEK SHR SECSHF
  1739. HSTACT:    DS    1    ;HOST ACTIVE FLAG
  1740. HSTWRT:    DS    1    ;HOST WRITTEN FLAG
  1741. DTPTR:    DW    0    ;DRIVE TABLE PTR
  1742. LOGFLG:    DB    0    ;NON-ZERO IF SELDSK
  1743.             ; LOGGED ON JADE DISK
  1744. ;
  1745. UNACNT:    DS    1    ;UNALLOC REC CNT
  1746. UNADSK:    DS    1    ;LAST UNALLOC DISK
  1747. UNATRK:    DS    1    ;LAST UNALLOC TRACK (MUST IMM
  1748.             ; FOLLOW UNADSK FOR LHLD)
  1749. UNASEC:    DS    1    ;LAST UNALLOC SECTOR
  1750. ;
  1751. ;  DEBLOCKING INFO ABOUT THE CURRENTLY-SELECTED DISK
  1752. ;
  1753. UNAVAL:    DS    1    ;# UNALLOC RECS/GROUP
  1754. CPMSPT:    DS    1    ;# CP/M SECTORS/TRACK
  1755. SECSHF:    DS    1    ;SECTOR SHIFT COUNT,
  1756.         ; LOG2 (# CP/M SECTORS/HOST BLOCK)
  1757. SECMSK:    DS    1    ;SECTOR MASK, # CP/M
  1758.         ; SECTORS/HOST BLOCK - 1
  1759. ;
  1760. ;  JADE DOUBLE D DCM PARAMETER BLOCK. ENTRIES
  1761. ; MUST BE IN THIS ORDER TO MATCH DCM ROUTINE
  1762. ; BLOCK.
  1763. ;
  1764. BTCMD:    DB    0    ;DCM COMMAND
  1765. BTDSK:    DS    1    ;JADE DD DRIVE #
  1766. BTTRK:    DS    1    ;TRACK NUMBER
  1767. BTSEC:    DS    1    ;SECTOR NUMBER
  1768. BTSP0:    DB    0    ;SPARE BYTE 0
  1769. BTCHR:    DB    0    ;LIST CHAR
  1770. BTMOD:    DB    0    ;MODE CONTROLS
  1771. BTSTS:    DB    0    ;COMMAND STATUS
  1772. BTLAD:    DW    0    ;LOAD ADDRESS
  1773. BTLNG:    DW    0    ;LOAD LENGTH
  1774. ;
  1775. ;  JADE-ONLY VARIABLES
  1776. ;
  1777. DADDR:    DW    0    ;DD MEMORY WINDOW ADDRESS
  1778. ;
  1779. ;  RESERVE DRIVE PARAMETER BLOCKS FOR JADE DRIVES
  1780. ;
  1781. DPBSZ    EQU    16    ;SIZE IS 16 BYTES
  1782. D2DPB:    DS    DPBSZ    ;RESERVE 16 BYTES/DISK C-D
  1783. ;
  1784. ;  EVERYTHING FROM THIS POINT FOR THE NEXT
  1785. ; 512 BYTES IS READ INTO MEMORY BY THE NORTH
  1786. ; STAR BOOT PROM. OUR GOAL HERE IS TO GET
  1787. ; A REASONABLE AMOUNT OF NORMAL BIOS CODE IN,
  1788. ; BUT AT THE SAME TIME WE NEED THE PORTIONS
  1789. ; THAT CAN READ THE DISK.
  1790. ;
  1791. ;  IF THIS SECTION OVERLAYS PREVIOUS BIOS CODE
  1792. ; OR DATA SPACE, THE PRECEDING BIOS MUST BE
  1793. ; TRIMMED DOWN.
  1794. ;
  1795. PRVCHK    EQU    $    ;** MUST NOT EXCEED BOOTA **
  1796. ;
  1797.     ORG    BIOS+(HSTSIZ*5)    ;ORG TO COLD BOOT
  1798. ;
  1799. BOOTA:    DB    BOOTA SHR 8    ;TELL PROM LOAD ADDR
  1800. ;
  1801. ;  THE NEXT NINE LOCATIONS ARE SKIPPED OVER
  1802. ; BY THE BOOT PROM, WHICH READS THIS SECTOR
  1803. ; THEN JUMPS TO BOOTA+0AH, SO PUT USEFUL VARIABLES
  1804. ; HERE. NOTE THAT ALL VARIABLES IN THIS SECTOR
  1805. ; WITH GENNED-IN VALUES ARE SET UP FOR COLD
  1806. ; BOOT LOADING OF BIOS.
  1807. ;
  1808. HSTADR:    DW    BIOS    ;READ BIOS INTO HERE TO START,
  1809.             ; BUT NORMALLY PTS TO HSTBUF
  1810. HSTDSK:    DB    0    ;HOST DISK NUMBER
  1811. HSTTRK:    DB    0    ;HOST TRACK NUMBER (MUST IMM
  1812.             ; FOLLOW HSTDSK FOR LHLD)
  1813. HSTSEC:    DB    5    ;HOST SECTOR NUMBER
  1814. ERFLAG:    DB    0    ;ERROR REPORTING
  1815. CURDSK:    DB    059H    ;CURRENT ACTIVE DISK,
  1816.             ; GENNED-IN FORCE SELECT
  1817. COLDB:    DB    1    ;COLD BOOT WHEN NON-ZERO
  1818. ERSEC:    DS    1    ;SECTOR IN ERROR
  1819. ;
  1820. ;  THIS IS THE SECTION OF THE COLD BOOT THAT
  1821. ; READS IN THE REST OF BIOS. ON MORE CONVENTIONAL
  1822. ; CP/M SYSTEMS, THIS WOULD BE THE BLOCK ZERO
  1823. ; BOOT. READ BIOS INTO MEMORY, THEN JUMP TO
  1824. ; IT TO FINISH COLD BOOTING.
  1825. ;
  1826. D3DPB:    EQU    $    ;*** OVERLAY N* COLD BOOT ***
  1827. ;
  1828. BOOT:    DI            ;ALLOW NO PROCESSOR INTERRUPTS
  1829.     LXI    SP,HSTBUF+HSTSIZ ;SET SP TO SCRATCH RAM
  1830.     CALL    SETUP        ;GIVE MOTORS EXTRA KICK
  1831.                 ; AND SEEK TRK 0
  1832. ;
  1833. BOOTL:    CALL    READNS        ;READ NEXT SECTOR OF BIOS
  1834.                 ;WITH COLDB NON-ZERO, NO
  1835.                 ; RETURN IF I/O ERROR
  1836.     LXI    H,HSTSEC    ;IF OK, BOP SEC NUM
  1837.     INR    M
  1838.     LHLD    HSTADR        ; AND ADVANCE READ ADDR
  1839.     LXI    D,HSTSIZ
  1840.     DAD    D
  1841.     SHLD    HSTADR
  1842.     MVI    A,BOOTA SHR 8    ;SEE IF READ ENUFF
  1843.     CMP    H
  1844.     JNZ    BOOTL        ;LOOP IF NOT
  1845.     JMP    INIT        ;GO START BIOS IF SO
  1846. ;
  1847. ;  REMAINING NEEDED VARIABLES
  1848. ;
  1849. RTCNT:    DS    1    ;ERROR RETRY COUNTER
  1850. NSDENS:    DS    1    ;DENSITY OF LAST NS DISK BLOCK
  1851.             ; READ, SD=128, DD=0
  1852. NSCNT:    DB    00H    ;COUNT AND DENSITY FLAG, SET
  1853.             ; BY WRITEHST TO MATCH ID SECTOR
  1854. ;
  1855. ;  NORTH STAR CURRENT TRACK TABLE
  1856. ;
  1857. NSTRK:    DB    059H    ;NO CURRENT TRACK YET
  1858.     DB    059H    ;EACH ENTRY CONTAINS
  1859. ;    DB    059H    ; THE LAST TRACK POSITION
  1860. ;    DB    059H    ; FOR THE UNIT 1-4
  1861. ;
  1862. ;  OTHER VARIABLES HERE BECAUSE THERE IS SPACE, CAN
  1863. ; BE MOVED IF NECESSARY
  1864. ;
  1865. RSFLAG:    DS    1    ;READ SECTOR FLAG
  1866. READOP:    DS    1    ;1 IF READ OPERATION
  1867. WRTYPE:    DS    1    ;WRITE OPERATION TYPE
  1868. DMAADR:    DS    2    ;LAST DMA ADDRESS
  1869. ENTPSW:    DW    0    ;ENTRY PSW AT DISK READ/WRITE
  1870. ;
  1871. ;  READHST PERFORMS THE PHYSICAL READ FROM THE
  1872. ; NORTH STAR DISK. ON ENTRY, DRIVE IS IN HSTDSK,
  1873. ; TRACK IS IN HSTTRK, SECTOR IS IN HSTSEC. ON
  1874. ; EXIT, ERROR FLAG IS IN ERFLAG (ZERO IF NONE).
  1875. ;
  1876. ;  ***  INTERRUPTS MUST BE DISABLED HERE  ***
  1877. ;
  1878. READHST:
  1879.     MVI    A,10        ;RETRY COUNT ON ERROR
  1880.     STA    RTCNT
  1881. ;
  1882. READRT:    CALL    SETUP        ;SELECT DRIVE AND
  1883.                 ; SEEK TO TRACK
  1884.     LDA    ERFLAG        ;CHECK FOR ERRORS
  1885.     ORA    A
  1886.     RNZ            ;INDEX PULSE NOT FOUND IS FATAL
  1887. ;
  1888. ;  HERE TO READ NORTH STAR WITHOUT TRACK SEEK FOR SPEED
  1889. ;
  1890. READNS:    CALL    POSEC        ;POSITION TO OUR SECTOR
  1891.     JNZ    SNFERR        ;ERROR IF NOT FOUND
  1892.     MVI    B,08CH        ;COUNT FOR SYNC CHAR LOOP
  1893.     LXI    D,CCMND+40H    ;SET UP READ DATA REGS
  1894. ;
  1895. ;  WAIT FOR RE SO WE CAN DO SECTOR READ, AND TEST
  1896. ; THE DOUBLE DENSITY BIT.
  1897. ;
  1898. WAITRE:    LDA    CCMND+10H    ;GET A-STATUS
  1899.     ANI    04H        ;CHECK RE
  1900.     JZ    WAITRE        ;LOOP UNTIL RE TRUE
  1901.     XTHL            ;KILL TIME TO GET INTO ZEROES
  1902.     XTHL
  1903.     XTHL
  1904.     XTHL
  1905.     XTHL
  1906.     XTHL
  1907.     XTHL
  1908.     XTHL
  1909.     LDA    CCMND+10H    ;GET A-STATUS AGAIN
  1910.     ANI    20H        ;ARE WE READING DOUBLE DENS?
  1911.     RAL            ;MAKE 80H IF NOT, ZERO IF SO
  1912.     RAL
  1913.     XRI    80H
  1914.     STA    NSDENS        ;SAVE DENSITY FOR CALLER
  1915. ;
  1916. ;  NOW WAIT FOR SYNC CHAR DETECTED. ERROR IF WE HAVE TO
  1917. ; WAIT TOO LONG.
  1918. ;
  1919. READ5:    LDA    CCMND+10H    ;WAIT FOR SYNC CHAR DETECTED
  1920.     RRC            ;CHECK BIT
  1921.     JC    READ15        ;OUT IF GOT IT
  1922.     DCR    B        ;COUNT DOWN IF NOT
  1923.     JNZ    READ5        ;GO BACK IF STILL OK
  1924.     MVI    A,1        ;SYNC ERROR IF WAITED TOO LONG
  1925.     LXI    H,SYEMSG    ;SYNC ERROR MESSAGE
  1926. ;
  1927. RERR:    STA    ERFLAG        ;STORE ERROR CODE
  1928.     LDA    RTCNT        ;COUNT OFF A RETRY
  1929.     DCR    A
  1930.     STA    RTCNT
  1931.     JNZ    READRT        ;IF COUNT LEFT, GO RETRY
  1932. ;
  1933. ;  READ ERROR RETRIES FAILED. FLAG ERROR.
  1934. ;
  1935.     JMP    DSKERR        ;TELL OPERATOR OF ERROR THEN OUT
  1936. ;
  1937. SNFERR:    STA    ERFLAG        ;SET ERROR FLAG
  1938.     LXI    H,SNFMSG
  1939.     JMP    DSKERR        ;REPORT ERROR ON WAY OUT
  1940. ;
  1941. ;  READ THE DATA INTO HSTBUF
  1942. ;
  1943. READ15:    LHLD    HSTADR        ;READ INTO HERE
  1944.     MVI    B,0        ;INIT CHECKSUM BYTE
  1945.     LDA    NSDENS        ;GET # BYTES TO READ
  1946.     MOV    C,A        ;PUT READ COUNT IN C-REG
  1947. ;
  1948. READ20:    LDAX    D        ;READ NEXT DATA BYTE
  1949.     MOV    M,A        ; AND PUT IT IN BUFFER
  1950.     XRA    B        ;ADD TO CHECKSUM
  1951.     RLC
  1952.     MOV    B,A
  1953.     INX    H        ;BOP BUFFER PTR
  1954.     NOP            ;KILL TIME
  1955.     LDAX    D        ;GET NEXT BYTE
  1956.     MOV    M,A
  1957.     XRA    B
  1958.     RLC
  1959.     MOV    B,A
  1960.     INX    H
  1961.     DCR    C        ;COUNT OFF LAST PAIR
  1962.     JNZ    READ20        ;GO BACK IF MORE TO DO
  1963.     LDAX    D        ; ELSE READ CRC BYTE
  1964.     XRA    B        ; AND CHECK IT AGAINST OURS
  1965.     STA    ERFLAG        ;IF OK, ZERO EFLAG
  1966.     RZ            ; AND RETURN TO CALLER
  1967.     MVI    A,2        ; ELSE FLAG CHECKSUM ERROR
  1968.     LXI    H,RERMSG    ;MESSAGE IF NEEDED
  1969.     JMP    RERR        ;GO MAYBE RETRY
  1970. ;
  1971. ;  SETUP SELECTS THE UNIT CORRESPONDING TO HSTDSK,
  1972. ; THEN SEEKS TO THE TRACK SPECIFIED BY HSTTRK.
  1973. ; WRITE PRECOMPENSATION IS SET IF REQUIRED AS
  1974. ; WELL. ON ERROR, ERFLAG CONTAINS A NON-ZERO
  1975. ; VALUE ON RETURN. ONLY UNITS 1 AND 2 ARE SUPPORTED
  1976. ; TO SAVE SPACE.
  1977. ;
  1978. SETUP:    LDA    NSCNT        ;GET DENSITY FLAG
  1979.     XRI    80H        ;INVERT TO SET DD
  1980.     MOV    C,A        ;SAVE MASK
  1981.     LDA    HSTDSK        ;WANT THIS DISK
  1982.     INR    A        ;REMAP TO CONTROLLER MASK
  1983. ;    CPI    03H        ;IF UNIT 1 OR 2,
  1984. ;    JC    SET0        ; GOT CORRECT MASK
  1985. ;    RAL            ;IF 3 OR 4, MUST MAP
  1986. ;    ANI    0CH        ; TO 4 OR 8 RESPECTIVELY
  1987. ;SET0:
  1988.     ORA    C        ;OR IN DENSITY MASK
  1989.     MOV    C,A        ;SAVE IN REG C
  1990.     CALL    WAIT1S        ;WAIT A SECTOR TIME, GET A-STAT
  1991.     ANI    10H        ;ARE MOTORS ALREADY ON?
  1992.     LDA    CCMND+15H    ;GIVE THEM EXTRA KICK ANYWAY
  1993.     JNZ    SET5        ;BRANCH IF SO
  1994.     MVI    D,17H        ;WAIT FOR MOTORS TO
  1995.     CALL    SCWAIT        ; COME UP TO SPEED IF NOT
  1996.     JMP    SET10        ; THEN GO SELECT DRIVE
  1997. ;
  1998. SET5:    LDA    CURDSK        ;IS THIS THE CURRENT DISK?
  1999.     CMP    C
  2000.     JZ    SET20        ;GO SEEK TO TRACK IF SO
  2001. ;
  2002. ;  MUST SELECT NEW DISK
  2003. ;
  2004. SET10:    MOV    A,C
  2005.     STA    CURDSK        ;NEW CURRENT DISK
  2006.     MVI    B,CORDER SHR 8    ;SET UP FOR SELECT
  2007.     LDAX    B        ; AND DO IT
  2008.     MVI    D,2        ;WAIT TWO SECTOR TIMES
  2009.     CALL    SCWAIT        ; BEFORE LOOKING FOR INDEX
  2010.     MVI    B,12        ;DON'T LOOK TOO LONG
  2011. ;
  2012. SET15:    CALL    WAIT1S        ;WAIT A SECTOR TIME, GET A-STAT
  2013.     ANI    40H        ;INDEX HOLE SEEN?
  2014.     JNZ    SET20        ;CAN GO SEEK NOW IF SO
  2015.     DCR    B        ;COUNT DOWN IF NOT
  2016.     JNZ    SET15        ; AND MAYBE GO LOOK AGAIN
  2017. ;
  2018. ;  INDEX HOLE NOT FOUND. DISK IS PROBABLY NOT LOADED.
  2019. ;
  2020.     MVI    A,4        ;NO INDEX PULSE
  2021.     STA    ERFLAG
  2022.     LXI    H,NIPMSG
  2023.     CALL    DSKERR        ;TELL OPERATOR
  2024.     CALL    NOTRDY        ; AND CLAIM DISK NOT READY
  2025.     MVI    A,059H        ;FORCE RESELECT OF DISK
  2026.     STA    CURDSK
  2027.     JMP    SETUP        ;TRY TO GET DISK AGAIN
  2028. ;
  2029. ;  SEEK TO TRACK SPECIFIED BY HSTTRK NOW, AND SET
  2030. ; WRITE PRECOMPENSATION IF APPROPRIATE.
  2031. ;
  2032. SET20:    LDA    HSTDSK        ;GET NSTRK INDEX
  2033.     MOV    C,A
  2034.     MVI    B,0
  2035.     LXI    H,NSTRK        ;PT AT TABLE
  2036.     DAD    B        ; THEN AT CORRECT ENTRY
  2037.     MOV    A,M        ;GET CURRENT TRACK
  2038.     PUSH    H        ;SAVE NSTRK PTR
  2039.     XRI    59H        ;DISK EVER ACCESSED?
  2040.     CZ    SEEK        ;IF NOT, HOME DRIVE
  2041.     POP    H        ;RESTORE NSTRK PTR
  2042.     LDA    HSTTRK        ;SEEK TO THIS TRACK
  2043.     PUSH    PSW        ;SAVE OVER CALL
  2044.     CALL    SEEK        ;DO FINAL SEEK
  2045.     POP    PSW        ;GET HSTTRK BACK
  2046.     CPI    14H+1        ;ARE WE BEYOND TRACK 14H?
  2047.     JC    SET25        ;GO ON IF NOT
  2048.     LDA    NSCNT        ;SEE IF DD OR SD
  2049.     ORA    A
  2050.     JNZ    SET25        ;NO PRECOMP IF SD
  2051.     LDA    CURDSK        ;IF SO, GET CURRENT MASK
  2052.     ORI    20H        ; AND SET PRECOMP BIT
  2053.     MVI    H,CORDER SHR 8
  2054.     MOV    L,A
  2055.     MOV    A,M        ;SET BIT IN CONTROLLER
  2056. ;
  2057. SET25:    XRA    A
  2058.     STA    ERFLAG        ;NO ERRORS
  2059.     RET
  2060. ;
  2061. ;  POSEC IS CALLED TO POSITION TO HSTSEC WITHIN
  2062. ; THE CURRENT TRACK. ERROR IS RETURNED BY NON-ZERO
  2063. ; IF WE CAN'T FIND THE SECTOR AFTER 30 TRIES.
  2064. ;
  2065. POSEC:    LDA    HSTSEC        ;GET TARGET SECTOR
  2066.     MOV    C,A        ;IN C
  2067.     STA    ERSEC        ;SET UP FOR POSSIBLE ERROR
  2068.     MVI    B,30        ;LOOK AT THIS MANY SECTORS
  2069. ;
  2070. POSC5:    CALL    WAIT1S        ;WAIT FOR NEXT SECTOR
  2071.     LDA    CCMND+35H    ;KICK MOTORS AND GET SECNUM
  2072.     ANI    0FH        ;STRIP NON-SECTOR BITS
  2073.     SUB    C        ;IS THIS THE TARGET SECTOR?
  2074.     RZ            ;OUT IF GOT IT
  2075.     DCR    B        ;COUNT OFF IF DIDN'T
  2076.     JNZ    POSC5        ;GO BACK IF NOT GIVING UP
  2077.     INR    B        ;SET NON-ZERO IF NOT FOUND
  2078.     RET
  2079. ;
  2080. ;  SEEK TO TRACK SPECIFIED BY ACC. CURRENT PTR INTO
  2081. ; NSTRK TABLE IS GIVEN BY HL. IF TRACK SPECIFIED IS
  2082. ; ZERO, SEEK WILL BE DONE UNTIL TRACK ZERO FLAG IS
  2083. ; SEEN, REGARDLESS OF CURRENT POSITION, UNLESS
  2084. ; WE ARE ALREADY THERE, SINCE NO SEEK IS DONE
  2085. ; IF ALREADY AT THE DESIRED TRACK.
  2086. ;
  2087. SEEK:    MOV    B,A        ;SAVE TARGET TRK #
  2088.     SUB    M        ;SEE HOW FAR AWAY WE ARE
  2089.                 ; FROM TARGET TRACK
  2090.     MOV    M,B        ; BUT ALWAYS SET NEW TRACK
  2091.     RZ            ;IF THERE, DONE
  2092.     LXI    H,CORDER+30H    ;ASSUME STEPPING IN
  2093.     MOV    C,A        ;SAVE STEP COUNT
  2094.     JP    STEPIN        ;BRANCH IF RIGHT
  2095.     CMA            ;IF WRONG, NEGATE COUNT
  2096.     INR    A
  2097.     MOV    C,A        ; THEN SAVE THAT
  2098.     LDA    CCMND+20H    ;GET B-STATUS
  2099.     ANI    01H        ;ARE WE ON TRACK ZERO?
  2100.     RNZ            ;MUST BE DONE IF SO
  2101.     MVI    L,10H        ;IF NOT, STEPPING OUT
  2102. ;
  2103. STEPIN:    LDA    CURDSK        ;GET CURRENT UNIT MASK
  2104.     ORA    L        ;FORM FINAL CORDER VALUE
  2105.     MOV    L,A
  2106.     MOV    D,M        ;SET THE STEP FLIP-FLOP
  2107.     ORI    10H
  2108.     MOV    L,A
  2109.     MOV    D,M        ;SET IT AGAIN FOR SOME REASON
  2110.     XRI    10H
  2111.     MOV    L,A
  2112.     MOV    D,M        ;NOW RESET THE STEP FLIP-FLOP
  2113. ;
  2114. ;  WAIT WHILE HEAD STARTS MOVING
  2115. ;
  2116.     MVI    A,14H
  2117. STEPW1:    MVI    D,38H
  2118. STEPW2:    DCR    D        ;KILL TIME
  2119.     JNZ    STEPW2
  2120.     DCR    A
  2121.     JNZ    STEPW1
  2122. ;
  2123. ;  THE STEP RATE DETERMINES HOW LONG TO WAIT. ONE SECTOR
  2124. ; TIME IS 20 MSEC. A SLOW SHUGART SA400 MAY REQUIRE 40
  2125. ; MSEC, OR TWO SECTOR TIMES. MOST TYPICAL SA400'S WILL
  2126. ; WORK WITH 20 MSEC, SO THAT'S WHAT WE'LL USE HERE. WE
  2127. ; WILL CALL SCWAIT INSTEAD OF WAIT1S IN CASE WE NEED TO
  2128. ; PATCH THIS VALUE.
  2129. ;
  2130.     MVI    D,1        ;NOW WAIT 20 MSEC
  2131. ;    MVI    D,2        ;NOW WAIT 40 MSEC
  2132.     CALL    SCWAIT
  2133.     LDA    CCMND+25H    ;GET B-STATUS AND KICK MOTORS
  2134.     ANI    01H        ;ARE WE AT TRACK ZERO?
  2135.     JNZ    WAIT1S        ;DONE STEPPING IF SO
  2136.     DCR    C        ; ELSE COUNT OFF LAST TRACK
  2137.     JNZ    STEPIN        ;GO BACK IF MORE TO DO
  2138.     CALL    WAIT1S        ;WAIT ONE MORE SECTOR TIME
  2139.                 ; TO MAKE SURE DONE STEPPING
  2140.     INR    B        ;SEEK TO TRACK ZERO?
  2141.     DCR    B
  2142.     RNZ            ;DONE IF NOT
  2143.     LDA    CCMND+25H    ;MUST HAVE TRK ZERO FLAG IF SO
  2144.     ANI    01H
  2145.     RNZ            ;OK IF SO
  2146.     JMP    STEPIN        ;GO STEP MORE IF NOT
  2147. ;
  2148. ;  SECTOR WAIT. ON ENTRY, # SECTORS TO WAIT IS IN D.
  2149. ; ON EXIT, D=0 AND ACC=A-STATUS. CALL WAIT1S TO WAIT
  2150. ; ONE SECTOR TIME.
  2151. ;
  2152. WAIT1S:    MVI    D,1        ;WAIT ONE SECTOR TIME
  2153. ;
  2154. SCWAIT:    LDA    CCMND+11H    ;RESET SECTOR FLAG
  2155. SCW5:    LDA    CCMND+10H    ;GET A-STATUS
  2156.     ORA    A        ;CHECK SECTOR FLAG
  2157.     JP    SCW5        ;WAIT FOR IT IF NOT UP
  2158.     LDA    CCMND+11H    ; ELSE RESET SECTOR FLAG
  2159.     DCR    D        ;COUNT DOWN WAIT COUNTER
  2160.     JNZ    SCW5        ;GO BACK IF MORE TO DO
  2161.     RET            ; ELSE RETURN A-STATUS IN ACC
  2162. ;
  2163. ;  DISK ERRORS REPORTED HERE, BECAUSE STUPID BDOS GIVES
  2164. ; NO USEFUL INFORMATION.
  2165. ;
  2166. DSKERR:    LDA    COLDB        ;IN COLD BOOT?
  2167.     ORA    A        ;IF SO, CNSOT NOT IN MEM YET
  2168.     JNZ    NSROM        ;BACK TO N* BOOT ROM ON SAME
  2169.     PUSH    H        ;SAVE BODY ADDRESS
  2170.     LXI    H,CRLF        ;EJECT LINE
  2171.     CALL    MSGOT
  2172.     POP    H
  2173.     CALL    MSGOT        ;REPORT BODY
  2174.     LDA    HSTDSK        ;THIS DISK
  2175. ;
  2176. ;  ENTER HERE AFTER JADE DD I/O ERROR
  2177. ;
  2178. JAERR:    ADI    'A'
  2179.     STA    ASCDSK
  2180.     LXI    H,ERRMSG
  2181.     CALL    MSGOT
  2182.     LDA    HSTTRK        ;THIS TRACK
  2183.     CALL    HXBOT
  2184.     LXI    H,SECMSG
  2185.     CALL    MSGOT
  2186.     LDA    ERSEC        ;THIS SECTOR
  2187.     JMP    HXBOT        ;OFF TO HXBOT TO FINISH
  2188. ;
  2189. EBOOT    EQU    $-1        ;LAST USED COLD BOOT BYTE
  2190. ;
  2191. ;
  2192. ;  NORTH STAR HOST SECTOR BUFFER
  2193. ;
  2194. HSTBUF:    DS    HSTSIZ        ;HOST BUFFER
  2195. ;
  2196. LAST    EQU    $-1        ;LAST USED BYTE IN MEM
  2197. ;
  2198.     END
  2199.