home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol017 / 21bios.asm < prev    next >
Assembly Source File  |  1984-04-29  |  48KB  |  1,947 lines

  1.     TITLE    'CP/M BASIC INPUT/OUTPUT ROUTINES'
  2. ; CP/M BASIC INPUT/OUTPUT OPERATING SYSTEM (BIOS)
  3. ; TARBELL ELECTRONICS
  4. ; 2.1 VERSION OF 1-9-80
  5. ; CHANGE SIGN-ON DATE FOR CP/M 2.1
  6. ;
  7. ; UPDATED BY:
  8. ; ROBERT M. WHITE
  9. ; H & W COMPUTER SYSTEMS, INC.
  10. ; 8530 STONEHAVEN
  11. ; BOISE, ID  83704
  12. ;
  13. ;
  14. ; THIS MODULE CONTAINS ALL THE INPUT/OUTPUT
  15. ; ROUTINES FOR THE CP/M SYSTEM, INCLUDING
  16. ; THE DISK ROUTINES.  It has been designed
  17. ; to provide a full implementation for a
  18. ; Tarbell controller and console configura-
  19. ; tion.  The disk drivers fully support
  20. ; various sector sizes and densities as
  21. ; documented later.  The I/O drivers fully
  22. ; support the IOBYTE as defined in the
  23. ; CP/M Alteration Manual.  Note this is an
  24. ; oversized BIOS and requires that the CCP
  25. ; be defined as a file on the default drive.
  26. ; Thus only the BDOS and BIOS are on the
  27. ; system tracks allowing a BIOS of 2.75k
  28. ; when both tracks are single density.
  29. ; Currently, a total of 4k is being allocated
  30. ; to the BIOS.  Therefore, the max CP/M
  31. ; memory size is 61k.  To calculate this,
  32. ; do as follows:
  33. ;    Max memory size+1 (64k) =10000H
  34. ;    10000H-1000H = F000H (Bios Base)
  35. ;    F000H-1600H = DA00H (CP/M Base)
  36. ;    DA00H-3400H = A600H (CBASE)
  37. ;    A600H/400H = 41
  38. ;    41+20 = 61 (Max CP/M Size)
  39. ;
  40. ; To SYSGEN, do the following:
  41. ;    1. Assemble this BIOS using MAC and
  42. ;       creating the file, 21BIOS.HEX.
  43. ;    2. Assemble the special Boot creating
  44. ;       the file, 21BOOT.HEX.
  45. ;    3. Create a CCP file on the
  46. ;       new default disk as follows:
  47. ;        DDT CPMxx.COM
  48. ;        -M980,1180,100
  49. ;        -^C
  50. ;        SAVE 8 CCP.COM
  51. ;    4. Put BDOS, BOOT & BIOS on the
  52. ;       new default disk as follows:
  53. ;        DDT CPMxx.COM
  54. ;        -M1180,1F80,980
  55. ;        -I21BOOT.HEX
  56. ;        -R900
  57. ;        -I21BIOS.HEX
  58. ;        -H1780,nnnn
  59. ;         xxxx yyyy       (Returned by DDT)
  60. ;        -Ryyyy
  61. ;        -^C
  62. ;        SYSGEN
  63. ;            (Answer as normal).
  64. ;
  65. ; Note -- A handy way of debugging this BIOS is
  66. ; to have an operating CP/M which is 16k larger.
  67. ; Boot this bios.  To capture data areas, simply
  68. ; re-boot the other and look at them with DDT.
  69. ; This technique was used extensively to get this
  70. ; BIOS operational.
  71. ;
  72. ;
  73. ; THIS SECTION DEFINES THE I/O PORTS AND
  74. ; STATUS BITS.  BY SETTING THE PROPER VALUES
  75. ; FOR THE EQU STATEMENTS, THE I/O MAY BE
  76. ; AUTOMATICALLY RECONFIGURED TO FIT MOST
  77. ; SITUATIONS.  THE TRUE AND FALSE ONES
  78. ; CONTROL CONDITIONAL ASSEMBLIES OF DIFFERENT
  79. ; SECTIONS OF I/O ROUTINES TO FIT DIFFERENT
  80. ; INTERFACE REQUIREMENTS.
  81.  
  82.     MACLIB    SPCLMAC
  83.  
  84. TRUE    EQU  0FFFFH    ;DEFINE VALUE OF TRUE.
  85. FALSE    EQU  NOT TRUE    ;DEFINE VALUE OF FALSE.
  86. BC    EQU  B        ;DOUBLE REGISTER EQUATES
  87. DE    EQU  D
  88. HL    EQU  H
  89.  
  90. ;***************************************************
  91. ;*** THIS BEGINS THE AREA WHICH REQUIRES CHANGES ***
  92. ;***      FOR DIFFERENT CONSOLE I/O SYSTEMS      ***
  93. ;***************************************************
  94.  
  95. MSIZE    EQU  61        ;MEMORY SIZE IN KBYTES.
  96. INTRP    EQU  FALSE    ;TRUE IF INTERRUPTS ALLOWED.
  97. DFTDSK    EQU  0        ;DEFAULT DISK ON BOOT (0-3)
  98. DFTUSR    EQU  0        ;DEFAULT USER ON BOOT (0-15)
  99.  
  100. OLDTARB EQU  FALSE    ;TRUE IF OLD TARBELL CONTROLLER (1771)
  101. TARBELL EQU  TRUE    ;TRUE IF NEW TARBELL CONTROLLER (1791)
  102.  
  103. DEBUG    EQU  FALSE    ;TRUE FOR SPECIAL DEBUGGING MESSAGES
  104. SPOOL    EQU  FALSE    ;TRUE IF USING KLH SPOOLER.
  105. NDISK    EQU  3        ;DEFINES THE NUMBER DRIVES IN SYSTEM.
  106.  
  107. CSTAT    EQU  16        ;CONSOLE STATUS PORT.
  108. CCOM    EQU  16        ;CONSOLE COMMAND PORT.
  109. CDATA    EQU  17        ;CONSOLE DATA PORT.
  110. CONUL    EQU  FALSE    ;CONSOLE NULLS?
  111. CNULL    EQU  0        ;CONSOLE NULL COUNT.
  112.  
  113. LSTAT    EQU  18        ;LIST STATUS PORT.
  114. LCOM    EQU  18        ;LIST COMMAND PORT.
  115. LDATA    EQU  19        ;LIST DATA PORT.
  116. LSTNUL    EQU  FALSE    ;LIST DEVICE NULLS?
  117. LNULL    EQU  0        ;LIST NULL COUNT.
  118. LSTPAG    EQU  FALSE    ;LIST DEVICE PAGING?
  119. LINCNT    EQU  66        ;LINES PER PAGE.
  120.  
  121. STPRAT    EQU  2        ;RATE 1=6MS, 2=10MS, 3=20MS.
  122. DUAL    EQU  FALSE    ;TRUE IF DUAL DRIVE.
  123. PERSCI    EQU  FALSE    ;TRUE IF FAST SEEK (PERSCI).
  124.  
  125. ;*******************************************************
  126. ;*** THIS IS THE END OF THE AREA WHICH NORMALLY NEED ***
  127. ;***     BE CHANGED FOR MOST CONSOLE I/O SYSTEMS     ***
  128. ;*******************************************************
  129.  
  130. DISK    EQU  0F8H    ;DISK BASE ADDRESS.
  131. DCOM    EQU  DISK    ;DISK COMMAND PORT.
  132. DSTAT    EQU  DISK    ;DISK STATUS PORT.
  133. TRACK    EQU  DISK+1    ;DISK TRACK PORT.
  134. SECTP    EQU  DISK+2    ;DISK SECTOR PORT.
  135. DDATA    EQU  DISK+3    ;DISK DATA PORT.
  136. WAIT    EQU  DISK+4    ;DISK WAIT PORT.
  137. DCONT    EQU  DISK+4    ;DISK CONTROL PORT.
  138.     IF    TARBELL
  139. DMACHK    EQU  DISK+5    ;DMA CHECK PORT.
  140.     ENDIF
  141.  
  142. RTCNT    EQU  10        ;RETRY COUNT.
  143.  
  144. CKBR    EQU  00000001B    ;KEYBOARD READY BIT.
  145. CPTR    EQU  00000010B    ;PRINT READY BIT.
  146. LKBR    EQU  00000001B    ;LISTER READY BIT.
  147. LPTR    EQU  00000010B    ;LISTER READY BIT.
  148.  
  149.  
  150. IOBYTE    EQU  3            ;ADDRESS OF I/O BYTE.
  151. CBASE    EQU  (MSIZE-20)*1024      ;BIAS FOR LARGER THAN 20K.
  152. CPMB    EQU  CBASE+3400H    ;START OF CPM 2.0
  153. BDOS    EQU  CPMB+806H        ;START OF BDOS 2.0.
  154. BIOS    EQU  CPMB+1600H        ;START OF CBIOS IO.
  155. CDISK    EQU  4            ;LOCATION 4 IS CURRENT DISK.
  156. NSECTS    EQU  44            ;NUMBER OF SECTORS IN IT.
  157.  
  158.     ORG  BIOS        ;START OF CBIOS STRUCTURE.
  159. ;
  160. ; I/O JUMP VECTOR
  161. ; THIS IS WHERE CPM CALLS WHENEVER IT NEEDS
  162. ; TO DO ANY INPUT/OUTPUT OPERATION.
  163. ; USER PROGRAMS MAY USE THESE ENTRY POINTS
  164. ; ALSO, BUT NOTE THAT THE LOCATION OF THIS
  165. ; VECTOR CHANGES WITH THE MEMORY SIZE.
  166. ;
  167.     JMP  BOOT        ;FROM COLD START LOADER.
  168. WBOOTE:    JMP  WBOOT        ;FROM WARM BOOT.
  169.     JMP  CONST        ;CHECK CONSOLE KB STATUS.
  170.     JMP  CONIN        ;READ CONSOLE CHARACTER.
  171.     JMP  CONOUT        ;WRITE CONSOLE CHARACTER.
  172.     JMP  LSTOUT        ;WRITE LISTING CHAR.
  173.     JMP  PUNOUT        ;WRITE PUNCH CHAR.
  174.     JMP  RDRIN        ;READ READER CHAR.
  175.     JMP  HOME        ;MOVE DISK TO TRACK ZERO.
  176.     JMP  SELDSK        ;SELECT DISK DRIVE.
  177.     JMP  SETTRK        ;SEEK TO TRACK IN REG A.
  178.     JMP  SETSEC        ;SET SECTOR NUMBER.
  179.     JMP  SETDMA        ;SET DISK STARTING ADR.
  180.     JMP  READ        ;READ SELECTED SECTOR.
  181.     JMP  WRITE        ;WRITE SELECTED SECTOR.
  182.     JMP  LSTST        ;LIST STATUS CHECK.
  183.     JMP  SECTRAN        ;SECTOR TRANSLATE ROUTINE.
  184.  
  185.     ; THESE ENTRY POINTS ADDED BY TARBELL ELECTRONICS.
  186.  
  187.     IF  SPOOL        ;IF USING KLH SPOOLER.
  188.     DB   0FFH        ;FLAG FOR SPOOLER.
  189.     DW   LTBSY        ;LISTER STATUS LOCATION
  190.     DW   LTBSY        ;FOR SPOOLER - -
  191.     DW   LTBSY        ;I DON'T KNOW WHY IT'S
  192.     DW   LTBSY        ;HERE 4 TIMES EITHER.
  193.     ENDIF
  194.  
  195. ;        SPECIAL ENTRY POINTS FOR DIRECT DISK I/O
  196.     JMP  Pselct        ;Select the drive in (C).
  197.     JMP  Phome        ;Home current drive.
  198.     JMP  Pseek        ;Seek track in (C).
  199.     JMP  Pread        ;Read a sector in (C), dma in (HL)
  200.     JMP  Pwrite        ;Write a sector in (C), dma in (HL)
  201.  
  202.  
  203.  
  204. ;*****************************************************
  205. ;*                                                   *
  206. ;*      Sector Deblocking Algorithms for CP/M 2.0    *
  207. ;*                                                   *
  208. ;*****************************************************
  209. ;
  210. ;    This section of programming provides the disk
  211. ;drivers for the BIOS.  They are designed to handle
  212. ;many combinations of disk formats and sector sizes.
  213. ;Currently, the definitions of these combinations are
  214. ;defined as in DFOCO distributed by S. J. Singer via
  215. ;the CP/M User's Group.  For further information, see
  216. ;the documentation for that fine program.
  217. ;    The actual routines are divided into two sec-
  218. ;tions.  The first performs logical blocking and de-
  219. ;blocking of the host physical sectors.  The second
  220. ;section contains the actual physical routines to per-
  221. ;form the I/O functions necessary for proper operation
  222. ;of the disk drives.  Currently, these routines assume
  223. ;a Tarbell Single or Double Density Controller.  The
  224. ;original logical routines were supplied by Digital
  225. ;Research as a part of CP/M 2.0.
  226. ;
  227. ;*****************************************************
  228. ;*                                                   *
  229. ;*         CP/M to host disk constants               *
  230. ;*                                                   *
  231. ;*****************************************************
  232. hstmax    equ    1024        ;host max disk sector size
  233. ;
  234. ;*****************************************************
  235. ;*                                                   *
  236. ;*        BDOS constants on entry to write           *
  237. ;*                                                   *
  238. ;*****************************************************
  239. wrall    equ    0        ;write to allocated
  240. wrdir    equ    1        ;write to directory
  241. wrual    equ    2        ;write to unallocated
  242.  
  243.  
  244.  
  245. ;/////////////////////////////////////////////////////
  246. ;/       Logical Disk I/O Driver Routines         /
  247. ;/////////////////////////////////////////////////////
  248.  
  249.  
  250. ;*****************************************************
  251. ;*                                                   *
  252. ;*    The BDOS entry points given below show the   *
  253. ;*      code which is relevant to deblocking only.   *
  254. ;*                                                   *
  255. ;*****************************************************
  256. ;
  257. ;    DISKDEF macro, or hand coded tables go here
  258. ;
  259. ;        * * *  Disk Parameter Header  * * *
  260. ;    In general, each disk has an associated Disk
  261. ;Parameter Header which both contains information about
  262. ;the disk drive and provides a scratchpad area for 
  263. ;certain BDOS operations.
  264. ;
  265. dphbase    equ    $        ;disk param block header
  266. DPE0    equ    $        ;** Disk A **
  267.     dw    00000H,00000H    ;XLT adr, Scratch
  268.     dw    00000H,00000H    ;Scratch, Scratch
  269.     dw    dirbuf,00000H    ;Dir Buf adr, DPB adr
  270.     dw    CSV0,ALV0    ;CSV adr, ALV adr
  271. DPE1    equ    $        ;** Disk B **
  272.     dw    00000H,00000H    ;XLT adr, Scratch
  273.     dw    00000H,00000H    ;Scratch, Scratch
  274.     dw    dirbuf,00000H    ;Dir Buf adr, DPB adr
  275.     dw    CSV1,ALV1    ;CSV adr, ALV adr
  276. DPE2    equ    $        ;** Disk C **
  277.     dw    00000H,00000H    ;XLT adr, Scratch
  278.     dw    00000H,00000H    ;Scratch, Scratch
  279.     dw    dirbuf,00000H    ;Dir Buf adr, DPB adr
  280.     dw    CSV2,ALV2    ;CSV adr, ALV adr
  281. DPE3    equ    $        ;** Disk D **
  282.     dw    00000H,00000H    ;XLT adr, Scratch
  283.     dw    00000H,00000H    ;Scratch, Scratch
  284.     dw    dirbuf,00000H    ;Dir Buf adr, DPB adr
  285.     dw    CSV3,ALV3    ;CSV adr, ALV adr
  286. ;
  287. ;        * * *  Disk Parameter Block  * * *
  288. ;    In general, each DPH, Disk Parameter Header, 
  289. ;points to a particular DPB, Disk Parameter Block.
  290. ;The DPB contains information directly relating to
  291. ;the organition of data on the disk and its hardware
  292. ;characteristics.
  293. ;
  294. ;        * *  DPB Field Displacements  * *
  295. dpbspt    equ    0    ;host CP/M sectors/track
  296. dpbbsh    equ    2    ;block shift factor
  297. dpbblm    equ    3    ;block shift mask
  298. dpbexm    equ    4    ;extent mask
  299. dpbdsm    equ    5    ;max block rcd #
  300. dpbdrm    equ    7    ;max dir mask
  301. dpbal0    equ    9    ;dir allocation vector
  302. dpbal1    equ    10    ;dir allocation vector
  303. dpbcks    equ    11    ;dir check value
  304. dpboff    equ    13    ;rsvd tracks offset
  305. dpbdfc    equ    15    ;disk format code
  306. dpbssc    equ    16    ;host sector size
  307. dpbhbm    equ    18    ;host sector mask
  308. dpbhbs    equ    19    ;host sector shift value
  309. dpbxlt    equ    20    ;xlt ptr
  310. dpblen    equ    22    ;DPB length
  311. ;
  312. dpbbase    equ    $    ;Base of Disk Parameter Blocks
  313. dpbs00    equ    $    ;** Single Density, 128 byte Sectors **
  314.     DPB    020H,128,26,1024,243,64,64,2,xlts00
  315. dpbs01    equ    $    ;** Single Density, 256 byte Sectors **
  316.     DPB    021H,256,16,2048,150,64,64,2,0
  317. dpbs02    equ    $    ;** Single Density, 512 byte Sectors **
  318.     DPB    022H,512,8,2048,150,64,64,2,0
  319. dpbs03    equ    $    ;** Single Density, 1024 byte Sectors **
  320.     DPB    023H,1024,4,2048,150,64,64,2,0
  321. dpbd00    equ    $    ;** Double Density, 128 byte Sectors **
  322.     DPB    010H,128,51,2048,239,128,128,2,xltd00
  323. dpbd01    equ    $    ;** Double Density, 256 byte Sectors **
  324.     DPB    011H,256,26,2048,243,128,128,2,0
  325. dpbd02    equ    $    ;** Double Density, 512 byte Sectors **
  326.     DPB    012H,512,16,2048,300,128,128,2,0
  327. dpbd03    equ    $    ;** Double Density, 1024 byte Sectors **
  328.     DPB    013H,1024,8,2048,300,128,128,2,0
  329. dpbnum    equ    ($-dpbbase)/dpblen    ;# of entries in table
  330.  
  331.  
  332. ;        * * *  Sector Translation Table  * * *
  333. ;    This section contains the STT, Sector Translation
  334. ;Table, for particular disk configurations (I.E.  DPB's).
  335. ;The table gives a logical to physical mapping of sector
  336. ;numbers.  Thereby, allowing different mappings for per-
  337. ;formance betterment.  Note that all entries must be rela-
  338. ;tive to zero, not one.
  339. xltbase    equ    $    ;Base of Sector Translation Tables
  340. xlts00    equ    $    ;** Single density, 128 byte sectors,
  341. ;            ;   26 Sec/Trk, Skew 6 **
  342.     db    0,6,12,18,24
  343.     db    4,10,16,22,2
  344.     db    8,14,20,1,7
  345.     db    13,19,25,5,11
  346.     db    17,23,3,9,15,21
  347. xltd00    equ    $    ;** Double density, 128 byte sectors,
  348. ;            ;   51 Sec/Trk, Skew 18 **
  349.     db    0,17,34,9,26,43,1,18,35,10,27
  350.     db    44,2,19,36,11,28,45,3,20,37,12
  351.     db    29,46,4,21,38,13,30,47,5,22,39
  352.     db    14,31,48,6,23,40,15,32,49,7,24
  353.     db    41,16,33,50,8,25,42
  354. ;
  355. ;
  356. ;*****************************************************
  357. ;*                                                   *
  358. ;*    BOOT - Cold Boot Routine.             *
  359. ;*        Executed whenever Reset is pressed.  *
  360. ;*                                                   *
  361. ;*****************************************************
  362.  
  363. BOOT:
  364. ;        Do initialization.
  365.     lxi    sp,080H    ;set stack ptr.
  366.     if    INTRP
  367.     ei        ;enable interrupts.
  368.     endif
  369.  
  370. ;        Initialize Mits 2SIO.
  371.     mvi    a,3    ;Issue reset.
  372.     out    ccom
  373.     out    lcom
  374.     mvi    a,015H    ;Set up Ports.
  375.     out    ccom
  376.     out    lcom
  377.     in    cdata    ;clear console port.
  378.  
  379. ;        Save last six bytes of CCP.
  380.     lxi    h,BDOS-6
  381.     lxi    d,ccpsav
  382.     mvi    c,6
  383.     mov    a,m
  384.     stax    d
  385.     inx    h
  386.     inx    d
  387.     dcr    c
  388.     jnz    $-5
  389.  
  390. ;        Zero defined Scratch area.
  391.     lxi    b,ENDZ-STARTZ
  392.     lxi    h,STARTZ
  393.     mvi    m,0
  394.     inx    h
  395.     dcx    b
  396.     mov    a,b
  397.     ora    c
  398.     jnz    $-6
  399.  
  400. ;        Set Low memory areas excluding jumps.
  401.     mvi    a,095H    ;IOBYTE := CON=CRT, LST=LPT, PUN=PTP,
  402.     sta    IOBYTE    ;       RDR=PTR
  403.     mvi    a,0    ;Default disk = A:
  404.     sta    CDISK
  405.  
  406. ;        Issue opening message.
  407.     lxi    h,smsg
  408.     call    Pmsg
  409.  
  410. ;        Finish by warm booting.
  411.     jmp    WBOOT
  412.  
  413.  
  414. ;*****************************************************
  415. ;*                                                   *
  416. ;*    WBOOT - Warm Boot Routine.             *
  417. ;*                                                   *
  418. ;*****************************************************
  419.  
  420. WBOOT:
  421. ;        Do initialization.
  422.     lxi    sp,080H    ;set stack ptr.
  423.     if    INTRP
  424.     di        ;disable interrupts.
  425.     endif
  426.  
  427. ;        Set up jumps for CP/M in low memory.
  428.     mvi    a,0C3H    ;put (JMP) for WBOOT.
  429.     sta    0
  430.     lxi    h,WBOOTE
  431.     shld    1
  432.     sta    5    ;put (JMP) for BDOS.
  433.     lxi    h,BDOS
  434.     shld    6
  435.  
  436. ;        Issue loading CCP message.
  437.     if    DEBUG
  438.     lxi    h,lodccp
  439.     call    pmsg
  440.     endif
  441.  
  442. ;        Zero Disk table.
  443.     mvi    c,4*2
  444.     lxi    h,dsktbl
  445.     mvi    m,0
  446.     inx    h
  447.     dcr    c
  448.     jnz    $-4
  449.  
  450. ;        Reset Deblock fields.
  451.     xra    a
  452.     sta    hstact    ;host buffer inactive
  453.     sta    unacnt    ;clear unalloc count.
  454.  
  455. ;        Select and login default disk drive.
  456.     mvi    c,DFTDSK    ;do it.
  457.     call    SELDSK
  458.  
  459. ;        Set default user to zero for now.
  460.     mvi    e,0
  461.     mvi    c,020H
  462.     call    BDOS
  463.  
  464. ;        Reset disk system.
  465.     mvi    c,00DH
  466.     call    BDOS
  467.  
  468. ;        Select default drive.
  469.     mvi    e,DFTDSK
  470.     mvi    c,00EH
  471.     call    BDOS
  472.  
  473. ;        Zero CCP's FCB.
  474.     lxi    h,ccpfcb+12
  475.     mvi    c,21
  476.     mvi    m,0
  477.     inx    h
  478.     dcr    c
  479.     jnz    $-4
  480.  
  481. ;        Open CCP's FCB.
  482.     lxi    d,ccpfcb
  483.     mvi    c,00FH
  484.     call    BDOS
  485.     inr    a        ;Error?
  486.     jc    Bterr        ;...yes.
  487.  
  488. ;        Read in the CCP.
  489.     mvi    c,16    ;set # of sectors in CCP.
  490.     lxi    d,128    ;set sector size.
  491.     lxi    h,CPMB    ;set CCP base address.
  492.  
  493.     call    Ccpred    ;Read a sector.
  494.     dad    d    ;bump ptr.
  495.     dcr    c    ;Decr count.
  496.     jnz    $-5    ;loop till done.
  497.  
  498. ;        Restore CCP's last six bytes.
  499.     lxi    h,ccpsav
  500.     lxi    d,BDOS-6
  501.     mvi    c,6
  502.     mov    a,m
  503.     stax    d
  504.     inx    h
  505.     inx    d
  506.     dcr    c
  507.     jnz    $-5
  508.  
  509. ;        Issue CCP loaded Message.
  510.     if    DEBUG
  511.     lxi    h,ccplod
  512.     call    Pmsg
  513.     endif
  514.  
  515. ;        Do misc initialization.
  516.     lxi    h,080H    ;set default buffer in dma.
  517.     shld    dmaadr
  518.     if    INTRP
  519.     ei        ;enable interrupts.
  520.     endif
  521.  
  522. ;        Set default drive and user and go to CCP.
  523.     lda    CDISK    ;get default drive.
  524.     mov    c,a    ;save it.
  525.     mvi    a,DFTUSR ;get Default user (0-15).
  526.     ral        ;Put it in high hex digit.
  527.     ral
  528.     ral
  529.     ral
  530.     add    c    ;add in default drive.
  531.     mov    c,a    ;set for CCP.
  532.     jmp    CPMB    ;go to CCP.
  533.  
  534.  
  535. ccpfcb:    db    0,'CCP     ','COM',0,0,0,0
  536.     db    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  537.     db    0
  538.  
  539. ;        * *  Read a sector of CCP.  * *
  540. Ccpred:
  541. ;        Do initialization.
  542.     push    b    ;save regs.
  543.     push    d
  544.     push    h
  545.  
  546. ;        Set DMA for read.
  547.     xchg
  548.     mvi    c,01AH
  549.     call    BDOS
  550.  
  551. ;        Issue the read.
  552.     lxi    d,ccpfcb
  553.     mvi    c,014H
  554.     call    BDOS
  555.     ora    a    ;Error?
  556.     jnz    Bterr    ;...yes.
  557.  
  558. ;        Return to caller.
  559.     pop    h    ;restore regs.
  560.     pop    d
  561.     pop    b
  562.     ret
  563.  
  564.  
  565. ;        * *  Handle boot errors  * *
  566. Bterr:
  567. ;        Tell operator.
  568.     lxi    h,btmsg    ;Issue Boot error msg.
  569.     call    Pmsg
  570.     call    CONIN    ;Wait.
  571.     jmp    WBOOT    ;Try warm boot again.
  572.  
  573.  
  574. ;*****************************************************
  575. ;*                                                   *
  576. ;*    SELDSK - Select a Disk.                 *
  577. ;*                                                   *
  578. ;*****************************************************
  579.  
  580. SELDSK:
  581. ;        Validate the disk #.
  582.     lxi    h,0        ;set for error.
  583.     mov    a,c        ;get the disk #.
  584.     cpi    NDISK        ;Undefined drive?
  585.     rnc            ;...yes, return w/error.
  586.     mov    a,c        ;selected disk number
  587.     sta    sekdsk        ;seek disk number
  588.  
  589. ;        Get ptr to disk's DPH.
  590.     mov    l,a        ;disk number to HL
  591.     mvi    h,0
  592.     rept    4        ;multiply by 16
  593.     dad    h
  594.     endm
  595.     lxi    d,dphbase    ;base of parm block
  596.     dad    d        ;hl=.dph(curdsk)
  597.     shld    sekdph        ;save it.
  598.  
  599. ;        Log the disk if not already logged.
  600.     mov    a,c        ;point to disk table entry.
  601.     call    Dskadr
  602.     mov    a,m        ;get flag byte.
  603.     ora    a        ;Already logged?
  604.     jm    $+6        ;...yes.
  605.     call    Logdsk        ;...no, log it in.
  606.  
  607. ;        now get address of dpb.
  608.     lhld    sekdph        ;hl = .dph(curdsk)
  609.     lxi    d,10        ;hl = .dphdpb(curdsk)
  610.     dad    d
  611.     mov    e,m        ;hl = .dpb(curdsk)
  612.     inx    h
  613.     mov    d,m
  614.     xchg
  615.     shld    sekdpb        ;save it.
  616.  
  617. ;        return to caller.
  618.     lhld    sekdph
  619.     ret
  620.  
  621.  
  622. ;*****************************************************
  623. ;*                                                   *
  624. ;*    Logdsk - Login disk in (C).                 *
  625. ;*                                                   *
  626. ;*****************************************************
  627.  
  628. Logdsk:
  629. ;        Get the format code from sector 1 track 0.
  630.     call    Pselct    ;Physically select the drive.
  631.     call    Phome    ;Home the head.
  632.     mvi    c,0    ;Seek track 0 setting density.
  633.     call    Pseek
  634.     mvi    c,1    ;Read in first Sector.
  635.     lxi    h,dirbuf
  636.     call    Pread
  637.     lda    dirbuf+07FH ;Get the format code.
  638.     sta    dskdfc    ;save it.
  639.  
  640. ;        Log the disk's DPH.
  641.     lhld    sekdph
  642.     call    Logdph
  643.  
  644. ;        Log it into the disk table.
  645.     lda    sekdsk    ;point to disk table entry.
  646.     call    Dskadr
  647.     lda    dskdfc    ;get the density code.
  648.     ani    010H
  649.     rrc        ;put it in low order byte.
  650.     rrc
  651.     rrc
  652.     rrc
  653.     ori    080H    ;add in logged bit.
  654.     mov    m,a    ;put it in table flag byte.
  655.  
  656. ;        return to caller.
  657.     ret
  658.  
  659.  
  660. ;*****************************************************
  661. ;*                                                   *
  662. ;*    Logdph - Login disk parameter header.         *
  663. ;*                                                   *
  664. ;*****************************************************
  665.  
  666. Logdph:
  667. ;        Get the right DPB.
  668.     xchg        ;de = .dph
  669.     lda    dskdfc    ;get format code for search.
  670.     call    Srcdpb    ;Search the DPB table.
  671.  
  672. ;        Put the XLT address in the DPH.
  673.     push    h    ;save DPB ptr.
  674.     rxdld    b,<>,dpbxlt ;Get XLT address.
  675.     xchg        ;put it in DPH.
  676.     mov    m,c
  677.     inx    h
  678.     mov    m,b
  679.  
  680. ;        Put DPB address in DPH.
  681.     lxi    d,9    ;point to dphdpb.
  682.     dad    d
  683.     pop    d    ;get DPB address.
  684.     mov    m,e    ;put it in DPH.
  685.     inx    h
  686.     mov    m,d
  687.  
  688. ;        return to caller.
  689.     ret
  690.  
  691.  
  692. ;*****************************************************
  693. ;*                                                   *
  694. ;*    Srcdpb - Search DPB table on format code.    *
  695. ;*                                                   *
  696. ;*****************************************************
  697.  
  698. Srcdpb:
  699. ;        Do initialization.
  700.     push    b    ;save regs.
  701.     push    d
  702.     mov    b,a    ;save format code.
  703.     mvi    c,dpbnum ;set for # of entries.
  704.     lxi    h,dpbbase ;point to DPB table.
  705.     lxi    d,dpblen ;get entry length.
  706.  
  707. ;        Scan the table taking default if not
  708. ;        found.
  709. Srcdpl:
  710.     push    h    ;save current entry ptr.
  711.     rxld    a,<>,dpbdfc ;get entry's format code.
  712.     pop    h
  713.     cmp    b    ;Did we find it?
  714.     jz    Srcdpf    ;...yes, return w/it.
  715.     dad    d    ;bump ptr to next entry.
  716.     dcr    c    ;loop till no more entries.
  717.     jnz    Srcdpl
  718.     lxi    h,dpbs00 ;Default to SD/SS 128 byte.
  719.  
  720. ;        Return to caller w/entry ptr.
  721. Srcdpf:
  722.     pop    d    ;restore regs.
  723.     pop    b
  724.     ret
  725.  
  726.  
  727. ;*****************************************************
  728. ;*                                                   *
  729. ;*    HOME - Home a particular disk.             *
  730. ;*                                                   *
  731. ;*****************************************************
  732.  
  733. HOME:
  734.     ;set track given by registers BC
  735.     lxi    h,0
  736.     shld    sektrk        ;track to seek
  737.     ret
  738.  
  739.  
  740. ;*****************************************************
  741. ;*                                                   *
  742. ;*    SETTRK - Set appropriate track.             *
  743. ;*                                                   *
  744. ;*****************************************************
  745.  
  746. SETTRK:
  747.     ;set track given by registers BC
  748.     mov    h,b
  749.     mov    l,c
  750.     shld    sektrk        ;track to seek
  751.     ret
  752.  
  753.  
  754. ;*****************************************************
  755. ;*                                                   *
  756. ;*    SETSEC - Set appropriate sector.         *
  757. ;*                                                   *
  758. ;*****************************************************
  759.  
  760. SETSEC:
  761.     ;set sector given by register c 
  762.     mov    a,c
  763.     sta    seksec        ;sector to seek
  764.     ret
  765.  
  766.  
  767. ;*****************************************************
  768. ;*                                                   *
  769. ;*    SETDMA - Set Data Memory Address.         *
  770. ;*                                                   *
  771. ;*****************************************************
  772.  
  773. SETDMA:
  774.     ;set dma address given by BC
  775.     mov    h,b
  776.     mov    l,c
  777.     shld    dmaadr
  778.     ret
  779.  
  780.  
  781. ;*****************************************************
  782. ;*                                                   *
  783. ;*    SECTRAN - Do Sector Translation.         *
  784. ;*                                                   *
  785. ;*****************************************************
  786.  
  787. SECTRAN:
  788.     ;translate sector number BC
  789.     mvi    h,0    ;hl = physical sector
  790.     mov    l,c
  791.     mov    a,d    ;if not using xlat tbl then
  792.     ora    e    ;   return.
  793.     rz
  794.     xchg        ;hl = .xlt
  795.     dad    b    ;hl = .xlt(sector)
  796.     mov    l,m    ;hl = xlt'd sector
  797.     mvi    h,0
  798.     ret
  799.  
  800.  
  801. ;*****************************************************
  802. ;*                                                   *
  803. ;*    The READ entry point takes the place of      *
  804. ;*    the previous BIOS defintion for READ.        *
  805. ;*                                                   *
  806. ;*****************************************************
  807. READ:
  808.     ;read the selected CP/M sector
  809.     xra    a        ;accum = 00
  810.     sta    unacnt        ;unacnt= 00
  811.     mvi    a,1
  812.     sta    readop        ;read operation
  813.     sta    rsflag        ;must read data
  814.     mvi    a,wrual
  815.     sta    wrtype        ;treat as unalloc
  816.     jmp    rwoper        ;to perform the read
  817.  
  818.  
  819. ;*****************************************************
  820. ;*                                                   *
  821. ;*    The WRITE entry point takes the place of     *
  822. ;*    the previous BIOS defintion for WRITE.       *
  823. ;*                                                   *
  824. ;*****************************************************
  825. WRITE:
  826.     ;write the selected CP/M sector
  827.     xra    a        ;0 to accumulator
  828.     sta    readop        ;not a read operation
  829.     mov    a,c        ;write type in c
  830.     sta    wrtype
  831.     cpi    wrual        ;write unallocated?
  832.     jnz    chkuna        ;check for unalloc
  833. ;
  834. ;    write to unallocated, set parameters
  835.     rxld    a,sekdpb,dpbblm    ;a = dpbblm(sekdsk) + 1
  836.     inr    a
  837.     sta    unacnt
  838.     lda    sekdsk        ;disk to seek
  839.     sta    unadsk        ;unadsk = sekdsk
  840.     lhld    sektrk
  841.     shld    unatrk        ;unatrk = sectrk
  842.     lda    seksec
  843.     sta    unasec        ;unasec = seksec
  844. ;
  845. chkuna:
  846.     ;check for write to unallocated sector
  847.     lda    unacnt        ;any unalloc remain?
  848.     ora    a
  849.     jz    alloc        ;skip if not
  850. ;
  851. ;    more unallocated records remain
  852.     dcr    a        ;unacnt = unacnt-1
  853.     sta    unacnt
  854.     lda    sekdsk        ;same disk?
  855.     lxi    h,unadsk
  856.     cmp    m        ;sekdsk = unadsk?
  857.     jnz    alloc        ;skip if not
  858. ;
  859. ;    disks are the same
  860.     lxi    h,unatrk
  861.     call    sektrkcmp    ;sektrk = unatrk?
  862.     jnz    alloc        ;skip if not
  863. ;
  864. ;    tracks are the same
  865.     lda    seksec        ;same sector?
  866.     lxi    h,unasec
  867.     cmp    m        ;seksec = unasec?
  868.     jnz    alloc        ;skip if not
  869. ;
  870. ;    match, move to next sector for future ref
  871.     inr    m        ;unasec = unasec+1
  872.     mov    a,m        ;end of track?
  873.     push    h
  874.     rxad    sekdpb,dpbspt
  875.     cmp    m
  876.     pop    h
  877.     jc    noovf        ;skip if no overflow
  878. ;
  879. ;    overflow to next track
  880.     mvi    m,0        ;unasec = 0
  881.     lhld    unatrk
  882.     inx    h
  883.     shld    unatrk        ;unatrk = unatrk+1
  884. ;
  885. noovf:
  886.     ;match found, mark as unnecessary read
  887.     xra    a        ;0 to accumulator
  888.     sta    rsflag        ;rsflag = 0
  889.     jmp    rwoper        ;to perform the write
  890. ;
  891. alloc:
  892.     ;not an unallocated record, requires pre-read
  893.     xra    a        ;0 to accum
  894.     sta    unacnt        ;unacnt = 0
  895.     inr    a        ;1 to accum
  896.     sta    rsflag        ;rsflag = 1
  897.  
  898.  
  899. ;*****************************************************
  900. ;*                                                   *
  901. ;*    Common code for READ and WRITE follows       *
  902. ;*                                                   *
  903. ;*****************************************************
  904. rwoper:
  905. ;        convert sector to host sector # by
  906. ;        dividing it by the number of sectors
  907. ;        per host sector.
  908.     xra    a        ;zero to accum
  909.     sta    erflag        ;no errors (yet)
  910.     lda    seksec        ;compute host sector
  911.     rxld    b,sekdpb,dpbhbs    ;b = dpbhbs(sekdpb)
  912.     dcr    b        ;b = 0?
  913.     inr    b
  914.     jz    rwope1        ;...yes, use as is.
  915.     ora    a        ;carry = 0
  916.     rar            ;shift right
  917.     dcr    b        ;decr shift count.
  918.     jnz    $-3        ;go shift it again.
  919. rwope1:
  920.     sta    sekhst        ;host sector to seek
  921. ;
  922. ;    active host sector?
  923.     lxi    h,hstact    ;host active flag
  924.     mov    a,m
  925.     mvi    m,1        ;always becomes 1
  926.     ora    a        ;was it already?
  927.     jz    filhst        ;fill host if not
  928. ;
  929. ;    host buffer active, same as seek buffer?
  930.     lda    sekdsk
  931.     lxi    h,hstdsk    ;same disk?
  932.     cmp    m        ;sekdsk = hstdsk?
  933.     jnz    nomatch
  934. ;
  935. ;    same disk, same track?
  936.     lxi    h,hsttrk
  937.     call    sektrkcmp    ;sektrk = hsttrk?
  938.     jnz    nomatch
  939. ;
  940. ;    same disk, same track, same buffer?
  941.     lda    sekhst
  942.     lxi    h,hstsec    ;sekhst = hstsec?
  943.     cmp    m
  944.     jz    match        ;skip if match
  945. ;
  946. nomatch:
  947.     ;proper disk, but not correct sector
  948.     lda    hstwrt        ;host written?
  949.     ora    a
  950.     cnz    writehst    ;clear host buff
  951. ;
  952. filhst:
  953.     ;may have to fill the host buffer
  954.     lda    sekdsk
  955.     sta    hstdsk
  956.     lhld    sektrk
  957.     shld    hsttrk
  958.     lda    sekhst
  959.     sta    hstsec
  960.     lhld    sekdph
  961.     shld    hstdph
  962.     lhld    sekdpb
  963.     shld    hstdpb
  964.     lda    rsflag        ;need to read?
  965.     ora    a
  966.     cnz    readhst        ;yes, if 1
  967.     xra    a        ;0 to accum
  968.     sta    hstwrt        ;no pending write
  969. ;
  970. match:
  971.     ;copy data to or from buffer
  972.     lda    seksec        ;mask buffer number
  973.     rxad    sekdpb,dpbhbm    ;hl = .dpbhbm(sekdpb)
  974.     ana    m        ;least signif bits
  975.     mov    l,a        ;ready to shift
  976.     mvi    h,0        ;double count
  977.     rept    7        ;shift left 7
  978.     dad    h
  979.     endm
  980. ;    hl has relative host buffer address
  981.     lxi    d,hstbuf
  982.     dad    d        ;hl = host address
  983.     xchg            ;now in DE
  984.     lhld    dmaadr        ;get/put CP/M data
  985.     mvi    c,128        ;length of move
  986.     lda    readop        ;which way?
  987.     ora    a
  988.     jnz    rwmove        ;skip if read
  989. ;
  990. ;    write operation, mark and switch direction
  991.     mvi    a,1
  992.     sta    hstwrt        ;hstwrt = 1
  993.     xchg            ;source/dest swap
  994. ;
  995. rwmove:
  996.     ;C initially 128, DE is source, HL is dest
  997.     ldax    d        ;source character
  998.     inx    d
  999.     mov    m,a        ;to dest
  1000.     inx    h
  1001.     dcr    c        ;loop 128 times
  1002.     jnz    rwmove
  1003. ;
  1004. ;    data has been moved to/from host buffer
  1005.     lda    wrtype        ;write type
  1006.     cpi    wrdir        ;to directory?
  1007.     lda    erflag        ;in case of errors
  1008.     rnz            ;no further processing
  1009. ;
  1010. ;    clear host buffer for directory write
  1011.     ora    a        ;errors?
  1012.     rnz            ;skip if so
  1013.     xra    a        ;0 to accum
  1014.     sta    hstwrt        ;buffer written
  1015.     call    writehst
  1016.     lda    erflag
  1017.     ret
  1018.  
  1019.  
  1020. ;*****************************************************
  1021. ;*                                                   *
  1022. ;*    Utility subroutine for 16-bit compare        *
  1023. ;*                                                   *
  1024. ;*****************************************************
  1025. sektrkcmp:
  1026.     ;HL = .unatrk or .hsttrk, compare with sektrk
  1027.     xchg
  1028.     lxi    h,sektrk
  1029.     ldax    d        ;low byte compare
  1030.     cmp    m        ;same?
  1031.     rnz            ;return if not
  1032. ;    low bytes equal, test high 1s
  1033.     inx    d
  1034.     inx    h
  1035.     ldax    d
  1036.     cmp    m    ;sets flags
  1037.     ret
  1038. ;
  1039. ;*****************************************************
  1040. ;*                                                   *
  1041. ;*    WRITEHST performs the physical write to      *
  1042. ;*    the host disk, READHST reads the physical    *
  1043. ;*    disk.                         *
  1044. ;*                                                   *
  1045. ;*****************************************************
  1046. writehst:
  1047.     ;hstdsk = host disk #, hsttrk = host track #,
  1048.     ;hstsec = host sect #. write "hstsiz" bytes
  1049.     ;from hstbuf and return error flag in erflag.
  1050.     ;return erflag non-zero if error
  1051.  
  1052. ;        Select the drive.
  1053.     lxi    h,hstdsk    ;c = disk #
  1054.     mov    c,m
  1055.     call    Pselct        ;Select it.
  1056.  
  1057. ;        Set the head on the proper track.
  1058.     lxi    h,hsttrk    ;c = track #
  1059.     mov    c,m
  1060.     call    Pseek        ;do it.
  1061.     sta    erflag        ;save error code.
  1062.     rnz            ;return if error.
  1063.  
  1064. ;        Write the sector.
  1065.     lxi    h,hstsec    ;c = sector #
  1066.     mov    c,m
  1067.     inr    c        ;make it relative to one.
  1068.     lxi    h,hstbuf    ;hl = .buffer
  1069.     call    Pwrite        ;do it.
  1070.     sta    erflag        ;save error code.
  1071.     ret
  1072.  
  1073.  
  1074. readhst:
  1075.     ;hstdsk = host disk #, hsttrk = host track #,
  1076.     ;hstsec = host sect #. read "hstsiz" bytes
  1077.     ;into hstbuf and return error flag in erflag.
  1078.  
  1079. ;        Select the drive.
  1080.     lda    hstdsk        ;c = disk #
  1081.     mov    c,a
  1082.     call    Pselct        ;Select it.
  1083.  
  1084. ;        Set the head on the proper track.
  1085.     lxi    h,hsttrk    ;c = track #
  1086.     mov    c,m
  1087.     call    Pseek        ;do it.
  1088.     sta    erflag        ;save error code.
  1089.     rnz            ;return if error.
  1090.  
  1091. ;        Read the sector.
  1092.     lxi    h,hstsec    ;c = sector #
  1093.     mov    c,m
  1094.     inr    c        ;make it relative to one.
  1095.     lxi    h,hstbuf    ;hl = .buffer
  1096.     call    Pread        ;do it.
  1097.     sta    erflag        ;save error code.
  1098.     ret
  1099.  
  1100.  
  1101. ;/////////////////////////////////////////////////////
  1102. ;/                                                   /
  1103. ;/    Physical Disk I/O Driver Routines         /
  1104. ;/                                                   /
  1105. ;/////////////////////////////////////////////////////
  1106.  
  1107.  
  1108. ;*****************************************************
  1109. ;*                                                   *
  1110. ;*    Pselct - Physical Device Select             *
  1111. ;*                                                   *
  1112. ;*****************************************************
  1113.  
  1114. Pselct:
  1115. ;        Trace activity.
  1116.     if    DEBUG
  1117.     push    h
  1118.     lxi    h,trcact
  1119.     mvi    m,1
  1120.     pop    h
  1121.     endif
  1122.  
  1123. ;    Save current disk's Track #.
  1124.     lda    dskcur    ;point to Disk table entry.
  1125.     call    Dskadr
  1126.     inx    h    ;point to track save.
  1127.     in    TRACK    ;get the track #.
  1128.     mov    m,a    ;save it.
  1129.  
  1130. ;        Get the new track #.
  1131.     mov    a,c    ;get new disk #.
  1132.     sta    dskcur    ;make it the current one.
  1133.     call    Dskadr    ;point to disk table entry.
  1134.     inx    h    ;point to track save.
  1135.     mov    a,m    ;get track #.
  1136.     sta    dsktrk    ;save it.
  1137.     out    TRACK    ;put it in controller.
  1138.  
  1139. ;        Set the new disk's latch.
  1140.     mov    a,c    ;get the disk #.
  1141.     if    OLDTARB
  1142.     cma        ;invert it.
  1143.     add    a    ;Put bits 1&2 in 4&5.
  1144.     add    a
  1145.     add    a
  1146.     add    a
  1147.     ori    2    ;make latch command.
  1148.     endif
  1149.     if    TARBELL
  1150.     add    a    ;Put bits 1&2 in 4&5.
  1151.     add    a
  1152.     add    a
  1153.     add    a
  1154.     endif
  1155.     sta    dsklth    ;save new latch.
  1156.  
  1157. ;        Return to caller.
  1158.     ret
  1159.  
  1160.  
  1161. ;*****************************************************
  1162. ;*                                                   *
  1163. ;*    Phome - Physical Device Home             *
  1164. ;*                                                   *
  1165. ;*****************************************************
  1166.  
  1167. Phome:
  1168. ;        Trace activity.
  1169.     if    DEBUG
  1170.     push    h
  1171.     lxi    h,trcact
  1172.     mvi    m,2
  1173.     pop    h
  1174.     endif
  1175.  
  1176. ;        Select the drive in single density.
  1177.     lda    dsklth    ;Get current latch.
  1178.     out    DCONT    ;Issue it to controller.
  1179.  
  1180. ;        Wait for device not to be busy.
  1181.     in    DSTAT    ;get disk status.
  1182.     rrc        ;check busy bit.
  1183.     jc    $-3    ;...loop till not busy.
  1184.  
  1185. ;        Issue Restore Command.
  1186.     mvi    a,002H    ;Restore cmd - no hdld, no verify
  1187.     out    DCOM    ;Issue it.
  1188.     in    WAIT    ;Wait for completion.
  1189.  
  1190. ;        Delay 200 msec.
  1191.     mvi    a,200
  1192.     call    delay
  1193.  
  1194. ;        Check the status for track zero.
  1195.     in    DSTAT
  1196.     ani    4    ;Track zero?
  1197.     jz    Phome    ;...no, try again.
  1198.  
  1199. ;        Reset track # in table.
  1200.     lda    dskcur    ;point to table entry.
  1201.     call    Dskadr
  1202.     inx    h    ;point to track #.
  1203.     mvi    m,0    ;reset it.
  1204.     lxi    h,dsktrk ;reset current track #.
  1205.     mvi    m,0
  1206.  
  1207. ;        Return to caller.
  1208.     ret
  1209.  
  1210.  
  1211. ;*****************************************************
  1212. ;*                                                   *
  1213. ;*    Pseek - Physical Device Seek             *
  1214. ;*                                                   *
  1215. ;*****************************************************
  1216.  
  1217. Pseek:
  1218. ;        Trace activity.
  1219.     if    DEBUG
  1220.     push    h
  1221.     lxi    h,trcact
  1222.     mvi    m,3
  1223.     pop    h
  1224.     endif
  1225.  
  1226. ;        Select the drive and density.
  1227.     mov    a,c    ;get track #.
  1228.     sta    dsktrk    ;save it.
  1229.     sta    dsktrs    ;...again.
  1230.     ora    a    ;Track zero?
  1231.     jz    Pseek1    ;...yes, force single density.
  1232.     lda    dskcur    ;point to disk table entry.
  1233.     call    Dskadr
  1234.     mov    a,m    ;get flag byte.
  1235.     ani    1    ;Double density?
  1236.     jz    $+5    ;...no.
  1237.     mvi    a,8    ;...yes, set it.
  1238. Pseek1: mov    b,a    ;save density.
  1239.     lda    dsklth    ;get current latch.
  1240.     ora    b    ;add in density.
  1241.     out    DCONT    ;put it to controller.
  1242.  
  1243. ;        If we've changed drives since last seek,
  1244. ;        force a seek to the same track to unload
  1245. ;        the head.  Thus insuring that the head
  1246. ;        load bit is properly set for this drive.
  1247.     lhld    dsklth    ;get old and new latches.
  1248.     mov    a,l    ;Are they the same?
  1249.     cmp    h
  1250.     lda    dsklth    ;reset them no matter what.
  1251.     sta    dskolt
  1252.     jnz    Pseek2-2 ;...no, insure seek to same track.
  1253.  
  1254. ;        Check to see if current track is desired one.
  1255.     in    TRACK    ;get current track.
  1256.     cmp    c    ;Are they the same?
  1257.     rz        ;...yes, return.
  1258.  
  1259. ;        Issue the Seek command.
  1260.     mvi    b,RTCNT    ;set retry count.
  1261. Pseek2: lda    dsktrk    ;get the desired track #.
  1262.     out    DDATA    ;tell controller.
  1263.     in    DSTAT    ;Wait till not busy.
  1264.     rrc
  1265.     jc    $-3
  1266.     mvi    a,014H+STPRAT ;seek cmd w/verify.
  1267.     out    DCOM
  1268.     in    Wait    ;Wait till complete.
  1269.     in    DSTAT    ;get disk status.
  1270.     if    DEBUG
  1271.     sta    trcerr
  1272.     endif
  1273.     ani    091H    ;Check for error.
  1274.     rz        ;...none, return.
  1275.  
  1276. ;        Handle errors.
  1277.     dcr    b    ;Decr retry count.
  1278.     jz    Pseek3    ;...hard error.
  1279.     call    Phome    ;home the device.
  1280.     lda    dsktrs    ;restore original trk #.
  1281.     sta    dsktrk
  1282.     jmp    Pseek2    ;Try seeking again.
  1283. Pseek3:
  1284.     call    Recov    ;Ask about recovery.
  1285.     lda    dsktrs    ;restore original trk #.
  1286.     sta    dsktrk
  1287.     jmp    Pseek2-2 ;Try it again.
  1288.  
  1289.  
  1290. ;*****************************************************
  1291. ;*                                                   *
  1292. ;*    Pread - Physical Sector read.             *
  1293. ;*                                                   *
  1294. ;*****************************************************
  1295.  
  1296. Pread:
  1297. ;        Trace activity.
  1298.     if    DEBUG
  1299.     push    h
  1300.     lxi    h,trcact
  1301.     mvi    m,4
  1302.     pop    h
  1303.     endif
  1304.  
  1305. ;        Save input parameters.
  1306.     shld    dskdma    ;dma address
  1307.     lxi    h,dsksec ;sector #
  1308.     mov    m,c
  1309.     if    INTRP
  1310.     di        ;disable interrupts.
  1311.     endif
  1312.  
  1313. ;        Set retry count and interrupt controller.
  1314. Prdagn:
  1315.     mvi    a,RTCNT    ;Set retry count.
  1316. Prdrty:
  1317.     sta    dskerr
  1318.     mvi    a,0D0H    ;Issue soft interrupt.
  1319.     out    DCOM
  1320.     xthl        ;Do some delay.
  1321.     xthl
  1322.  
  1323. ;        Set the Sector.
  1324.     lda    dsksec    ;get it.
  1325.     out    SECTP
  1326.  
  1327. ;        Point to buffer.
  1328.     lhld    dskdma
  1329.  
  1330. ;        Issue Read command to controller.
  1331.     in    DSTAT    ;get head load status.
  1332.     ani    020H
  1333.     xri    020H    ;invert it.
  1334.     rrc        ;put it in proper bit.
  1335.     rrc
  1336.     rrc
  1337.     if    OLDTARB
  1338.     ori    088H    ;Read cmd w/o hdld
  1339.     endif
  1340.     if    TARBELL
  1341.     ori    080H    ;Read cmd w/o hdld
  1342.     endif
  1343.     out    DCOM    ;Issue it.
  1344.  
  1345. ;        Read the data.
  1346. Prdlop:
  1347.     in    WAIT    ;Wait for INTRQ.
  1348.     ora    a    ;Is it there?
  1349.     jp    Prddon    ;...yes, we're done.
  1350.     in    DDATA    ;get a char.
  1351.     mov    m,a    ;put it in buffer.
  1352.     inx    h    ;bump ptr.
  1353.     jmp    Prdlop    ;go get another.
  1354.  
  1355. ;        Analyze read status.
  1356. Prddon:
  1357.     in    DSTAT    ;get it.
  1358.     if    DEBUG
  1359.     sta    trcerr
  1360.     endif
  1361.     if    INTRP
  1362.     ei        ;enable interrupts.
  1363.     endif
  1364.     ani    09DH    ;any errors?
  1365.     rz        ;...no, return.
  1366.     call    Erchk    ;...yes, insure proper track.
  1367.     lda    dskerr    ;get retry count.
  1368.     dcr    a    ;Decr it.
  1369.     jnz    Prdrty    ;...Try reading it again.
  1370.     call    Recov    ;Give possible operater cancel.
  1371.     jmp    Prdagn    ;Try reading again.
  1372.  
  1373.  
  1374. ;*****************************************************
  1375. ;*                                                   *
  1376. ;*    Pwrite - Physical Sector Write.             *
  1377. ;*                                                   *
  1378. ;*****************************************************
  1379.  
  1380. Pwrite:
  1381. ;        Trace activity.
  1382.     if    DEBUG
  1383.     push    h
  1384.     lxi    h,trcact
  1385.     mvi    m,5
  1386.     pop    h
  1387.     endif
  1388.  
  1389. ;        Save input parameters.
  1390.     shld    dskdma    ;dma address
  1391.     lxi    h,dsksec ;sector #
  1392.     mov    m,c
  1393.     if    INTRP
  1394.     di        ;disable interrupts.
  1395.     endif
  1396.  
  1397. ;        Set retry count and interrupt controller.
  1398. Pwragn:
  1399.     mvi    a,RTCNT    ;Set retry count.
  1400. Pwrrty:
  1401.     sta    dskerr
  1402.     mvi    a,0D0H    ;Issue soft interrupt.
  1403.     out    DCOM
  1404.     xthl        ;Do some delay.
  1405.     xthl
  1406.  
  1407. ;        Set the Sector.
  1408.     lda    dsksec    ;get it.
  1409.     out    SECTP
  1410.  
  1411. ;        Point to buffer.
  1412.     lhld    dskdma
  1413.  
  1414. ;        Issue Write command to controller.
  1415.     in    DSTAT    ;get head load status.
  1416.     ani    020H
  1417.     xri    020H    ;invert it.
  1418.     rrc        ;put it in proper bit.
  1419.     rrc
  1420.     rrc
  1421.     if    OLDTARB
  1422.     ori    0A8H    ;Write cmd w/o hdld
  1423.     endif
  1424.     if    TARBELL
  1425.     ori    0A0H    ;Write cmd w/o hdld
  1426.     endif
  1427.     out    DCOM    ;Issue it.
  1428.  
  1429. ;        Write the data.
  1430. Pwrlop:
  1431.     in    WAIT    ;Wait for INTRQ.
  1432.     ora    a    ;Is it there?
  1433.     jp    Pwrdon    ;...yes, we're done.
  1434.     mov    a,m    ;get a char from the buffer.
  1435.     out    DDATA    ;put it to disk.
  1436.     inx    h    ;bump ptr.
  1437.     jmp    Pwrlop    ;go get another.
  1438.  
  1439. ;        Analyze read status.
  1440. Pwrdon:
  1441.     mvi    a,1    ;delay some.
  1442.     call    Delay
  1443.     in    DSTAT    ;get it.
  1444.     if    DEBUG
  1445.     sta    trcerr
  1446.     endif
  1447.     if    INTRP
  1448.     ei        ;enable interrupts.
  1449.     endif
  1450.     ani    0FDH    ;any errors?
  1451.     rz        ;...no, return.
  1452.     call    Erchk    ;...yes, insure proper track.
  1453.     lda    dskerr    ;get retry count.
  1454.     dcr    a    ;Decr it.
  1455.     jnz    Pwrrty    ;...Try reading it again.
  1456.     call    Recov    ;Give possible operater cancel.
  1457.     jmp    Pwragn    ;Try reading again.
  1458.  
  1459.  
  1460.  
  1461.  
  1462. ;*****************************************************
  1463. ;*                                                   *
  1464. ;*    Erchk - Insure proper seek on read/write     *
  1465. ;*                                                   *
  1466. ;*****************************************************
  1467.  
  1468. Erchk:
  1469. ;        Return if not Rcd not found error.
  1470.     push    psw    ;save error flags.
  1471.     ani    010H    ;Record not found?
  1472.     jnz    Erchk1    ;...yes, read address and seek.
  1473.     pop    psw    ;...no, return.
  1474.     ora    a
  1475.     ret
  1476.  
  1477. ;        Read the next address.
  1478. Erchk1:
  1479.     mvi    a,0C4H    ;Read address w/15ms delay
  1480.     out    DCOM
  1481.     in    WAIT    ;Wait for DRQ or INTRQ.
  1482.     in    DDATA    ;Read track address.
  1483.     push    psw    ;save it.
  1484.  
  1485. ;        Flush rest of address data.
  1486. Erchk2:
  1487.     in    Wait    ;Wait for INTRQ.
  1488.     ora    a    ;Read done?
  1489.     jp    Erchk3    ;...yes.
  1490.     in    DDATA    ;...no, flush rest.
  1491.     jmp    Erchk2
  1492.  
  1493. ;        Check on Read Status.
  1494. Erchk3:
  1495.     in    DSTAT    ;Get read Status.
  1496.     ora    a    ;Sucessful?
  1497.     jz    Erchk4    ;...yes.
  1498.     pop    psw    ;...no, clean up stack.
  1499.     call    Phome    ;       home head
  1500.     jmp    Erchk1    ;    and try again.
  1501.  
  1502. ;        Put track # read in controller.
  1503. Erchk4:
  1504.     pop    psw    ;restore track address.
  1505.     out    TRACK    ;put it in controller.
  1506.  
  1507. ;        Seek to proper track.
  1508.     lda    dsktrk    ;get the proper track #.
  1509.     mov    c,a
  1510.     call    Pseek    ;do the seek.
  1511.     pop    psw    ;restore error flag.
  1512.     ret
  1513.  
  1514.  
  1515.  
  1516. ;*****************************************************
  1517. ;*                                                   *
  1518. ;*    Dskadr - Get disk table entry ptr.         *
  1519. ;*                                                   *
  1520. ;*****************************************************
  1521.  
  1522. Dskadr:
  1523.     push    d    ;save regs.
  1524.     mov    l,a    ;hl = disp to entry.
  1525.     mvi    h,0
  1526.     dad    h
  1527.     lxi    d,dsktbl ;get base adr.
  1528.     dad    d    ;add base to disp.
  1529.     pop    d
  1530.     ret
  1531.  
  1532.  
  1533. ;*****************************************************
  1534. ;*                                                   *
  1535. ;*    Recov - Recover from read, seek and write    *
  1536. ;*        errors.                     *
  1537. ;*                                                   *
  1538. ;*****************************************************
  1539.  
  1540. Recov:
  1541.     lxi    h,errmsg    ;Issue error message
  1542.     call    Pmsg        ;      to console.
  1543.     call    conin        ;get a response from operator.
  1544.     cpi    003H        ;Control C?
  1545.     jz    WBOOT        ;...yes, abort.
  1546.     ret
  1547.  
  1548.  
  1549. ;*****************************************************
  1550. ;*                                                   *
  1551. ;*    Pmsg - Print message on console.         *
  1552. ;*                                                   *
  1553. ;*****************************************************
  1554.  
  1555. Pmsg:
  1556.     mov    a,m        ;get next char of msg.
  1557.     ora    a        ;if zero, eom.
  1558.     rz
  1559.     push    b        ;save bc.
  1560.     mov    c,a        ;print char on console.
  1561.     call    CONOUT
  1562.     pop    b        ;restore bc.
  1563.     inx    h        ;bump msg ptr.
  1564.     jmp    Pmsg        ;loop till eom.
  1565.  
  1566.  
  1567. ;*****************************************************
  1568. ;*                                                   *
  1569. ;*    Delay - Delay (A) msec.                 *
  1570. ;*                                                   *
  1571. ;*****************************************************
  1572.  
  1573. Delay:
  1574.     push    d    ;save regs.
  1575.     push    h
  1576. Delay1: lxi    d,1
  1577.     lxi    h,65335    ;Constant for 1 msec @ 4mhz
  1578.     dad    d
  1579.     jnc    $-1
  1580.     dcr    a    ;Decr msec count.
  1581.     jnz    Delay1    ;...loop till done.
  1582.     pop    h    ;restore regs.
  1583.     pop    d
  1584.     ret
  1585.  
  1586.  
  1587. ;*****************************************************
  1588. ;*                                                   *
  1589. ;*            BDOS Messages             *
  1590. ;*                                                   *
  1591. ;*****************************************************
  1592.  
  1593. btmsg:    db    '** Boot Error **',0
  1594. errmsg: db    '** BDOS Error **',0
  1595. smsg:    db    00DH,00AH,'Tarbell'
  1596.     if    OLDTARB
  1597.     db    '(1771) '
  1598.     endif
  1599.     if    TARBELL
  1600.     db    '(1791) '
  1601.     endif
  1602.     db    MSIZE/10+'0',MSIZE mod 10 + '0'
  1603.     db    'K CP/M 2.1',0
  1604.     if    DEBUG
  1605. lodccp:    db    00DH,00AH,'***Loading CCP---',0
  1606. ccplod:    db    00DH,00AH,'***CCP is loaded!',0
  1607.     endif
  1608.  
  1609.  
  1610.  
  1611.  
  1612. ;****************************************************************************
  1613. ;*                L-O-G-I-C-A-L  D-E-V-I-C-E  D-R-I-V-E-R-S                 *
  1614. ;*    THE FOLLOWING SECTION CONTAINS THE LOGICAL DEVICE DRIVERS FOR       *
  1615. ;*    EACH LOGICAL DEVICE IN THE SYSTEM.  THESE DEVICES ARE DEFINED       *
  1616. ;*    BY THE IOBYTE FUNCTION FOUND IN THE CP/M ALTERATION GUIDE.           *
  1617. ;****************************************************************************
  1618.  
  1619.  
  1620. ;*************************** CON - SYSTEM CONSOLE **************************
  1621. CONST:
  1622.     LDA     IOBYTE        ;GET IOBYTE.
  1623.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1624.     DW    TTYST
  1625.     DW    CRTST
  1626.     DW    RDRST
  1627.     DW    DUMST
  1628. CONIN:
  1629.     LDA     IOBYTE        ;GET IOBYTE.
  1630.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1631.     DW    TTYIN
  1632.     DW    CRTIN
  1633.     DW    RDRIN
  1634.     DW    DUMIN
  1635. CONOUT:
  1636.     LDA     IOBYTE        ;GET IOBYTE.
  1637.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1638.     DW    TTYOUT
  1639.     DW    CRTOUT
  1640.     DW    PUNOUT
  1641.     DW    DUMOUT
  1642.  
  1643.  
  1644. ;*************************** LST - OUTPUT LIST DEVICE **********************
  1645. LSTST:
  1646.     LDA     IOBYTE        ;GET IOBYTE.
  1647.     RLC            ;SHIFT BITS.
  1648.     RLC
  1649.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1650.     DW    TTYST
  1651.     DW    CRTST
  1652.     DW    LPTST
  1653.     DW    DUMST
  1654. LSTOUT:
  1655.     LDA     IOBYTE        ;GET IOBYTE.
  1656.     RLC            ;SHIFT BITS.
  1657.     RLC
  1658.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1659.     DW    TTYOUT
  1660.     DW    CRTOUT
  1661.     DW    LPTOUT
  1662.     DW    DUMOUT
  1663.  
  1664.  
  1665. ;*************************** PUN - PAPER TAPE PUNCH ************************
  1666. PUNOUT:
  1667.     LDA     IOBYTE        ;GET IOBYTE.
  1668.     RRC            ;SHIFT BITS.
  1669.     RRC
  1670.     RRC
  1671.     RRC
  1672.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1673.     DW    TTYOUT
  1674.     DW    PTPOUT
  1675.     DW    DUMOUT
  1676.     DW    DUMOUT
  1677.  
  1678.  
  1679. ;*************************** RDR - PAPER TAPE READER ***********************
  1680. RDRST:
  1681.     LDA     IOBYTE        ;GET IOBYTE.
  1682.     RRC            ;SHIFT BITS.
  1683.     RRC
  1684.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1685.     DW    TTYST
  1686.     DW    PTRST
  1687.     DW    DUMST
  1688.     DW    DUMST
  1689. RDRIN:
  1690.     LDA     IOBYTE        ;GET IOBYTE.
  1691.     RRC            ;SHIFT BITS.
  1692.     RRC
  1693.     CALL    IOCAL        ;EXIT TO SELECTED ROUTINE.
  1694.     DW    TTYIN
  1695.     DW    PTRIN
  1696.     DW    DUMIN
  1697.     DW    DUMIN
  1698.  
  1699.  
  1700. ;*************************** I/O DISPATCHER ********************************
  1701. IOCAL:
  1702.     RLC            ;SHIFT BITS.
  1703.     ANI    006H        ;LIMIT BITS.
  1704.     XTHL            ;SAVE HL, GET TABLE ADDRESS.
  1705.     PUSH    D        ;SAVE DE.
  1706.     MOV    E,A        ;GET SELECTION VALUE.
  1707.     MVI    D,0
  1708.     DAD    D        ;GET TABLE ENTRY.
  1709.     MOV    A,M
  1710.     INX    H
  1711.     MOV     H,M
  1712.     MOV    L,A
  1713.     POP    D        ;RESTORE DE.
  1714.     XTHL            ;RESTORE HL, SAVE RTN ADDRESS.
  1715.     RET            ;EXIT TO ROUTINE.
  1716.  
  1717.  
  1718.  
  1719.  
  1720. ;****************************************************************************
  1721. ;*              P-H-Y-S-I-C-A-L  D-E-V-I-C-E  D-R-I-V-E-R-S                 *
  1722. ;*    THE FOLLOWING SECTION CONTAINS THE PHYSICAL DEVICE DRIVERS FOR      *
  1723. ;*    EACH ACTUAL DEVICE IN THE SYSTEM.  FOR EACH DEVICE, THERE MUST      *
  1724. ;*    EXIST AT LEAST TWO OF THREE ROUTINES, A DEVICE STATUS ROUTINE        *
  1725. ;*    AND A DEVICE INPUT OR OUTPUT ROUTINE.  THE LOGICAL PORTION OF        *
  1726. ;*    THE BIOS WILL ONLY CALL A STATUS, INPUT OR OUTPUT ROUTINE.        *
  1727. ;****************************************************************************
  1728.  
  1729.  
  1730. ;*************************** DUM - DUMMY DEVICE ****************************
  1731. DUMST:
  1732.     MVI    A,0FFH        ;INDICATE READY.
  1733.     RET
  1734. DUMIN:
  1735.     MVI    A,01AH        ;INDICATE <EOF>.
  1736.     RET
  1737. DUMOUT:
  1738.     RET
  1739.  
  1740.  
  1741. ;*************************** CRT - HIGH SPEED CONSOLE **********************
  1742. CRTST:
  1743.     IN    CSTAT        ;GET CONSOLE STATUS.
  1744.     ANI    CKBR        ;IF NOT READY,
  1745.     MVI    A,0
  1746.     RZ            ;   RETURN.
  1747.     CMA            ;RETURN 0FFH.
  1748.     RET
  1749. CRTIN:
  1750.     IN    CSTAT        ;GET CONSOLE STATUS.
  1751.     ANI    CKBR        ;IF NOT READY,
  1752.     JZ    CRTIN        ;   LOOP.
  1753.     IN    CDATA        ;READ THE CHAR.
  1754.     ANI    07FH        ;MAKE MOST SIG. BIT=0.
  1755.     RET
  1756. CRTOUT:
  1757.     IN    CSTAT        ;GET CONSOLE STATUS.
  1758.     ANI    CPTR        ;IF NOT READY,
  1759.     JZ    CRTOUT        ;   LOOP.
  1760.     MOV    A,C        ;GET THE CHAR.
  1761.     OUT    CDATA        ;PRINT IT.
  1762.     RET
  1763.  
  1764.  
  1765. ;*************************** LPT - LINE PRINTER ****************************
  1766. ;NOTE -- THIS SECTION GIVES AN LA-36 DECWRITER SOME INTELLIGENCE.
  1767. LPTST:
  1768.     IN    LSTAT        ;GET PRINTER STATUS.
  1769.     ANI    LPTR        ;IF NOT READY,
  1770.     MVI    A,0
  1771.     RZ            ;   RETURN.
  1772.     CMA            ;RETURN 0FFH.
  1773.     RET
  1774. LPTIN    EQU    DUMIN
  1775. LPTOUT:
  1776.     MOV    A,C        ;GET CHAR.
  1777.     CPI    007H        ;<BELL>?
  1778.     JZ    LPTOUTC        ;...YES.
  1779.     CPI    008H        ;<BACKSPACE>?
  1780.     JZ    LPTBS        ;...YES.
  1781.     CPI    009H        ;<HORIZONTAL TAB>?
  1782.     JZ    LPTHT        ;...YES.
  1783.     CPI    00AH        ;<LINE FEED>?
  1784.     JZ    LPTLF        ;...YES.
  1785.     CPI    00CH        ;<FORM FEED>?
  1786.     JZ    LPTFF        ;...YES.
  1787.     CPI    00DH        ;<CARRIAGE RETURN>?
  1788.     JZ    LPTCR        ;...YES.
  1789.  
  1790. LPTCLI:
  1791.     LDA    CLCNT        ;INCR COLUMN COUNT.
  1792.     INR    A
  1793.     STA    CLCNT
  1794.     MOV    B,A        ;SAVE IT.
  1795.  
  1796. LPTOUTC:
  1797.     IN    LSTAT        ;GET PRINTER STATUS.
  1798.     ANI    LPTR        ;IF NOT READY,
  1799.     JZ    LPTOUTC        ;   LOOP.
  1800.     MOV    A,C        ;GET THE CHAR.
  1801.     OUT    LDATA        ;PRINT IT.
  1802.     RET
  1803.  
  1804. LPTBS:
  1805.     LDA    CLCNT        ;DECR COLUMN COUNT.
  1806.     DCR    A
  1807.     RZ            ;IF <0 THEN RETURN W/O PRINTING.
  1808.     STA    CLCNT
  1809.     JMP    LPTOUTC
  1810.  
  1811. LPTHT:
  1812.     MVI    C,' '        ;ISSUE <BLANK>.
  1813.     CALL    LPTCLI
  1814.     MOV    A,B        ;GET COLUMN COUNT.
  1815.     ANI    8-1        ;ROUND TO MOD 8.
  1816.     JNZ    LPTHT        ;LOOP TO MOD 8.
  1817.     RET
  1818.  
  1819. LPTLF:
  1820.     LDA    LFCNT        ;INCR LF COUNT.
  1821.     CPI    66        ;MAX VALUE?
  1822.     JC    $+4        ;...NO.
  1823.     XRA    A        ;...YES, RESET IT.
  1824.     INR    A
  1825.     STA    LFCNT
  1826.     JMP    LPTOUTC
  1827.  
  1828. LPTFF:
  1829.     LDA    LFCNT        ;TOP OF FORM?
  1830.     CPI    1
  1831.     RZ            ;...YES.
  1832.     MVI    C,00AH        ;ISSUE <LF>.
  1833.     CALL    LPTLF
  1834.     JMP    LPTFF
  1835.  
  1836. LPTCR:
  1837.     XRA    A        ;ZERO COLUMN COUNT.
  1838.     STA    CLCNT
  1839.     JMP    LPTOUTC
  1840.  
  1841. CLCNT:    DB    0        ;COLUMN COUNT
  1842. LFCNT:    DB    1        ;LINE FEED COUNT
  1843.  
  1844.  
  1845. ;************************ PTP - PAPER TAPE PUNCH ***************************
  1846. PTPST    EQU    DUMST
  1847. PTPIN    EQU    DUMIN
  1848. PTPOUT    EQU    DUMOUT
  1849.  
  1850.  
  1851. ;************************ PTR - PAPER TAPE READER **************************
  1852. PTRST    EQU    DUMST
  1853. PTRIN    EQU    DUMIN
  1854. PTROUT    EQU    DUMOUT
  1855.  
  1856.  
  1857. ;************************ TTY - SLOW SPEED CONSOLE *************************
  1858. TTYST:
  1859.     IN    LSTAT        ;GET TTY STATUS.
  1860.     ANI    LKBR        ;IF NOT READY,
  1861.     MVI    A,0
  1862.     RZ            ;   RETURN.
  1863.     CMA            ;RETURN 0FFH.
  1864.     RET
  1865. TTYIN:
  1866.     IN    LSTAT        ;GET TTY STATUS.
  1867.     ANI    LKBR        ;IF NOT READY,
  1868.     JZ    TTYIN        ;   LOOP.
  1869.     IN    LDATA        ;READ THE CHAR.
  1870.     ANI    07FH        ;MAKE MOST SIG. BIT=0.
  1871.     RET
  1872. TTYOUT    EQU    LPTOUT
  1873.  
  1874.  
  1875.  
  1876.  
  1877. ;*****************************************************
  1878. ;*                                                   *
  1879. ;*    Unitialized RAM data areas             *
  1880. ;*                                                   *
  1881. ;*****************************************************
  1882. ;
  1883. STARTZ:        ;** Start of zeroed area **
  1884. sekdsk:    ds    1        ;seek disk number
  1885. sektrk:    ds    2        ;seek track number
  1886. seksec:    ds    1        ;seek sector number
  1887. sekdph: ds    2        ;seek .dph(sekdsk)
  1888. sekdpb: ds    2        ;seek .dpb(sekdsk)
  1889. ;
  1890. hstdsk:    ds    1        ;host disk number
  1891. hsttrk:    ds    2        ;host track number
  1892. hstsec:    ds    1        ;host sector number
  1893. hstdph: ds    2        ;host .dph(sekdsk)
  1894. hstdpb: ds    2        ;host .dpb(sekdsk)
  1895. ;
  1896. sekhst:    ds    1        ;seek shr secshf
  1897. hstact:    ds    1        ;host active flag
  1898. hstwrt:    ds    1        ;host written flag
  1899. ;
  1900. unacnt:    ds    1        ;unalloc rec cnt
  1901. unadsk:    ds    1        ;last unalloc disk
  1902. unatrk:    ds    2        ;last unalloc track
  1903. unasec:    ds    1        ;last unalloc sector
  1904. ;
  1905. dskcur:    ds    1        ;current disk #
  1906. dsktrk:    ds    2        ;current track #
  1907. dsksec:    ds    1        ;current sector #
  1908. dsktrs:    ds    1        ;current trk # (saved)
  1909. dskdfc:    ds    1        ;current format code
  1910. ;        note - the following two latches must be kept
  1911. ;            contiguous.
  1912. dsklth:    ds    1        ;current disk latch
  1913. dskolt:    ds    1        ;old disk latch
  1914. dskdma:    ds    2        ;current dma address
  1915. dskerr:    ds    1        ;current disk error count
  1916. dsktbl: ds    4*2        ;disk parameter table
  1917. ;                ;  one entry for each
  1918. ;                ;  physical drive
  1919. ;    db    0nnH        ;flags
  1920. ;                 80 - 0=not logged, 1=disk logged
  1921. ;                 40 - 0=single density, 1=double
  1922. ;    db    nn        ;current track
  1923. ENDZ:        ;** End of Zeroed Area **
  1924.  
  1925.  
  1926.     if    DEBUG
  1927. trcact:    ds    1        ;last traced activity number
  1928. trcerr:    ds    1        ;last traced controller error
  1929.     endif
  1930. erflag:    ds    1        ;error reporting
  1931. rsflag:    ds    1        ;read sector flag
  1932. readop:    ds    1        ;1 if read operation
  1933. wrtype:    ds    1        ;write operation type
  1934. ccpsav:    ds    6        ;CCP non-128-byte boundary data.
  1935. dmaadr:    ds    2        ;last dma address
  1936. ALV0:    ds    48
  1937. CSV0:    ds    32
  1938. ALV1:    ds    48
  1939. CSV1:    ds    32
  1940. ALV2:    ds    48
  1941. CSV2:    ds    32
  1942. ALV3:    ds    48
  1943. CSV3:    ds    32
  1944. dirbuf:    ds    128        ;directory buffer
  1945. hstbuf:    ds    hstmax        ;host buffer
  1946.     end
  1947.