]> cloudbase.mooo.com Git - z180-stamp-cpm3.git/commitdiff
Add new driver: cfio
authorLeo C <erbl259-lmu@yahoo.de>
Thu, 19 May 2016 23:37:07 +0000 (01:37 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Sat, 21 May 2016 20:58:04 +0000 (22:58 +0200)
cbios/Makefile
cbios/cfio.180 [new file with mode: 0644]
cbios/config.inc
cbios/cpm3slr.lib
cbios/drvtbl.180
cbios/gencpm.dat

index 39a747a42e874399214860699f4be52247c05f38..f6bad229673d2bfc93a06be5e38af06aa946e03e 100644 (file)
@@ -2,7 +2,7 @@
 
 SRC := bioskrnl.180 boot.180 chario.180 drvtbl.180
 SRC += move.180 time.180 mm.180 misc.180 utils.180
-SRC += msgbuf.180 conbuf.180 ascip.180 sdio.180
+SRC += msgbuf.180 conbuf.180 ascip.180 sdio.180 cfio.180
 SRC += scb.180
 
 INC := config.inc z180reg.inc z180.lib
diff --git a/cbios/cfio.180 b/cbios/cfio.180
new file mode 100644 (file)
index 0000000..a76c9bd
--- /dev/null
@@ -0,0 +1,787 @@
+       TITLE 'compactflash disk handler'\r
+\r
+;    CP/M-80 Version 3     --  Modular BIOS\r
+\r
+\r
+    ; Disk drive dispatching tables for linked BIOS\r
+\r
+       public cf0,cf1,cf2,cf3\r
+\r
+    ; Variables containing parameters passed by BDOS\r
+\r
+       extrn @xdph\r
+       extrn @adrv,@rdrv\r
+       extrn @trk,@sect,@cnt\r
+       extrn @dma,@dbnk,@cbnk\r
+\r
+    ; System Control Block variables\r
+\r
+       extrn @ermde            ; BDOS error mode\r
+\r
+    ; Utility routines in standard BIOS\r
+\r
+       extrn ?wboot            ; warm boot vector\r
+       extrn ?pmsg,pr.inln     ; print message @<HL>, print inline message\r
+       extrn pr.crlf           ; print <cr><lf>\r
+       extrn phex2\r
+       extrn pr.decl\r
+       extrn ?pderr            ; print BIOS disk error header\r
+       extrn ?conin,?cono      ; con in and out\r
+       extrn ?const            ; get console status\r
+       extrn ?bnksl\r
+\r
+       extrn bnk2phy           ;\r
+       extrn add_hla\r
+\r
+\r
+    ; Port Address Equates\r
+\r
+       include config.inc\r
+       include z180reg.inc\r
+\r
+    ; CP/M 3 Disk definition macros\r
+\r
+       maclib cpm3slr.lib\r
+\r
+    ; Z180 macro library instruction definitions (ignored by slr180)\r
+\r
+       include z180.lib\r
+\r
+DEBUG  equ     false           ; not used\r
+MULTIIO        equ     true            ; Multi I/O currently not fully implemented.\r
+\r
+    ; IDE Task File Register Definitions\r
+\r
+;IdeDOR        equ     IDEBASE+6       ; Digital Output Register\r
+IDEDat equ     IDEBASE+0       ; Data Register\r
+IDEErr equ     IDEBASE+1       ; Error Register\r
+IDEFeat        equ     IDEBASE+1       ; Feature Register\r
+IDESCnt        equ     IDEBASE+2       ; Sector Count\r
+IDESNum        equ     IDEBASE+3       ; Sector Number\r
+IDECLo equ     IDEBASE+4       ; Cylinder Low\r
+IDECHi equ     IDEBASE+5       ; Cylinder High\r
+IDESDH equ     IDEBASE+6       ; Drive and Head\r
+IDECmd equ     IDEBASE+7       ; Command / Status\r
+\r
+    ; IDE Hard disk commands:\r
+\r
+CmdHome        equ     10h             ; Recalibrate\r
+CmdRd  equ     20h             ; Read Sector\r
+CmdWr  equ     30h             ; Write Sector\r
+CmdInit        equ     91h             ; Initialize Drive Params\r
+CmdId  equ     0ECh            ; Read ID\r
+CmdSF  equ     0EFh            ; Set Feature\r
+\r
+    ; Partition Table Structures\r
+\r
+PART_TYPE      equ     4\r
+PART_START     equ     8\r
+PART_SIZE      equ     12\r
+\r
+    ; Partition table id\r
+    ; (see http://www.win.tue.nl/~aeb/partitions/partition_types-1.html)\r
+\r
+PARTID1_FAT16  equ     00EH\r
+PARTID2_FAT16  equ     006H\r
+PARTID_CPM     equ     052H\r
+\r
+MAXDISKS       equ     4\r
+\r
+; parttabl fields\r
+PTAB_TYPE      equ     0       ; 1 byte\r
+PTAB_START     equ     1       ; 4 byte (28 bit, max 128 GiB)\r
+PTAB_SIZE      equ     5       ; 4 byte (3 needed, 20 bit, max 512 MiB)\r
+PTAB_SPT       equ     9       ; 1 byte\r
+PTAB_BSH       equ     10      ; 1 byte\r
+\r
+PARTENTRY_SIZE equ     11\r
+\r
+\r
+    ; common control characters\r
+\r
+cr     equ     13\r
+lf     equ     10\r
+bell   equ     7\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+    ; Macro: wait while device is busy\r
+\r
+WAITNOTBUSY    macro\r
+       local   wait\r
+wait:  in      a,(IdeCmd)\r
+       rla\r
+       jr      c,wait\r
+       endm\r
+\r
+    ; Macro: wait while device is busy\r
+\r
+WAITREADY      macro\r
+       local   wait\r
+wait:  in      a,(IdeCmd)\r
+       xor     01000000b\r
+       and     11000000b\r
+       jr      nz,wait\r
+       endm\r
+\r
+    ; Macro: wait for DRQ signal\r
+\r
+WAITDRQ        macro\r
+       local   wait\r
+wait:  in      a,(IdeCmd)\r
+       bit     3,a\r
+       jr      z,wait\r
+       endm\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+       dseg\r
+\r
+    ; Extended Disk Parameter Headers (XPDHs)\r
+\r
+       ; dph   translate$table,        - disk parameter header\r
+       ;       disk$parameter$block,\r
+       ;       checksum$size,                  (optional)\r
+       ;       alloc$size                      (optional)\r
+\r
+       dw      cf$write\r
+       dw      cf$read\r
+       dw      cf$login\r
+       dw      cf$init0\r
+       db      0,0             ; relative drive zero\r
+cf0:   dph 0,dpbsimhd512,0\r
+\r
+       dw      cf$write\r
+       dw      cf$read\r
+       dw      cf$login\r
+       dw      cf$init1\r
+       db      1,0             ; relative drive one\r
+cf1:   dph 0,dpbsimhd512,0\r
+\r
+       dw      cf$write\r
+       dw      cf$read\r
+       dw      cf$login\r
+       dw      cf$init2\r
+       db      2,0             ; relative drive zero\r
+cf2:   dph 0,dpbsimhd512,0\r
+\r
+       dw      cf$write\r
+       dw      cf$read\r
+       dw      cf$login\r
+       dw      cf$init3\r
+       db      3,0             ; relative drive one\r
+cf3:   dph 0,dpbsimhd512,0\r
+\r
+       cseg                    ; DPB must be resident\r
+\r
+       ; dpb   physical$sector$size,   - disk parameter block\r
+       ;       physical$sectors$per$track,\r
+       ;       number$tracks,\r
+       ;       block$size,\r
+       ;       number$dir$entries,\r
+       ;       track$offset,\r
+       ;       checksum$vec$size               (optional)\r
+\r
+dpbsimhd512:\r
+       dpb 512,8,2048,4096,1024,6,8000h\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+       dseg                    ; rest is banked\r
+\r
+; Disk I/O routines for standardized BIOS interface\r
+\r
+; Initialization entry point.\r
+; called for first time initialization.\r
+\r
+cf$init0:\r
+       call    pr.inln                 ;\r
+       db      'cfio: CompactFlash Memory Card driver'cr,lf,0\r
+\r
+       ld      hl,parttbl              ; Clear partition table\r
+       ld      b,PARTENTRY_SIZE*MAXDISKS\r
+ini_clrtbl:\r
+       ld      (hl),0\r
+       inc     hl\r
+       djnz    ini_clrtbl\r
+\r
+       call    cf_init                 ; init ide interface / cf card\r
+       jr      nz,pend\r
+\r
+       call    ident_read              ; identify drive\r
+       jr      nz,pend\r
+\r
+       call    prnt_info               ; print device information\r
+       call    ptab_read               ; read the partition table\r
+\r
+       ld      c,0                     ; number of found disks (paritions)\r
+       jr      nz,pend\r
+\r
+       ld      hl,tmpsecbuf+512-1      ; Point to  first byte of partition table\r
+       ld      a,(hl)                  ; Test, if it has a valid MBR\r
+       cp      0AAH                    ;\r
+       jr      nz,pend                 ;\r
+       dec     hl\r
+       ld      a,(hl)                  ;\r
+       cp      055H                    ;\r
+       jr      nz,pend                 ;\r
+\r
+    ; Search for valid Partitions\r
+\r
+       ld      hl,tmpsecbuf+512-2-64+PART_TYPE ; Point to  partition type of first first partition table entry\r
+       ld      de,parttbl              ;\r
+       ld      b,4                     ; Max # of partition table entries\r
+ploop:\r
+       ld      a,(hl)                  ; Get Partitiontype\r
+       cp      PARTID_CPM              ; Test for CP/M Partition\r
+       ld      a,16                    ; Offset to next entry\r
+       jr      nz,nextp\r
+       push    bc\r
+       ld      a,(hl)                  ; (Re)get Partitiontype\r
+       ld      (de),a                  ; Save paritition type\r
+       inc     de\r
+       inc     hl                      ; Point to partition start (lba)\r
+       inc     hl\r
+       inc     hl\r
+       inc     hl\r
+       ld      bc,8                    ; Copy partition start and size\r
+       ldir\r
+       rept    PARTENTRY_SIZE-8-1\r
+        inc    de\r
+       endm\r
+       pop     bc\r
+       inc     c                       ; One more found\r
+       ld      a,c\r
+       cp      MAXDISKS\r
+       jr      z,pend\r
+       ld      a,4\r
+nextp:\r
+       call    add_hla\r
+       djnz    ploop\r
+pend:\r
+       ;TODO: variable disk format: sectors per track, ...\r
+\r
+       call    prnt_ptab               ; Print partition table info\r
+       ret\r
+\r
+\r
+cf$init1:\r
+cf$init2:\r
+cf$init3:\r
+       ret     ; all initialization done by drive 0\r
+\r
+; Read ID from Hard Disk\r
+\r
+ident_read:\r
+       WAITREADY\r
+       ld      a,0E0h          ; assume unit 0,\r
+       out     (IdeSDH),a      ;\r
+       ld      a,CmdId\r
+       out     (IdeCmd),a      ; command: read sector data\r
+       ld      hl,tmpsecbuf\r
+       ld      bc,IdeDat       ; B = 0 (counter), C = I/O address\r
+       WAITDRQ                 ; wait for DRQ to become active\r
+       inir\r
+       inir                    ; read 512 data bytes (2 x 256)\r
+       WAITNOTBUSY\r
+       in      a,(IdeCmd)      ; check final drive status\r
+       and     10001001b       ; Busy, DRQ, or Error?\r
+       ret     z               ; no: everything is ok\r
+       ld      a,1             ; return with A=1 on error\r
+       ret\r
+\r
+\r
+; Read partition table\r
+\r
+ptab_read:\r
+       WAITREADY\r
+       ld      a,0E0h          ; assume unit 0, lba mode\r
+       out     (IdeSDH),a      ;\r
+       xor     a               ; sector 0 (lba)\r
+       out     (IdeSNum),a     ;\r
+       out     (IdeCLo),a\r
+       out     (IdeCHi),a      ;\r
+       inc     a               ; one sector to read\r
+       out     (IdeSCnt),a     ; set sector count\r
+\r
+       ld      a,CmdRd\r
+       out     (IdeCmd),a      ; command: read sector data\r
+       ld      hl,tmpsecbuf\r
+       ld      bc,IdeDat       ; B = 0 (counter), C = I/O address\r
+       WAITDRQ                 ; wait for DRQ to become active\r
+       inir\r
+       inir                    ; read 512 data bytes (2 x 256)\r
+       WAITNOTBUSY\r
+       in      a,(IdeCmd)      ; check final drive status\r
+       and     10001001b       ; Busy, DRQ, or Error?\r
+       ret     z               ; no: everything is ok\r
+       ld      a,1             ; return with A=1 on error\r
+       ret\r
+\r
+cf_init:\r
+       WAITREADY\r
+       ld      a,0E0h          ; assume unit 0, lba mode\r
+       out     (IdeSDH),a      ;\r
+       ld      a,1             ; Enable 8-bit data transfer.\r
+       out     (IDEFeat),a\r
+       ld      a,CmdSF\r
+       out     (IdeCmd),a      ; command: read sector data\r
+       WAITNOTBUSY\r
+       in      a,(IdeCmd)      ; check final drive status\r
+       and     10001001b       ; Busy, DRQ, or Error?\r
+       ret     z               ; no: everything is ok\r
+       ld      a,1             ; return with A=1 on error\r
+       ret\r
+\r
+\r
+pr_char_nlbl:\r
+       bit     0,b\r
+       jr      z,pr_char\r
+       cp      ' '\r
+       ret     z\r
+       res     0,b\r
+       ; fall thru\r
+pr_char:\r
+       push    hl\r
+       push    de\r
+       push    bc\r
+       ld      c,a\r
+       call    ?cono\r
+       pop     bc\r
+       pop     de\r
+       pop     hl\r
+       ret\r
+\r
+; Print an id string\r
+; Remove leading and trailing spaces\r
+\r
+pr_id:\r
+       push    hl              ; Save string address\r
+       ld      b,0\r
+       add     hl,bc\r
+       dec     hl              ; Point to last char.\r
+       ld      a,' '\r
+prn_el:                                ; Reduce string len by number of trailing spaces\r
+       dec     hl\r
+       cpi\r
+       jr      nz,prn_el1      ; No more spaces\r
+       jp      po,prn_el2      ; No more characters\r
+       cpd\r
+       dec     hl\r
+       jr      nz,prn_el1\r
+       jp      po,prn_el2\r
+       jr      prn_el\r
+prn_el1:\r
+       inc     c\r
+prn_el2:\r
+       pop     hl              ; Restore beginning of string\r
+       ld      a,c\r
+       or      a               ; Test number of remaining chars\r
+       ret     z               ; Done, if string was spaces only\r
+\r
+       ld      b,1             ; Flag, skip spaces\r
+prn_lp:\r
+       inc     hl              ;Text is low byte high byte format\r
+       ld      a,(hl)\r
+       call    pr_char_nlbl\r
+       dec     c\r
+       ret     z\r
+       dec     hl\r
+prn_lp1:\r
+       ld      a,(hl)\r
+       call    pr_char_nlbl\r
+       dec     c\r
+       ret     z\r
+       inc     hl\r
+       inc     hl\r
+       jr      prn_lp\r
+\r
+; Print divice information\r
+\r
+prnt_info:\r
+       call    pr.inln\r
+       db      '    Model: ',0\r
+       ld      hl,tmpsecbuf + 27*2     ; Model number\r
+       ld      c,20*2                  ; max character count\r
+       call    pr_id                   ;\r
+       call    pr.inln\r
+       db      ', S/N: ',0\r
+       ld      hl,tmpsecbuf + 10*2     ; Serial number\r
+       ld      c, 10*2\r
+       call    pr_id\r
+       call    pr.inln\r
+       db      ', Rev: ',0\r
+       ld      hl,tmpsecbuf + 23*2     ; Firmware revision\r
+       ld      c, 4*2\r
+       call    pr_id\r
+\r
+       call    pr.inln\r
+       db      cr,lf,'    Size: ',0\r
+       ld      hl,(tmpsecbuf+60*2)     ;Total Sectors Addressable in LBA Mode\r
+       ld      de,(tmpsecbuf+61*2)     ;\r
+       push    hl\r
+       push    de\r
+       ld      bc,1\r
+       call    pr.decl\r
+       call    pr.inln\r
+       db      ' Sectors (',0\r
+       pop     de\r
+       pop     hl\r
+       srl     d\r
+       rr      e\r
+       rr      h\r
+       rr      l\r
+       ld      bc,1\r
+       call    pr.decl\r
+       call    pr.inln\r
+       db      ' KiB)',cr,lf,0\r
+       ret\r
+\r
+; Print partition table info\r
+\r
+prnt_ptab:\r
+       ld      ix,parttbl\r
+       ld      c,0\r
+prp_lp:\r
+       ld      a,c\r
+       cp      4\r
+       ret     z\r
+       ld      a,(ix+PTAB_TYPE)\r
+       or      a\r
+       ret     z\r
+\r
+       push    bc\r
+       call    pr.inln\r
+       db      '    ',0\r
+       ld      a,(@adrv)\r
+       add     a,c\r
+       add     a,'A'\r
+       call    pr_char\r
+       call    pr.inln\r
+       db      ': CP/M partition at: ',0\r
+       ld      l,(ix+PTAB_START+0)\r
+       ld      h,(ix+PTAB_START+1)\r
+       ld      e,(ix+PTAB_START+2)\r
+       ld      d,(ix+PTAB_START+3)\r
+       ld      bc,1\r
+       call    pr.decl\r
+       call    pr.inln\r
+       db      ', size: ',0\r
+       ld      l,(ix+PTAB_SIZE+0)\r
+       ld      h,(ix+PTAB_SIZE+1)\r
+       ld      e,(ix+PTAB_SIZE+2)\r
+       ld      d,(ix+PTAB_SIZE+3)\r
+       srl     d\r
+       rr      e\r
+       rr      h\r
+       rr      l\r
+       ld      bc,1\r
+       call    pr.decl\r
+       call    pr.inln\r
+       db      'KiB',cr,lf,0\r
+       ld      bc,PARTENTRY_SIZE\r
+       add     ix,bc\r
+       pop     bc\r
+       inc     c\r
+       jr      prp_lp\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+; This entry is called when a logical drive is about to\r
+; be logged into for the purpose of density determination.\r
+; It may adjust the parameters contained in the disk\r
+; parameter header pointed at by <DE>\r
+;\r
+;     absolute drive number in @adrv (8 bits)  +0\r
+;     relative drive number in @rdrv (8 bits)  +1\r
+\r
+cf$login:\r
+       xor     a\r
+       ld      (residual),a    ; just in case\r
+\r
+       ld      hl,parttbl\r
+       ld      a,(@rdrv)\r
+       ld      e,a\r
+       ld      d,PARTENTRY_SIZE\r
+       mlt     de\r
+       add     hl,de\r
+       ld      a,(hl)\r
+       or      a\r
+       ret     nz\r
+       ld      hl,0\r
+       ld      (@xdph),hl\r
+       ret                     ;\r
+\r
+; disk READ and WRITE entry points.\r
+; these entries are called with the following arguments:\r
+;\r
+;     absolute drive number in @adrv (8 bits)  +0\r
+;     relative drive number in @rdrv (8 bits)  +1\r
+;     disk track address    in @trk (16 bits)  +2\r
+;     disk sector address   in @sect(16 bits)  +4\r
+;     multi sector count    in @cnt  (8 bits)  +6\r
+;     disk transfer address in @dma (16 bits)  +7\r
+;     disk transfer bank    in @dbnk (8 bits)  +9\r
+;     pointer to XDPH      in <DE>\r
+;\r
+;     they transfer the appropriate data, perform retries\r
+;     if necessary, then return an error code in <A>\r
+\r
+cf$read:\r
+       ld      de,read$msg             ; point at " Read "\r
+       ld      bc,M_DIM1*256 + CmdRd   ; Transfermode: i/o to memory++\r
+       jr      rw$common\r
+cf$write:\r
+       ld      de,write$msg            ; point at " Write "\r
+       ld      bc,0*256 + CmdWr        ; Transfermode: memory++ to i/o\r
+rw$common:\r
+\r
+   if MULTIIO\r
+       ld      hl,residual     ; remainng sectors from last multi io?\r
+       ld      a,(hl)\r
+       sub     a,1\r
+       jr      c,rwc_new_sectors\r
+\r
+       ld      (hl),a\r
+       xor     a\r
+       ret\r
+   endif\r
+\r
+rwc_new_sectors:\r
+       ld      (operation$name),de ; save message for errors\r
+       in0     a,(dcntl)\r
+       and     a,~(M_DMS1+M_DIM1+M_DIM0)\r
+       or      b\r
+       out0    (dcntl),a\r
+\r
+       ld      b,1             ; assume 1 sector to transfer\r
+   if MULTIIO\r
+       ld      a,(@cnt)\r
+       or      a\r
+       jr      z,rwc_doit\r
+\r
+       ld      b,a             ; number of sectors to transfer\r
+       dec     a               ; save remaining\r
+       ld      (hl),a\r
+       xor     a               ; reset multi sector count\r
+       ld      (@cnt),a\r
+rwc_doit:\r
+   endif\r
+\r
+       ld      iy,parttbl\r
+       ld      a,(@rdrv)\r
+       ld      e,a\r
+       ld      d,PARTENTRY_SIZE\r
+       mlt     de\r
+       add     iy,de\r
+\r
+retry:\r
+       ld      a,b\r
+       out     (IdeSCnt),a     ; set sector count\r
+\r
+; compute logical block number (lba) --> cf-controller\r
+\r
+       ; TODO: sectors per track from dpb\r
+       ; lba = track * 8 + sector\r
+\r
+       xor     a\r
+       ld      hl,(@trk)\r
+       add     hl,hl\r
+       adc     a,a             ; *2\r
+       add     hl,hl\r
+       adc     a,a             ; *4\r
+       add     hl,hl\r
+       adc     a,a             ; *8\r
+       ld      de,(@sect)\r
+       add     hl,de\r
+       adc     a,0\r
+\r
+       push    hl              ; check, if block# fits in partition\r
+       ld      e,(iy+PTAB_SIZE+0)\r
+       ld      d,(iy+PTAB_SIZE+1)\r
+       sbc     hl,de\r
+       ld      l,a\r
+       sbc     a,(iy+PTAB_SIZE+2)\r
+       ld      a,l\r
+       pop     hl\r
+       jr      c,lba_ok\r
+       ld      a,1             ; block# >= partition size, return error\r
+       ret\r
+\r
+lba_ok:\r
+       WAITREADY\r
+       ld      e,a             ; add partition start\r
+       ld      a,(iy+PTAB_START+0)\r
+       add     a,l\r
+       out     (IdeSNum),a\r
+       ld      a,(iy+PTAB_START+1)\r
+       adc     a,h\r
+       out     (IdeCLo),a\r
+       ld      a,(iy+PTAB_START+2)\r
+       adc     a,e\r
+       out     (IdeCHi),a\r
+       ld      a,(iy+PTAB_START+3)\r
+       adc     a,0\r
+       and     00FH\r
+       or      0E0H\r
+       out     (IdeSDH),a\r
+\r
+       ld      hl,(@dma)\r
+       ld      a,(@dbnk)\r
+\r
+; compute pysical transfer address --> DMA\r
+\r
+       call    bnk2phy         ; phys. linear address\r
+       out0    mar1l,l\r
+       out0    mar1h,h\r
+       out0    mar1b,a\r
+       ld      a,IdeDat\r
+       out0    iar1l,a\r
+       xor     a\r
+       out0    iar1h,a\r
+       out0    iar1b,a\r
+       out0    bcr1l,a\r
+       ld      a,c\r
+       out     (IDECmd),a\r
+       push    bc\r
+nxt_sec:\r
+       ld      a,2\r
+       out0    bcr1h,a\r
+       WAITDRQ\r
+       ld      a,M_DE1+M_NDWE0\r
+       out0    (dstat),a\r
+wait_dma:\r
+       in0     a,(dstat)\r
+       bit     DE1,A\r
+       jr      nz,wait_dma\r
+\r
+       WAITNOTBUSY\r
+       in      a,(IdeCmd)      ; check final drive status\r
+       bit     0,a             ; any error?\r
+       jr      nz,err_out\r
+       djnz    nxt_sec\r
+err_out:\r
+       pop     bc\r
+       ld      e,a\r
+       and     10001001b       ; Busy, DRQ, or Error?\r
+       ret     z               ; Return to BDOS if no error\r
+\r
+; suppress error message if BDOS is returning errors to application...\r
+\r
+       ld      a,(@ermde)\r
+       cp      0ffh\r
+       jr      z,hard$error\r
+\r
+       ; Had permanent error, print message like:\r
+       ; BIOS Err on d: T-nn, S-mm, <operation> <type>, Retry ?\r
+\r
+       call    ?pderr          ; print message header\r
+\r
+       ld      hl,(operation$name)\r
+       call    ?pmsg           ; last function (read or write)\r
+\r
+       ld      hl,msg$drq\r
+       bit     3,e\r
+       call    nz,?pmsg\r
+\r
+       bit     0,e\r
+       jr      z,prompt\r
+\r
+       in      a,(IDEErr)\r
+       ld      hl,error$table  ; point at table of message addresses\r
+errm1:\r
+       ld      e,(hl)\r
+       inc     hl\r
+       ld      d,(hl)\r
+       inc     hl              ; get next message address\r
+       add     a,a\r
+       push    af              ; shift left and push residual bits with status\r
+       ex      de,hl\r
+       call    c,?pmsg\r
+       ex      de,hl           ; print message, saving table pointer\r
+       pop     af\r
+       jr      nz,errm1        ; if any more bits left, continue\r
+\r
+prompt:\r
+       call    pr.inln\r
+       db      ' Retry (Y/N) ? ',0\r
+\r
+       call    u$conin$echo    ; get operator response\r
+       cp      'Y'\r
+       jp      z,retry         ; Yes, then retry\r
+\r
+hard$error:\r
+                               ; otherwise,\r
+       xor     a\r
+       ld      (residual),a\r
+\r
+       ld      a,1             ; return hard error to BDOS\r
+       ret\r
+\r
+cancel:                                ; here to abort job\r
+       jp      ?wboot          ; leap directly to warmstart vector\r
+\r
+\r
+; get console input, echo it, and shift to upper case\r
+\r
+u$conin$echo:\r
+       push    bc\r
+u$c0:\r
+       call    ?const\r
+       or      a\r
+       jr      z,u$c1          ; see if any char already struck\r
+       call    ?conin\r
+       jr      u$c0            ; yes, eat it and try again\r
+u$c1:\r
+       call    ?conin\r
+       push    af\r
+       ld      c,a\r
+       cp      ' '-1\r
+       call    nc,?cono\r
+       pop     af\r
+       pop     bc\r
+       cp      'a'\r
+       ret     c\r
+       sub     'a'-'A'         ; make upper case\r
+       ret\r
+\r
+    ; error message components\r
+\r
+operation$name:\r
+       dw      read$msg\r
+read$msg:\r
+       db      ', Read, ',0\r
+write$msg:\r
+       db      ', Write, ',0\r
+msg$drq:\r
+       db      'DRQ, ',0\r
+error$table:\r
+       dw      b7$msg\r
+       dw      b6$msg\r
+       dw      b5$msg\r
+       dw      b4$msg\r
+       dw      b3$msg\r
+       dw      b2$msg\r
+       dw      b1$msg\r
+       dw      b0$msg\r
+\r
+b7$msg:                db      ' Bad Block detected,',0\r
+b6$msg:                db      ' Uncorrectable Data Error,',0\r
+b5$msg:                db      ' Media Changed,',0\r
+b4$msg:                db      ' Sector ID Not Found,',0\r
+b3$msg:                db      ' Media Change Requst,',0\r
+b2$msg:                db      ' Aborted Command,',0\r
+b1$msg:                db      ' Track 0 Not Found,',0\r
+b0$msg:                db      ' AM Not Found (or general error),',0\r
+\r
+\r
+residual:\r
+       db      0\r
+\r
+parttbl:\r
+       ds      PARTENTRY_SIZE*MAXDISKS\r
+\r
+tmpsecbuf:             ;temporary sector buffer\r
+       ds      512\r
+\r
+       end\r
index 4421478fec378303972501fa13e56ec1b3c10299..bea6e05cd302ac06d0121ae98c256d77570e4109 100644 (file)
@@ -3,8 +3,6 @@ FALSE   equ     0
 TRUE   equ     NOT FALSE\r
 \r
 \r
-DEBUG  equ     true\r
-\r
 banked equ     true\r
 \r
 ;-----------------------------------------------------\r
@@ -159,6 +157,8 @@ AVRINT5             equ     4Fh
 AVRINT6                equ     5Fh\r
 ;PMSG          equ     80h\r
 \r
+IDEBASE                equ     60h\r
+\r
 ;-----------------------------------------------------\r
 ; Definition of (logical) top 2 memory pages\r
 \r
index 2414bf406457a32247efae4fdd550959051a2338..9d708af9c35b77befdc885fb73877a33625aad47 100644 (file)
@@ -49,10 +49,14 @@ dph macro ?trans,?dpb,?csize,?asize
        db 0                    ; media flag\r
        dw ?dpb                 ; disk parameter block\r
     if not nul ?csize\r
+      if ?csize = 0\r
+       dw 0                    ; permanently mounted, no checksum vector\r
+      else\r
        dw ?csv                 ; checksum vector\r
+      endif\r
     else\r
-       dw 0FFFEh               ; checksum vector allocated by\r
-    endif                      ; GENCPM\r
+       dw 0FFFEh               ; checksum vector alloc'd by GENCPM\r
+    endif\r
     if not nul ?asize\r
        dw ?alv                 ; allocation vector\r
     else\r
@@ -63,7 +67,9 @@ dph macro ?trans,?dpb,?csize,?asize
        db 0                    ; hash bank\r
 \r
     if not nul ?csize\r
+      if ?csize <> 0\r
 ?csv   ds      ?csize          ; checksum vector\r
+      endif\r
     endif\r
     if not nul ?asize\r
 ?alv   ds      ?asize          ; allocation vector\r
index 52590e7554313cfa8cba61e3c82eb51b2c73eb20..dc2d59ca9cd98836000d851de82c96d7dd7e51bf 100644 (file)
@@ -1,12 +1,13 @@
-        public @dtbl\r
-        extrn sd0,sd1,sd2,sd3\r
-        extrn sd4,sd5,sd6,sd7\r
-\r
-        cseg\r
-\r
-@dtbl   dw sd0,sd1,sd2,sd3      ; drives A-D\r
-        dw sd4,sd5,sd6,sd7      ; drives E-H\r
-        dw 0,0,0,0              ; drives I-L\r
-        dw 0,0,0,0              ; drives M-P\r
-\r
-        end\r
+       public @dtbl
+       extrn sd0,sd1,sd2,sd3
+        extrn sd4,sd5,sd6,sd7
+       extrn cf0,cf1,cf2,cf3
+
+        cseg
+
+@dtbl  dw sd0,sd1,sd2,sd3      ; drives A-D
+        dw sd4,sd5,sd6,sd7      ; drives E-H
+       dw cf0,cf1,cf2,cf3      ; drives I-L
+       dw 0,0,0,0              ; drives M-P
+
+        end
index bbd632bdbf1e5b22571310d16c62ee20dfd9f15a..605cd9186f5abff937ee94d7dbecb2fe65e05267 100644 (file)
@@ -9,9 +9,11 @@ BNKSWT   = Y
 COMBAS   = F0\r
 LERROR   = Y\r
 NUMSEGS  = 03\r
-MEMSEG00 = 50,4E,00\r
-MEMSEG01 = 10,E0,02\r
-MEMSEG02 = 01,EF,03\r
+==== BASE ====\r
+MEMSEG00 = 50,30,00\r
+MEMSEG01 = 10,B0,02\r
+MEMSEG02 = 01,BF,03\r
+==== BASE ====\r
 MEMSEG03 = 00,C0,04\r
 MEMSEG04 = 00,C0,05\r
 MEMSEG05 = 00,C0,06\r
@@ -49,10 +51,10 @@ ALTBNKSE = N
 ALTBNKSF = N\r
 ALTBNKSG = N\r
 ALTBNKSH = N\r
-ALTBNKSI = N\r
-ALTBNKSJ = N\r
-ALTBNKSK = N\r
-ALTBNKSL = N\r
+ALTBNKSI = Y\r
+ALTBNKSJ = Y\r
+ALTBNKSK = Y\r
+ALTBNKSL = Y\r
 ALTBNKSM = N\r
 ALTBNKSN = N\r
 ALTBNKSO = N\r
@@ -65,10 +67,10 @@ NDIRRECE = 00
 NDIRRECF = 00\r
 NDIRRECG = 00\r
 NDIRRECH = 00\r
-NDIRRECI = 01\r
-NDIRRECJ = 01\r
-NDIRRECK = 01\r
-NDIRRECL = 01\r
+NDIRRECI = 00\r
+NDIRRECJ = 00\r
+NDIRRECK = 00\r
+NDIRRECL = 00\r
 NDIRRECM = 01\r
 NDIRRECN = 01\r
 NDIRRECO = 01\r
@@ -81,10 +83,10 @@ NDTARECE = 00
 NDTARECF = 00\r
 NDTARECG = 00\r
 NDTARECH = 00\r
-NDTARECI = 01\r
-NDTARECJ = 01\r
-NDTARECK = 01\r
-NDTARECL = 01\r
+NDTARECI = 00\r
+NDTARECJ = 00\r
+NDTARECK = 00\r
+NDTARECL = 00\r
 NDTARECM = 01\r
 NDTARECN = 01\r
 NDTARECO = 01\r
@@ -98,9 +100,9 @@ ODIRDRVF = B
 ODIRDRVG = A\r
 ODIRDRVH = B\r
 ODIRDRVI = A\r
-ODIRDRVJ = A\r
+ODIRDRVJ = B\r
 ODIRDRVK = A\r
-ODIRDRVL = A\r
+ODIRDRVL = B\r
 ODIRDRVM = A\r
 ODIRDRVN = A\r
 ODIRDRVO = A\r
@@ -114,9 +116,9 @@ ODTADRVF = B
 ODTADRVG = A\r
 ODTADRVH = B\r
 ODTADRVI = A\r
-ODTADRVJ = A\r
+ODTADRVJ = B\r
 ODTADRVK = A\r
-ODTADRVL = A\r
+ODTADRVL = B\r
 ODTADRVM = A\r
 ODTADRVN = A\r
 ODTADRVO = A\r
@@ -155,4 +157,4 @@ OVLYDTAO = Y
 OVLYDTAP = Y\r
 CRDATAF  = N\r
 DBLALV   = Y\r
-\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a
\ No newline at end of file
+\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\r