]> cloudbase.mooo.com Git - avrcpm.git/blobdiff - avrcpm/avr/z80.asm
* avr/z80.asm:
[avrcpm.git] / avrcpm / avr / z80.asm
index 333350f593409882a5792a05e5356f666c060efb..e61fc136ce3fe983626506e9bc7bc78ea72818b7 100644 (file)
@@ -43,6 +43,8 @@
        #define BAUD   38400           /* console baud rate */
 #endif
  
+#define PARTID 0x52            /* Partition table id */
+                               /* http://www.win.tue.nl/~aeb/partitions/partition_types-1.html */
 
 #define UBRR_VAL  ((F_CPU+BAUD*8)/(BAUD*16)-1)  /* clever rounding */
 
 .def   oph     = r23   ;
 .def   z_pcl   = r24   ;
 .def   z_pch   = r25   ;
+; xl           ;r26
+; xh           ;r27
 ; yl           ;r28
 ; yh           ;r29
 ; zl           ;r30    ;
@@ -447,13 +451,114 @@ ramfillw:
 
 
 
-;Load initial sector from MMC (512 bytes)
+;----------------------------------------------------------------------------
+
+; Offsets:
+#define PART_TYPE   4
+#define PART_START  8
+#define PART_SIZE  12
+
+;Load first sector from MMC (boot sector)
+
+boot_again:
        ldi     yh,0
        ldi     yl,0
        ldi     xh,0
        ldi     xl,0
        rcall   mmcReadSect
 
+;Test, if it has a valid MBR
+
+       lds     temp,hostbuf+510        ;MBR signature (0xAA55)  at and of sector?
+       lds     temp2,hostbuf+511
+       ldi     temp4,0xAA
+       cpi     temp,0x55               
+       cpc     temp2,temp4
+       breq    boot_part
+
+;No MBR, no partition table ...
+       ldi     opl,1
+       sts     ndisks,opl
+       rjmp    boot_ipl
+               
+;Search Partition Table for CP/M partitions
+boot_part:
+       ldi     zl,low(hostbuf+510-64)
+       ldi     zh,high(hostbuf+510-64)
+       ldi     yl,low(hostdstart)
+       ldi     yh,high(hostdstart)
+       ldi     opl,0
+       ldi     oph,high(hostbuf+510)
+boot_ploop:
+       ldd     temp,z+PART_TYPE
+       cpi     temp,PARTID
+       brne    boot_nextp
+       
+       ldd     temp,z+PART_START
+       st      y+,temp
+       ldd     temp2,z+PART_START+1
+       st      y+,temp2
+       ldd     temp3,z+PART_START+2
+       st      y+,temp3
+       ldd     temp4,z+PART_START+3
+       st      y+,temp4
+       
+       rcall   printstr
+       .db     "CP/M partition at: ",0
+       rcall   print_ultoa
+       rcall   printstr
+       .db     ", size: ",0,0
+       ldd     temp,z+PART_SIZE
+       ldd     temp2,z+PART_SIZE+1
+       ldd     temp3,z+PART_SIZE+2
+       ldd     temp4,z+PART_SIZE+3
+       lsr     temp4
+       ror     temp3
+       ror     temp2
+       ror     temp
+       rcall   print_ultoa
+       rcall   printstr
+       .db     "KB.",13,0,0
+       
+       inc     opl
+       cpi     temp2,MAXDISKS
+       breq    boot_pend       
+boot_nextp:
+       adiw    zl,16
+       cpi     zl,low(hostbuf+510)
+       cpc     zh,oph
+       brsh    boot_pend
+       rjmp    boot_ploop
+boot_pend:
+       sts     ndisks,opl
+
+; Read first sector of first CP/M partition
+
+       lds     xl,hostdstart
+       lds     xh,hostdstart+1
+       lds     yl,hostdstart+2
+       lds     yh,hostdstart+3
+       rcall   mmcReadSect
+
+boot_ipl:
+       lds     opl,ndisks
+       tst     opl
+       brne    boot_ipl2
+       rcall   printstr
+       .db     "No bootable CP/M disk found! Please change MMC/SD-Card",13,0
+       ldi     temp2,18
+boot_wl:
+       ldi     temp,255
+       rcall   delay_ms
+       dec     temp2
+       brne    boot_wl
+       rjmp    boot_again
+       
+
+boot_ipl2:
+
+;First sector of disk or first CP/M partition is in hostbuf.
+
 ;Save to Z80 RAM (only 128 bytes because that's retro)
        ldi zl,low(hostbuf)
        ldi zh,high(hostbuf)
@@ -664,6 +769,7 @@ notrace6:
 ;*****************************************************
 ;*         CP/M to host disk constants               *
 ;*****************************************************
+       .equ    MAXDISKS  = 4           ;Max number of Disks (partitions)
        .equ    blksize = 1024          ;CP/M allocation size
        .equ    hostsize = 512          ;host disk sector size
 ;      .equ    hostspt = 20            ;host disk sectors/trk
@@ -683,13 +789,15 @@ notrace6:
 
 
        .dseg
+ndisks:                .byte   1       ;Number of CP/M disks
 
 seekdsk:       .byte   1       ;seek disk number
 seektrk:       .byte   2       ;seek track number
 seeksec:       .byte   1       ;seek sector number
 
 hostdsk:       .byte   1       ;host disk number
-hostlba:       .byte   2       ;host track number
+hostlba:       .byte   3       ;host sector number (relative to partition start)
+hostdstart:    .byte   4*MAXDISKS ; host disks start sector (partition)
 
 unacnt:                .byte   1       ;unalloc rec cnt
 unadsk:                .byte   1       ;last unalloc disk
@@ -711,6 +819,9 @@ portRead:
        cpi temp2,1
        breq conInp
 
+       cpi     temp2,15
+       breq    dskDiskCheck
+
        cpi     temp2,TIMER_MSECS
        brlo    pr_noclock
        cpi     temp2,TIMER_MSECS+6
@@ -727,6 +838,9 @@ portWrite:
        breq dbgOut
        cpi temp2,2
        breq conOut
+
+       cpi temp2,15
+       breq dskDiskSel
        cpi temp2,16
        breq dskTrackSel_l
        cpi temp2,17
@@ -774,6 +888,18 @@ conOut:
        rjmp uartputc
 
 
+dskDiskCheck:
+       lds     temp,seekdsk
+       lds     temp2,ndisks    ;check if selected disk # is less then # of disks
+       cp      temp,temp2
+       ldi     temp,0
+       brlt    PC+2
+       ldi     temp,0xff               ;error return
+       ret
+
+dskDiskSel:
+       sts seekdsk,temp
+       ret
 
 dskTrackSel_l:
        sts seektrk,temp
@@ -979,6 +1105,7 @@ dsk_rwoper:
 
        lds     xl,seeksec              ;
        ldi     xh,0                    ;
+       ldi     yl,0                    ;
        lds     temp3,seektrk           ;
        lds     temp4,seektrk+1         ;
        ldi     temp,CPMSPT             ;
@@ -987,6 +1114,7 @@ dsk_rwoper:
        adc     xh,r1                   ;
        mul     temp4,temp              ;
        add     xh,r0                   ;xh:xl := sec + trk * SectorsPerTrack
+       adc     yl,r1                   ;
        clr     _0
 
        mov     temp,xl
@@ -998,24 +1126,27 @@ dsk_rwoper:
 dsk_sh1:
        lsr     xh
        ror     xl
+       ror     yl
        dec     temp
        brne    dsk_sh1
-                                       ;xh:xl = host block to seek
+                                       ;yl:xh:xl = host block to seek
 ;      active host sector?
        sbis    flags,hostact           ;host active?
         rjmp   dsk_filhst              ;fill host if not
 
 ;      host buffer active, same as seek buffer?
        lds     temp,seekdsk
-       lds     temp3,hostdsk           ;same disk?
-       cp      temp,temp3              ;seekdsk = hostdsk?
+       lds     temp2,hostdsk           ;same disk?
+       cp      temp,temp2              ;seekdsk = hostdsk?
        brne    dsk_nomatch
 
 ;      same disk, same block?
-       lds     temp3,hostlba
-       lds     temp4,hostlba+1
-       cp      xl,temp3
-       cpc     xh,temp4        
+       lds     temp,hostlba
+       lds     temp2,hostlba+1
+       lds     temp3,hostlba+2
+       cp      xl,temp
+       cpc     xh,temp2
+       cpc     yl,temp3
        breq    dsk_match
 ;
 dsk_nomatch:
@@ -1029,6 +1160,7 @@ dsk_filhst:
        sts     hostdsk,temp
        sts     hostlba,xl
        sts     hostlba+1,xh
+       sts     hostlba+2,yl
 
        sbic    flags,rsflag            ;need to read?
         rcall  dsk_readhost            ;yes, if 1
@@ -1121,10 +1253,25 @@ dsk_writehost:
        push    yl
        push    xh
        push    xl
-       lds     xl,hostlba
-       lds     xh,hostlba+1
-       ldi     yl,0
-       ldi     yh,0
+       ldi     zl,low(hostdstart)
+       ldi     zh,high(hostdstart)
+       lds     temp,hostdsk
+       lsl     temp
+       lsl     temp
+       add     zl,temp
+       adc     zh,_0
+       
+       ldd     xl,z+0
+       ldd     xh,z+1
+       ldd     yl,z+2
+       ldd     yh,z+3
+       lds     temp,hostlba
+       add     xl,temp
+       lds     temp,hostlba+1
+       adc     xh,temp
+       lds     temp,hostlba+2
+       adc     zl,temp
+       adc     zh,_0
        rcall   mmcWriteSect
        pop     xl
        pop     xh
@@ -1142,10 +1289,25 @@ dsk_readhost:
        push    yl
        push    xh
        push    xl
-       lds     xl,hostlba
-       lds     xh,hostlba+1
-       ldi     yl,0
-       ldi     yh,0
+       ldi     zl,low(hostdstart)
+       ldi     zh,high(hostdstart)
+       lds     temp,hostdsk
+       lsl     temp
+       lsl     temp
+       add     zl,temp
+       adc     zh,_0
+
+       ldd     xl,z+0
+       ldd     xh,z+1
+       ldd     yl,z+2
+       ldd     yh,z+3
+       lds     temp,hostlba
+       add     xl,temp
+       lds     temp,hostlba+1
+       adc     xh,temp
+       lds     temp,hostlba+2
+       adc     zl,temp
+       adc     zh,_0
        rcall   mmcReadSect
        pop     xl
        pop     xh