]> cloudbase.mooo.com Git - avrcpm.git/blobdiff - avr/dsk_fsys.asm
* cpm/BIOS.MAC
[avrcpm.git] / avr / dsk_fsys.asm
index 228438f1df05468510002c14c1c5a64521027ced..4f9b226322ec1cf0e183ee77aba86d61cf51dd5a 100644 (file)
@@ -1,6 +1,7 @@
 ;    Filesystem functions for the Interaction with BIOS and Disks
 ;
 ;    Copyright (C) 2010 Frank Zoll
+;    Copyright (C) 2010,2011,2013 Leo C.
 ;
 ;    This file is part of avrcpm.
 ;
@@ -20,7 +21,6 @@
 ;    $Id$
 ;
 
-.equ DSKSEL_DEBUG = 0
 
 ; ---------------- Defines for the Filesystem Interface -------
 
        .equ    WRUAL = 2               ;write to unallocated
        .equ    WRTMSK= 3               ;write type mask
 
-       .equ    READ_FUNC  = 7
-       .equ    WRITE_FUNC = 6
-       .equ    BOOT_FUNC  = 5
-       .equ    HOME_FUNC  = 4
-
 ;----------------------------------------------- Start of Data Segment
 
        .dseg
 
+fsys_vars:
+
 ; The following 3 variables are copied from DRAM.
 ; Don't change order.
 
@@ -81,6 +78,7 @@ biosdirbuf:   .byte   2       ;
 biosenddat:    .byte   2       ;
 
 ndisks:                .byte   1               ;Number of CP/M disks
+       .equ o_ndisks   = ndisks-fsys_vars
 
 ; The following 5 variables are accessed from 8080/z80 via the
 ; virtual port interface. Don't change order.
@@ -91,20 +89,35 @@ seekdsk:    .byte   1               ;seek disk number
 seektrk:       .byte   2               ;seek track number
 seeksec:       .byte   2               ;seek sector number
 dmaadr:                .byte   2               ;last dma address
+       .equ o_bcbadr   = bcbadr-fsys_vars
+       .equ o_seekdsk  = seekdsk-fsys_vars
+       .equ o_seektrk  = seektrk-fsys_vars
+       .equ o_seeksec  = seeksec-fsys_vars
+       .equ o_dmaadr   = dmaadr-fsys_vars
 
 hdrsize:       .byte   1               ;Image header size (offset)
 cpmspt:                .byte   1               ;CP/M sectors per track
 secpblk:       .byte   1               ;sectors per block (alloc size)
 unacnt:                .byte   1               ;unalloc rec cnt
 unadsk:                .byte   1               ;last unalloc disk
-unatrk:                .byte   2               ;last unalloc track
-unasec:                .byte   2               ;last unalloc sector
+unalba:                .byte   2               ;last unalloc disk block
+       .equ o_hdrsize  = hdrsize-fsys_vars
+       .equ o_cpmspt   = cpmspt-fsys_vars
+       .equ o_secpblk  = secpblk-fsys_vars
+       .equ o_unacnt   = unacnt-fsys_vars
+       .equ o_unadsk   = unadsk-fsys_vars
+       .equ o_unalba   = unalba-fsys_vars
 
 erflag:                .byte   1               ;error reporting
 wrtype:                .byte   1               ;write operation type
+       .equ o_erflag   = erflag-fsys_vars
+       .equ o_wrtype   = wrtype-fsys_vars
 
 hostdsk:       .byte   1               ;host disk number
 hostlba:       .byte   2               ;host sector number (relative to partition start)
+       .equ o_hostdsk  = hostdsk-fsys_vars
+       .equ o_hostlba  = hostlba-fsys_vars
+
 hostparttbl:   .byte   PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
 hostparttbltop:
 hostbuf:       .byte   HOSTSIZE        ;host buffer (from/to SD-card)
@@ -125,15 +138,14 @@ dbg_prdrvtbl:
        push    temp
        printnewline
        printstring "drvtbl ("
-       lds     xl,biosdrvtbl
-       lds     xh,biosdrvtbl+1
+       ldsw    x,biosdrvtbl
        movw    temp,x
-       rcall   printhexw
+       lcall   printhexw
        printstring "): "
        ldi     temp3,16
 dbg_pcpel:
-       rcall   dram_readw_pp
-       rcall   printhexw
+       lcall   dram_readw_pp
+       lcall   printhexw
        printstring " "
        dec     temp3
        brne    dbg_pcpel
@@ -148,19 +160,19 @@ dbg_print_biosd:
        printnewline
        lds     temp,bcbadr
        lds     temp2,bcbadr+1
-       rcall   printhexw
+       lcall   printhexw
        printstring "  "
        lds     temp,biosdrvtbl
        lds     temp2,biosdrvtbl+1
-       rcall   printhexw
+       lcall   printhexw
        printstring "  "
        lds     temp,biosdirbuf
        lds     temp2,biosdirbuf+1
-       rcall   printhexw
+       lcall   printhexw
        printstring "  "
        lds     temp,biosenddat
        lds     temp2,biosenddat+1
-       rcall   printhexw
+       lcall   printhexw
        printstring "  "
        ret
 .endif
@@ -255,7 +267,7 @@ dskDiskCheck:
 .if    DSKSEL_DEBUG
        printnewline
        printstring "DiskCheck: "
-       rcall   printhexw
+       lcall   printhexw
 .endif
        cpi     temp,RAMDISKNR
        brsh    dsk_dchrd                       ;maybe ramdisk
@@ -299,7 +311,7 @@ dsk_dchpart1:
 .if    DSKSEL_DEBUG
        printnewline
        printstring "Select: "
-       rcall   printhex
+       lcall   printhex
 .endif
        rcall   dpb_drvtbl_entry_get
        or      temp,temp2              ;if !0, drive is allready initialized
@@ -315,7 +327,7 @@ dsk_dchend:
        rcall   dpb_drvtbl_entry_get
 
        printstring ", "
-       rcall   printhexw
+       lcall   printhexw
        pop     temp
 .endif 
 
@@ -350,6 +362,7 @@ dsk_dchrd_err:
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
+
 dskErrorRet:
        lds     temp,erflag
        ret
@@ -359,10 +372,6 @@ dskErrorRet:
 ; ====================================================================
 
 
-       .dseg
-tmpdpb:        .byte   16
-
-       .cseg
 
 str_CPM_Disk:
        .db     10,"<CPM_Disk>",0
@@ -422,34 +431,6 @@ dpbdat_simhd:                      ;
 #endif
 
 
-; Copy the dpb data from flash memory, pointed to by Z, to temp ram.
-
-dpb_copy_p:
-       push    yh
-       push    yl
-       ldi     temp2,16
-       ldiw    y,tmpdpb
-cpydpb_pl:
-       lpm     temp,z+
-       st      y+,temp
-       dec     temp2
-       brne    cpydpb_pl
-       pop     yl
-       pop     yh
-       ret
-
-; Copy the dpb data, pointed to by Z to temp ram.
-
-dpb_copy:      
-       st      y+,temp
-       ldi     temp2,15
-cpydpb_l:
-       ld      temp,z+
-       st      y+,temp
-       dec     temp2
-       brne    cpydpb_l
-       ret
-
 
 ; ====================================================================
 ; Function: get drive table entry pointer for drive # in temp
@@ -586,10 +567,10 @@ dsk_tst_yaze:
        lcall   strncmp_p
        brne    dsk_tyze_not
        
-       ldiw    z,hostbuf+32
-       ldiw    y,tmpdpb
+       ldiw    z,hostbuf+31
+       clt                             ;dpb in RAM
        ldi     temp,1                  ;1 sector header size
-       rcall   dpb_copy        
+       st      z,temp
 
        ori     temp,0xff
        ret
@@ -609,6 +590,7 @@ dsk_tyze_not:
 ; Description: Test, if first 2 Sectors are filled with 0xE5,
 ;              and Size = 8192KB + 256Bytes.
 ; ====================================================================
+
 dsk_tst_myz80:
 
        mov     zl,temp3
@@ -630,6 +612,8 @@ dsk_tmyz80_loop:
        dec     temp2
        brne    dsk_tmyz80_loop
 
+       ldiw    z,dpbdat_myz80*2
+       set
        ori     temp,0xff
        ret
 
@@ -650,6 +634,7 @@ dsk_tmyz80_not:
 ;              Actually, only the first phys. sector is tested, since 
 ;              the other 47 sectors are not in memory at this time.
 ; ====================================================================
+
 dsk_tst_simhd:
 
        mov     zl,temp3
@@ -674,12 +659,13 @@ dsk_tsimhd_loop:
        ld      temp,z+
        cpi     temp,0xE5
        brne    dsk_tsimhd_not
-       dec     _tmp0
-       brne    dsk_tsimhd_loop
-       dec     temp2
+       add     _tmp0,_255
+       adc     temp2,_255
        brne    dsk_tsimhd_loop
 
 dsk_tsimhd_found:
+       ldiw    z,dpbdat_simhd*2
+       set
        ori     temp,0xff
        ret
 
@@ -719,22 +705,19 @@ dsk_format_get:
 ; Test for simhd format.
 
        rcall   dsk_tst_simhd
-       ldiw    z,dpbdat_simhd*2
-       brne    dsk_imgt_fixed
+       brne    dsk_imgt_done
 
 ; Test for MyZ80 format.
 
        rcall   dsk_tst_myz80
-       ldiw    z,dpbdat_myz80*2
-       brne    dsk_imgt_fixed
+       brne    dsk_imgt_done
        
 ; No special image found. Use avrcpm.
 
        ldiw    z,dpbdat_avrcpm*2
-
-dsk_imgt_fixed:
-       rcall   dpb_copy_p
+       set
        ori     temp,0xff
+
 dsk_imgt_done:
        ret     
 
@@ -756,32 +739,27 @@ dpb_imgdata_get:
        rcall   dsk_format_get  
        breq    dpb_imgd_err            ;no known format detected
 
-;
+dpb_imgd_0:
+       brtc    dpb_imgd_variable
+dpb_imgd_fixed:
+       lpm     temp, z+                ;image header
+       lpm     yl,z+                   ;low(SPT)
+       lpm     yh,z+                   ;high(SPT)
+       lpm     temp2,z+                ;BSH
+       rjmp    dpb_imgd_common
+
+dpb_imgd_variable:
+       ld      temp, z+                ;image header
+       ld      yl,z+                   ;low(SPT)
+       ld      yh,z+                   ;high(SPT)
+       ld      temp2,z+                ;BSH
+
+dpb_imgd_common:
        mov     zl,temp3
        rcall   dsk_getpartentry        ;get partition entry
-       ldiw    y,tmpdpb
-       
-;      std     y+12,_0                 ;Test: set check size to 0
-;      std     y+13,_0
-       
-       ldd     temp,y+0
-       andi    temp,~dskType_MASK
-       ldd     temp2,z+PTAB_TYPE
-       andi    temp2,dskType_MASK
-       or      temp,temp2
-       std     z+PTAB_TYPE,temp
-       ldd     temp,y+1
-       std     z+PTAB_SPT,temp
-       ldd     temp,y+2
-       tst     temp                    ;more then 256 sectors per track?
-       brne    dsk_imgprp_err          ;todo: support 16 bit sector numbers
-       ldd     temp2,y+3
-       andi    temp2,0x0f
-       swap    temp2
-       std     z+PTAB_BSH,temp2
-       
-       ori     temp,255
-       ret
+       std     z+PTAB_SPT,yl
+       tst     yh                      ;more then 256 sectors per track?
+       breq    dpb_imgd_1              ;todo: support 16 bit sector numbers
 
 dsk_imgprp_err:
        printnewline
@@ -795,6 +773,20 @@ dpb_imgd_err:
        clr     temp
        ret
 
+dpb_imgd_1:
+       andi    temp2,0x0f
+       swap    temp2
+       std     z+PTAB_BSH,temp2
+       
+       andi    temp,~dskType_MASK
+       ldd     temp2,z+PTAB_TYPE
+       andi    temp2,dskType_MASK
+       or      temp,temp2
+       std     z+PTAB_TYPE,temp
+
+       ori     temp,255
+       ret
+
 ; ====================================================================
 ; Function: 
 ; ====================================================================
@@ -853,22 +845,43 @@ dpb_di_1:
        breq    dpb_di_err_p1
        movw    x,temp
        
-       ldiw    z,tmpdpb+1              ;skip sector offset byte
+       adiw    z,1                     ;skip sector offset byte
+       push    temp3
+       ldi     temp3,15
 dpb_dicpl:
-       ld      temp,z+
+       brtc    PC+2                    ;
+        lpm    temp,z+
+       brts    PC+2                    ;
+        ld     temp,z+
        rcall   dram_write_pp
-       cpi     zl,low(tmpdpb + 16)
+       dec     temp3
        brne    dpb_dicpl
+       pop     temp3
        sbiw    x,15
+       sbiw    z,15
        movw    temp,x
        movw    x,y
        adiw    x,10
        rcall   dram_writew_pp          ;DPB
-       
+
+       brtc    dpb_dicks_variable
+dpb_dicks_fixed:
+       adiw    z,5
+       lpm     _tmp0,z+                ;dsm
+       lpm     _tmp1,z+
+       adiw    z,11-5-2
+       lpm     temp,z+                 ;cks
+       lpm     temp2,z+
+       rjmp    dpb_dicks_common
+dpb_dicks_variable:
+       ldd     _tmp0,z+5               ;dsm
+       ldd     _tmp1,z+5+1
+       ldd     temp,z+11               ;cks
+       ldd     temp2,z+11+1
+
 ; get mem for dir check vector
 
-       lds     temp,tmpdpb+12          ;cks
-       lds     temp2,tmpdpb+12+1
+dpb_dicks_common:
        cp      temp,_0
        cpc     temp2,_0
        breq    dpb_dicks0
@@ -879,8 +892,7 @@ dpb_dicks0:
 
 ; get mem for alloc vector
 
-       lds     temp,tmpdpb+6           ;dsm
-       lds     temp2,tmpdpb+6+1
+       movw    temp,_tmp0
        subi    temp, low (-8)
        sbci    temp2,high(-8)
        lsr     temp2
@@ -922,12 +934,13 @@ dpb_di_err:
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
+
 dsk_setdrvparam:
        ldd     temp2,z+PTAB_TYPE
        andi    temp2,~dskType_MASK     ;Lower nibble is image header size
-       sts     hdrsize,temp2
+       std     y+o_hdrsize,temp2
        ldd     temp2,z+PTAB_SPT
-       sts     cpmspt,temp2
+       std     y+o_cpmspt,temp2                ;CP/M sectors per track
        ldd     temp2,z+PTAB_BSH
        swap    temp2
        andi    temp2,0x0f
@@ -937,7 +950,7 @@ dsk_sdrvpl:
        lsl     _tmp0
        dec     temp2
        brne    dsk_sdrvpl
-       sts     secpblk,_tmp0
+       std     y+o_secpblk,_tmp0               ;Sectors per block
        ret
        
 
@@ -946,58 +959,71 @@ dsk_sdrvpl:
 ; ====================================================================
 ; Parameters
 ; --------------------------------------------------------------------
-; Registers  : none
-; Variables  : [r] seeksec             Sector to read
-;              [r] seektrk             Track  to read
+; Registers  : 
+; Variables  : 
+;              
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
+
 dskDoIt:
+
+       ldiw    y,fsys_vars
+       std     y+o_erflag,_0
+
 .if DISK_DEBUG
        push    temp
+       sbrc    temp,HOME_FUNC
+       rjmp    dskdbghome
+       sbrc    temp,BOOT_FUNC
+       rjmp    dskdbgboot
+.if DISK_DEBUG > 1
        sbrc    temp,READ_FUNC
-       rjmp    dskdbgr
+       rjmp    dskdbgread
        sbrc    temp,WRITE_FUNC
-       rjmp    dskdbgw
+       rjmp    dskdbgwrite
+.endif
        rjmp    dskdbge
 
-dskdbgr:
+dskdbgread:
        printnewline
-       printstring "Disk read:  "
+       printstring "dsk RD: "
        rjmp    dskdbg1
-dskdbgw:
+dskdbgwrite:
        printnewline
-       printstring "Disk write: "
+       printstring "dsk WR: "
+       rjmp    dskdbg1
+dskdbghome:
+       printnewline
+       printstring "  HOME: "
+       rjmp    dskdbg1
+dskdbgboot:
+       printnewline
+       printstring "  BOOT: "
 dskdbg1:
-       lds             temp,seekdsk
+       ldd     temp,y+o_seekdsk
        subi    temp,-('A')
        rcall   uartputc
-       printstring ": track "
-       lds     temp2,seektrk+1
-       lds     temp,seektrk
+       printstring ": trk "
+       ldd     temp2,y+o_seektrk+1
+       ldd     temp,y+o_seektrk
        lcall   printhexw
-       printstring ", sector "
-       lds     temp,seeksec
+       printstring ", sec "
+       ldd     temp,y+o_seeksec
        lcall   printhex
-       printstring ", dma-addr "
-       lds     temp2,dmaadr+1
-       lds     temp,dmaadr
+       printstring ", dma "
+       ldd     temp2,y+o_dmaadr+1
+       ldd     temp,y+o_dmaadr
        lcall   printhexw
-       pop             temp
-       push    temp
-       sbrs    temp,WRITE_FUNC
-       rjmp    dskdbge
-       printstring " wrtype "
-       andi    temp,3
-       lcall   printhex
 dskdbge:
-       pop temp
+       pop     temp
 .endif
+
        ;See what has to be done.
        sbrc    temp,READ_FUNC
-       rjmp    dsk_read
+       rjmp    dsk_readwrite
        sbrc    temp,WRITE_FUNC
-       rjmp    dsk_write
+       rjmp    dsk_readwrite
        sbrc    temp,HOME_FUNC
        rjmp    dsk_home
        sbrc    temp,BOOT_FUNC
@@ -1008,10 +1034,10 @@ dskdbge:
        ljmp    haltinv
 
 dsk_boot:
-       sts     ndisks,_0       ;no active partitions
+       std     y+o_ndisks,_0   ;no active partitions
 dsk_inval_hostbuf:
        cbi     flags,hostact   ;host buffer inactive
-       sts     unacnt,_0       ;clear unalloc count
+       std     y+o_unacnt,_0   ;clear unalloc count
        ret
 
 dsk_home:
@@ -1021,239 +1047,190 @@ dsk_home:
 
 
 
-; ====================================================================
-; Function: Does a Disk read operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers  : in: temp                        
-; Variables  : [r] seekdsk             Number of Disk to Read
-;                         [r] seeksec          Sector to read
-;              [r] seektrk             Track  to read
-; --------------------------------------------------------------------
-; Description:
-; ====================================================================
-dsk_read:
-       sts     erflag,_0
-       sbi     flags,readop            ; Set read operation flag
 
-       ;RAM disk?
-       lds     zl,seekdsk
+dsk_readwrite:
+
+; RAM disk?
+
+       ldd     zl,y+o_seekdsk
 #if RAMDISKCNT
        cpi     zl,RAMDISKNR
-       brlt    PC+2
-        rjmp   rdsk_read
+       brlt    dsk_rw_noramdisk
+       sbrc    temp,WRITE_FUNC
+        rjmp   rdsk_write
+       rjmp    rdsk_read
+dsk_rw_noramdisk:
 #endif
-       rcall   dsk_getpartentry        ; Get Paritiontableentry
-       ld      temp,z                  ; Get Partitiontype
-       andi    temp,dskType_MASK
+       rcall   dsk_getpartentry        ;Get Paritiontableentry
+       ld      temp2,z                 ;Get Partitiontype
+       andi    temp2,dskType_MASK
 
 ; Isn't it a Disk ?
-       cpi     temp,dskType_None
+
+       cpi     temp2,dskType_None
        brne    PC+2
-       rjmp    dsk_read_err
+       ret                             ;return error
 
 ; It must be a FAT16-Imagefile or CP/M Partition.
 
-       rcall   dsk_setdrvparam         ;todo: do this only if needed (disk change)
+       sbrc    temp,WRITE_FUNC
+        rjmp   dsk_write
 
-       sts     unacnt,_0
+       sbi     flags,readop            ;Set read operation flag
        sbi     flags,rsflag            ;must read data
+       std     y+o_unacnt,_0
        ldi     temp,WRUAL              ;write type
-       sts     wrtype,temp             ;treat as unalloc
-
-       rjmp    dsk_rwoper              ;to perform the read
-
-dsk_read_err:
-       ret
+       std     y+o_wrtype,temp         ;treat as unalloc
+       rjmp    dsk_rw
 
-; ====================================================================
-; Function: Does a Disk write operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers  : in: temp                Write type      
-; Variables  : [r] seekdsk             Number of Disk to Read
-;                         [r] seeksec          Sector to read
-;              [r] seektrk             Track  to read
-; --------------------------------------------------------------------
-; Description:
-; ====================================================================
 dsk_write:
-       ;write the selected sector
-       sts     erflag,_0
-       cbi     flags,readop            ; not a read operation
-       ;RAM disk?
-       lds     zl,seekdsk
-#if RAMDISKCNT
-       cpi     zl,RAMDISKNR
-       brlt    PC+2
-        rjmp   rdsk_write
-#endif
-       rcall   dsk_getpartentry        ; Get Paritiontableentry
-       ld      temp2,z                 ; Get Partitiontype
-       andi    temp2,dskType_MASK
+       cbi     flags,readop            ;Not a read operation
+       andi    temp,WRTMSK
+       std     y+o_wrtype,temp         ;save write type
+dsk_rw:
+       rcall   dsk_setdrvparam         ;todo: do this only if needed (disk change)
 
-; Isn't it a Disk ?
-       cpi     temp2,dskType_None
-       brne    PC+2
-       rjmp    dsk_write_err
+; Convert track/sector to an LBA address (in 128byte blocks)
 
+       ldd     xl,y+o_seeksec          ;
+       ldi     xh,0                    ;
+       ldi     temp2,0                 ;
+       ldd     temp,y+o_hdrsize        ;add image header size
+       add     xl,temp                 ;
+       adc     xh,_0                   ;
+       ldd     temp,y+o_cpmspt         ;
+       ldd     _tmp0,y+o_seektrk       ;
+       mul     temp,_tmp0              ;
+       add     xl,r0                   ;
+       adc     xh,r1                   ;
+       ldd     _tmp0,y+o_seektrk+1     ;
+       mul     temp,_tmp0              ;
+       add     xh,r0                   ;temp2:xh:xl := sec + trk * SectorsPerTrack
+       adc     temp2,r1                ;
+       mov     temp3,xl
+       andi    temp3,SECMSK            ;mask buffer number
 
-; It must be a FAT16-Imagefile or CP/M Partition.
+; Convert from CP/M LBA blocks to host LBA blocks
 
-       rcall   dsk_setdrvparam         ;TODO: do this only if needed (disk change)
+       ldi     temp,SECSHF
+dsk_sh1:
+       lsr     temp2
+       ror     xh
+       ror     xl
+       dec     temp
+       brne    dsk_sh1
+                                       ;todo: temp2 should be 0 here. 
+                                       ;xh:xl = host block to seek
+; 
+       sbic    flags,readop
+        rjmp   dsk_rwoper              ;to perform the read
 
-       andi    temp,WRTMSK
-       sts     wrtype,temp             ;save write type
+; Write operation
 
+       cbi     flags,rsflag            ;rsflag = 0
+       ldd     temp,y+o_wrtype         ;
        cpi     temp,WRUAL              ;write unallocated?
        brne    dsk_chkuna              ;check for unalloc
 
 ; write to unallocated, set parameters
-       lds     temp,secpblk            ;next unalloc recs (blocksize/128)
+
+       ldd     temp,y+o_secpblk        ;next unalloc recs (blocksize/128)
+       cpi     temp3,0                 ;cpm sector on phys. sector boundary?
+       breq    dsk_una1
+       sbi     flags,rsflag            ;  no, rsflag = 1
        subi    temp,HOSTBLK            ;don't write
-       lds     _tmp0,hdrsize           ;  in next bock
+       ldd     _tmp0,y+o_hdrsize       ;  in next bock
        add     temp,_tmp0              ;  if there is a header
-       sts     unacnt,temp
-       lds     temp,seekdsk            ;disk to seek
-       sts     unadsk,temp             ;unadsk = sekdsk
-       lds     temp,seektrk
-       sts     unatrk,temp             ;unatrk = sectrk
-       lds     temp,seektrk+1
-       sts     unatrk+1,temp           ;unatrk = sectrk
-       lds     temp,seeksec
-       sts     unasec,temp             ;unasec = seksec
+dsk_una1:
+       std     y+o_unacnt,temp
+       ldd     temp,y+o_seekdsk        ;disk to seek
+       std     y+o_unadsk,temp         ;unadsk = sekdsk
+       std     y+o_unalba,  xl         ;unalba = seeklba (== hostlba)
+       std     y+o_unalba+1,xh
+
+; check for write to unallocated sector
 
 dsk_chkuna:
-       ;check for write to unallocated sector
-       lds     temp,unacnt             ;any unalloc remain?
+
+       ldd     temp,y+o_unacnt         ;any unalloc remain?
        tst     temp
        breq    dsk_alloc               ;skip if not
 
 ; more unallocated records remain
+
        dec     temp                    ;unacnt = unacnt-1
-       sts     unacnt,temp
-       lds     temp,seekdsk            ;same disk?
-       lds     temp2,unadsk
+       std     y+o_unacnt,temp
+       ldd     temp,y+o_seekdsk        ;same disk?
+       ldd     temp2,y+o_unadsk
        cp      temp,temp2              ;seekdsk = unadsk?
        brne    dsk_alloc               ;skip if not
 
 ; disks are the same
-       lds     temp,unatrk
-       lds     temp2,unatrk+1
-       lds     _tmp0,seektrk
-       lds     _tmp1,seektrk+1
-       cp      temp,_tmp0              ;seektrk = unatrk?
-       cpc     temp2,_tmp1
-       brne    dsk_alloc               ;skip if not
 
-; tracks are the same
-       lds     temp,seeksec            ;same sector?
-       lds     temp2,unasec
-       cp      temp,temp2              ;seeksec = unasec?
+       ldd     _tmp0,y+o_unalba
+       ldd     _tmp1,y+o_unalba+1
+       cp      _tmp0,xl                ;seeklba = unalba?
+       cpc     _tmp1,xh
        brne    dsk_alloc               ;skip if not
 
-; match, move to next sector for future ref
-       inc     temp2           ;unasec = unasec+1
-       sts     unasec,temp2
-       lds     _tmp0,cpmspt
-       cp      temp2,_tmp0             ;end of track? (count CP/M sectors)
-       brlo    dsk_noovf               ;skip if no overflow
-
-; overflow to next track
-       sts     unasec,_0               ;unasec = 0
-       lds     temp,unatrk
-       lds     temp2,unatrk+1
-       subi    temp, low(-1)           ;unatrk = unatrk+1
-       sbci    temp2,high(-1)
-       sts     unatrk,temp
-       sts     unatrk+1,temp2
+; block address is the same
+; move to next sector for future ref
+
+       mov     temp,temp3
+       inc     temp                    ;next part
+       andi    temp,SECMSK
+       brne    dsk_noovf               ;skip if no overflow
+
+; overflow to next block
+
+       sub     _tmp0,_255              ;unalba = unalba+1
+       sbc     _tmp1,_255
+       std     y+o_unalba,  _tmp0
+       std     y+o_unalba+1,_tmp1
 
 dsk_noovf:
-       cbi     flags,rsflag            ;rsflag = 0
        rjmp    dsk_rwoper              ;to perform the write
 
+; not an unallocated record, requires pre-read
+
 dsk_alloc:
-       ;not an unallocated record, requires pre-read
-       sts     unacnt,_0               ;unacnt = 0
+       std     y+o_unacnt,_0           ;unacnt = 0
        sbi     flags,rsflag            ;rsflag = 1
-       rjmp    dsk_rwoper
 
-dsk_write_err:
-       ret
 
-; ====================================================================
-; Function: Does a Disk read/write operation
-; ====================================================================
-; Parameters
-; --------------------------------------------------------------------
-; Registers  : none
-; Variables  : [r] seekdsk             Number of Disk to Read
-;                         [r] seeksec          Sector to read
-;              [r] seektrk             Track  to read
-; --------------------------------------------------------------------
-; Description:
-; ====================================================================
+; Enter here to perform the read/write
+
 dsk_rwoper:
-       ;enter here to perform the read/write
-.if DISK_DEBUG
-       printstring ", flags: "
+
+.if DISK_DEBUG > 1
+       printstring ", flags|wtyp "
        in      temp,flags
+       cbr     temp,WRTMSK
+       ldd     _tmp0,y+o_wrtype
+       or      temp,_tmp0
+       lcall   printhex
+       printstring ", buf "
+       mov     temp,temp3
        lcall   printhex
 .endif
 
-; Convert track/sector to an LBA address (in 128byte blocks)
-
-       lds     xl,seeksec              ;
-       ldi     xh,0                    ;
-       ldi     yl,0                    ;
-       lds     temp,hdrsize            ;add image header size
-       add     xl,temp                 ;
-       adc     xh,_0                   ;
-       lds     temp,seektrk            ;
-       lds     temp2,seektrk+1         ;
-       lds     temp3,cpmspt            ;
-       mul     temp,temp3              ;
-       add     xl,r0                   ;
-       adc     xh,r1                   ;
-       mul     temp2,temp3             ;
-       add     xh,r0                   ;yl:xh:xl := sec + trk * SectorsPerTrack
-       adc     yl,r1                   ;
-       mov     temp,xl
-       andi    temp,SECMSK             ;mask buffer number
-       push    temp                    ;save for later
-
-; Convert from CP/M LBA blocks to host LBA blocks
-       ldi     temp,SECSHF
-dsk_sh1:
-       lsr     yl
-       ror     xh
-       ror     xl
-       dec     temp
-       brne    dsk_sh1
-                                       ;todo: yl should be 0 here. 
-                                       ;xh:xl = host block to seek
+       push    temp3
        movw    temp,x
-       lds     temp3,seekdsk
+       ldd     temp3,y+o_seekdsk
        rcall   dsk_rw_hostbuf
+       pop     temp                    ;get back buffer number (which part of hostbuf)
+       ldiw    y,fsys_vars
 
 ; copy data to or from buffer
+
        ldiw    z,hostbuf
-       ldi     temp,128
-       pop     temp2                   ;get buffer number (which part of hostbuf)
-       mul     temp2,temp
+       ldi     temp3,128
+       mul     temp,temp3
        add     zl,r0                   ;offset in hostbuf
        adc     zh,r1
-.if DISK_DEBUG > 2
-       movw    temp,r0
-       printstring "; host buf adr: "
-       lcall   printhexw
-.endif
 
-       lds     xl,dmaadr
-       lds     xh,dmaadr+1
-       ldi     temp3,128               ;length of move
+       ldd     xl,y+o_dmaadr
+       ldd     xh,y+o_dmaadr+1
        sbic    flags,readop            ;which way?
        rjmp    dsk_rmove               ;skip if read
 
@@ -1276,14 +1253,14 @@ dsk_rmove:
 
 dsk_rwmfin:
 ; data has been moved to/from host buffer
-       lds     temp,wrtype             ;write type
+       ldd     temp,y+o_wrtype         ;write type
        cpi     temp,WRDIR              ;to directory?
        breq    dsk_wdir
        ret                             ;no further processing
 
 ; clear host buffer for directory write
 dsk_wdir:
-       lds     temp,erflag
+       ldd     temp,y+o_erflag
        tst     temp                    ;errors?
        breq    dsk_wdir1
        ret                             ;skip if so
@@ -1304,11 +1281,13 @@ dsk_wdir1:
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
+
 dsk_readhost_lba:
-#if 0
+
+.if HOSTRW_DEBUG
        printnewline
-       printstring "readhst lba"
-#endif
+       printstring "Readhost LBA"
+.endif
        sbi     flags,rsflag            ;must read data
        rcall   dsk_rw_hostbuf
        lds     temp,erflag             ;returns 0, if ok
@@ -1327,8 +1306,9 @@ dsk_readhost_lba:
 ; Description: 
 ; ====================================================================
 dsk_rw_hostbuf:
+       ldiw    y,fsys_vars
                                        ;xh:xl = host block to seek
-       sts     erflag,_0               ;no errors (yet)
+       std     y+o_erflag,_0           ;no errors (yet)
 
 ; active host sector?
 
@@ -1339,15 +1319,15 @@ dsk_rw_hostbuf:
 
 ; host buffer active, same as seek buffer?
 
-       lds     _tmp0,hostdsk           ;same disk?
+       ldd     _tmp0,y+o_hostdsk               ;same disk?
        cp      temp3,_tmp0             ;seekdsk = hostdsk?
        brne    dsk_nomatch
 
 ; same disk, same block?
 
-       lds     _tmp0,hostlba
-       cp      temp,_tmp0
-       lds     _tmp0,hostlba+1
+       ldd     _tmp0,y+o_hostlba
+       cp      temp, _tmp0
+       ldd     _tmp0,y+o_hostlba+1
        cpc     temp2,_tmp0
        breq    dsk_match
 
@@ -1365,9 +1345,10 @@ dsk_nomatch:
 
 ; may have to fill the host buffer
 dsk_filhst:
-       sts     hostlba,temp
-       sts     hostlba+1,temp2
-       sts     hostdsk,temp3
+       ldiw    y,fsys_vars
+       std     y+o_hostlba,temp
+       std     y+o_hostlba+1,temp2
+       std     y+o_hostdsk,temp3
 
        sbic    flags,rsflag            ;need to read?
        rcall   dsk_readhost            ;yes, if 1
@@ -1388,24 +1369,32 @@ dsk_match:
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
+
 dsk_writehost:
-       lds     zl,hostdsk
-       rcall   dsk_getpartentry
-       ld      temp,z
-       andi    temp,dskType_MASK
 
-#if FAT16_SUPPORT
-; Is it a FAT16 Diskimage ?
-       cpi     temp,dskType_FAT
-       brne    PC+2
-       rjmp    fat_writehost
-#endif
+.if HOSTRW_DEBUG
+.if DISK_DEBUG == 0
+       printnewline
+       printstring "Host write: "
+.else
+       printstring ", hst WR "
+.endif
+.endif
 
-; Is it a CP/M Partition ?
-       cpi     temp,dskType_CPM
-       brne    PC+2
-       rjmp    cpm_writehost
-; Disktype not supported -> Return 
+       rcall   dsk_hostparam
+       breq    dsk_hstwr_err
+       
+       ldiw    z,hostbuf
+       rcall   mmcWriteSect
+       tst     temp
+       brne    dsk_hstwr_err
+       
+dsk_hstwr_ok:
+       sts     erflag,_0
+       ret
+
+dsk_hstwr_err:
+       sts     erflag,_255
        ret
 
 ; ====================================================================
@@ -1420,36 +1409,146 @@ dsk_writehost:
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
+
 dsk_readhost:
 
-#if 0
+.if HOSTRW_DEBUG
+.if DISK_DEBUG == 0
        printnewline
-       printstring "readhost"
-       ldiw    z,biosdrvtbl
-       rcall   dbg_hexdump_line
-       adiw    z,16
-       rcall   dbg_hexdump_line
-#endif
-                       
+       printstring "Host read:  "
+.else
+       printstring ", hst RD "
+.endif
+.endif
+
+       rcall   dsk_hostparam
+       breq    dsk_hstrd_err
+       
+       ldiw    z,hostbuf
+       lcall   mmcReadSect
+       tst     temp
+       brne    dsk_hstrd_err
+
+dsk_hstrd_ok:
+       sts     erflag,_0
+       ret
+
+dsk_hstrd_err:
+       sts     erflag,_255
+       ret
+
+; ====================================================================
+; Function: Does a Disk write operation
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers  : none
+; Variables  : [r] seekdsk             Number of Disk to Read
+;                         [r] seeksec          Sector to read
+;              [r] seektrk             Track  to read
+; hostdsk = host disk #,  (partition #)
+; hostlba = host block #, relative to partition start 
+; Read/Write "hostsize" bytes to/from hostbuf
+; --------------------------------------------------------------------
+; Description:
+; ==================================================================== 
+
+dsk_hostparam:
+
        lds    zl,hostdsk
+
+.if HOSTRW_DEBUG
+       mov     temp,zl
+       subi    temp,-('A')
+       lcall   uartputc
+.endif
        rcall  dsk_getpartentry
-       ld     temp,z
+       lds     xl,hostlba              ; get sector to access
+       lds     xh,hostlba+1
+
+.if HOSTRW_DEBUG
+       printstring ": lba "
+       push    r15
+       push    r14
+       clr     r14
+       clr     r15
+       movw    temp,x
+       lcall   print_ultoa
+       pop     r14
+       pop     r15
+.endif
+
+       ldd     _tmp0,z+PTAB_SIZE               ; get disksize
+       ldd     _tmp1,z+PTAB_SIZE+1
+       
+       cp      xl,_tmp0                        ; check given sector against disksize
+       cpc     xh,_tmp1
+       brcc    dsk_hst_param_err
+
+       ldd     temp,z+PTAB_TYPE
        andi    temp,dskType_MASK
 
 #if FAT16_SUPPORT
 ; Is it a FAT16 Diskimage ?
        cpi     temp,dskType_FAT
-       brne    PC+2
-       rjmp    fat_readhost
+       brne    dsk_hstpar_nofat
+       rcall   fat_lba_to_phys
+       rjmp    dsk_hstpar_gotit
+dsk_hstpar_nofat:
 #endif
-
+#if CPMDSK_SUPPORT
 ; Is it a CP/M Partition ?
        cpi     temp,dskType_CPM
-       brne    PC+2
-       rjmp    cpm_readhost
-; Disktype not supported -> Return 
+       brne    dsk_hstpar_nocpm
+       lcall   cpm_lba_to_phys
+       rjmp    dsk_hstpar_gotit
+dsk_hstpar_nocpm:
+#endif
+; Disktype not supported
+       rjmp    dsk_hst_param_err
+
+dsk_hstpar_gotit:
+
+.if HOSTRW_DEBUG
+       printstring ", abs "
+       push    r15
+       push    r14
+       push    temp2
+       push    temp
+       movw    temp,x
+       movw    r14,y
+       lcall   print_ultoa
+       pop     temp
+       pop     temp2
+       pop     r14
+       pop     r15
+.endif
+
+       ori     temp,255
        ret
 
+dsk_hst_param_err:
+
+.if HOSTRW_DEBUG
+       printstring ", max: "
+       push    r15
+       push    r14
+       push    temp2
+       push    temp
+       movw    temp,_tmp0
+       clr     r14
+       clr     r15
+       lcall   print_ultoa
+       pop     temp
+       pop     temp2
+       pop     r14
+       pop     r15
+       printstring " "
+.endif
+       
+       clr     temp
+       ret
 
+; --------------------------------------------------------------------
 ; vim:set ts=8 noet nowrap