.equ MEMTEST = 1
.equ BOOTWAIT = 1
.equ PORT_DEBUG = 0
-.equ DISK_DEBUG = 0
+.equ DISK_DEBUG = 0 /* Increase for more debugging */
.equ HOSTRW_DEBUG= 0
.equ MEMFILL_CB = 1
.equ STACK_DBG = 0
.if MEMTEST
rcall printstr
- .db "Testing RAM: fill...",0,0
+ .db 13,"Testing RAM: fill...",0
;Fill RAM
ldi xl,0
rcall printhex
ldi temp,'@'
rcall uartPutc
- mov temp,xh
- rcall printhex
- mov temp,xl
- rcall printhex
+ movw temp,x
+ rcall printhexw
ldi temp,13
rcall uartPutc
ramtestrok:
.endif
-
;----------------------------------------------------------------------------
-; Partition table offsets:
-#define PART_TYPE 4
-#define PART_START 8
-#define PART_SIZE 12
-
- rcall printstr
- .db "Initing mmc...",13,0
-
boot_again:
- rcall mmcInit
-;Load first sector from MMC (boot sector)
-
- ldi yh,0 ; Sector 0
- ldi yl,0
- movw x,y
- rcall mmcReadSect
-
-;Test, if it has a valid MBR
-
- ldi yl,low(hostparttbl)
- ldi yh,high(hostparttbl)
- ldi zl,low(hostbuf+510-1) ;Point to last byte of partition table
- ldi zh,high(hostbuf+510-1)
-
- ldi opl,0 ;opl holds number of found disks (paritions)
- ldd temp,z+1 ;MBR signature (0xAA55) at and of sector?
- ldd temp2,z+2
- ldi temp4,0xAA
- cpi temp,0x55
- cpc temp2,temp4
- breq boot_part
-
-;No MBR, no partition table ...
- inc opl ;pretend we have one.
- ldi temp,high((1<<16) * 128/512)
- std y+0,_0 ;start at beginning of card
- std y+1,_0
- std y+2,_0
- std y+3,_0
- std y+4,_0 ;max CP/M 2.2 disk size
- std y+5,temp
- std y+6,_0
- std y+7,_0
- rjmp boot_ipl
-
-;Search Partition Table for CP/M partitions
-boot_part:
- sbiw z,63 ;Now at first byte of partition table
- ldi oph,high(hostbuf+510)
-boot_ploop:
- ldd temp,z+PART_TYPE
- cpi temp,PARTID
- brne boot_nextp
-
-; Found a CP/M partition
-
- 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
- st y+,temp
- ldd temp2,z+PART_SIZE+1
- st y+,temp2
- ldd temp3,z+PART_SIZE+2
- st y+,temp3
- ldd temp4,z+PART_SIZE+3
- st y+,temp4
- lsr temp4
- ror temp3
- ror temp2
- ror temp
- rcall print_ultoa
- rcall printstr
- .db "KB.",13,0,0
-
- inc opl
- cpi opl,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:
-
-; Read first sector of first CP/M partition
-
- lds xl,hostparttbl
- lds xh,hostparttbl+1
- lds yl,hostparttbl+2
- lds yh,hostparttbl+3
- rcall mmcReadSect
+ rcall printstr
+ .db 13,"Initing mmc...",0
+ rcall dsk_partinit
+ rcall printstr
+ .db 13,"Partinit done.",0
-boot_ipl:
- sts ndisks,opl
- tst opl
+ lds temp,ndisks
+ tst temp
brne boot_ipl2
rcall printstr
.db "No bootable CP/M disk found! Please change MMC/SD-Card",13,0
ldi temp2,18
-boot_wl:
+boot_iplwl:
ldi temp,255
rcall delay_ms
dec temp2
- brne boot_wl
+ brne boot_iplwl
rjmp boot_again
boot_ipl2:
+; Read first sector of first CP/M partition
+
+ lds xl,hostparttbl
+ lds xh,hostparttbl+1
+ lds yl,hostparttbl+2
+ lds yh,hostparttbl+3
+ rcall mmcReadSect
+
+ rcall dsk_cboot ;init (de)blocking buffer
+
;First sector of disk or first CP/M partition is in hostbuf.
;Save to Z80 RAM (only 128 bytes because that's retro)
brne iplwriteloop
cpi zh,high(hostbuf+128)
brne iplwriteloop
- rcall dsk_boot_nommc ;init (de)blocking buffer
;Init z80
rcall printstr
.db 13,"PC=",0
- mov temp,z_pch
- rcall printhex
- mov temp,z_pcl
- rcall printhex
+ movw temp,z_pcl
+ rcall printhexw
ldi temp,' '
; ldi temp,10
; rcall uartputc
rcall printstr
.db "PC=",0
push temp
- mov temp,z_pch
- rcall printhex
- mov temp,z_pcl
- rcall printhex
+ movw temp,z_pcl
+ rcall printhexw
pop temp
rcall printstr
.db ", opcode=",0
rjmp notrace2
rcall printstr
.db ", decoded=",0,0
- mov temp,insdech
- rcall printhex
- mov temp,insdecl
- rcall printhex
+ movw temp,insdecl
+ rcall printhexw
rcall printstr
.db ".",13,0,0
notrace2:
rjmp notrace3
rcall printstr
.db "pre: oph:l=",0
- mov temp,oph
- rcall printhex
- mov temp,opl
- rcall printhex
+ mov tempw,opl
+ rcall printhexw
rcall printstr
.db " -- ",0,0
notrace3:
rjmp notrace4
rcall printstr
.db ",post:oph:l=",0,0
- mov temp,oph
- rcall printhex
- mov temp,opl
- rcall printhex
+ movw temp,opl
+ rcall printhexw
notrace4:
.endif
rjmp main
+
+
; ----------------Virtual peripherial interface ------
;The hw is modelled to make writing a CPM BIOS easier.
.cseg
+conStatus:
+
+ lds temp,rxcount
+ tst temp
+ breq PC+2
+ ldi temp,0xff
+ ret
+
+conInp:
+ rjmp uartGetc
+
+dbgOut:
+ rcall printstr
+ .db "Debug: ",0
+ rcall printhex
+ rcall printstr
+ .db 13,0
+ ret
+
+conOut:
+ rjmp uartputc
+
+
;Called with port in temp2. Should return value in temp.
portRead:
cpi temp2,0
ret
-conStatus:
-
- lds temp,rxcount
- tst temp
- breq PC+2
- ldi temp,0xff
- ret
-
-conInp:
- rjmp uartGetc
-
-dbgOut:
- rcall printstr
- .db "Debug: ",0
- rcall printhex
- rcall printstr
- .db 13,0
- ret
+dskDiskCheck:
+ lds temp,seekdsk
+ cpi temp,RAMDISKNR
+ brsh dsk_dchrd ;maybe ramdisk
-conOut:
- rjmp uartputc
+ lds temp2,ndisks ;check if selected disk # is less then # of disks
+ tst temp2
+ brne dsk_dchpart1
+; Need to init
-dskDiskCheck:
+ rcall dsk_partinit
+ lds temp2,ndisks
lds temp,seekdsk
- lds temp2,ndisks ;check if selected disk # is less then # of disks
+
+dsk_dchpart1:
cp temp,temp2
- brlt dsk_dchend
+ brsh dsk_dcher
- cpi temp,RAMDISKNR
- brlt dsk_dcher
+dsk_dchend:
+ ldi temp,0
+ ret
+
+dsk_dchrd:
cpi temp,RAMDISKNR+RAMDISKCNT
- brlt dsk_dchend
+ brlo dsk_dchend
dsk_dcher:
- ldi temp,0xff ;error return
+ ldi temp,0xff ;error return
ret
+
+
-dsk_dchend:
- ldi temp,0
- ret
dskErrorRet:
lds temp,erflag
rcall uartputc
rcall printstr
.db ": track ",0,0
- lds temp,seektrk+1
- rcall printhex
+ lds temp2,seektrk+1
lds temp,seektrk
- rcall printhex
+ rcall printhexw
rcall printstr
- .db " sector ",0,0
+ .db ", sector ",0
lds temp,seeksec
rcall printhex
rcall printstr
- .db " dma-addr ",0,0
- lds temp,dmaadr+1
- rcall printhex
+ .db ", dma-addr ",0
+ lds temp2,dmaadr+1
lds temp,dmaadr
- rcall printhex
+ rcall printhexw
pop temp
push temp
sbrs temp,WRITE_FUNC
rjmp haltinv
dsk_boot:
-; TODO: Partition table must also be reread to make this work.
-; rcall mmcInit
-dsk_boot_nommc:
+ sts ndisks,_0 ;no active partitions
+dsk_cboot:
cbi flags,hostact ;host buffer inactive
sts unacnt,_0 ;clear unalloc count
ret
mul temp2,temp
add zl,r0 ;offset in hostbuf
adc zh,r1
-.if 0 ; DISK_DEBUG
+.if DISK_DEBUG > 2
push r0
push r1
clr _0
rcall printstr
.db "; host buf adr: ",0,0
+ pop temp2
pop temp
- rcall printhex
- pop temp
- rcall printhex
+ rcall printhexw
.endif
clr _0
lds xl,dmaadr
lds xh,dmaadr+1
- ldi temp3,128 ;length of move
+ ldi temp3,128 ;length of move
sbic flags,readop ;which way?
rjmp dsk_rmove ;skip if read
DRAM_SETADDR xh, ~0,(1<<ram_ras), ~0,(1<<ram_a8)|(1<<ram_oe)
cbi P_RAS,ram_ras
-.if DISK_DEBUG
+.if DISK_DEBUG > 1
mov temp,xh
rcall printhex
rcall printstr
sbis flags,readop
rjmp rdsk_wr
-.if DISK_DEBUG
+.if DISK_DEBUG > 1
rcall printstr
.db 13,"rd-adr: ",0
.endif
rdsk_wr:
-.if DISK_DEBUG
+.if DISK_DEBUG > 1
rcall printstr
.db 13,"wr-adr: ",0
.endif
out DDRC,temp
out PORTC,temp
ret
+
+;---------------------------------------------------------------------
+
+; Partition table offsets:
+#define PART_TYPE 4
+#define PART_START 8
+#define PART_SIZE 12
+
+ .dseg
+tmp_tbl:
+ .byte 8*MAXDISKS
+
+ .cseg
+dsk_partinit:
+
+ rcall mmcInit
+
+;Load first sector from MMC (boot sector)
+
+ ldi yh,0 ; Sector 0
+ ldi yl,0
+ movw x,y
+ rcall mmcReadSect
+
+ ldi yl,low(tmp_tbl)
+ ldi yh,high(tmp_tbl)
+ ldi temp2,8*MAXDISKS
+dsk_picl:
+ st y+,_0
+ dec temp2
+ brne dsk_picl
+ sbiw y,8*MAXDISKS
+#if 0
+ rcall printstr
+ .db ", ",0,0
+ movw temp,y
+ rcall printhexw
+#endif
+
+;Test, if it has a valid MBR
+
+ ldi zl,low(hostbuf+510-1) ;Point to last byte of partition table
+ ldi zh,high(hostbuf+510-1)
+
+ ldi temp3,0 ;temp3 holds number of found disks (paritions)
+ ldd temp,z+1 ;MBR signature (0xAA55) at and of sector?
+ ldd temp2,z+2
+ ldi temp4,0xAA
+ cpi temp,0x55
+ cpc temp2,temp4
+ breq dsk_part
+
+;No MBR, no partition table ...
+ inc temp3 ;pretend we have one.
+ ldi temp,high((1<<16) * 128/512)
+ std y+0,_0 ;start at beginning of card
+ std y+1,_0
+ std y+2,_0
+ std y+3,_0
+ std y+4,_0 ;max CP/M 2.2 disk size
+ std y+5,temp ;
+ std y+6,_0
+ std y+7,_0
+ rjmp dsk_pend
+
+;Search Partition Table for CP/M partitions
+dsk_part:
+ sbiw z,63 ;Now at first byte of partition table
+ ldi temp4,high(hostbuf+510)
+dsk_ploop:
+ ldd temp,z+PART_TYPE
+ cpi temp,PARTID
+ brne dsk_nextp
+
+; Found a CP/M partition
+
+ ldd temp,z+PART_START
+ st y+,temp
+ ldd temp,z+PART_START+1
+ st y+,temp
+ ldd temp,z+PART_START+2
+ st y+,temp
+ ldd temp,z+PART_START+3
+ st y+,temp
+
+ ldd temp,z+PART_SIZE
+ st y+,temp
+ ldd temp,z+PART_SIZE+1
+ st y+,temp
+ ldd temp,z+PART_SIZE+2
+ st y+,temp
+ ldd temp,z+PART_SIZE+3
+ st y+,temp
+
+
+ inc temp3
+ cpi temp3,MAXDISKS
+ breq dsk_pend
+dsk_nextp:
+ adiw zl,16
+ cpi zl,low(hostbuf+510)
+ cpc zh,temp4
+ brlo dsk_ploop
+
+dsk_pend:
+ sts ndisks,temp3
+
+;Store new partitions and check if the SD card has been changed.
+
+ ldi yl,low(tmp_tbl)
+ ldi yh,high(tmp_tbl)
+ ldi zl,low(hostparttbl)
+ ldi zh,high(hostparttbl)
+ ldi temp3,8*MAXDISKS
+ clt
+dsk_pcpl:
+ ld temp,y+
+ ld temp2,z
+ st z+,temp
+ cp temp,temp2
+ cpse temp,temp2
+ set
+ dec temp3
+ brne dsk_pcpl
+
+ brtc dsk_pcpe
+
+ lds temp,ndisks
+ tst temp
+ breq dsk_pcpe
+
+; SD card changed, print Info.
+
+ sbiw z,8*MAXDISKS
+
+dsk_pprl:
+ ldd temp,z+4
+ ldd temp2,z+5
+ or temp,temp2
+ ldd temp2,z+6
+ or temp,temp2
+ ldd temp2,z+7
+ or temp,temp2
+
+ breq dsk_pcpe
+
+ rcall printstr
+ .db 13,"CP/M partition at: ",0,0
+ ldd temp,z+0
+ ldd temp2,z+1
+ ldd temp3,z+2
+ ldd temp4,z+3
+ rcall print_ultoa
+ rcall printstr
+ .db ", size: ",0,0
+ ldd temp,z+4
+ ldd temp2,z+5
+ ldd temp3,z+6
+ ldd temp4,z+7
+ lsr temp4
+ ror temp3
+ ror temp2
+ ror temp
+ rcall print_ultoa
+ rcall printstr
+ .db "KB.",0
+ adiw z,8
+ ldi temp,high(hostparttbl)
+ cpi xl,low (hostparttbl)
+ cpc xh,temp
+ brlo dsk_pprl
+
+dsk_pcpe:
+ lds temp,ndisks
+ ret
+
;***************************************************************************
; ----------------- MMC/SD routines ------------------
;Read OCR till card is ready
- ldi temp2,20 ;repeat counter
+ ldi temp2,100 ;repeat counter
mmcInitOcrLoop:
push temp2
ldi temp2,1
rcall mmcWaitResp ;wait until mmc-card send a byte <> 0xFF
- ;the first answer must be 0x01 (Idle-Mode)
+ ;the first answer must be 0x01 (Idle-Mode)
cpi temp,0
- breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK
+ breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK
sbi P_MMC_CS,mmc_cs ;disable /CS
-; rcall mmcByteNoSend ;unnecessary
+ rcall mmcByteNoSend
ldi temp,10
rcall delay_ms
pop temp2
dec temp2
- cpi temp2,0
brne mmcInitOcrLoop ;repeat
ldi temp2,4
;Set up wdt to time out after 1 sec.
resetAVR:
+ lds temp,txcount ;Wait, till tx buffer is empty
+ tst temp
+ brne resetAVR
+
cli
ldi temp,(1<<WDCE)
outm8 WDTCSR,temp
cpc zh,zl
brlo syscl_end
- sts cnt_1ms,_0
- sts cnt_1ms+1,_0
+ ldi zl,0 ;can't use _0 register in int.
+ sts cnt_1ms,zl
+ sts cnt_1ms+1,zl
lds zl,uptime+0
inc zl
ret
-;Prints the lower nibble of temp in hex to the uart
+;Prints temp2:temp in hex to the uart
+printhexw:
+ push temp
+ mov temp,temp2
+ rcall printhex
+ pop temp
+ ;fall thru
+
+;Prints temp in hex to the uart
+printhex:
+ swap temp
+ rcall printhexn
+ swap temp
+ ;fall thru
+
+;Prints the lower nibble
printhexn:
push temp
andi temp,0xf
cpi temp,0xA
brlo printhexn_isno
- subi temp,-('A'-10)
- rcall uartputc
- pop temp
- ret
+ subi temp,-7
printhexn_isno:
subi temp,-'0'
rcall uartputc
pop temp
ret
-;Prints temp in hex to the uart
-printhex:
- swap temp
- rcall printhexn
- swap temp
- rcall printhexn
- ret
-
;Prints the zero-terminated string following the call statement.
printstr:
.if STACK_DBG
rcall printstr
.db "Stack push ",0
- mov temp,oph
- rcall printhex
- mov temp,opl
- rcall printhex
+ mov tempw,opl
+ rcall printhexw
rcall printstr
.db ", SP is now ",0
- mov temp,z_sph
- rcall printhex
- mov temp,z_spl
- rcall printhex
+ mov tempw,z_spl
+ rcall printhexw
rcall printstr
.db ".",13,0
.endif
.if STACK_DBG
rcall printstr
.db "Stack pop: val ",0
- mov temp,oph
- rcall printhex
- mov temp,opl
- rcall printhex
+ movw temp,opl
+ rcall printhexw
rcall printstr
.db ", SP is now",0
- mov temp,z_sph
- rcall printhex
- mov temp,z_spl
- rcall printhex
+ movw temp,z_spl
+ rcall printhexw
rcall printstr
.db ".",13,0
.endif
do_op_inv:
rcall printstr
.db "Invalid opcode @ PC=",0,0
- mov temp,z_pch
- rcall printhex
- mov temp,z_pcl
- rcall printhex
+ movw temp,z_pcl
+ rcall printhexw
;----------------------------------------------------------------
haltinv: