home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol236 / diskhndl.mqc / DISKHNDL.MAC
Encoding:
Text File  |  1986-02-11  |  16.1 KB  |  476 lines

  1.         title 'disk handling routines'
  2.  
  3. true        equ -1
  4. false       equ 0
  5.  
  6. banked      equ true
  7. check       equ false
  8.  
  9.             .Z80
  10.  
  11. .comment *
  12. disk handling routines for assembly by m80
  13.  
  14. routines  (dph address in DE):
  15.    fread    return 0 in A for success, 1 for failure
  16.    fwrite   return 0 for success, 1 for error, 2 for write protected disk
  17.    flogin   login - set density
  18.    finita   initialize drive a
  19.    finitb   initialize drive b
  20.    finitc   initialize drive c
  21.  
  22. external variables
  23.    @adrv    absolute drive code
  24.    @rdrv    relative drive code
  25.    @dma     disk transfer address
  26.    @trk     track
  27.    @sect    sector
  28.    @ermde   error mode
  29.    @dbnk    bank
  30.  
  31. external routines
  32.    ?pmsg    print message
  33.    ?pdec    print decimal
  34.    ?pderr   print disk error header
  35.    ?wboot   warm boot
  36.    ?conin,?cono,?const   console routines
  37.    ?move,?xmove,?trans   bank transfer routines
  38.  
  39. codes for disk format
  40.    bit 5: 1 for double sided
  41.    bit 4: 1
  42.    bit 2,3: 0 for 128 byte sectors,
  43.             1 for 256 byte sectors,
  44.             2 for 512 byte sectors,
  45.             3 for 1024 byte sectors
  46.    all bits=0 if density determination fails
  47.  
  48.          *
  49.  
  50.          dseg
  51.  
  52.          entry fread,fwrite,flogin,finita,finitb,finitc
  53.          external @adrv,@rdrv,@dma,@trk,@sect,@ermde
  54.          external ?pmsg,?pdec,?pderr,?wboot,?conin,?cono,?const,?move
  55.                      if banked
  56.          external ?xmove,?trans,@cbnk,@dbnk
  57.                      endif
  58.          external adrv,bdrv,cdrv,ddrv   ; drives
  59.          external dskdef                ; disk characteristics
  60. cr      equ     13
  61. lf      equ     10
  62. xbuff   equ     0E800H          ;Buffer for r/w to nonzero banks
  63. ntry    equ     4               ;number of retries
  64.  
  65. origin  equ     0E000H
  66. djboot  equ     origin          ;Disk Jockey 2D cold boot
  67. djcin   equ     origin+3h       ;Disk Jockey 2D character input routine
  68. djcout  equ     origin+6h       ;Disk Jockey 2D character output routine
  69. djhome  equ     origin+9h       ;Disk Jockey 2D track zero seek
  70. djtrk   equ     origin+0ch      ;Disk Jockey 2D track seek routine
  71. djsec   equ     origin+0fh      ;Disk Jockey 2D set sector routine
  72. djdma   equ     origin+12h      ;Disk Jockey 2D set DMA address
  73. djread  equ     origin+15h      ;Disk Jockey 2D read routine
  74. djwrit  equ     origin+18h      ;Disk Jockey 2D write routine
  75. djsel   equ     origin+1bh      ;Disk Jockey 2D select drive routine
  76. djtsta  equ     origin+21h      ;Disk Jockey 2D terminal status routine
  77. djstat  equ     origin+27h      ;Disk Jockey 2D status routine
  78. djerr   equ     origin+2ah      ;Disk Jockey 2D error, flash led
  79. djden   equ     origin+2dh      ;Disk Jockey 2D set density routine
  80. djside  equ     origin+30h      ;Disk Jockey 2D set side routine
  81. djleav  equ     origin+222h     ;leave routine in dj rom
  82. djprep  equ     origin+233h     ;prep routine in dj rom
  83.  
  84.  
  85. finita:                           ; initialize disk a
  86.          ld a,'A'
  87.          ld (drvtp),a             ; disk A expected
  88.          ld c,0
  89.          call djsel               ; physical drive A
  90.          xor a                    ; clear a
  91.          ld (adrv-1),a            ; error or unset code for disk format
  92.          ret
  93. finitb:                           ; initialize disk b
  94.          xor a                    ; clear a
  95.          ld (bdrv-1),a            ; error or unset code for disk format
  96.          ret
  97. finitc:                           ; initialize disk c
  98.          xor a                    ; clear a
  99.          ld (cdrv-1),a            ; error or unset code for disk format
  100.          ret
  101.  
  102. setup:                            ; set up disk parameters
  103.          push de                  ; keep de
  104.          call dsk                 ; check correct disk loaded
  105.                      if banked
  106.          ld a,(@dbnk)             ; check bank
  107.          and a
  108.          jr z,bnk0                ; bank 0
  109.                                   ; get sector length / 128
  110.          pop bc                   ; get dhp
  111.          push bc                  ;   & restore to stack
  112.          ld hl,12
  113.          add hl,bc                ; points to address of dpb
  114.          ld c,(hl)
  115.          inc hl
  116.          ld b,(hl)                ; bc contains address of dpb
  117.          ld hl,16
  118.          add hl,bc                ; hl points to phm
  119.          ld a,(hl)
  120.          inc a                    ; a contains sector length / 128
  121.          ld (seclen),a            ; store in seclen
  122.          ld bc,xbuff              ; temporary buffer
  123.          jr bnkx
  124.                      endif
  125. bnk0:    ld bc,(@dma)             ; get dma
  126. bnkx:    xor a                    ; necessary to detect dma error
  127.          call djdma               ; set dma
  128.          and a
  129.          jp nz,err2               ; dma invalid
  130.          ld a,(@sect)             ; get sector
  131.          ld c,a
  132.          call djsec               ; set sector
  133.          jp c,err1
  134.          ld a,(@trk)              ; get track
  135.          ld b,a
  136.          pop hl
  137.          dec hl                   ; points to disk format
  138.          ld a,(hl)                ; get disk format
  139.          ld (fmt),a               ; keep disk format
  140.          or a                     ; get flags
  141.          jp z,nologi              ; login not done or failed
  142.          bit 5,a                  ; check for double sided
  143.          ld c,0
  144.          jr z,ss                  ; jump if single sided
  145.          srl b                    ; divide track by 2 - rem to carry bit
  146.          rl c                     ; side 1 if track number odd
  147. ss:      call djside              ; set side (to 0 for ss disk)
  148.          ld c,b
  149.          call djtrk               ; set track
  150.          jp c,err1
  151.          ret
  152.  
  153. dsk:                              ; check correct disk loaded
  154.          ex de,hl
  155.          dec hl
  156.          dec hl                   ; points to unit
  157.          ld a,(drvtp)             ; get current disk name
  158.          cp (hl)
  159.          ret z                    ; return if disk ok
  160.          ld a,(hl)
  161.          ld (drvtp),a             ; store disk name
  162.          call clear               ; clear console input
  163.          ld hl,chdsk              ; change disk message
  164.          call ?pmsg               ; type message
  165.          call ?conin              ; wait for input
  166.          call crlf
  167.          call djhome              ; track 0
  168.          ret
  169.  
  170. chdsk:   db cr,lf,'Load disk '    ; change disk message
  171. drvtp:   db 'A'
  172.          db ', <ret>',0
  173.                      if banked
  174. seclen:  ds 1                     ; sector length / 128
  175.                      endif
  176. fmt:     ds 1                     ; disk format
  177.  
  178. clear:                            ; clear console buffer
  179.          call ?const              ; check for character
  180.          or a                     ; set flags
  181.          ret z                    ; return if no character
  182.          call ?conin              ; get character
  183.          jr clear                 ; try again
  184.  
  185. yesno:                            ; return with zero set if y or Y entered
  186.          call ?conin
  187.          cp 'y'
  188.          ret z
  189.          cp 'Y'
  190.          ret z
  191.          cp 'n'
  192.          jr z,yesno1
  193.          cp 'N'
  194.          jr z,yesno1
  195.          jr yesno                 ; cycle if not y,Y,n or N
  196. yesno1:  and a                    ; to set flag to nz
  197.          ret
  198.  
  199. crlf:                             ; output a cr and lf
  200.          ld hl,lcrlf
  201.          call ?pmsg
  202.          ret
  203.  
  204. lcrlf:   db cr,lf,0
  205.  
  206. fread:                            ; read sector
  207.                      if check
  208.          ld hl,xr
  209.          call record
  210.                      endif
  211.          call setup               ; set disk parameters
  212. cycr1:   ld b,ntry                ; number of attempts
  213. cycr:    push bc                  ; store these
  214.          call djread              ; diskjockey read
  215.          pop bc
  216.                      if banked
  217.          jr nc,fre1               ; exit if successful
  218.                      else
  219.          ret nc
  220.                      endif
  221.          and a                    ; set flags
  222.          call m,notred            ; drive not ready
  223.          djnz cycr                ; try ntry times
  224.          call errcd
  225.                      if banked
  226.          jr nz,fre2               ; exit anyway
  227.                      else
  228.          ret nz
  229.                      endif
  230.          jr cycr1
  231.                      if banked
  232. fre1:    call frex
  233.          xor a                    ; return code
  234.          ret
  235. fre2:    push af                  ; keep error code
  236.          call frex
  237.          pop af                   ; return code
  238.          ret
  239. frex:    ld a,(@dbnk)             ; interblock transf reqd?
  240.          and a
  241.          ret z                    ; return if reading from bank 0
  242.          ld b,a                   ; destination
  243.          ld hl,(@dma)
  244.          ld c,0                   ; source
  245.          ld de,xbuff
  246.          ld a,(seclen)            ; get sector length / 128
  247.          call ?trans              ; interblock transfer
  248.          ret
  249.                      endif
  250.  
  251. fwrite:                           ; write sector
  252.                      if check
  253.          ld hl,xw
  254.          call record
  255.                      endif
  256.          call setup               ; set disk parameters
  257.                      if banked
  258.          ld a,(@dbnk)             ; check bank
  259.          and a
  260.          jr z,cycw1               ; jump if bank 0
  261.          ld c,a                   ; source
  262.          ld de,(@dma)
  263.          ld b,0                   ; destination
  264.          ld hl,xbuff
  265.          ld a,(seclen)
  266.          call ?trans              ; interblock transfer
  267.                      endif
  268. cycw1:   ld b,ntry                ; number of attempts
  269. cycw:    push bc                  ; store these
  270.          call djwrite             ; diskjockey write
  271.          pop bc
  272.          ret nc                   ; return if successful
  273.          and a                    ; set flags
  274.          call m,notred            ; drive not ready
  275.          djnz cycw                ; try ntry times
  276.          call errcd
  277.          ret nz                   ; return anyway
  278.          jr cycw1
  279. flogin:                           ; login drive
  280.          push de                  ; contains dph location
  281.                  ; now carry out dummy op to get disk characteristics
  282.          call dsk                 ; check correct disk
  283.          call djhome              ; to track 0
  284.          ld c,1
  285.          call djsec               ; sector 1
  286.          ld c,0
  287.          call djside              ; side 0
  288.          ld c,2
  289.          call djtrk               ; track 2
  290.          call djprep              ; dummy disk op
  291.          call djleav
  292.          jr nc,contin             ; jump if successful
  293.          pop hl
  294.          ld d,h                   ; so we can jump to flogin
  295.          ld e,l
  296.          dec hl
  297.          ld (hl),0                ; to indicate login failed
  298.          bit 7,a
  299.          jr nz,nr1                ; jump if not ready
  300.          push de                  ; keep de
  301.          call errcd
  302.          pop de
  303.          ret nz                   ; return anyway
  304.          jr flogin
  305. nr1:     push de                  ; keep de
  306.          call notred
  307.          pop de
  308.          jr flogin
  309.  
  310. contin:  call djstat              ; get disk characteristics
  311.          or 10h                   ; set bit 4
  312.          pop hl                   ; get dph location
  313.          ld d,h                   ; copy it to de
  314.          ld e,l
  315.          dec hl                   ; points to disk format
  316.          ld (hl),a                ; store disk characteristics
  317.          rrca                     ; move right 
  318.          and 16h                  ; 2 * sec.lng.code + 16 * side.code
  319.          ld hl,dskdef             ; get table of disk table addresses
  320.          ld b,0
  321.          ld c,a
  322.          add hl,bc                ; hl points to address of skew table
  323.          ldi                      ; copy two bytes
  324.          ldi
  325.          ld bc,6
  326.          add hl,bc                ; address of pointer to dpb
  327.          ld bc,10
  328.          ex de,hl
  329.          add hl,bc                ; pointer to dpb in dph
  330.          ex de,hl
  331.          ldi                      ; copy two bytes
  332.          ldi
  333.          ret 
  334.  
  335.               ; handle errors
  336. notred:                           ; drive not ready
  337.          push bc
  338.          call clear
  339.          ld hl,x0
  340.          call ?pmsg
  341.          call ?conin              ; wait for keyboard entry
  342.          pop bc
  343.          ret
  344. err1:    call ?pderr
  345.          ld hl,x1
  346.          call ?pmsg
  347.          jp ?wboot
  348. err2:    call ?pderr
  349.          ld hl,x11
  350.          call ?pmsg
  351.          jp ?wboot
  352. err3:                             ; check for disk change
  353.          call djstat              ; get actual disk format
  354.          or 10h                   ; set bit 4
  355.          ld hl,fmt
  356.          cp (hl)                  ; compare with recorded format
  357.          jr z,err1                ; no disk change detected
  358.          ld a,0ffh                ; disk change code
  359.          pop hl                   ; adjust stack
  360.          ret                      ; return
  361.  
  362. errcd:   bit 6,a
  363.          jr nz,wrpr               ; write protected disk
  364.          bit 4,a
  365.          jr nz,err3               ; invalid record/sector
  366.          ld a,1                   ; error code
  367.          ld (ecx),a
  368.          ld a,(@ermde)            ; error mode
  369.          inc a                    ; zero if @ermde=0ffh
  370.          jr z,herror              ; if error messages are not being written
  371.          call ?pderr              ; bios error message
  372.          call clear
  373.          ld hl,x2
  374.          call ?pmsg               ; ask whether to try again
  375.          call yesno
  376.          ret z                    ; try again
  377. ec1:     ld hl,x21
  378.          call ?pmsg               ; ask whether to return to cpm
  379.          call yesno
  380.          jp z,?wboot              ; return to cpm
  381.          ld hl,x22
  382.          call ?pmsg               ; ask whether to return error code
  383.          call yesno
  384.          push af                  ; keep flag
  385.          ld hl,x23
  386.          call ?pmsg
  387.          pop af
  388.          jr z,herror
  389.          ld a,0                   ; if no: clear error code, leave nz flag
  390.          ret
  391.  
  392. wrpr:    ld a,2                   ; error return code
  393.          ld (ecx),a               ; store in ecx
  394.          ld a,(@ermde)            ; error mode
  395.          inc a                    ; zero if @ermde=0ffh
  396.          jr z,herror              ; if error messages are not being written
  397.          call ?pderr              ; bios error message
  398.          call clear
  399.          ld hl,x24
  400.          call ?pmsg
  401.          jr ec1
  402.  
  403. nologi:  call ?pderr
  404.          ld hl,x3
  405.          call ?pmsg
  406.          jp ?wboot
  407.  
  408. herror:  ld a,(ecx)
  409.          and a                    ; to set flags
  410.          ret
  411.  
  412. ecx:     ds 1                     ; code for error location
  413.  
  414. x0:      db cr,lf,'close drive <ret>',cr,lf,0
  415. x1:      db cr,lf,'invalid sector/record',cr,lf,0
  416. x11:     db cr,lf,'illegal dma',cr,lf,0
  417. x2:      db cr,lf,'parity error - try again (y/n)?',0
  418. x21:     db cr,lf,'   - return to cpm (y/n)?',0
  419. x22:     db ' - return error code (y/n)?',0
  420. x23:     db ' - continuing',cr,lf,0
  421. x24:     db cr,lf,'write protected disk',0
  422. x3:      db cr,lf,'drive not logged in',cr,lf,0
  423.  
  424.                      if check   ; debugging messages
  425.  
  426. xcrlf:   db cr,lf,0
  427. xr:      db 'read ',0
  428. xw:      db 'write ',0
  429. xtrk:    db '  trk ',0
  430. xsect:   db '  sect ',0
  431. xdma:    db '  dma ',0
  432.                      if banked
  433. xcbnk:   db '  cbnk ',0
  434. xdbnk:   db '  dbnk ',0
  435.                      endif
  436.  
  437. record:  push de
  438.          push hl
  439.          ld hl,xcrlf
  440.          call ?pmsg
  441.          pop hl
  442.          call ?pmsg
  443.          ld hl,xtrk
  444.          call ?pmsg
  445.          ld hl,(@trk)
  446.          call ?pdec
  447.          ld hl,xsect
  448.          call ?pmsg
  449.          ld hl,(@sect)
  450.          call ?pdec
  451.          ld hl,xdma
  452.          call ?pmsg
  453.          ld hl,(@dma)
  454.          call ?pdec
  455.                      if banked
  456.          ld hl,xcbnk
  457.          call ?pmsg
  458.          ld hl,(@cbnk)
  459.          ld h,0
  460.          call ?pdec
  461.          ld hl,xdbnk
  462.          call ?pmsg
  463.          ld hl,(@dbnk)
  464.          ld h,0
  465.          call ?pdec
  466.                      endif
  467.          ld hl,xcrlf
  468.          call ?pmsg
  469.          pop de
  470.          ret
  471.                      endif
  472.  
  473.          end
  474. p 'N'
  475.          jr z,yesno1
  476.          jr yesno                 ; cycle if not y,Y,n