]> cloudbase.mooo.com Git - avrcpm.git/blobdiff - avrcpm/avr/dsk_fsys.asm
* Start of dynamic disk size code.
[avrcpm.git] / avrcpm / avr / dsk_fsys.asm
index 6645bf989eb5f7d71762a457cfc5fae38b139fa6..85656202b3c1661a45ac13cd98064eb836bbb265 100644 (file)
 ;    $Id$
 ;
 
+.equ DSKSEL_DEBUG = 0
 
 ; ---------------- Defines for the Filesystem Interface -------
 
-
 ;*****************************************************
 ;*        Disk-Manager constants                     *
 ;*****************************************************
        .equ    dskType_None            = 0
        .equ    dskType_CPM             = 1
        .equ    dskType_FAT             = 2
-       .equ    dskType_RAM             = 3
+;      .equ    dskType_RAM             = 3
 
 ;*****************************************************
 ;*         CP/M to host disk constants               *
 
        .dseg
 
-ndisks:                        .byte   1               ;Number of CP/M disks
+; The following 3 variables are copied from DRAM.
+; Don't change order.
+
+biosdrvtbl:    .byte   2       ;
+biosdirbuf:    .byte   2       ;
+biosenddat:    .byte   2       ;
+
+ndisks:                .byte   1               ;Number of CP/M disks
+
+; The following 5 variables are accessed from 8080/z80 via the
+; virtual port interface. Don't change order.
 
-seekdsk:               .byte   1               ;seek disk number
-seektrk:               .byte   2               ;seek track number
-seeksec:               .byte   1               ;seek sector number
+biospar_base:
+bcbadr:                .byte   2               ;adr of BiosControlBlock
+seekdsk:       .byte   1               ;seek disk number
+seektrk:       .byte   2               ;seek track number
+seeksec:       .byte   2               ;seek sector number
+dmaadr:                .byte   2               ;last dma address
 
-unacnt:                        .byte   1               ;unalloc rec cnt
-unadsk:                        .byte   1               ;last unalloc disk
-unatrk:                        .byte   2               ;last unalloc track
-unasec:                        .byte   1               ;last unalloc sector
+unacnt:                .byte   1               ;unalloc rec cnt
+unadsk:                .byte   1               ;last unalloc disk
+unatrk:                .byte   2               ;last unalloc track
+unasec:                .byte   1               ;last unalloc sector
 
-erflag:                        .byte   1               ;error reporting
-wrtype:                        .byte   1               ;write operation type
-dmaadr:                        .byte   2               ;last dma address
+erflag:                .byte   1               ;error reporting
+wrtype:                .byte   1               ;write operation type
 
-hostbuf:               .byte   hostsize ;host buffer (from/to SD-card)
-hostparttbl:           .byte   PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
+hostbuf:       .byte   hostsize ;host buffer (from/to SD-card)
+hostparttbl:   .byte   PARTENTRY_SIZE*MAXDISKS ;host partition table (type, start sector, sector count)
 hostparttbltop:
-hostdsk:               .byte   1               ;host disk number
-hosttype:              .byte   1               ;host disk type (same entry as 1 parition entry)
-hostlba:               .byte   3               ;host sector number (relative to partition start)
+hostdsk:       .byte   1               ;host disk number
+hosttype:      .byte   1               ;host disk type (same entry as 1 parition entry)
+hostlba:       .byte   3               ;host sector number (relative to partition start)
 
 
 ; ------------------------------- Start of Code Segment
        .cseg
 
+;---------------------------------------------------------------------
+
+.if DSKSEL_DEBUG
+
+dbg_prdrvtbl:
+       push    xh
+       push    xl
+       push    temp3
+       push    temp2
+       push    temp
+       printnewline
+       printstring "drvtbl ("
+       lds     xl,biosdrvtbl
+       lds     xh,biosdrvtbl+1
+       movw    temp,x
+       rcall   printhexw
+       printstring "): "
+       ldi     temp3,16
+dbg_pcpel:
+       rcall   dram_readw_pp
+       rcall   printhexw
+       printstring " "
+       dec     temp3
+       brne    dbg_pcpel
+       pop     temp
+       pop     temp2
+       pop     temp3
+       pop     xl
+       pop     xh
+       ret
+               
+dbg_print_biosd:
+       printnewline
+       lds     temp,bcbadr
+       lds     temp2,bcbadr+1
+       rcall   printhexw
+       printstring "  "
+       lds     temp,biosdrvtbl
+       lds     temp2,biosdrvtbl+1
+       rcall   printhexw
+       printstring "  "
+       lds     temp,biosdirbuf
+       lds     temp2,biosdirbuf+1
+       rcall   printhexw
+       printstring "  "
+       lds     temp,biosenddat
+       lds     temp2,biosenddat+1
+       rcall   printhexw
+       printstring "  "
+       ret
+.endif
+       
 ; ====================================================================
 ; Function: Get a Pointer to a Partitiontable entry
 ; ====================================================================
@@ -96,6 +160,8 @@ hostlba:             .byte   3               ;host sector number (relative to partition start)
 ; --------------------------------------------------------------------
 ; Registers  : [w] z                   Pointer to the Partitionentry
 ;              [r] xl                  Number of Diskentry to Read
+;             [w] _tmp0                scratch
+;             [w] _tmp1                "
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
@@ -109,78 +175,410 @@ dsk_getpartentry:
        ret
 
 ; ====================================================================
-; Function: 
+; Function: Virtual Port Interface
 ; ====================================================================
 ; Parameters
 ; --------------------------------------------------------------------
-; Registers  : none
-; Variables  : [r] seeksec             Sector to read
-;              [r] seektrk             Track  to read
+; Registers  : 
+; Variables  : 
+;              
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
+       
+dsk_param_getadr:
+       ldiw    z,biospar_base
+       add     zl,temp3
+       adc     zh,_0
+       ret
+
+dsk_param_wr:
+       rcall   dsk_param_getadr
+       st      z,temp
+       cpi     temp3,bcbadr+1-seektrk
+       brne    dsk_param_wr1
+       std     z+1,_0
+dsk_param_wr1: 
+       cpi     temp3,bcbadr+1-biospar_base
+       breq    SetBCB
+       ret
+
+dsk_param_rd:
+       cpi     temp3,seekdsk-biospar_base
+       breq    dskDiskCheck
+       rcall   dsk_param_getadr
+       ld      temp,z
+       ret
+
+SetBCB:
+       lds     xl,bcbadr
+       mov     xh,temp
+       ldiw    z,biosdrvtbl
+       ldi     temp3,6
+sbcb_l:
+       rcall   dram_read_pp
+       st      z+,temp
+       dec     temp3
+       brne    sbcb_l
+       
+;      rcall   dbg_print_biosd
+       rcall   dsk_drvtblinit
+;      rcall   dbg_prdrvtbl
+
+       ret
+
+; ====================================================================
+; Function: Check if disk exists
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers  : 
+; Variables  : 
+;              return 0,  if selected disk not exist.
+;              return !0, if disk exist
 ; --------------------------------------------------------------------
 ; Description:
 ; ====================================================================
 dskDiskCheck:
-       lds             temp2,seekdsk
-       cpi             temp2,RAMDISKNR
+       lds     temp,ndisks
+       lds     temp2,seekdsk
+.if    DSKSEL_DEBUG
+       printnewline
+       printstring "DiskCheck: "
+       rcall   printhexw
+.endif
+       cpi     temp2,RAMDISKNR
        brsh    dsk_dchrd                       ;maybe ramdisk
 
 ; Check if selected disk # is less then # of disks.
 
-       lds             temp,ndisks     
-       tst             temp
+       lds     temp,ndisks     
+       tst     temp                            ;0 disks?
        brne    dsk_dchpart1
 
 ; No disks yet, need to init
 
-       rcall   mgr_init_partitions
-       cbr             temp,0x80
-       lds             temp2,seekdsk
+       rcall   mgr_init_partitions             ;disk chanched?
+;      sbrs    temp,7  
+;       rjmp   dsk_dchpart0
+       push    temp
+       rcall   dsk_drvtblinit
+;      rcall   dbg_prdrvtbl
+       pop     temp
+dsk_dchpart0:
+       cbr     temp,0x80
+       lds     temp2,seekdsk
        
 dsk_dchpart1:
-       cp              temp2,temp
-       brsh    dsk_dcher
+       cp      temp2,temp
+       brsh    dsk_dch_err
+
+.if    DSKSEL_DEBUG
+       printnewline
+       printstring "Select: "
+       mov     temp,temp2
+       rcall   printhex
+.endif
+       ldsw    x,biosdrvtbl
+       lsl     temp2                   ;drive #
+       add     xl,temp2
+       adc     xh,_0
+       rcall   dram_readw_pp           ;get drive table entry
+
+       or      temp,temp2              ;if !0, drive is allready initialized
+       brne    dsk_dchend
+       lds     temp,seekdsk
+       rcall   dsk_diskinit
        
 dsk_dchend:
-       ldi             temp,0
+.if    DSKSEL_DEBUG
+       push    temp
+       ldsw    x,biosdrvtbl
+       lds     temp,seekdsk
+       lsl     temp                    ;drive #
+       add     xl,temp
+       adc     xh,_0
+       rcall   dram_readw_pp
+       printstring ", "
+       rcall   printhexw
+       pop     temp
+.endif 
+
        ret
 
+dsk_dch_err:
+       ldi     temp,0                  ;error return
+       ret     
+       
+;      Check RAMDISK
+
 dsk_dchrd:
 #if RAMDISKCNT
-       cpi             temp,RAMDISKNR+RAMDISKCNT
-       brlo    dsk_dchend
+       cpi     temp,RAMDISKNR+RAMDISKCNT
+       brsh    dsk_dchrd_err
+
+       ldi     temp,0xff               ;return ok
+       ret
 #endif
-dsk_dcher:
-       ldi             temp,0xff                       ;error return
+dsk_dchrd_err:
+       ldi     temp,0                  ;error return
        ret
-       
+
+
+; ====================================================================
+; Function: Return status of last disk i/o function
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers  : 
+; Variables  : 
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
 dskErrorRet:
-       lds             temp,erflag
+       lds     temp,erflag
        ret
 
-dskDiskSel:
-       sts     seekdsk,temp
-       ret
+               
+; -------------------------------------------------------------------
 
-dskTrackSel_l:
-       sts     seektrk,temp
-       sts     seektrk+1,_0
-       ret
 
-dskTrackSel_h:
-       sts     seektrk+1,temp
+       .dseg
+tmpdpb:        .byte   15
+
+       .cseg
+
+; Test DPBs (avrcpm format)
+
+dpblist:
+;dpb243        
+       .db 0x1A,0x00           ;spt
+       .db 0x03,0x07           ;block shift, bock mask
+       .db 0x00,0xF2           ;extent mask, low(disk size -1), 
+       .db 0x00,0x3F           ;high(disk size -1), low(dir max)
+       .db 0x00,0xC0           ;high(dir max), alloc0
+       .db 0x00,0x10           ;alloc1, low(chk size)
+       .db 0x00,0x02           ;high(chk size), low(offset)
+       .db 0x00,0x00           ;high(offset), fill
+;dpb243        
+       .db 0x1A,0x00           ;spt
+       .db 0x03,0x07           ;block shift, bock mask
+       .db 0x00,0xF2           ;extent mask, low(disk size -1), 
+       .db 0x00,0x3F           ;high(disk size -1), low(dir max)
+       .db 0x00,0xC0           ;high(dir max), alloc0
+       .db 0x00,0x10           ;alloc1, low(chk size)
+       .db 0x00,0x02           ;high(chk size), low(offset)
+       .db 0x00,0x00           ;high(offset), fill
+;dpb243        
+       .db 0x1A,0x00           ;spt
+       .db 0x03,0x07           ;block shift, bock mask
+       .db 0x00,0xF2           ;extent mask, low(disk size -1), 
+       .db 0x00,0x3F           ;high(disk size -1), low(dir max)
+       .db 0x00,0xC0           ;high(dir max), alloc0
+       .db 0x00,0x10           ;alloc1, low(chk size)
+       .db 0x00,0x02           ;high(chk size), low(offset)
+       .db 0x00,0x00           ;high(offset), fill
+;dpb243        
+       .db 0x1A,0x00           ;spt
+       .db 0x03,0x07           ;block shift, bock mask
+       .db 0x00,0xF2           ;extent mask, low(disk size -1), 
+       .db 0x00,0x3F           ;high(disk size -1), low(dir max)
+       .db 0x00,0xC0           ;high(dir max), alloc0
+       .db 0x00,0x10           ;alloc1, low(chk size)
+       .db 0x00,0x02           ;high(chk size), low(offset)
+       .db 0x00,0x00           ;high(offset), fill
+#if 0
+;rd1016        
+       .db 0x20,0x00           ;spt
+       .db 0x04,0x0F           ;block shift, bock mask
+       .db 0x00,0xFB           ;extent mask, low(disk size -1), 
+       .db 0x01,0xBF           ;high(disk size -1), low(dir max)
+       .db 0x00,0xE0           ;high(dir max), alloc0
+       .db 0x00,0x30           ;alloc1, low(chk size)
+       .db 0x00,0x02           ;high(chk size), low(offset)
+       .db 0x00,0x00           ;high(offset), fill
+;rd9192s
+       .db 0x20,0x00           ;spt
+       .db 0x05,0x1F           ;block shift, bock mask
+       .db 0x01,0xFD           ;extent mask, low(disk size -1), 
+       .db 0x07,0xFF           ;high(disk size -1), low(dir max)
+       .db 0x01,0xF0           ;high(dir max), alloc0
+       .db 0x00,0x80           ;alloc1, low(chk size)
+       .db 0x00,0x02           ;high(chk size), low(offset)
+       .db 0x00,0x00           ;high(offset), fill
+#endif
+
+; Test
+cpy_dpb:
+       push    zh
+       push    zl
+       push    yh
+       push    yl
+       ldiw    z,dpblist*2
+       ldi     temp2,16
+       mul     temp,temp2
+       add     zl,_tmp0
+       adc     zh,_tmp1
+       ldiw    y,tmpdpb
+cpydpb_l:
+       lpm     temp,z+
+       st      y+,temp
+       cpi     yl,low(tmpdpb + 15)
+       brne    cpydpb_l
+       pop     yl
+       pop     yh
+       pop     zl
+       pop     zh
        ret
+       
+; clear drive table
+; for now, only  entries 1 - 3 are cleared.
 
-dskSecSel:
-       sts     seeksec,temp
+; ====================================================================
+; Function: Clear drive table
+; ====================================================================
+; Parameters
+; --------------------------------------------------------------------
+; Registers  : 
+; Variables  : 
+;              
+; --------------------------------------------------------------------
+; Description:
+; ====================================================================
+
+; For now, only  entries 1 - 3 are cleared.
+
+dsk_drvtblinit:
+       ldsw    x,biosdrvtbl
+       adiw    x,2
+       ldi     temp3,3
+dsk_drvi_l:
+       ldi     temp,0
+       ldi     temp2,0
+       rcall   dram_writew_pp
+       dec     temp3
+       brne    dsk_drvi_l
+       
+       lds     temp,biosenddat
+       lds     temp2,biosenddat+1
+       rcall   heap_init
+       clr     temp
        ret
 
-dskDmal:
-       sts     dmaadr,temp
+       
+; ----------------------------------------------------------------------
+; Init CP/M data structures 
+;      temp = drive #
+;
+;      return !0 if ok
+;              0 on error
+
+
+dsk_diskinit:
+       mov     temp3,temp              ;save disk #
+
+
+; Test
+       rcall   cpy_dpb
+       
+       
+
+
+; get mem for DPH 
+;         -----------------------------------------------------------------
+; DPH:    |  XLT  |       |       |       |DIRBUF |  DPB  |  CSV  |  ALV  |
+;         -----------------------------------------------------------------
+;(offset)     0       2       4       6       8      10      12      14
+
+       ldi     temp, low (16)
+       ldi     temp2,high(16)
+       rcall   heap_get
+       brne    dsk_di_1
+       rjmp    dsk_di_err              ;
+dsk_di_1:
+       movw    x,temp
+       movw    y,temp
+       ldi     temp,0
+       ldi     temp2,0
+       rcall   dram_writew_pp          ;XLT
+       adiw    x,6
+       lds     temp,biosdirbuf
+       lds     temp2,biosdirbuf+1
+       rcall   dram_writew_pp          ;DIRBUF
+
+; get mem for DPB      
+;      -------------------------------------------------------------
+; DPB: |  SPT  |BSH|BLM|EXM|  DSM  |  DRM  |AL0|AL1|  CKS  |  OFF  |
+;      -------------------------------------------------------------
+;          0                   5       7              11      13    
+       
+       ldi     temp, low (15)
+       ldi     temp2,high(15)
+       rcall   heap_get
+       breq    dsk_di_err_p1
+       movw    x,temp
+       
+       ldiw    z,tmpdpb
+dsk_dicpl:
+       ld      temp,z+
+       rcall   dram_write_pp
+       cpi     zl,low(tmpdpb + 15)
+       brne    dsk_dicpl
+       sbiw    x,15
+       movw    temp,x
+       movw    x,y
+       adiw    x,10
+       rcall   dram_writew_pp          ;DPB
+       
+; get mem for dir check vector
+
+       lds     temp,tmpdpb+11          ;cks
+       lds     temp2,tmpdpb+11+1
+       cp      temp,_0
+       cpc     temp2,_0
+       breq    dsk_dicks0
+       rcall   heap_get
+       breq    dsk_di_err_p1
+dsk_dicks0:
+       rcall   dram_writew_pp          ;CSV
+
+; get mem for alloc vector
+
+       lds     temp,tmpdpb+5           ;dsm
+       lds     temp2,tmpdpb+5+1
+       subi    temp, low (-8)
+       sbci    temp2,high(-8)
+       lsr     temp2
+       ror     temp
+       lsr     temp2
+       ror     temp
+       lsr     temp2
+       ror     temp                    ;(dsm+1+7)/8
+       rcall   heap_get
+       breq    dsk_di_err_p1
+       rcall   dram_writew_pp          ;ALV
+
+; success, insert DPH into drvtbl
+
+       lds     xl,biosdrvtbl
+       lds     xh,biosdrvtbl+1
+       lsl     temp3                   ;drive #
+       add     xl,temp3
+       adc     xh,_0
+       movw    temp,y
+       rcall   dram_writew_pp  
+       ori     temp,0xff               ;return ok
        ret
 
-dskDmah:
-       sts     dmaadr+1,temp
+; error, free mem
+
+dsk_di_err_p1:
+       movw    temp,y
+       rcall   heap_release
+dsk_di_err:
+       eor     temp,temp               ;return 0 (+ Z-flag)
        ret
+       
 
 ; ====================================================================
 ; Function: Does a Disk interaction
@@ -277,6 +675,7 @@ dsk_home:
 dsk_read:
        sts             erflag,_0
        sbi             flags,readop            ; Set read operation flag
+
        ;RAM disk?
        lds     xl,seekdsk
 #if RAMDISKCNT
@@ -291,6 +690,7 @@ dsk_read:
        cpi             temp,dskType_None
        brne    PC+2
        rjmp    dsk_read_err
+
 ; It must be a FAT16-Imagefile or CP/M Partition.
        sts             unacnt,_0
        sbi             flags,rsflag            ;must read data