home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / cpm / utils / a / bios-5.arc / CXDISK.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-05-08  |  33.0 KB  |  1,712 lines

  1. ; Date:  05/07/89           
  2. ;
  3. ; changes made to this module were to remove test for 
  4. ; disk status line (it is displayed all of the time now), and
  5. ; to remove unecessary disk definitions ( only A, B, and C now)
  6. ; The virtual drive E: has been removed,  and the 40 column disk status
  7. ; display has been removed (previously it was always running no matter
  8. ; what.
  9. ;
  10. ; compare with an original copy of CXDISK.ASM if you want to
  11. ; find what the changes were
  12. ;
  13. ;  User assumes _ALL_ liability for use of this module.  Original
  14. ;  copyright is still maintained by Commodore
  15. ;
  16. ;-------------------------------------------------------------------------
  17. ; ADDITIONS by Randy Winchester, 6 May 89
  18. ;
  19. ; Drive D: has been put back.
  20. ;
  21. ; A Drive E: has been added.  This is not to be confused with the Drive E:
  22. ; virtual disk of earlier CP/M releases.  The purpose of the Drive E: entry
  23. ; is to make room for a driver for the Quick Brown Box.  The QBB is
  24. ; installed with QD.COM from Herne Data Systems, Ltd, as Drive F: so as not
  25. ; to conflict with any software that might expect Drive E: to behave the
  26. ; way it used to.
  27. ;
  28. ; Added MFM definitions for Gene Pizzetta's 1581 796K format.  Disks can be
  29. ; formatted using Gene's public domain FORMAT81.COM.
  30. ;
  31. ; Added MFM definitions for Miklos Garamszeghy's MAXI 1571 format.  This
  32. ; allows 398K per disk.  Disks can be formatted using Herne Data System's
  33. ; Jugg'ler, FORMAT22, which is a free demo of Jugg'ler, or the following 128
  34. ; direct mode command:  print#15,"u0"+chr$(102)+chr$(128)+chr$(0)+chr$(3)+
  35. ;                       chr$(39)+chr$(5)+chr$(0)+chr$(0)+chr$(229)
  36. ; This was taken from the April 1988 issue of "The Transactor."
  37. ;-------------------------------------------------------------------------
  38. ;
  39. ;
  40. ;
  41. ;    *****************************************
  42. ;    *                    *
  43. ;    *    Commodore Disk    Controller    *
  44. ;    *    Module for CP/M 3.0 BIOS    *
  45. ;    *                    *
  46. ;    *****************************************
  47. ;
  48. ;
  49. ;
  50.     title 'CXDISK   Commodore C-128 Disk Controller     6 May   89'
  51.  
  52.  
  53.  
  54.  
  55. ; CP/M 3 Disk definition macros
  56.  
  57.     maclib    cpm3
  58.  
  59.     maclib    z80
  60.  
  61. ; C-128 system equates
  62.  
  63.     maclib    cxequ
  64.  
  65.     page
  66.  
  67. ; Disk drive dispatching tables for linked BIOS
  68.  
  69.     public    cmdsk0,cmdsk1,cmdsk2,cmdsk3,cmdsk4
  70.  
  71. ; System Control Block variables
  72.     extrn    @ermde        ; BDOS error mode
  73.  
  74. ; Utility routines in standard BIOS
  75.     extrn    ?wboot        ; warm boot vector
  76.     extrn    ?pmsg        ; print message @<HL> up to 00
  77.                 ; saves <BC> & <DE>
  78.     extrn    ?pdec        ; print binary number in <HL> from 0 to 65535
  79.     extrn    ?pderr        ; print BIOS disk error header
  80.     extrn    ?conin,?cono    ; con in and out
  81.     extrn    ?const        ; get console status
  82.     extrn    ?sctrn        ; sector translation routine
  83.     extrn    @covec
  84.  
  85. ;    status line calls
  86.  
  87.     extrn    ?save,?recov,?stat
  88.  
  89. ; System function call
  90.     extrn    ?kyscn
  91.     extrn    ?fun65
  92.     extrn    ?bank
  93.     extrn    ?di$int
  94.  
  95.     public    ?dskst
  96.     public    ?dkmov
  97.     extrn    ?stat
  98.  
  99.     page
  100. ;
  101. ; Initialization entry point.
  102. ; called for first time initialization.
  103. ;
  104.     DSEG
  105. init$154X:
  106.     xra    a
  107.     sta    fast
  108.     lxi    h,MFM$table
  109.     shld    MFM$tbl$ptr
  110.     ret
  111.  
  112.  
  113.     page
  114. ;
  115. ; This entry is called when a logical drive is about to
  116. ;  be logged into for the purpose of density and type determination.
  117. ;  It may adjust the parameters contained in the disk
  118. ;  parameter header pointed to by <DE>
  119. ;
  120.     DSEG
  121. ;
  122. ;    if disk type GCR or drive type 1541
  123. ;       if 1st sector has 'CBM' (1st 3 bytes)
  124. ;          if last byte = -1 (0FFh)
  125. ;             set C128 double sided
  126. ;          else
  127. ;             set C128 single sided
  128. ;          endif
  129. ;       else
  130. ;          set C64 type
  131. ;       endif
  132. ;    else (must be MFM)
  133. ;       TEST MFM
  134. ;    endif
  135. ;
  136. login$154X:
  137.     call    get$drv$info    ; set the drive to check (DPH$pointer set)
  138.  
  139.     mvi    a,vic$test
  140.     call    ?fun65
  141.     mov    b,a
  142.     ani    0ch
  143.     cpi    0ch
  144.     jrz    GCR$type    ; jump if not a 1571
  145.  
  146.     mov    a,b
  147.     rlc
  148.     jrc    MFM$type
  149.  
  150.     page
  151. ;
  152. ;
  153. ;
  154. GCR$type:
  155.     lhld    DPH$pointer
  156.     dcx    h
  157.     mvi    m,dsk$c64
  158.     lxi    d,dpb$c64$cpm    ; set DPB to C64
  159.     call    set$dpb$only
  160.  
  161.     xra    a
  162.     sta    vic$sect    ; set track 1 sector 0 (1st sector
  163.     inr    a        ; on the disk)
  164.     sta    vic$trk
  165.  
  166.     lxi    h,@buffer
  167.     shld    local$DMA    ; move DMA pointer to disk buffer
  168.     call    login$rd
  169.     ana    a        ; read error ?
  170.     rnz            ; yes, just return
  171.  
  172.     RCALL    FR$check$CBM
  173.     rnz            ; return if not 'CBM'
  174.                 ; A=0FFh if double sided
  175.     inr    a
  176.  
  177.     lhld    DPH$pointer
  178.     dcx    h        ; does not affect flags
  179.     mvi    m,dsk$c128
  180.  
  181.     lxi    d,dpb$c128$SS
  182.     jrnz    set$dpb$only
  183.  
  184.     lxi    d,dpb$c128$DS
  185.  
  186.     page
  187. ;
  188. ;
  189. ;
  190. set$dpb$only:
  191.     lxi    b,0        ; set sector translation to zero
  192. set$format:
  193.     lhld    DPH$pointer
  194.     mov    m,c
  195.     inx    h
  196.     mov    m,b        ; install sector translation
  197.     lxi    b,25-1        ; ofset to DPB
  198.     dad    b        ; HL points to DPB now
  199.     lxi    b,17        ; dpb size
  200.     xchg            ; move to DPB location
  201.     ldir
  202.     ret
  203.  
  204.  
  205.     page
  206. ;
  207. ;    TEST MFM()
  208. ;    save number bytes/sector
  209. ;       if double sided
  210. ;          mark two sided
  211. ;       endif
  212. ;       find start and end sector numbers
  213. ;       scan table of disk for match (if more then 1 match ask user) 
  214. ;
  215. MFM$type:
  216.     mvi    c,01100000b
  217.     ana    c            ; A = status(trk1) shifted left 1 
  218.     push    psw            ; save in case bad query
  219.     push    b            ; save BC
  220.  
  221.     call    get$max$num$B        ; used to set the pointer only
  222.     mov    b,m            ; get size, and disk lock flag
  223.     inx    h
  224.     mov    a,m
  225.     inx    h
  226.     mov    h,m            ; get last MFM$mactch$ptr
  227.     mov    l,a
  228.     mov    a,b            ; get lock flag in A
  229.     ani    80h            ; lock bit set ?
  230.     sta    lock$flag        ;   (save old lock status)
  231.     shld    last$match        ; save last match pointer
  232.     jrz    not$$locked$entry    ; yes, then set same disk type
  233. ; set$locked$entry
  234.     xra    a
  235.     sta    lock$flag
  236.     mvi    c,0B0h
  237.     lda    vic$data        ; get sector size info
  238.     ana    c
  239.     mov    b,a            ; save disk sector size info
  240.     xchg                ; save HL
  241.     lhld    DPH$pointer
  242.     dcx    h
  243.     mov    a,c
  244.     ana    m            ; get old disk sector size
  245.     cmp    b            ; are they the same?
  246.     jrnz    not$locked$entry    ; no, then unlock disk anyway
  247.  
  248.     xchg                ; get last match pointer (in DE)
  249.     pop    psw            ; yes, remove two data elements 
  250.     pop    psw            ; ..save on stack
  251.     jr    set$this$entry
  252.  
  253. not$locked$entry:
  254.     lxi    h,MFM$match$tbl        ; clear Match table
  255.     shld    MFM$cur$ptr
  256.     lxi    d,MFM$match$tbl+1
  257.     mvi    m,0
  258.     lxi    b,(MFM$tbl$entries*2)-1+1+1    ; table, offset and count
  259.     ldir
  260.     mvi    a,4
  261.     sta    vic$trk            ; do query on track 4
  262.     mvi    a,vic$query
  263.     call    ?fun65
  264.     pop    b            ; recover BC
  265.     ani    0eh            ; query error ?
  266.     jrnz    query$error        ; yes, use only bits 5 and 6 
  267.     lda    @buffer            ; get trk 4 status
  268.     mov    b,a            ; save in B
  269.     ani    0eh            ; trk 4 status error ?
  270.     jrnz    query$error        ; yes, use only bits 5 and 6
  271.     mov    a,b            ; recover B (trk 4 status)
  272.     add    a            ; shift left
  273.     ana    c            ; mask sector size bits
  274.     mov    b,a
  275.     pop    psw            ; get trk 1 sector size bits
  276.     cmp    b            ; same as trk 4 sector size?
  277.     mvi    c,01111111b
  278.     jrz    trk$1$trk$4        ; yes, (then test for mult format)
  279.     mvi    a,80h            ; set MSB to mean mult format
  280.     add    b            ; ..(track 0 different sector size
  281.                     ; ..then track 4) 
  282.     mov    b,a            ; save in B
  283.     mvi    c,11111111b
  284. trk$1$trk$4:
  285.     lda    @buffer+1        ; get number of sectors/track
  286.     sui    4            ; remove 4 to extend the range
  287.     add    a            ; shift    left
  288.     add    b            ; combine with rest of mask
  289.     mov    b,a            ; save in B for now
  290.  
  291.     lda    @buffer+3        ; minimum sector number
  292.     add    b            ; add in start sector #
  293.     push    psw            ; save on stack for a moment
  294.  
  295. query$error:
  296.     pop    psw            ; get value to match 
  297.     ana    c            ; test only those bits in the mask
  298.  
  299.     lhld    MFM$tbl$ptr
  300.     mvi    b,MFM$tbl$entries
  301. check$next:
  302.     push    b            ; save BC for a moment
  303.     mov    b,a            ; move compare value to 
  304.     mov    a,m            ; get type info
  305.     ana    c            ; test only the good info
  306.     cmp    b            ; match the current type byte
  307.     mov    a,b            ;   (recover A)
  308.     pop    b            ;   (recover BC)
  309.     jrnz    not$found        ; no, do not queue data
  310.                     ; yes queue table entry address
  311.  
  312.     xchg                ; save adr in DE
  313.     lhld    MFM$cur$ptr
  314.     mov    m,e
  315.     inx    h
  316.     mov    m,d
  317.     inx    h
  318.     shld    MFM$cur$ptr
  319.     lxi    h,MFM$count
  320.     inr    m            ; add one to counter
  321.     xchg
  322.  
  323.     page
  324. ;
  325. ;
  326. not$found:
  327.     lxi    d,32            ; table entry size
  328.     dad    d
  329.     djnz    check$next
  330.  
  331.     lda    MFM$count        ; number of matches in table 
  332.     ana    a            ; test for zero
  333.     jz    tell$user$no$entry    ; none, tell the user 
  334.  
  335.     dcr    a            ; only one ?
  336.     jrnz    user$select        ; no, go check with user (which one)
  337.     lhld    MFM$match$tbl        ; yes, use the only one found
  338.  
  339. ;
  340. ;    install data form pointer in HL
  341. ;
  342. set$this$entry:
  343.     push    h        ; save table pointer
  344.     inx    h
  345.     mov    a,m        ; get type info. 
  346.     xchg            ; save table address in DE
  347.     lhld    DPH$pointer
  348.     dcx    h
  349.     mov    m,a        ; save type code
  350.     xchg            ; get table adr to HL
  351.     inx    h        ; HL points to sector translation table 
  352.     mov    c,m        ; ..zero if none
  353.     inx    h
  354.     mov    b,m
  355.     inx    h        ; HL points to DPB
  356.     xchg            ; DE points to DPB (HL trash)
  357.     call    set$format
  358.     mov    b,m        ; get the number of sect/trk from MFM table
  359.     lda    lock$flag    ; get the current lock flag value
  360.     ora    b        ; combine with sect/trk
  361.     xchg            ; HL=to adr,  DE=from adr
  362.     mov    m,a        ; install sect/trk and lock flag
  363.     pop    d        ; recover table pointer
  364.     inx    h
  365.     mov    m,e
  366.     inx    h
  367.     mov    m,d        ; save MFM table pointer at end of DPH
  368.     ret
  369.  
  370.     page
  371. ;
  372. ;    let the user select the Disk type s/he wants
  373. ;
  374. user$select:
  375.     inr    a            ; number of entries to try to match
  376.     mov    b,a            ; set in B as loop count
  377.     lhld    last$match        ; get value to match with
  378.     mov    d,h
  379.     mov    e,l            ; last match pointer is in DE
  380.  
  381.     lxi    h,MFM$match$tbl
  382.     shld    MFM$cur$ptr
  383.     mvi    c,0            ; start offset at zero
  384.  
  385. try$next$format:
  386.     mov    a,e
  387.     cmp    m
  388.     inx    h
  389.     jrnz    not$last$match
  390.     mov    a,d
  391.     cmp    m
  392.     jrnz    not$last$match
  393. ;
  394. ; match, set pointer
  395. ;
  396.     mov    a,c            ; get offset in A
  397.     push    psw
  398.     call    save$dsk$window
  399.     pop    psw
  400.     jr    set$offset
  401.  
  402. not$last$match:
  403.     inx    h            ; each pointer uses two bytes 
  404.     inr    c            ; advance the index
  405.     djnz    try$next$format        ; test for more, loop if so
  406.  
  407.     call    save$dsk$window
  408.  
  409.     lhld    MFM$cur$ptr
  410. user$loop:
  411.     mov    e,m            ; HL=(MFM$cur$ptr)
  412.     inx    h
  413.     mov    d,m
  414.     lxi    h,22            ; offset to NAME field
  415.     dad    d            ; point to Disk name
  416.     call    dsk$window$old
  417.  
  418. dsk$user$sel$wait:
  419.     call    ?kyscn
  420.     inr    b            ; test for key pressed
  421.     jrz    dsk$user$sel$wait
  422.     dcr    b            ; adjust back
  423.     mov    a,b            ; move matrix position to A
  424.     cpi    SF$exit
  425.     jrnz    CK$dsk$user$rt
  426.  
  427.     mov    a,c
  428.     ani    4            ; control key down ?
  429.     jrz    no$cntr$key        ; no, don't lock this selection
  430.     mvi    a,80h            ; yes, lock disk type to this drive
  431. no$cntr$key:
  432.     sta    lock$flag        ;
  433.     call    dsk$window$remove
  434.     lhld    MFM$cur$ptr
  435.     mov    e,m
  436.     inx    h
  437.     mov    d,m
  438.     xchg
  439.     jr    set$this$entry
  440.  
  441.     page
  442. ;
  443. ;
  444. ;
  445. CK$dsk$user$rt:
  446.     cpi    SF$right        ;
  447.     jrnz    CK$dsk$user$lf
  448.  
  449. ; move window down
  450.     lda    MFM$count        ; get number of items in list
  451.     mov    b,a            ; save in B
  452.     lda    MFM$offset        ; get current position
  453.     inr    a            ; advance position
  454.     cmp    b            ; at last position ? (n-1+1 =count)
  455.     jrnz    set$offset        ; no, then use A as new position
  456.     xra    a            ; yes, move back to start
  457.     jr    set$offset
  458.     
  459. CK$dsk$user$lf:
  460.     cpi    SF$left            ;
  461.     jrnz    dsk$user$sel$wait
  462.  
  463. ; move window up
  464.     lda    MFM$offset
  465.     dcr    a            ; back up offset (under flow?)
  466.     jp    set$offset        ; result positive, jump
  467.     lda    MFM$count        ; get last item number
  468.     dcr    a            ; pointer is 0 to n-1 (not 1 to n)
  469. set$offset:
  470.     sta    MFM$offset        ; set new list offset
  471.     inr    a            ; add one to adjust for DCR below
  472.     lxi    h,MFM$match$tbl        ; set to the beginning
  473.  
  474. adjust$dsk$loop:
  475.     shld    MFM$cur$ptr        ; set pointer here !
  476.     dcr    a            ; at offset yet?
  477.     jrz    user$loop        ; yes, go display name
  478.     inx    h
  479.     inx    h
  480.     jr    adjust$dsk$loop
  481.  
  482.     page
  483. ;
  484. ;
  485. ;
  486. tell$user$no$entry:
  487.     lda    vic$data        ; get disk test status
  488.     ani    0b0h            ; save only sector size and MFM flag
  489.     lhld    DPH$pointer
  490.     dcx    h
  491.     mov    m,a            ; set disk size and Type0 (MFM)
  492.  
  493.     lxi    h,dsk$window*256+buff$pos
  494.     lxi    d,no$dsk$msg
  495. disp$msg$DE$HL:
  496.     call    dsk$window$new
  497. dsk$no$entry$wait:
  498.     call    ?kyscn
  499.     inr    b
  500.     jrz    dsk$no$entry$wait
  501.     dcr    b
  502.     mov    a,b
  503.     cpi    SF$exit
  504.     jrnz    dsk$no$entry$wait
  505. ;    jr    dsk$window$remove
  506.  
  507.     page
  508. ;
  509. ;
  510. ;
  511. dsk$window$remove:
  512.     lhld    window$info
  513.     mov    b,h
  514.     mov    c,l
  515.     jmp    ?recov
  516. ;
  517. ;
  518. ;
  519. save$dsk$window:
  520.     lxi    h,dsk$window*256+buff$pos    ; H=size l=pos
  521.     shld    window$info
  522.     mov    b,h
  523.     mov    c,l
  524.     jmp    ?save
  525. ;
  526. ;
  527. ;
  528. dsk$window$new:
  529.     shld    window$info
  530.     xchg
  531.     mov    b,d
  532.     mov    c,e
  533.     push    h
  534.     call    ?save
  535.     pop    h
  536.  
  537. dsk$window$old:
  538.     lda    window$info        ; get start index
  539.     inr    a
  540.     mov    c,a            ; place in C
  541.  
  542. dsk$out$next:
  543.     push    h
  544.     lhld    window$info
  545.     mov    a,h
  546.     add    l            ; compute max index (start+size)
  547.     dcr    a            ; ..less 1
  548.     pop    h
  549.     cmp    c
  550.     rz    
  551.     mov    b,m
  552.     call    dsk$B$out
  553.     inx    h
  554.     jr    dsk$out$next
  555.  
  556. ;
  557. ;
  558. ;
  559. dsk$B$out:
  560.     mvi    a,01000000b            ; set reverse video attr
  561.     push    b
  562.     push    h
  563.     call    ?stat                ; display space
  564.     pop    h
  565.     pop    b                ; recover count
  566.     inr    c
  567.     ret
  568.  
  569.     page
  570. ;
  571. ; disk READ and WRITE entry points.
  572. ; These entries are called with the following arguments:
  573. ;    relative drive number in @rdrv (8 bits)
  574. ;    absolute drive number in @adrv (8 bits)
  575. ;    disk transfer address in @dma (16 bits)
  576. ;    disk transfer bank    in @dbnk (8 bits)
  577. ;    disk track address    in @trk (16 bits)
  578. ;    disk sector address    in @sect (16 bits)
  579. ;    pointer to XDPH in <DE>
  580. ;
  581. ;   return with an error code in <A>
  582. ;     A=0    no errors
  583. ;     A=1    non-recoverable error
  584. ;    A=2    disk write protected
  585. ;    A=FF    media change detected
  586. ;
  587.     DSEG
  588. read$154X:
  589.     call    get$drv$info
  590.     jm    mfm$rd
  591.     call    set$up$GCR        ; compute effective track and sector
  592. login$rd:
  593.     lda    vic$drv
  594.     mov    b,a
  595.     lda    fast            ; get fast flags
  596.     ana    b            ; isolate fast bit for this drive
  597.     jrnz    rd$fast            ; go handle fast drive
  598. rd$slow:
  599.     mvi    a,vicrd            ; read a sector of data (A=1)
  600.     call    dsk$fun            ; a=0 if no errors
  601.     jnz    test$error        ; check for disk error or media change
  602. ;
  603. ;
  604. ;
  605. buf$move:
  606.     xra    a            ; set direction to read
  607.     call    ?dkmov            ; go move buffer to DMA
  608.     lda    sect$cnt
  609.     ana    a
  610.     rz                ; a=0 means not read errors
  611.     call    set$up$next
  612.     jr    rd$slow
  613.  
  614.     page
  615. ;
  616. ;    A=drive type info
  617. ;
  618. mfm$rd:
  619.     call    set$up$MFM
  620.  
  621. rd$fast:
  622.     mvi    a,vic$rd$f
  623.     call    dsk$fun            ; go read the disk
  624.  
  625.     ani    0eh            ; mask off error bits
  626.     jrnz    test$error
  627.  
  628.     call    get$sector$size
  629.     inr    d
  630.     inr    e            ; adjust count for pre-decrement
  631.  
  632.     call    ?di$int
  633.     lxi    b,0DD00h        ; D2PRA
  634.     inp    a            ; get current clock polarity 
  635.     xri    10h            ; toggle clk$bit
  636.     outp    a            ; to have status sent (extra clock
  637.                     ; supplied by rd$1571$data for multi
  638.                     ; sector transfers)
  639.     lda    vic$count
  640. rd$multi$sect:
  641.     push    psw
  642.     push    d        ; save the sector size
  643.     call    rd$1571$data    ; read disk data to DMA address
  644.     pop    d
  645.  
  646.     lda    vic$data
  647.     ani    0eh
  648.     jrnz    test$error$pop    ; A=0 if no errors
  649.     pop    psw
  650.     dcr    a
  651.     jrnz    rd$multi$sect
  652.     ei
  653.     lda    sect$cnt
  654.     ana    a        ; any sectors left to read
  655.     jrz    done$rd$1571
  656.  
  657.     call    set$up$next
  658.     jr    rd$fast
  659.  
  660. done$rd$1571:
  661.     lxi    b,0DD00h        ;   D2PRA
  662.     inp    a
  663.     ani    not(10h)        ; set clk$bit hi
  664.     outp    a
  665.     xra    a            ; A=0 for no errors
  666.     ret
  667.  
  668.  
  669.     page
  670. ;
  671. ;
  672. ;
  673. write$154X:
  674.     call    get$drv$info
  675.     jm    mfm$wr
  676.     call    set$up$GCR
  677.     lda    vic$drv
  678.     mov    b,a
  679.     lda    fast            ; get fast flags
  680.     ana    b            ; isolate fast bit for this drive
  681.     jrnz    wr$fast$drive        ; go handle fast drive
  682. wr$slow:
  683.     mvi    a,-1            ; set direction to write
  684.     call    ?dkmov            ; go move DMA to buffer
  685.  
  686.     mvi    a,vicwr            ; write a sector of data
  687.     call    dsk$fun            ; a=0 if no errors
  688.     ani    0eh
  689.     jrnz    test$error
  690.     lda    sect$cnt
  691.     ana    a
  692.     rz
  693.     call    set$up$next
  694.     jr    wr$slow
  695.  
  696. test$error$pop:
  697.     pop    psw
  698. test$error:
  699.     ei
  700.     lda    vic$data
  701.     ani    0fh            ; check for disk error or media change
  702.     cpi    0bh            ; disk change ?
  703.     jrz    change$error
  704.     cpi    08h            ; test for write protect error
  705.     jrz    write$prot$error
  706.  
  707.     mvi    a,1            ;  get general error flag
  708.     ret
  709.  
  710. ;
  711. ;
  712. write$prot$error:
  713.     mvi    a,2
  714.     ret
  715.  
  716. ;
  717. ;
  718. change$error:
  719.     mvi    a,-1
  720.     ret
  721.  
  722.     page
  723. ;
  724. ;
  725. ;
  726. mfm$wr:
  727.     call    set$up$MFM
  728. wr$fast$drive:
  729.     mvi    a,vic$wr$f
  730.     call    dsk$fun            ; go send the write command
  731.  
  732.     call    get$sector$size        ; setup DMA adr and transfer count
  733.     lda    vic$count
  734. wr$multi$sect:
  735.     push    psw
  736.     push    d            ; save sector size
  737.     call    wr$1571$data        ; write data to disk from DMA address
  738.     pop    d
  739.     ani    0eh
  740.     jrnz    test$error$pop
  741.     pop    psw
  742.     dcr    a
  743.     jrnz    wr$multi$sect
  744.  
  745.     ei
  746.     lda    sect$cnt
  747.     ana    a
  748.     rz                ; return if no errors (A=0)
  749.     call    set$up$next
  750.     jr    wr$fast$drive
  751.  
  752.     page
  753. ;
  754. ;
  755. ;
  756. get$drv$info:
  757.     lhld    @dma
  758.     shld    local$dma
  759.     xchg
  760.     shld    DPH$pointer
  761.  
  762.     lda    @adrv            ; get drive number (0 to F)
  763.     dcx    h            ; point at drive mask
  764.     dcx    h
  765.     mov    a,m            ; get drive mask
  766.     mov    b,a            ; save in B
  767.     sta    vic$drv            ; save vic drive # (values 1,2,4,8)
  768.  
  769.     inx    h            ; point at disk type
  770.     xra    a
  771.     sta    sect$cnt        ; clear the count
  772.     inr    a
  773.     sta    vic$count
  774.     mov    a,m            ; get disk type
  775.     ana    a
  776.     ret
  777.  
  778. ;
  779. ;    
  780. ;
  781. ;
  782. get$max$num$b:
  783.     lhld    DPH$pointer
  784.     lxi    b,42            ; offset to number of sectors on track
  785.     dad    b
  786.     mov    a,m            ; get number sectors/track/side
  787.     ani    1fh
  788.     mov    b,a
  789.     ret
  790. ;
  791. ;
  792. ;
  793. get$sector$size:
  794.     lhld    DPH$pointer
  795.     dcx    h
  796.     mov    a,m            ; disk type in B (bit 5,4 size info)
  797.     rrc                ; ..00 = 080h byte sectors
  798.     rrc                ; ..01 = 100h byte sectors
  799.     rrc                ; ..10 = 200h byte sectors
  800.     rrc                ; ..11 = 400h byte sectors
  801.     ani    3
  802.     jrz    set$128
  803.     jpo    not$3            ; jump if (A=) 01b or 10b
  804.     inr    a            ; make A = 4
  805. not$3:
  806.     mvi    e,0            ; set E to zero
  807.     mov    d,a            ; set sector size (1,2 or 4)
  808. get$DMA:
  809.     lhld    local$DMA        ; get the current DMA pointer
  810.     ret
  811.  
  812. set$128:
  813.     lxi    d,128
  814.     jr    get$DMA 
  815.  
  816.     page
  817. ;
  818. ;
  819. ;
  820.     DSEG
  821. set$up$GCR:
  822.     cpi    dsk$c128
  823.     jnz    tst$c64
  824.  
  825.     mvi    a,4
  826.     sta    sect$cnt
  827.     lxi    h,sect$buffer
  828.     shld    sect$buf$ptr
  829.  
  830.     lhld    @trk            ; 1 K sector pointer 
  831.     dad    h
  832.     dad    h            ; make 256 byte pointer
  833. ;
  834. ;    build a list of tracks and sectors
  835. ;
  836. next$sect:
  837.     shld    @trk
  838.     RCALL    FR$trk$sect
  839.     lhld    vic$trk            ; get trk(L) and sector(H) to HL
  840.     xchg
  841.     lhld    sect$buf$ptr
  842.     mov    m,e
  843.     inx    h
  844.     mov    m,d
  845.     inx    h
  846.     shld    sect$buf$ptr
  847.     lhld    @trk
  848.     inr    l            ; update saved above at next$sect
  849.     mov    a,l
  850.     ani    3
  851.     jrnz    next$sect
  852. ;
  853. ;    check list of trk-sectors for number of sectors on this trk
  854.     lxi    h,sect$buffer
  855.     shld    sect$buf$ptr
  856.     lda    vic$drv
  857.     mov    b,a
  858.     lda    fast
  859.     ana    b            ; drive type 1571
  860.     jrz    handle$1541        ; no, handle as 1541
  861.  
  862.     lda    sect$cnt        ; number of sectors to rd/wr
  863.     mov    b,a
  864.     inx    h
  865.     mov    a,m            ; get 1st sector #
  866.     sta    vic$sect
  867.     dcx    h
  868.     mov    a,m            ; get 1st track #
  869.     sta    vic$trk
  870.  
  871. try$next:
  872.     cmp    m            ; test for same trk #
  873.     jrnz    exit$no$match
  874.     inx    h
  875.     inx    h            ; advance to next trk
  876.     shld    sect$buf$ptr
  877.     djnz    try$next    
  878.  
  879. exit$no$match:
  880.     lda    sect$cnt        ; number of sectors to rd/wr
  881.     sub    b            ; remove number left
  882.                     ; (leaving number matched)
  883.     sta    vic$count        ; save number to read
  884.     mov    a,b            ; get remaining count
  885.     sta    sect$cnt        ; save remaining count
  886.     ret
  887.  
  888.  
  889. set$up$next:
  890.     lda    vic$count        ; get number of sectors read
  891.     lhld    local$DMA        ; get current DMA pointer
  892.     add    h            ; advance pointer by number of
  893.     mov    h,a            ; sectors read
  894.     shld    local$DMA
  895. handle$1541:
  896.     lhld    sect$buf$ptr
  897.     mov    a,m
  898.     sta    vic$trk
  899.     inx    h
  900.     mov    a,m
  901.     sta    vic$sect
  902.     inx    h
  903.     shld    sect$buf$ptr
  904.     lda    vic$drv
  905.     mov    b,a
  906.     lda    fast
  907.     ana    b
  908.     jrz    set$up$next$slow
  909.     lda    sect$cnt
  910.     sta    vic$count
  911.     xra    a            ; two reads max with fast drive
  912.     jr    set$up$next$exit
  913.  
  914. set$up$next$slow:
  915.     lda    sect$cnt
  916.     dcr    a
  917. set$up$next$exit:
  918.     sta    sect$cnt
  919.     ret
  920.  
  921. tst$c64:
  922.     cpi    dsk$c64    
  923.     jrnz    tst$none    ; compute adjusted track number
  924. ;
  925. ;    this routine will adjust the track number if necessary.
  926. ;    The C64 CP/M disk has the C64 directory in the center
  927. ;    of the disk. This routine checks and adds one to the track
  928. ;    number if we have reached or passed the directory track. 
  929. ;    An additional offset of is added to make the track number
  930. ;    range from 1 to N+1 instead of 0 to N.
  931. ;
  932. set$up$c64:
  933.     lda    @trk
  934.     inr    a
  935.     cpi    dir$track    ; carry=1 if A < dir$track
  936.     cmc            ; add one if dir$track or more (carry not set)
  937.     aci    0        ; add the carry bit in
  938.  
  939. set$up$cont:
  940.     sta    vic$trk
  941.     lda    @sect
  942.     sta    vic$sect
  943.     ret
  944. ;
  945. ;    This format is for direct track and sector addressing 
  946. ;
  947. tst$none:
  948. ;    cpi    dsk$none    ; don't test extras for now....??
  949. ;    rnz
  950. do$type$7:
  951.     lda    @trk
  952.     jr    set$up$cont
  953.  
  954.     page
  955. ;
  956. ;    A=dsk$info on entry
  957. ;
  958. set$up$MFM:
  959.     mvi    d,0        ; D=side # (0)
  960.     mov    e,a        ; save dsk$info in E
  961.     ani    TypeX        ; look at Type0 to Type7
  962.     jrz    do$type$0    ;
  963.     cpi    Type2
  964.     lda    @trk        ; used by Type1, Type2 and Type3
  965.     jrz    do$type$2
  966.     jrc    do$type$1
  967.  
  968. ;    cpi    Type6
  969. ;    jrz    do$type$6
  970. ;    jnc    do$type$7    ; MSB of sector(byte) set for 2nd side of disk
  971.  
  972.     cpi    Type7
  973.     jz    do$type$7    ; MSB of sector(byte) set for 2nd side of disk
  974. ;
  975. ;    only types 0 to 2 and 7 are currenty defined
  976. ;        Type3 to Type6 will do Type2
  977. ;do$type$3:
  978. ;do$type$6:
  979.  
  980. do$type$2:
  981.     mov    b,a        ; save a copy in B
  982.     sui    40
  983.     jrc    do$type$0    ; jump if still on side 0
  984.     mvi    a,79        ; on back side count 39,38,37,...,0
  985.     sub    b
  986. set$trk:
  987.     mvi    d,80h        ; D=side # (1)
  988.     sta    @trk
  989.     jr    do$type$0
  990.  
  991.     page
  992. ;
  993. ;    divide the track number by two and if Head=1
  994. ;        add #sect/side to @sect
  995. ;
  996. do$type$1:
  997.     cmc            ; carry was set clear it
  998.     rar            ; divide track by 2 (carry gets LSB)
  999.     sta    @trk
  1000.     jrnc    do$type$0
  1001.     call    get$max$num$b    ; HL and C changed
  1002.     lda    @sect
  1003.     add    b
  1004.     sta    @sect
  1005.  
  1006. do$type$0:
  1007.     lda    @trk
  1008.     sta    vic$trk
  1009.     call    get$max$num$b    ; B=number of sectors per track per side
  1010.     lda    @sect        ; ..HL and C changed
  1011.     cmp    b
  1012.     jrc    is$side$0
  1013.     mvi    d,80h        ; D=side # (1)
  1014.     bit    C1$bit,e    ; dsk$info in E
  1015.                 ; sector numbering continues on side 1 ?
  1016.     jrnz    is$side$0    ; yes, do not remove side one bias
  1017.     sub    b        ; no, remove side one bias
  1018. is$side$0:
  1019.     mov    c,a        ; hold @sect in C    
  1020.     mov    a,e        ; get dsk$info to A
  1021.     ani    S1        ; A=Starting  sector number (0 or 1)
  1022.     add    c        ; add back @sect
  1023.     ora    d        ; add in the side bit
  1024.     sta    vic$sect
  1025.     ret
  1026.  
  1027.     page
  1028. ;
  1029. ;    input:
  1030. ;        DE = number bytes to read
  1031. ;        HL = DMA address
  1032. ;
  1033.     CSEG
  1034. rd$1571$data:
  1035.     lda    @dbnk            ; get the disk DMA bank
  1036.     call    ?bank            ; set it
  1037.  
  1038.     lxi    b,0DC0Dh        ; D1ICR
  1039. rd$1571$stat$wait:
  1040.     inp    a
  1041.     ani    8            ; data ready bit set?
  1042.     jrz    rd$1571$stat$wait    ; no, loop
  1043.  
  1044.     mvi    c,0ch            ; D1SDR
  1045.     inp    a            ; read the status byte
  1046.     sta    vic$data        ; save it
  1047.     ani    0eh            ; any errors ?
  1048.     jrnz    rd$1571$exit        ; yes, exit
  1049.  
  1050.     lxi    b,0DD00h
  1051.     inp    a            ; get current clock polarity
  1052.  
  1053. rd$1571$next:
  1054.     lxi    b,0DD00h        ; D2PRA
  1055.     xri    10h            ; toggle clk$bit
  1056.     outp    a            ; clock the 1571 for a byte
  1057.  
  1058.     dcr    e            ; DE=count
  1059.     jnz    rd$1571$more        ; leave as normal jump to keep
  1060.     dcr    d            ; the transfer speed at it's max
  1061.     jrz    rd$1571$exit        ; ...
  1062.  
  1063. ;
  1064. rd$1571$more:
  1065.     dcr    b
  1066. rd$1571$wait:
  1067.     mvi    c,0dh            ; D1ICR (DC0Dh)
  1068.     inp    c
  1069.     bit    3,c
  1070.     jz    rd$1571$wait
  1071.     mvi    c,0ch            ; D1SDR
  1072.     ini                ; (hl) <- (bc) ; hl <- hl+1 ; b <- b-1
  1073.     jmp    rd$1571$next
  1074.  
  1075.  
  1076. rd$1571$exit:
  1077.     sta    bank$0            ; restore current mem config
  1078.     ret
  1079.  
  1080.     page
  1081.  
  1082. clk$in    equ    40h
  1083. ;
  1084. ;    input:
  1085. ;        DE = number of bytes to write
  1086. ;        HL = DMA address
  1087. ;
  1088. wr$1571$data:
  1089.     call    ?di$int
  1090. ; do spout inline
  1091.     lxi    b,mode$reg
  1092.     mvi    a,fast$wr$en
  1093.     sta    io$0
  1094.     outp    a            ; set data direction to output
  1095.     sta    bank$0
  1096.  
  1097.     lxi    b,0dc05h        ; low (D1T1h)
  1098.     xra    a
  1099.     outp    a
  1100.     dcr    c            ; low(D1T1l)
  1101.     mvi    a,3            ; clk = osc/3
  1102.     outp    a            ;
  1103.  
  1104.     mvi    c,0eh            ; D1CRA
  1105.     inp    a
  1106.     ani    80h
  1107.     ori    55h
  1108.     outp    a
  1109.     dcr    c            ; D1ICR
  1110.     inp    a
  1111.  
  1112.     lda    @dbnk            ; get the disk DMA bank
  1113.     call    ?bank            ; set it
  1114.  
  1115.     mvi    a,clk$in
  1116.     sta    cur$clk
  1117.  
  1118.     page
  1119. ;
  1120. ;
  1121. clk$wait:
  1122.     lxi    b,0dd00h        ; D2PRA
  1123.     inp    a
  1124.     inp    c            ; debounce
  1125.     cmp    c
  1126.     jrnz    clk$wait
  1127.  
  1128.     lda    cur$clk            ; get old clk value
  1129.     xra    c            ; check if changed 
  1130.     ani    clk$in            ; (only clock in bit)
  1131.     jrz    clk$wait        ; loop if not
  1132.  
  1133.     mov    a,c            ; 
  1134.     sta    cur$clk            ; make this the current clk value
  1135.     lxi    b,0dc0ch        ; D1SDR
  1136.     mov    a,m
  1137.     outp    a            ; send character to drive
  1138.     inx    h            ; advance pointer
  1139.     dcx    d            ; dec the char count
  1140.  
  1141.     inr    c            ; D1ICR
  1142. send$wait:
  1143.     inp    a
  1144.     ani    8
  1145.     jz    send$wait
  1146.  
  1147.     mov    a,d
  1148.     ora    e
  1149.     jnz    clk$wait        ; go send the next byte
  1150.  
  1151. ; do spin
  1152.     lxi    b,0DC0Eh        ; D1CRA
  1153.     inp    a
  1154.     ani    80h
  1155.     ori    8
  1156.     outp    a
  1157.     lxi    b,mode$reg
  1158.     mvi    a,fast$rd$en
  1159.     sta    io$0            ; enable the MMU
  1160.     outp    a            ; set data direction to input
  1161.     sta    bank$0            ; disable MMU
  1162. ; spin done
  1163.  
  1164.     page
  1165.  
  1166.     lxi    b,0DC0Dh        ; D1ICR
  1167.     inp    a            ; clear data pending flag
  1168.  
  1169.     lxi    b,0DD00h        ; D2PRA
  1170.     inp    a
  1171.     ori    10h            ; set clk$bit low (hardware inverted)
  1172.     outp    a            ; 
  1173.  
  1174.     lxi    b,0DC0Dh        ; D1ICR
  1175. wait$status:
  1176.     inp    a
  1177.     ani    8
  1178.     jrz    wait$status
  1179.  
  1180.     lxi    b,0DC0Ch        ; D1SDR
  1181.     inp    d
  1182.  
  1183.     lxi    b,0DD00h        ; D2PRA
  1184.     inp    a
  1185.     ani    not(10h)        ; set clk$bit hi (hardware inverted)
  1186.     outp    a            ; 
  1187.  
  1188.     mov    a,d            ; recover the status byte
  1189.     sta    vic$data
  1190.  
  1191.     ei
  1192.     ret
  1193.  
  1194.     page
  1195. ;
  1196. ;    This routine is used to move a sector of data
  1197. ;     to/from the sector buffer and the DMA pointer.
  1198. ;         A=0 for buffer to DMA  (disk read)
  1199. ;         A<>0 for DMA to buffer (disk write)
  1200. ;
  1201.     CSEG
  1202. ?dkmov:
  1203.     lhld    local$DMA    ; current DMA adr
  1204.     lxi    d,@buffer    ; location of disk read/write buffer
  1205.     lxi    b,256        ; sector size
  1206. ;
  1207. ;
  1208. dk$cont:
  1209.     ora    a
  1210.     jrnz    dsk$read    ; swap pointer for read
  1211.     xchg
  1212. ;
  1213. ;
  1214. dsk$read:
  1215.     lda    @dbnk        ; get the disk bank
  1216.     call    ?bank
  1217.     ldir            ; do the data move
  1218.     sta    bank$0        ; current bank will ALWAYS be 0
  1219.     ret
  1220.  
  1221. ;
  1222. ;
  1223. ;
  1224.     DSEG
  1225. dsk$fun:
  1226.     sta    vic$cmd
  1227.     call    disp$dsk$info        ; yes, go display disk info
  1228.     jmp    ?fun65+3        ; go do the function
  1229.  
  1230.     page
  1231. ;
  1232. ;*****************************************************************
  1233. ;
  1234.     DSEG
  1235. ?dskst:
  1236. disp$dsk$info:
  1237.     mvi    a,72            ; r/w in col 72 (col 0-79)
  1238.     sta    offset
  1239.     lda    vic$cmd
  1240.     mvi    b,'R'
  1241.     dcr    a            ; ?1 normal$rd
  1242.     jrz    out$cmd$rd
  1243.     dcr    a            ; ?2 normal$wr
  1244.     jrz    out$cmd$wr
  1245.     dcr    a            ; ?3 fast$rd
  1246.     jrz    out$cmd$rd
  1247.     dcr    a            ; ?4 fast$wr
  1248.     rnz
  1249. out$cmd$wr:
  1250.     mvi    b,'W'
  1251. out$cmd$rd:
  1252.     call    disp$B
  1253.     call    disp$space
  1254.     mvi    b,'A'-1
  1255.     lda    vic$drv
  1256. next$drv:
  1257.     inr    b
  1258.     rrc
  1259.     jrnc    next$drv
  1260.  
  1261.     call    disp$B
  1262.     lda    vic$trk
  1263.     call    disp$dec
  1264.     lda    vic$sect
  1265.     ani    80h
  1266.     cz    disp$space
  1267.     mvi    b,'-'
  1268.     cnz    disp$B
  1269.     lda    vic$sect    
  1270.     ani    7fh
  1271.  
  1272.     page
  1273. ;
  1274. ;
  1275. ;
  1276. disp$dec:
  1277.     mvi    b,'0'-1
  1278.  
  1279. conv$loop:
  1280.     inr    b
  1281.     sui    10
  1282.     jrnc    conv$loop
  1283.  
  1284.     adi    '0'+10
  1285.     push    psw
  1286.     call    disp$B
  1287.     pop    psw
  1288. disp$A:
  1289.     mov    b,a
  1290. disp$B:
  1291.     lda    offset
  1292.     mov    c,a            ; col # in C
  1293.     inr    a
  1294.     sta    offset            ; advance cursor position
  1295.     xra    a            ; no attribute to write
  1296.     call    ?stat
  1297.  
  1298.     xra    a
  1299.     ret
  1300.  
  1301. disp$space:
  1302.     mvi    b,' '
  1303.     jr    disp$B
  1304.  
  1305.     page
  1306.  
  1307. ;*****************************************************************
  1308. ;
  1309. ; Extended Disk Parameter Headers (XDPHs)
  1310. ;
  1311.     CSEG            ; place tables in common
  1312. ;
  1313. ;    1st disk drive on the system
  1314. ;
  1315.     dw    write$154X
  1316.     dw    read$154X
  1317.     dw    login$154X
  1318.     dw    init$154X
  1319.     db    1        ; bit 0 set (drive 0)
  1320.     db    dsk$c128    ; format type byte
  1321. cmdsk0:    
  1322.     dph    0,dpb$0
  1323.  
  1324. dpb$0:
  1325.     dpb    1024,1,1360,2048,128,0
  1326.     db    0        ; max sector number and lock flag
  1327.     dw    0        ; MFM table pointer
  1328.  
  1329.     page
  1330. ;
  1331. ;    2nd disk Drive on the system
  1332. ;
  1333.     dw    write$154X
  1334.     dw    read$154X
  1335.     dw    login$154X
  1336.     dw    init$154X
  1337.     db    2        ; bit 1 set (drive 1)
  1338.     db    dsk$c128    ; format type byte 
  1339. cmdsk1:
  1340.     dph    0,dpb$1
  1341.  
  1342. dpb$1:
  1343.     dpb    1024,1,1360,2048,128,0
  1344.     db    0        ; max sector number and lock flag
  1345.     dw    0        ; MFM table pointer
  1346.  
  1347.     page
  1348. ;
  1349. ;    3rd disk drive on the system
  1350. ;
  1351.     dw    write$154X
  1352.     dw    read$154X
  1353.     dw    login$154X
  1354.     dw    init$154X
  1355.     db    4        ; bit 2 set (drive 2)
  1356.     db    dsk$c128    ; format type byte
  1357. cmdsk2:    
  1358.     dph    0,dpb$2
  1359.  
  1360. dpb$2:
  1361.     dpb    1024,1,1360,2048,128,0
  1362.     db    0        ; max sector number and lock flag
  1363.     dw    0        ; MFM table pointer
  1364.  
  1365.     page
  1366. ;
  1367. ;    4th disk drive on the system
  1368. ;    (Drive D: returned to active duty. -RW)
  1369. ;
  1370.     dw    write$154X
  1371.     dw    read$154X
  1372.     dw    login$154X
  1373.     dw    init$154X
  1374.     db    8        ; bit 3 set (drive 3) (-RW)
  1375.     db    dsk$c128    ; format type byte
  1376. cmdsk3:
  1377.     dph    0,dpb$3
  1378.  
  1379. dpb$3:
  1380.     dpb    1024,1,1360,2048,128,0
  1381.     db    0        ; max sector number and lock flag
  1382.     dw    0        ; MFM table pointer
  1383.  
  1384.     page
  1385. ;
  1386. ;    5th disk drive on the system
  1387. ;    (Drive E: will be used as Drive F: by the Quick Brown Box -RW)
  1388. ;
  1389.     dw    write$154X
  1390.     dw    read$154X
  1391.     dw    login$154X
  1392.     dw    init$154X
  1393.     db    16        ; bit 4 set (drive 4) (-RW)
  1394.     db    dsk$c128    ; format type byte
  1395. cmdsk4:
  1396.     dph    0,dpb$4
  1397.  
  1398. dpb$4:
  1399.     dpb    1024,1,1360,2048,128,0
  1400.     db    0        ; max sector number and lock flag
  1401.     dw    0        ; MFM table pointer
  1402.  
  1403.     page
  1404. ;
  1405. ;    NOTE: The blocking factor for all of these formats is
  1406. ;        1K (2K for double sided), thus the fractional
  1407. ;        parts are unusable by CP/M.  They can be accessed
  1408. ;        by absolute sector addressing.
  1409. ;
  1410. ;    NOTE: 1571 and 1541 disk drives use track numbers
  1411. ;        of 1 to 35 and sector numbers of 0 to nn
  1412.  
  1413. ;
  1414. ;        The method used to access the full disk
  1415. ;        is to tell the system that there is 1 sector
  1416. ;        per track and then to use the track # as an
  1417. ;        absolute sector address and do conversion in BIOS.
  1418. ;
  1419. ; DPB FOR C128 CP/M 3.0 disk        ( 170K, 34K larger then C64 CP/M)
  1420. ;    256 byte sectors        ( 170.75K )
  1421. ;    1 sectors/track
  1422. ;        up to 21 physical sectors (0 to 16,17,18 or 20)
  1423. ;    680 tracks/disk (usable, 683 real)
  1424. ;        35 physical tracks (0 to 34)
  1425. ;    1K allocation blocks
  1426. ;    64 directory entries
  1427. ;    track offset of 2 (2 sectors) (handled by set$up$c128)
  1428. ;
  1429.     DSEG        ; these tables are moved to common when used
  1430. dpb$c128$SS:
  1431.     dpb    1024,1,170,1024,64,0
  1432.  
  1433.     page
  1434. ;
  1435. ; DPB FOR C128 CP/M 3.0 double sided disk    ( 340K )
  1436. ;    256 byte sectors            ( 341.5K )    
  1437. ;    1 sectors/track
  1438. ;        up to 21 physical sectors (0 to 16,17,18 or 20)
  1439. ;    1360 tracks/disk (usable, 1366 real)
  1440. ;        70 physical tracks (0 to 34 side 0, 35 to 69 side 1)
  1441. ;    2K allocation units
  1442. ;    128 directory entrys
  1443. ;    track offset of 1 (1 sectors) taken care of in set$up$c128
  1444. ;
  1445. dpb$c128$DS:
  1446.     dpb    1024,1,340,2048,128,0
  1447.  
  1448.     page
  1449. ;
  1450. ; DPB FOR C64 CP/M 2.2 disk --             ( 136K )
  1451. ;    256 byte sectors
  1452. ;    17 sectors / tracks    (sector numbering 0-16)
  1453. ;        sector 18 to n on the outer tracks are unused
  1454. ;    34 tracks / disk
  1455. ;        tracks track 2 to 16    (track numbering 0-34)
  1456. ;        track 17 is the C128 directory track (not counted)
  1457. ;        track 19 to 34
  1458. ;    1K allocation blocks
  1459. ;    64 directory entrys
  1460. ;    track offset of 2 (1st two tracks used for CP/M 2.2 boot)
  1461. ;
  1462. dpb$c64$cpm:
  1463.     dpb    256,17,34,1024,64,2
  1464.                 
  1465.     page
  1466. ;
  1467.     DSEG
  1468. MFM$table:
  1469.     db    S256*2+(16*2-8)+1    ; 256 byte sect, 16 sect/trk
  1470.     db    MFM+S256+Type0+C0+S1    ;     DSDD
  1471.     dw    0            ; start on track 4 sect 1 (2 alc)
  1472.     dpb    256,32,40,2048,128,2    ; sect# 1 to 16
  1473.     db    16            ; (top and bottom numbered the same)
  1474.     db    'Epson QX10'        ;1 Epson QX10
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.     db    80h+S512*2+(10*2-8)+1    ; 512 byte sect, 10 sect/trk
  1481. ;    db    S256*2            ; track 0 is 256 bytes/sector
  1482.     db    MFM+S512+Type0+C0+S1    ;    DSDD
  1483.     dw    0            ; start on track 2 sect 1 (2 alc)
  1484.     dpb    512,20,40,2048,128,2    ; sect# 1 to 10
  1485.     db    10            ; (top and bottom numbered the same)
  1486.     db    'Epson QX10'        ;2
  1487.  
  1488.     page
  1489.  
  1490.     db    S512*2+(8*2-8)+1    ; 512 byte sect 8 sect/trk
  1491.     db    MFM+S512+Type2+C0+S1    ;     SSDD
  1492.     dw    0            ; start on track 1 sector 1 (2 alc)
  1493.     dpb    512,8,40,1024,64,1    ; sect# 1 to 8
  1494.     db    8            ;
  1495.     db    ' IBM-8 SS '        ;3
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.     db    S512*2+(8*2-8)+1    ; 512 byte sect 8 sect/trk
  1502.     db    MFM+S512+Type2+C0+S1    ;     DSDD
  1503.     dw    0            ; start on track 1 sector 1 (1 alc)
  1504.     dpb    512,8,80,2048,64,1    ; sect# 1 to 8
  1505.     db    8            ; (top and bottom numbered the same)
  1506.     db    ' IBM-8 DS '        ;4
  1507.  
  1508.     page
  1509.  
  1510.     db    S512*2+(10*2-8)+0    ; 512 byte sector, 10 sect/trk
  1511.     db    MFM+S512+Type1+C1+S0    ;    DSDD
  1512.     dw    0            ; start on track 0 sector 10 (2 alc)
  1513.     dpb    512,10,80,2048,128,1    ; sect# 0 to 9 on top (even tracks)
  1514.     db    10            ; sect# 10 to 19 on bottom (odd tracks)
  1515.     db    'KayPro IV '        ;5
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.     db    S512*2+(10*2-8)+0    ; 512 byte sect, 10 sect/trk
  1522.     db    MFM+S512+Type0+C1+S0    ;     SSDD
  1523.     dw    0            ; start on track 1 sector 0 (4 alc)
  1524.     dpb    512,10,40,1024,64,1    ; sect# 0 to 9 
  1525.     db    10            ;
  1526.     db    'KayPro II '        ;6
  1527.  
  1528.     page
  1529.  
  1530.     db    S1024*2+(5*2-8)+1    ; 1024 byte sect, 5 sect/trk
  1531.     db    MFM+S1024+Type0+C0+S1    ;     SSDD
  1532.     dw    0            ; start on track 3 sector 1 (2 alc)
  1533.     dpb    1024,5,40,1024,64,3    ; sect# 1 to 5
  1534.     db    5            ;
  1535.     db    'Osborne DD'        ;7
  1536.  
  1537.  
  1538.  
  1539.  
  1540.     db    S512*2+(9*2-8)+1    ; 512 byte sect 9 sect/track (uses 8)
  1541.     db    MFM+S512+Type1+C0+S1    ;     DSDD
  1542.     dw    0            ; start on trk 0, sect 1, hd 1 (1 alc)
  1543.     dpb    512,8,80,2048,64,1    ; sect# 1 to 9
  1544.     db    8            ; (top and bottom numbered the same)
  1545.     db    '  Slicer  '        ;8
  1546.  
  1547.     page
  1548.  
  1549.     db    S256*2+(16*2-8)+1    ; 256 byte sect, 16 sect/trk
  1550.     db    MFM+S256+Type0+C0+S1    ;     DSDD
  1551.     dw    0            ; start on track 4 sect 1 (2 alc)
  1552.     dpb    256,32,40,2048,128,4    ; sect# 1 to 16
  1553.     db    16            ; (top and bottom numbered the same)
  1554.     db    'Epson Euro'        ;9 Epson European (MFCP/M ?)
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.     db    -1
  1561.     db    MFM            ; 
  1562.     dw    0            ; 
  1563.     dpb    512,20,40,2048,128,2    ; 
  1564.     db    8            ;
  1565.     db    '   None   '        ;10
  1566.  
  1567.     page
  1568.  
  1569.  
  1570.     db    80h+S512*2+(10*2-8)+1    ; 256 byte sector, 16 sectors/track
  1571.     db    MFM+S512+Type0+C0+S1    ; DSDD
  1572.     dw    0            ; start on track 2 sect 1 (2 alc)
  1573.     dpb    512,20,80,2048,128,0    ; sect# 1 to 10
  1574.     db    10            ; (top and bottom numbered the same)
  1575.     db    ' 1581 GP  '        ;11 - Gene Pizzetta's 1581 format
  1576.  
  1577.  
  1578.  
  1579.     db    62h
  1580.     db    0b0h
  1581.     db    0
  1582.     db    0
  1583.     db    50h
  1584.     db    0
  1585.     db    04
  1586.     db    0fh
  1587.     db    01
  1588.     db    0c8h
  1589.     db    0
  1590.     db    7fh
  1591.     db    0
  1592.     db    0c0h
  1593.     db    0
  1594.     db    20h
  1595.     db    0
  1596.     db    0
  1597.     db    0
  1598.     db    03
  1599.     db    07
  1600.     db    05
  1601.         db      'Maxi 1571 '        ;12 -  M. Garamszeghy's 398K format
  1602.  
  1603.     page
  1604.  
  1605.     db    -1
  1606.     db    MFM            ; 
  1607.     dw    0            ; 
  1608.     dpb    512,20,40,2048,128,2    ; 
  1609.     db    8            ;
  1610.     db    '   None   '        ;13
  1611.  
  1612.     db    -1
  1613.     db    MFM            ; 
  1614.     dw    0            ; 
  1615.     dpb    512,20,40,2048,128,2    ; 
  1616.     db    8            ;
  1617.     db    '   None   '        ;14
  1618.  
  1619.     page
  1620.  
  1621.     db    -1
  1622.     db    MFM            ; 
  1623.     dw    0            ; 
  1624.     dpb    512,20,40,2048,128,2    ; 
  1625.     db    8            ;
  1626.     db    '   None   '        ;15
  1627.  
  1628.     db    -1
  1629.     db    MFM            ; 
  1630.     dw    0            ; 
  1631.     dpb    512,20,40,2048,128,2    ; 
  1632.     db    8            ;
  1633.     db    '   None   '        ;16
  1634.  
  1635.  
  1636.     page
  1637. ;
  1638. ;    not functional yet
  1639. ;
  1640.  
  1641. ;    db    S1024*2+(5*2-8)+1    ; 1024 byte sect 5 sect/track
  1642. ;    db    MFM+S1024+Type0+C0+S1    ;     SSDD
  1643. ;    dw    0            ; start on trk 2, sect 1 (2 alc)
  1644. ;    dpb    1024,5,40,2048,128,2    ; sect# 1 to 5
  1645. ;    db    5            ;
  1646. ;    db    'Morrow MD2'        ; 
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652. ;    db    S1024*2+(5*2-8)+1    ; 1024 byte sect  5 sect/trk
  1653. ;    db    MFM+S1024+Type0+C0+S1    ;     DSDD
  1654. ;    dw    0            ; start on trk 1, sect 1, hd 0 (3 alc)
  1655. ;    dpb    1024,10,40,2048,192,1    ; sect# 1 to 5
  1656. ;    db    5            ;
  1657. ;    db    'Morrow MD3'        ; 
  1658.  
  1659.  
  1660. MFM$tbl$entries    equ    ($-MFM$table)/32
  1661.  
  1662.     db    -1
  1663.     db    -1
  1664.  
  1665.     page
  1666.  
  1667.     cseg
  1668. cur$clk:    ds    1
  1669.  
  1670.     dseg
  1671. lock$flag    ds    1
  1672. last$match    ds    2
  1673. window$info:    ds    2
  1674.  
  1675. dsk$window    equ    12
  1676.  
  1677. no$dsk$msg:
  1678.         ;1234567890
  1679.     db    ' Missing  ' 
  1680.  
  1681.  
  1682. MFM$match$tbl:
  1683.     ds    2*MFM$tbl$entries    ; MFM$count MUST follow this parm
  1684. MFM$count:
  1685.     ds    1            ; MFM$offset MUST follow this parm
  1686. MFM$offset:
  1687.     ds    1
  1688.  
  1689. MFM$cur$ptr:
  1690.     ds    2
  1691.  
  1692. DPH$pointer:
  1693.     ds    2
  1694.  
  1695. sect$cnt:
  1696.     ds    1
  1697. sect$buf$ptr:
  1698.     ds    2
  1699. sect$buffer:
  1700.     ds    4*2
  1701.  
  1702. local$DMA:
  1703.     ds    2
  1704.  
  1705. status$atr    equ    0
  1706. offset:        db    0
  1707.  
  1708.     end
  1709.  
  1710.