home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / cpm / utils / a / dskdrv16.lzh / IO-KP.DRV < prev    next >
Encoding:
Text File  |  1991-01-16  |  11.8 KB  |  484 lines

  1. ; rename this IO-KP.DRV to RSXIO.INC for assembly with RSXMAST
  2. subttl    'DSKDRIVE machine dependant drivers'
  3. ;
  4. ; Most of this file can be used unchanged with any 1790 series
  5. ; disk controller chip.  The actual seek mechanism, at the end,
  6. ; will have to be customized.  This version is for the 1983
  7. ; style Kaypro 4.  The kp84 equate converts to the 1984 model,
  8. ; BUT HAS NOT BEEN CHECKED.
  9. ;
  10. ; rdhst/wthst read or write to/from buff from/to hstrk/hstsec.
  11. ; One physical block is transferred.  Errflg is set to zero on
  12. ; a good transfer, else non-zero.  This is the total responsiblity
  13. ; of this portion of the system.  It refers to the extended disk
  14. ; parameter tables for host configuration.
  15. ;
  16. ; Set only one of the following true (choose Kaypro model)
  17. k83    equ    true
  18. k84    equ    false;        *** NOT checked. CAUTION    ***
  19. k10    equ    false;        *** NOT checked. Kaypro 10    ***
  20. ;
  21. ; This option, when set yes, increases disk transfer time
  22. detect    equ    no;        yes to detect disk not mounted
  23. ;                no to wait for disk to be mounted
  24. ;
  25. ; 1791/2/3 Controller chip specific
  26. ; For most Z80 implementations the data request and interrupt from
  27. ; the 1791 is connected to NMI (possibly gated by the CPU halt
  28. ; status line).  Thus a CPU halt is ended by the appropriate
  29. ; controller status, with the RET instruction in memory location
  30. ; 066h.  A status read after the interrupt will reset the interrupt,
  31. ; as will satisfying the data request.  8080s need more hardware.
  32. wrtmsk    equ    0FDH;        Status bits useful after write
  33. rdmask    equ    09DH;            "    "    read
  34. clrcmd    equ    000H;        home disk
  35. rdcmd    equ    08CH;        read physical sector
  36. wtcmd    equ    0ACH;        write physical sector
  37. radrcmd    equ    0C4H;        read address command
  38. seekcmd    equ    014H;        seek track
  39. ficmd    equ    0D0H;        clear controller.
  40. ;
  41. ; Z80 opcodes used in driver
  42. outi    macro
  43.  db    0edh,0a3h
  44.     endm
  45. ini    macro
  46.  db    0edh,0a2h
  47.     endm
  48. ;
  49. ; This writes a physical sector to the disk.  The size, etc.
  50. ; of that sector are controlled by the extended disk parameter
  51. ; tables.  All i/o is performed to/from buff.
  52. ; a,f,b,c,d,e,h,l
  53. wthst:    call    rwtbgn
  54. wthst1:    ei;            during seeks
  55.     call    setup;        (disables interrupts)
  56.     jnz    rwtxit
  57.     mvi    e,wtcmd;    write command
  58.     rrc
  59.     jnc    wthst2;        Not 128 byte physical rcd
  60.     mvi    b,128
  61.     call    dcmnde
  62.     jmp    w256
  63. wthst2:    mvi    b,0
  64.     rrc
  65.     jnc    wthst3;        Not 256 byte physical rcd
  66.     call    dcmnde
  67.     jmp    w256
  68. wthst3:    rrc
  69.     jnc    wthst4;        1024 byte physical rcd
  70.     call    dcmnde
  71.     jmp    w512;        512 byte physical rcd
  72. wthst4:    call    dcmnde
  73. ;    "    "
  74. w1024:    hlt;            Else 1024 byte rcd.
  75.     outi;                        *** Z80 code
  76.     jnz    w1024
  77. w768:    hlt
  78.     outi
  79.     jnz    w768
  80. w512:    hlt
  81.     outi
  82.     jnz    w512
  83. w256:    hlt
  84.     outi
  85.     jnz    w256;        May be a W128, on entry bc
  86.     call    notbsy
  87.     ani    wrtmsk
  88.     jz    rwtxit
  89.     call    clear
  90.     dcr    d
  91.     jnz    wthst1;        retry
  92.     ori    0FFH;        Signal error
  93.     jmp    rwtxit
  94. ;
  95. ; Set up NMI return, save controller track setting.
  96. ; Sets the number of retries to be performed.
  97. ; a,f,d
  98. rwtbgn:    lda    0066H
  99.     sta    save66
  100.     mvi    a,0C9H;        "RET" instruction for NMI
  101.     sta    0066H
  102.     in    trkreg
  103.     sta    trksav
  104.     mvi    d,10;        retries
  105.     ret
  106. ;
  107. ; Similar to wthst, reads from disk into buff, using the
  108. ; extended parameter table.
  109. ; a,f,b,c,d,e,h,l
  110. rdhst:    call    rwtbgn
  111. rdhst1:    ei
  112.     call    setup;        (disables interrupts)
  113.     jnz    rwtxit
  114.     mvi    e,rdcmd;    read command
  115.     rrc
  116.     jnc    rdhst2;        Not 128 bytes per phys. block
  117.     mvi    b,128
  118.     call    dcmnde
  119.     jmp    r256
  120. rdhst2:    mvi    b,0;        i.e. 256
  121.     rrc
  122.     jnc    rdhst3;        Not 256 bytes per block
  123.     call    dcmnde
  124.     jmp    r256
  125. rdhst3:    rrc
  126.     jnc    rdhst4;        1024 byte physical record
  127.     call    dcmnde
  128.     jmp    r512;        512 bytes per block
  129. rdhst4:    call    dcmnde
  130. ;    "    "
  131. r1024:    hlt;            else 1024 bytes per block
  132.     ini;                        *** Z80 code
  133.     jnz    r1024
  134. r768:    hlt
  135.     ini
  136.     jnz    r768
  137. r512:    hlt
  138.     ini
  139.     jnz    r512
  140. r256:    hlt
  141.     ini
  142.     jnz    r256;        May be r128, on entry (b)
  143.     call    notbsy
  144.     ani    rdmask
  145.     jz    rwtxit
  146.     call    clear
  147.     dcr    d
  148.     jnz    rdhst1;        retry
  149.     ori    0FFH;        Signal error
  150. ;    "    "
  151. ; Exit, restoring 66, trkreg, setting errflg on (a)
  152. rwtxit:    push    psw
  153.     lda    save66
  154.     sta    0066H
  155.     lda    trksav;        restore the controller, in
  156.     out    trkreg;        case bios assumes unchanged
  157.     pop    psw
  158.     ei
  159.     sta    errflg
  160.     ret
  161. ;
  162. ; The actual selection and addressing of the disk controller.  This
  163. ; is responsible for address conversion, and uses the extended disk
  164. ; parameter table.  z flag for success, nz for failure. d preserved.
  165. ; a,f,b,c,e,h,l
  166. setup:    lhld    hsttrk
  167.     shld    adrtrk
  168.     lda    hstsec
  169.     sta    adrsec
  170.     xra    a
  171.     sta    side;        default use side 0
  172.     lda    config
  173.     ani    0fh;        remove density selection
  174.     cpi    maxcase+1
  175.     jnc    error
  176.     lxi    h,cases;    Execute the appropriate code
  177.     call    docase;        This varies with the format
  178.     call    seek;         being read/written.
  179. ;    "    "
  180. ; Setup registers for read/write commands
  181.     lda    hstblk;        block size in 128 byte records
  182.     mvi    c,datapt;    port to read/write data from/to
  183.     lxi    h,buff;        and where to/from
  184.     di;            Can't interrupt during rd/wrt
  185.     ret;            with z/nz flag from seek
  186. ;
  187. ; docase (a) on table (hl)^ to muck with disk addressing.
  188. ; a,f,h,l (and the destination code)
  189. docase:    add    a
  190.     add    l
  191.     mov    l,a
  192.     adc    h
  193.     sub    l
  194.     mov    h,a
  195.     mov    a,m
  196.     inx    h
  197.     mov    h,m
  198.     mov    l,a
  199.     pchl
  200. ;
  201. cases:    dw    case0, case1, case2
  202.     dw    case3, case4
  203. ;
  204. ; Native and logical addresses are the same
  205. case0:    ret
  206. ;
  207. ; logical sectors from 0 to offsec-1 are on side 0.
  208. ; from offsec up are on side 1, and addressed by adding nsecs.
  209. ; a,f,h,l
  210. case1:    lda    adrsec;        config = 1
  211.     lxi    h,offsec
  212.     sub    m
  213.     rc
  214.     lxi    h,nsecs
  215.     add    m
  216.     sta    adrsec
  217. ;    "    "
  218. ; set side one to be accessed
  219. ; a,f
  220. sside1:    mvi    a,1
  221.     sta    side
  222.     ret
  223. ;
  224. ; odd logical tracks on side 1, even on side 0.
  225. ; physical track address = logical track/2
  226. ; Side 1 uses an offset to the sector address.
  227. ; a,f,h,l
  228. case2:    lhld    adrtrk
  229.     mov    a,l
  230.     ani    1
  231.     sta    side
  232.     mov    a,h
  233.     rar
  234.     mov    h,a
  235.     mov    a,l
  236.     rar
  237.     mov    l,a
  238.     shld    adrtrk
  239.     rnc;            on side 0
  240.     lxi    h,nsecs
  241.     lda    adrsec;        side 1, correct sector address
  242.     add    m
  243.     sta    adrsec
  244.     ret
  245. ;
  246. ; 1st ntrks are on side 0, others side 1.  For logical track
  247. ; on side 1, physical track is logical track - ntrks.
  248. ; a,f,h,l
  249. case3:    lda    adrtrk
  250.     lxi    h,ntrks
  251.     cmp    m;        tracks per side
  252.     rc
  253.     sub    m;        On second side
  254.     sta    adrtrk
  255.     jmp    sside1
  256. ;
  257. ; 1st ntrks are on side 0, others on side 1.  For side 1 track
  258. ; numbers count down from ntrk, i.e. the disk looks like
  259. ;
  260. ;  side0    0   1   2   .   .      ntrk-1
  261. ;  side1   2ntrk-1   .  .   ntrk+1 ntrk   (CPM86 on IBM PC)
  262. ; a,f,h,l
  263. case4:    lda    adrtrk
  264.     lxi    h,ntrks
  265.     cmp    m
  266.     rc;            On first side
  267.     cma
  268.     add    m
  269.     add    m;        Now we count down
  270.     sta    adrtrk
  271.     jmp    sside1
  272. ;
  273. ; Haven't the vaguest idea how to address this disk
  274. ; a,f
  275. error:    ori    0FFH;        config unknown, error
  276.     sta    dsktrk;        and mark disk unused
  277.     ret
  278. ;
  279. ; Clear disc controller.  nz flag for timeout
  280. ; a,f
  281. clear:    mvi    a,clrcmd;    reset controller
  282.     call    dcmnd
  283.     call    notbsy
  284.     ani    1
  285.     rnz;            timed out
  286.     sta    dsktrk
  287.     ret
  288. ;
  289. ; await not busy controller status
  290. ; a,f
  291. notbsy:    push    h
  292.     lxi    h,0
  293.     call    dkwait
  294.     pop    h
  295.     ral;            restore status
  296.     ret;            with busy bit (1) if time out
  297. ;
  298. ; Timed out wait for non-busy controller.  Time varies with hl
  299. ; Carry set for timeout. (a) is status right shifted
  300. ; a,f,h,l
  301. dkwait:    in    statpt
  302.     rar
  303.     rnc;            not busy, ok
  304.     if    detect
  305.      dcr    l;        preserve status in a
  306.      jnz    dkwait;        for possible time-out exit
  307.      dcr    h;        (re-getting may be different)
  308.      jnz    dkwait
  309.      push    psw;        busy time-out, save status bits
  310.      mvi    a,ficmd
  311.      call    dcmnd;        clear controller chip
  312.      pop    psw;        show status bits
  313.      stc;            and signal error
  314.      ret
  315.     else;        not detect
  316.      jmp    dkwait
  317.     endif
  318. ;
  319. ; command (e) to disk controller
  320. ; a,f
  321. dcmnde:    mov    a,e
  322. ;    "    "
  323. ; command (a) to disk controller. Pause for status valid
  324. ; f
  325. dcmnd:    out    ctrlpt
  326.     push    b;        and 20 uSec. delay
  327.     mvi    b,(20*clkspd - 37)/14;    clkspd >= 3(00 khz)
  328. dcmnd1:    dcr    b
  329.     jnz    dcmnd1;        pause for controller status
  330.     pop    b
  331.     ret
  332. ;
  333. ; pause (b) * 10 Millisec.  Set for 2.5 Mhz clock.
  334. ; a,f,b
  335. pause:    push    d
  336. pause1:    lxi    d,41*clkspd;    clkspd in 100khz units
  337. pause2:    dcx    d
  338.     mov    a,e
  339.     ora    d
  340.     jnz    pause2
  341.     dcr    b
  342.     jnz    pause1
  343.     pop    d
  344.     ret
  345. ;
  346. ; =================================================================
  347. ; Everything above this point probably does not have to be changed
  348. ; for any machine using the 1790 series disk controllers.  The rest
  349. ; will have to be customized.
  350. ; =================================================================
  351. ;
  352. ; Kaypro Specific
  353. sideb    equ    2;        side selection, bit number
  354. drvmsk    equ    3;        bits 0 & 1 select drive
  355. densb    equ    32;        bit weight for density selection
  356. ;
  357.     if    k83;        1983 version
  358. bitpt     equ    1ch;        system control port
  359. mtrb     equ    6;        bit number
  360. mtron     equ    0
  361. abit     equ    0;        bit number
  362. bbit     equ    1;        bit number
  363. side0     equ    0
  364. side1     equ    1 shl sideb
  365.     endif
  366.     if    k84 or K10;    1984 version
  367. bitpt     equ    14H;        system control port
  368. mtrb     equ    4;        bit number
  369. mtron     equ    1
  370. abit     equ    1;        bit number
  371. bbit     equ    0;        bit number
  372. side0     equ    1 shl sideb
  373. side1     equ    0
  374.     endif
  375. drivea    equ    1 shl abit
  376. driveb    equ    1 shl bbit
  377. ;
  378. ; Field to be controlled here
  379. modmsk    equ    drvmsk+(1 shl mtrb)+(1 shl sideb)+densb
  380. ;
  381. ; Host specific routines here - setup for Kaypro 4
  382. ; This performs the actual seek, sets density, etc.
  383. ; *** ENTRY IN THE MIDDLE at "seek"            ***  <<<
  384. ; a,f,b,c,e,h,l (allowed).  (d is retry count)
  385. ;
  386. seek3:    call    clear;        Never used yet, clear controller
  387.     jnz    error;        timeout error, no disk mounted
  388. seek4:    lda    adrtrk;        Do physical seek
  389.     out    datapt;        changing tracks
  390.     mvi    a,seekcmd;    seek track
  391.     call    dcmnd
  392.     call    notbsy
  393.     ani    99H;        Check status
  394.     jz    seek5;        good seek, finish up
  395.     ani    1
  396.     jnz    error;        no disk, error exit
  397.     call    error;        mark physical seek needed
  398.     dcr    d
  399.     jz    error;        no more retries, error
  400. ;    "    "
  401. ; Main routine entry point.            <<< *** ENTRY HERE <<
  402. seek:    lda    dsktrk;        If we have switched drives
  403.     out    trkreg;        set the controller to match history
  404. ;    "    "
  405. ; set up density
  406.     lda    config;        Set up for side and density
  407.     ora    a
  408.     lxi    h,dendbl
  409.     jp    seek1;        Normal double density system
  410.     inx    h;        else set single density command
  411. seek1:    mov    b,m
  412. ;    "    "
  413. ; set up side selection
  414.     lda    side;        Move side selection bit into place.
  415.     if    k84 OR k10;    Side bit is complemented
  416.      cma
  417.     endif
  418.     ani    1
  419.     ral;            Position the side select bit
  420.     ral
  421.     ora    b;        Compute drive selection/density code
  422.     mov    b,a
  423. ;    "    "
  424. ; Kaypro combines all these things in one port
  425.     in    bitpt;        Keep bank (80), turn mtr on (40=0)
  426.     push    psw;        clear DDEN (20), keep lptstrobe (10)
  427.     ani    NOT modmsk;    ignore prtbusy(8), clear side(4),
  428.     ora    b;        drive code (2, 1)     bit weights
  429.     ori    mtron shl mtrb
  430. ;    "    "
  431. ; add in the physical drive selection coding.
  432.     lxi    h,dskode
  433.     ora    m
  434. ;    "    "
  435. ; now we actually select drive/side/density and turn on motors
  436.     out    bitpt
  437.     pop    psw
  438.     ani    1 shl mtrb
  439.     if    k84 OR k10;    inverted motor control bit
  440.      xri    mtron shl mtrb
  441.     endif
  442.     mvi    b,50;        *10 = 500 millisec
  443.     cnz    pause;        if motor was off wait for it
  444.     lda    dsktrk
  445.     inr    a;        check for 1st access to this drv
  446.     jz    seek3;        1st access to this drive
  447.     dcr    a
  448.     lxi    h,adrtrk
  449.     cmp    m
  450.     jnz    seek4;        Need a physical seek
  451. ;    "    "
  452. ; All well, final setup and exit
  453. seek5:    if    detect
  454.      mvi    a,radrcmd
  455.      call    dcmnd;        try to read an address
  456.      call    notbsy
  457.      ani    1
  458.      jnz    error;        busy time out, no disk
  459.     endif;        detect
  460.     lda    adrsec;        Successful seek or not needed
  461.     lxi    h,sec1st;    last buggery with sec. address
  462.     add    m
  463.     out    secreg;        set physical sector
  464.     lda    adrtrk
  465.     sta    dsktrk;        record what track we are on
  466.     xra    a
  467.     ret
  468. ;
  469. ; These four bytes following MUST BE the last portion of this file.
  470. ; This makes them accessible by a negative offset from the "info"
  471. ; pointer, which is returned by the master RSX enquiry call, and
  472. ; allows supporting software to dynamically reconfigure the system.
  473. ; This portion must be customized on installation to host only.
  474. ;
  475. modrv:    db    drv-'A';    and drive id to use (0=A). patchable
  476. ;
  477. dskode:    if    k10;        Only 1 floppy drive
  478.      db    drivea;        addressed as C.
  479.     else
  480.      db    driveb;        drive selection coding. drive B
  481.     endif
  482. dendbl:    db    0;        base command for double density
  483. densgl:    db    densb;        base command for single density
  484. í