From 66faee4cd936c9a6b7a28745aec45cd5877ce07a Mon Sep 17 00:00:00 2001 From: Leo Date: Wed, 28 Jul 2010 20:21:17 +0000 Subject: [PATCH] * avr/z80.asm: - Scan partition table of sd-card and mount CP/M partitions as disk drives. * cpm/bios.asm: - seldsk: More then 1 disk selectable (4 for now). The actual number of disks will be determined in avr-part. - dph/dpb tables extended accordingly. git-svn-id: svn://cu.loc/avr-cpm/trunk@60 57430480-672e-4586-8877-bcf8adbbf3b7 --- avrcpm/avr/z80.asm | 196 ++++++++++++++++++++++++++++++++++++++++---- avrcpm/cpm/bios.asm | 60 +++++++++++--- 2 files changed, 227 insertions(+), 29 deletions(-) diff --git a/avrcpm/avr/z80.asm b/avrcpm/avr/z80.asm index 333350f..e61fc13 100644 --- a/avrcpm/avr/z80.asm +++ b/avrcpm/avr/z80.asm @@ -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 */ @@ -161,6 +163,8 @@ .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 diff --git a/avrcpm/cpm/bios.asm b/avrcpm/cpm/bios.asm index a242c55..a91de4f 100644 --- a/avrcpm/cpm/bios.asm +++ b/avrcpm/cpm/bios.asm @@ -171,10 +171,18 @@ seldsk: ld hl,0 ;error return code ld a,c out (15),a - cp 0 ;only one disk supportet - jp nz,seldsk_na - ld hl,dph ;return disk parameter header address -seldsk_na: + in a,(15) ;querry, if disk exists + or a ;0 = disk is ok + ret nz + + ld l,c + ld h,0 + add hl,hl + add hl,hl + add hl,hl + add hl,hl ;*16 + ld de,dpbase + add hl,de ;return disk parameter header address ret home: @@ -240,15 +248,39 @@ prmsg: ;Disk Parameter Header -dph: - dw 0 ;XLT: No sector translation table +dpbase: +dpe0: dw 0 ;XLT: No sector translation table + dw 0 ;000: Scratchpad + dw 0 ;000: Scratchpad + dw 0 ;000: Scratchpad + dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad + dw dpb ;DPB: Address of a disk parameter block + dw chk0 ;CSV: Address of scratchpad area for changed disks + dw all0 ;ALV: Address of an allocation info sratchpad +dpe1: dw 0 ;XLT: No sector translation table + dw 0 ;000: Scratchpad + dw 0 ;000: Scratchpad + dw 0 ;000: Scratchpad + dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad + dw dpb ;DPB: Address of a disk parameter block + dw chk1 ;CSV: Address of scratchpad area for changed disks + dw all1 ;ALV: Address of an allocation info sratchpad +dpe2: dw 0 ;XLT: No sector translation table + dw 0 ;000: Scratchpad + dw 0 ;000: Scratchpad + dw 0 ;000: Scratchpad + dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad + dw dpb ;DPB: Address of a disk parameter block + dw chk2 ;CSV: Address of scratchpad area for changed disks + dw all2 ;ALV: Address of an allocation info sratchpad +dpe3: dw 0 ;XLT: No sector translation table dw 0 ;000: Scratchpad dw 0 ;000: Scratchpad dw 0 ;000: Scratchpad dw dirbuf ;DIRBUF: Address of a dirbuff scratchpad dw dpb ;DPB: Address of a disk parameter block - dw chk ;CSV: Address of scratchpad area for changed disks - dw all ;ALV: Address of an allocation info sratchpad + dw chk3 ;CSV: Address of scratchpad area for changed disks + dw all3 ;ALV: Address of an allocation info sratchpad dpb: dw 26 ;SPT: sectors per track @@ -266,10 +298,14 @@ dpb: dirbuf: ds 128 -chk: - ds 16 +chk0: ds 16 +all0: ds 31 +chk1: ds 16 +all1: ds 31 +chk2: ds 16 +all2: ds 31 +chk3: ds 16 +all3: ds 31 -all: - ds 31 end -- 2.39.2