#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 ;
-;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)
;*****************************************************
;* 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
.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
cpi temp2,1
breq conInp
+ cpi temp2,15
+ breq dskDiskCheck
+
cpi temp2,TIMER_MSECS
brlo pr_noclock
cpi temp2,TIMER_MSECS+6
breq dbgOut
cpi temp2,2
breq conOut
+
+ cpi temp2,15
+ breq dskDiskSel
cpi temp2,16
breq dskTrackSel_l
cpi temp2,17
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
lds xl,seeksec ;
ldi xh,0 ;
+ ldi yl,0 ;
lds temp3,seektrk ;
lds temp4,seektrk+1 ;
ldi temp,CPMSPT ;
adc xh,r1 ;
mul temp4,temp ;
add xh,r0 ;xh:xl := sec + trk * SectorsPerTrack
+ adc yl,r1 ;
clr _0
mov temp,xl
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:
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
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
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