;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
+;
+; $Id$
+;
;.nolist
#if defined atmega8
#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 */
#define RXBUFSIZE 64 /* USART recieve buffer size. Must be power of 2 */
#define TXBUFSIZE 64 /* USART transmit buffer size. Must be power of 2 */
+#define DRAM_WAITSTATES 1 /* Number of additional clock cycles for dram read access */
#define REFR_RATE 64000 /* dram refresh rate in cycles/s. */
/* Most drams need 1/15.6µs. */
#define REFR_PRE 8 /* timer prescale factor */
#define REFR_CNT F_CPU / REFR_RATE / REFR_PRE
-#if defined __ATmega8__
- .equ refr_vect = OC2addr
-#else
- .equ refr_vect = OC2Aaddr
-#endif
#define DRAM_WORD_ACCESS 0 /* experimental */
.equ BOOTWAIT = 1
.equ PORT_DEBUG = 0
.equ DISK_DEBUG = 0
+.equ HOSTRW_DEBUG= 0
.equ MEMFILL_CB = 1
.equ STACK_DBG = 0
.equ PRINT_PC = 0
.equ ZFL_C = 0
;Register definitions
-.undef xl ;r26
-.undef xh ;r27
.def _tmp = r0 ; 0
.def _0 = r1
.def oph = r23 ;
.def z_pcl = r24 ;
.def z_pch = r25 ;
-.def adrl = r26 ;
-.def adrh = r27 ;
+; xl ;r26
+; xh ;r27
; yl ;r28
; yh ;r29
; zl ;r30 ;
.equ UBRR0H = UBRRH
.equ UBRR0L = UBRRL
.equ OCR2A = OCR2
+.equ OC2Aaddr= OC2addr
.equ TCCR2A = TCCR2
.equ TCCR2B = TCCR2
.equ TIMSK1 = TIMSK
+;----------------------------------------
+; add wait states
+; dram_wait number_of_cycles
+
+.macro dram_wait
+.if @0 > 1
+ rjmp PC+1
+ dram_wait @0 - 2
+.elif @0 > 0
+ nop
+ dram_wait @0 - 1
+.endif
+.endm
+
+
.cseg
.org 0
rjmp start ; reset vector
-.org refr_vect
+.org OC2Aaddr
rjmp refrint ; tim2cmpa
.org OC1Aaddr ; Timer/Counter1 Compare Match A
rjmp sysclockint ; 1ms system timer
ldi temp,(1<<WDCE)
outm8 WDTCSR,temp
+; - Clear RAM
+
+ ldi zl,low(SRAM_START)
+ ldi zh,high(SRAM_START)
+ ldi temp2,high(ramtop)
+clr_l:
+ st z+,_0
+ cpi zl,low(ramtop)
+ cpc zh,temp2
+ brne clr_l
+
; - Setup Ports
ldi temp,(1<<PUD) ;disable pullups
outm8 P_PUD,temp
; - Init serial port
- sts rxcount,_0 ; reset receive buffer
- sts rxidx_r,_0
- sts rxidx_w,_0
- sts txcount,_0 ; reset transmit buffer
- sts txidx_r,_0
- sts txidx_w,_0
-
ldi temp, (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0)
outm8 UCSR0B,temp
.ifdef URSEL
ldi temp, LOW(UBRR_VAL)
outm8 UBRR0L,temp
-;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
-
- ldi temp,REFR_CNT*2 ; 2 cycles per int
- outm8 OCR2A,temp
- inm8 temp,TCCR2A
- ori temp,(1<<WGM21) ;CTC mode
- outm8 TCCR2A,temp
- inm8 temp,TCCR2B
- ori temp,REFR_CS ;clk/REFR_PRE
- outm8 TCCR2B,temp
- inm8 temp,TIMSK2
- ori temp, (1<<OCIE2A)
- outm8 TIMSK2,temp
-
; Init clock/timer system
- ldi zl,low(timer_base)
- ldi zh,high(timer_base)
- ldi temp2,timer_size
-ti_loop:
- st z+,_0
- dec temp2
- brne ti_loop
-
; Init timer 1 as 1 ms system clock tick.
ldi temp,high(F_CPU/1000)
ori temp,(1<<OCIE1A)
outm8 TIMSK1,temp
+;Init timer2. Refresh-call should happen every (8ms/512)=312 cycles.
+
+ ldi temp,REFR_CNT*2 ; 2 cycles per int
+ outm8 OCR2A,temp
+ inm8 temp,TCCR2A
+ ori temp,(1<<WGM21) ;CTC mode
+ outm8 TCCR2A,temp
+ inm8 temp,TCCR2B
+ ori temp,REFR_CS ;clk/REFR_PRE
+ outm8 TCCR2B,temp
+ inm8 temp,TIMSK2
+ ori temp, (1<<OCIE2A)
+ outm8 TIMSK2,temp
+
sei
.db "CPM on an AVR, v1.0",13,0,0
- rcall printstr
- .db "Initing mmc...",13,0
- rcall mmcInit
-
-
.if MEMTEST
rcall printstr
.db "Testing RAM: fill...",0,0
;Fill RAM
- ldi adrl,0
- ldi adrh,0
+ ldi xl,0
+ ldi xh,0
ramtestw:
- mov temp,adrh
- eor temp,adrl
+ mov temp,xh
+ eor temp,xl
rcall memwritebyte
- adiw adrl,1
+ adiw xl,1
brcc ramtestw
rcall printstr
.db "wait...",0
.db "reread...",13,0,0
;re-read RAM
- ldi adrl,0
- ldi adrh,0
+ ldi xl,0
+ ldi xh,0
ramtestr:
rcall memReadByte
- mov temp2,adrh
- eor temp2,adrl
+ mov temp2,xh
+ eor temp2,xl
cp temp,temp2
breq ramtestrok
rcall printhex
ldi temp,'<'
rcall uartPutc
- mov temp,adrh
- eor temp,adrl
+ mov temp,xh
+ eor temp,xl
rcall printhex
ldi temp,'@'
rcall uartPutc
- mov temp,adrh
+ mov temp,xh
rcall printhex
- mov temp,adrl
+ mov temp,xl
rcall printhex
ldi temp,13
rcall uartPutc
ramtestrok:
- adiw adrl,1
+ adiw xl,1
brcc ramtestr
.endif
.if MEMFILL_CB
;Fill ram with cbs, which (for now) will trigger an invalid opcode error.
- ldi adrl,0
- ldi adrh,0
+ ldi xl,0
+ ldi xh,0
ramfillw:
ldi temp,0xcb
rcall memwritebyte
- adiw adrl,1
+ adiw xl,1
brcc ramfillw
.endif
+ rcall printstr
+ .db "Initing mmc...",13,0
+ rcall mmcInit
+
+;----------------------------------------------------------------------------
+
+; Partition table 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
+ movw x,y
+ 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
+ ldi opl,0 ;opl holds number of found disks (paritions)
+ breq boot_part
+
+;No MBR, no partition table ...
+ inc opl ;pretend we have one.
+ 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(hostparttbl)
+ ldi yh,high(hostparttbl)
+ 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
+
+boot_ipl:
+ sts ndisks,opl
+ 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:
-;Load initial sector from MMC (512 bytes)
- ldi adrh,0
- ldi adrl,0
- rcall mmcReadSect
+;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)
- ldi adrh,0x20
- ldi adrl,0x00
+ ldi xh,0x20
+ ldi xl,0x00
iplwriteloop:
ld temp,z+
rcall memWriteByte
- adiw adrl,1
+ adiw xl,1
cpi zl,low(hostbuf+128)
brne iplwriteloop
cpi zh,high(hostbuf+128)
brsh noprintpc
rcall printstr
- .db "PC=",0
+ .db 13,"PC=",0
mov temp,z_pch
rcall printhex
mov temp,z_pcl
rcall printhex
- ldi temp,10
- rcall uartputc
+ ldi temp,' '
+; ldi temp,10
+; rcall uartputc
noprintpc:
.endif
; *** Stage 1: Fetch next opcode
- movw adrl,z_pcl
+ movw xl,z_pcl
rcall memReadByte
;18 - Sector select
;20 - Write addr l
;21 - Write addr h
-;22 - Trigger - write 1 to read, 2 to write a sector using the above info;
-; 3 - 5, write to allocated/dirctory/unallocated
+;22 - Trigger - write to read, to write a sector using the above info;
+; , write to allocated/dirctory/unallocated
.equ READ_FUNC = 7
.equ WRITE_FUNC = 6
;*****************************************************
;* 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
+hostparttbl: .byte 8*MAXDISKS ; host partition table (start sector, sector count)
hostdsk: .byte 1 ;host disk number
-hostlba: .byte 2 ;host track number
+hostlba: .byte 3 ;host sector number (relative to partition start)
unacnt: .byte 1 ;unalloc rec cnt
unadsk: .byte 1 ;last unalloc disk
cpi temp2,1
breq conInp
+ cpi temp2,15
+ breq dskDiskCheck
+ cpi temp2,22
+ breq dskErrorRet
+
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
+
+dsk_dchend:
+ ldi temp,0
+ ret
+
+dskErrorRet:
+ lds temp,erflag
+ ret
+
+dskDiskSel:
+ sts seekdsk,temp
+ ret
dskTrackSel_l:
sts seektrk,temp
ret
dskDoIt:
+.if DISK_DEBUG
+ push temp
+ sbrc temp,READ_FUNC
+ rjmp dskdbgr
+ sbrc temp,WRITE_FUNC
+ rjmp dskdbgw
+ rjmp dskdbge
+
+dskdbgr:
+ rcall printstr
+ .db 13,"Disk read: ",0
+ rjmp dskdbg1
+dskdbgw:
+ rcall printstr
+ .db 13,"Disk write: ",0
+dskdbg1:
+ lds temp,seekdsk
+ subi temp,-('A')
+ rcall uartputc
+ rcall printstr
+ .db ": track ",0,0
+ lds temp,seektrk+1
+ rcall printhex
+ lds temp,seektrk
+ rcall printhex
+ rcall printstr
+ .db " sector ",0,0
+ lds temp,seeksec
+ rcall printhex
+ rcall printstr
+ .db " dma-addr ",0,0
+ lds temp,dmaadr+1
+ rcall printhex
+ lds temp,dmaadr
+ rcall printhex
+ pop temp
+ push temp
+ sbrs temp,WRITE_FUNC
+ rjmp dskdbge
+ rcall printstr
+ .db " wrtype ",0,0
+ andi temp,3
+ rcall printhex
+dskdbge:
+ pop temp
+.endif
;See what has to be done.
sbrc temp,READ_FUNC
rjmp dsk_read
dsk_read:
-.if 0
- rcall timer_quit
- rcall printstr
- .db " In",0
-.endif
+ sbi flags,readop ;read operation
+ ;RAM disk?
+ lds temp2,seekdsk
+; cpi temp2,RAMDISKNR
+; brlt PC+2
+; rjmp rdskDoIt
-.if DISK_DEBUG
- push temp
- rcall printstr
- .db 13,0
- rcall printstr
- .db "Disk read: track ",0
- lds temp,seektrk+1
- rcall printhex
- lds temp,seektrk
- rcall printhex
- rcall printstr
- .db " sector ",0,0
- lds temp,seeksec
- rcall printhex
- rcall printstr
- .db " dma-addr ",0,0
- lds temp,dmaadr+1
- rcall printhex
- lds temp,dmaadr
- rcall printhex
-; rcall printstr
-; .db ".",13,0,0
- pop temp
-.endif
sts unacnt,_0
- sbi flags,readop ;read operation
sbi flags,rsflag ;must read data
ldi temp,WRUAL ;write type
sts wrtype,temp ;treat as unalloc
dsk_write:
;write the selected CP/M sector
- andi temp,WRTMSK
- sts wrtype,temp ;save write type
cbi flags,readop ;not a read operation
-.if DISK_DEBUG
- push temp
- rcall printstr
- .db 13,0
- rcall printstr
- .db "Disk write: track ",0,0
- lds temp,seektrk+1
- rcall printhex
- lds temp,seektrk
- rcall printhex
- rcall printstr
- .db " sector ",0,0
- lds temp,seeksec
- rcall printhex
- rcall printstr
- .db " dma-addr ",0,0
- lds temp,dmaadr+1
- rcall printhex
- lds temp,dmaadr
- rcall printhex
- rcall printstr
- .db " wrtype ",0,0
- lds temp,wrtype
- rcall printhex
-; rcall printstr
-; .db ".",13,0,0
- pop temp
-.endif
+ ;RAM disk?
+ lds temp2,seekdsk
+; cpi temp2,RAMDISKNR
+; brlt PC+2
+; rjmp rdskDoIt
+ andi temp,WRTMSK
+ sts wrtype,temp ;save write type
cpi temp,WRUAL ;write unallocated?
brne dsk_chkuna ;check for unalloc
dsk_rwoper:
;enter here to perform the read/write
+.if DISK_DEBUG
+ rcall printstr
+ .db ", flags: ",0
+ in temp,flags
+ rcall printhex
+.endif
sts erflag,_0 ;no errors (yet)
;Convert track/sector to an LBA address (in 128byte blocks)
- lds adrl,seeksec ;
- ldi adrh,0 ;
+ lds xl,seeksec ;
+ ldi xh,0 ;
+ ldi yl,0 ;
lds temp3,seektrk ;
lds temp4,seektrk+1 ;
ldi temp,CPMSPT ;
mul temp3,temp ;
- add adrl,r0 ;
- adc adrh,r1 ;
+ add xl,r0 ;
+ adc xh,r1 ;
mul temp4,temp ;
- add adrh,r0 ;adrh:adrl := sec + trk * SectorsPerTrack
+ add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack
+ adc yl,r1 ;
clr _0
- mov temp,adrl
+ mov temp,xl
andi temp,SECMSK ;mask buffer number
push temp ;save for later
-.if DISK_DEBUG
- rcall printstr
- .db "; bufnr: ",0,0
- rcall printhex
-.endif
;Convert from CP/M LBA blocks to host LBA blocks
ldi temp,SECSHF
dsk_sh1:
- lsr adrh
- ror adrl
+ lsr yl
+ ror xh
+ ror xl
dec temp
brne dsk_sh1
- ;adrh:adrl = host block to seek
+ ;yl:xh:xl = host block to seek
; active host sector?
- sbis flags,hostact ;host active?
+ in _tmp,flags ;host active flag
+ sbi flags,hostact ;always becomes 1
+ sbrs _tmp,hostact ;was it already?
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 adrl,temp3
- cpc adrh,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:
;proper disk, but not correct sector
- sbic flags,hostwrt ;host written?
+ sbis flags,hostwrt ;host written?
+ rjmp dsk_filhst
+ push xl
+ push xh
+ push yl
rcall dsk_writehost ;clear host buff
+ pop yl
+ pop xh
+ pop xl
dsk_filhst:
;may have to fill the host buffer
lds temp,seekdsk
sts hostdsk,temp
- sts hostlba,adrl
- sts hostlba+1,adrh
+ sts hostlba,xl
+ sts hostlba+1,xh
+ sts hostlba+2,yl
sbic flags,rsflag ;need to read?
rcall dsk_readhost ;yes, if 1
cbi flags,hostwrt ;no pending write
dsk_match:
- sbi flags,hostact ;host buffer active now
;copy data to or from buffer
ldi zl,low(hostbuf)
mul temp2,temp
add zl,r0 ;offset in hostbuf
adc zh,r1
-.if DISK_DEBUG
+.if 0 ; DISK_DEBUG
push r0
push r1
clr _0
.endif
clr _0
- lds adrl,dmaadr
- lds adrh,dmaadr+1
- push yl
- ldi yl,128 ;length of move
+ lds xl,dmaadr
+ lds xh,dmaadr+1
+ ldi temp3,128 ;length of move
sbic flags,readop ;which way?
rjmp dsk_rmove ;skip if read
; mark write operation
sbi flags,hostwrt ;hostwrt = 1
dsk_wmove:
- rcall memReadByte
- st z+,temp
- adiw adrl,1
- dec yl
+ rcall memReadByte
+ st z+,temp
+ adiw xl,1
+ dec temp3
brne dsk_wmove
rjmp dsk_rwmfin
dsk_rmove:
ld temp,z+
rcall memWriteByte
- adiw adrl,1
- dec yl
+ adiw xl,1
+ dec temp3
brne dsk_rmove
dsk_rwmfin:
- pop yl
; data has been moved to/from host buffer
lds temp,wrtype ;write type
cpi temp,WRDIR ;to directory?
breq dsk_wdir
- lds temp,erflag
-.if 0
- rcall timer_quit
- rcall printstr
- .db " Out",0
-.endif
ret ;no further processing
dsk_wdir:
; clear host buffer for directory write
dsk_wdir1:
rcall dsk_writehost ;clear host buff
cbi flags,hostwrt ;buffer written
- lds temp,erflag
ret
+;*****************************************************
+
+; hostdsk = host disk #, (partition #)
+; hostlba = host block #, relative to partition start
+; Read/Write "hostsize" bytes to/from hostbuf
+
+
+dsk_hostparam:
+ ldi zl,low(hostparttbl)
+ ldi zh,high(hostparttbl)
+ lds temp,hostdsk
+.if HOSTRW_DEBUG
+ push temp
+ subi temp,-('A')
+ rcall uartputc
+ rcall printstr
+ .db ": ",0,0
+ pop temp
+.endif
+
+ lsl temp
+ lsl temp
+ lsl temp
+ add zl,temp
+ adc zh,_0
+
+ lds temp,hostlba
+ lds temp2,hostlba+1
+ lds temp3,hostlba+2
+
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db "lba: ",0
+ clr temp4
+ rcall print_ultoa
+.endif
+
+ ldd xl,z+4
+ ldd xh,z+5
+ ldd yl,z+6
+
+ cp temp,xl
+ cpc temp2,xh
+ cpc temp3,yl
+ brcs dsk_hp1
+
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db ", max: ",0
+ push temp4
+ push temp3
+ push temp2
+ push temp
+ movw temp,x
+ mov temp3,yl
+ clr temp4
+ rcall print_ultoa
+ pop temp
+ pop temp2
+ pop temp3
+ pop temp4
+ rcall printstr
+ .db " ",0
+.endif
+
+ clr temp
+ ret
+
+dsk_hp1:
+ ldd xl,z+0
+ ldd xh,z+1
+ ldd yl,z+2
+ ldd yh,z+3
+
+ add xl,temp
+ adc xh,temp2
+ adc zl,temp3
+ adc zh,_0
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db ", abs:",0,0
+ push temp4
+ push temp3
+ push temp2
+ push temp
+ movw temp,x
+ movw temp3,y
+ rcall print_ultoa
+ pop temp
+ pop temp2
+ pop temp3
+ pop temp4
+ rcall printstr
+ .db " ",0
+.endif
+ ori temp,255
+dsk_hpex:
+ ret
;*****************************************************
;* WRITEhost performs the physical write to *
;*****************************************************
dsk_writehost:
- ;hostdsk = host disk #, hostlba = host block #.
- ;Write "hostsize" bytes from hostbuf and return
- ;error flag in erflag.
- ;Return erflag non-zero if error
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db 13,"host write ",0,0
+.endif
+ rcall dsk_hostparam
+ brne dsk_wr1
+ ldi temp,255
+ sts erflag,temp
+ ret
- push adrh
- push adrl
- lds adrl,hostlba
- lds adrh,hostlba+1
+dsk_wr1:
rcall mmcWriteSect
- pop adrl
- pop adrh
sts erflag,_0
ret
dsk_readhost:
- ;hostdsk = host disk #, hostlba = host block #.
- ;Read "hostsiz" bytes into hostbuf and return
- ;error flag in erflag.
-
- push adrh
- push adrl
- lds adrl,hostlba
- lds adrh,hostlba+1
+.if HOSTRW_DEBUG
+ rcall printstr
+ .db 13,"host read ",0,0
+.endif
+ rcall dsk_hostparam
+ brne dsk_rd1
+ ldi temp,255
+ sts erflag,temp
+ ret
+
+dsk_rd1:
rcall mmcReadSect
- pop adrl
- pop adrh
sts erflag,_0
ret
mmcByte:
.if MMC_DEBUG
- push zl
- push zh
rcall printstr
.db "MMC: <--",0
rcall printhex
in temp,SPDR
.if MMC_DEBUG
- push temp
rcall printstr
.db ", -->",0
rcall printhex
rcall printstr
.db ".",13,0
- pop temp
- pop zh
- pop zl
.endif
ret
ret
-;Call this with adrh:adrl = sector number
-;16bit lba address means a max reach of 32M.
+;Call this with yh:yl:xh:xl = sector number
+;
mmcReadSect:
ldi temp,0x50
out SPCR,temp
rcall mmcByteNoSend
ldi temp,0x51 ;cmd (read sector)
rcall mmcByte
- ldi temp,0
- lsl adrl
- rol adrh
- rol temp
+ lsl xl ;convert to byte address (*512)
+ rol xh
+ rol yl
+ mov temp,yl
rcall mmcByte
- mov temp,adrh ;pxl
+ mov temp,xh ;pxl
rcall mmcByte
- mov temp,adrl ;pyh
+ mov temp,xl ;pyh
rcall mmcByte
ldi temp,0 ;pyl
rcall mmcByte
ret
-;Call this with adrh:adrl = sector number
-;16bit lba address means a max reach of 32M.
+;Call this with yh:yl:xh:xl = sector number
+;
mmcWriteSect:
ldi temp,0x50
out SPCR,temp
ldi temp,0x58 ;cmd (write sector)
rcall mmcByte
- ldi temp,0
- lsl adrl
- rol adrh
- rol temp
+ lsl xl ;convert to byte address (*512)
+ rol xh
+ rol yl
+ mov temp,yl
rcall mmcByte
- mov temp,adrh ;pxl
+ mov temp,xh ;pxl
rcall mmcByte
- mov temp,adrl ;pyh
+ mov temp,xl ;pyh
rcall mmcByte
ldi temp,0 ;pyl
rcall mmcByte
out P_AH,temp
.endm
-;Loads the byte on address adrh:adrl into temp.
-;must not alter adrh:adrl
+;Loads the byte on address xh:xl into temp.
+;must not alter xh:xl
dram_read:
cli
- DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8), (1<<ram_oe)
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8), (1<<ram_oe)
cbi P_RAS,ram_ras
- DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
cbi P_CAS,ram_cas
cbi P_A8,ram_a8
- nop
+ dram_wait DRAM_WAITSTATES ;
in temp,P_DQ-2 ; PIN
sbi P_CAS,ram_cas
cbi P_CAS,ram_cas
andi temp,0x0f
swap temp
- nop
+ dram_wait DRAM_WAITSTATES ;
in temp2,P_DQ-2 ; PIN
andi temp2,0x0f
or temp,temp2
#if DRAM_WORD_ACCESS
dram_read_w:
- cpi adrl,255
+ cpi xl,255
brne dram_read_w1
rcall dram_read
push temp
- adiw adrl,1
+ adiw xl,1
rcall dram_read
mov temp2,temp
pop temp
dram_read_w1:
cli
- DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
cbi P_RAS,ram_ras
- DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
cbi P_CAS,ram_cas
cbi P_A8,ram_a8
nop
; push temp
mov _wl,temp
- inc adrl
- DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
+ inc xl
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_oe)), (1<<ram_a8)
cbi P_CAS,ram_cas
cbi P_A8,ram_a8
nop
ret
#endif
-;Writes the byte in temp to adrh:adrl
-;must not alter adrh:adrl
+;Writes the byte in temp to xh:xl
+;must not alter xh:xl
dram_write:
cli
andi temp,RAM_DQ_MASK & ~(1<<ram_w)
ori temp,(1<<ram_cas)
out PORTC,temp
- DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
cbi P_RAS,ram_ras
- DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
cbi PORTC,ram_cas
sbi PORTC,ram_cas
#if DRAM_WORD_ACCESS
dram_write_w:
- cpi adrl,255
+ cpi xl,255
brne dram_write_w1
push temp2
rcall dram_write
pop temp
- adiw adrl,1
+ adiw xl,1
rcall dram_write
ret
ori temp,(1<<ram_cas)
out PORTC,temp
- DRAM_SETADDR adrh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
+ DRAM_SETADDR xh, ~0,(1<<ram_ras), ~(1<<ram_a8),(1<<ram_oe)
cbi P_RAS,ram_ras
- DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
cbi PORTC,ram_cas
sbi PORTC,ram_cas
sbi PORTC,ram_cas
pop temp
- inc adrl
+ inc xl
mov temp2,temp
andi temp,RAM_DQ_MASK & ~(1<<ram_w)
ori temp,(1<<ram_cas)
out PORTC,temp
- DRAM_SETADDR adrl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
+ DRAM_SETADDR xl, ~(1<<ram_ras),0, ~((1<<ram_a8)),(1<<ram_oe)
cbi PORTC,ram_cas
sbi PORTC,ram_cas
; ****************************************************************************
; refresh interupt; exec 2 cbr cycles
-refrint:
- ;4 CAS RAS
+refrint: ;4
+
+ sbis P_RAS,ram_ras ;2
+ reti
+ ; CAS RAS
cbi P_CAS,ram_cas ;2 1| 1|
; 1| 1|
cbi P_RAS,ram_ras ;2 |0 1|
; nop ;1 |0 |0
sbi P_RAS,ram_ras ;2 |0 |0
; |0 |0
+ dram_wait DRAM_WAITSTATES-1 ;
; nop ;1 |0 |0
cbi P_RAS,ram_ras ;2 |0 1|
; |0 1|
; 1| 1|
reti ;4 --> 21 cycles
-; ****************************************************************************
; ------------- system timer 1ms ---------------
.dseg
push yh
push yl
push z_flags
+ push temp4
+ push temp3
+ push temp2
+ push temp
clr yl ;yl = stack level
dec yl
brne ultoa6
+ pop temp
+ pop temp2
+ pop temp3
+ pop temp4
pop z_flags
pop yl
pop yh
push yh
push yl
push temp
- in r29,sph
- in r28,spl
+ in yh,sph
+ in yl,spl
ldd zl,y+7
ldd zh,y+6
txfifo:
.byte TXBUFSIZE
+ramtop:
.cseg
; Save received character in a circular buffer. Do nothing if buffer overflows.
uartgetc:
lds temp,rxcount ; Number of characters in buffer
tst temp
- breq uartgetc
+ breq uartgetc ;Wait for char
push zh
push zl
ret
do_fetch_mbc:
- movw adrl,z_c
+ movw xl,z_c
rcall memReadByte
mov opl,temp
ret
do_fetch_mde:
- movw adrl,z_e
+ movw xl,z_e
rcall memReadByte
mov opl,temp
ret
do_fetch_mhl:
- movw adrl,z_l
+ movw xl,z_l
rcall memReadByte
mov opl,temp
ret
do_fetch_msp:
- movw adrl,z_spl
+ movw xl,z_spl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
ret
do_fetch_dir8:
- movw adrl,z_pcl
+ movw xl,z_pcl
rcall memReadByte
adiw z_pcl,1
mov opl,temp
ret
do_fetch_dir16:
- movw adrl,z_pcl
+ movw xl,z_pcl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
ret
do_fetch_rst:
- movw adrl,z_pcl
- subi adrl,1
- sbci adrh,0
+ movw xl,z_pcl
+ subi xl,1
+ sbci xh,0
rcall memReadByte
andi temp,0x38
ldi oph,0
ret
do_store_mbc:
- movw adrl,z_c
+ movw xl,z_c
mov temp,opl
rcall memWriteByte
ret
do_store_mde:
- movw adrl,z_e
+ movw xl,z_e
mov temp,opl
rcall memWriteByte
ret
do_store_mhl:
- movw adrl,z_l
+ movw xl,z_l
mov temp,opl
rcall memWriteByte
ret
do_store_msp:
- movw adrl,z_spl
+ movw xl,z_spl
#if DRAM_WORD_ACCESS
movw temp,opl
rcall memWriteWord
#else
mov temp,opl
rcall memWriteByte
- adiw adrl,1
+ adiw xl,1
mov temp,oph
rcall memWriteByte
#endif
ret
do_store_am:
- movw adrl,opl
+ movw xl,opl
mov temp,z_a
rcall memWriteByte
ret
.equ OP_EI = (38<<10)
.equ OP_INV = (39<<10)
.equ OP_CPFA = (40<<10)
+.equ OP_INCA = (41<<10)
+.equ OP_DECA = (42<<10)
opjumps:
rjmp do_op_nop
rjmp do_op_ei
rjmp do_op_inv
rjmp do_op_cpfa
+ rjmp do_op_inca
+ rjmp do_op_deca
;How the flags are supposed to work:
;----------------------------------------------------------------
-.equ AVR_T = 6
-.equ AVR_H = 5
-.equ AVR_S = 4
-.equ AVR_V = 3
-.equ AVR_N = 2
-.equ AVR_Z = 1
-.equ AVR_C = 0
+.equ AVR_T = SREG_T
+.equ AVR_H = SREG_H
+.equ AVR_S = SREG_S
+.equ AVR_V = SREG_V
+.equ AVR_N = SREG_N
+.equ AVR_Z = SREG_Z
+.equ AVR_C = SREG_C
;------------------------------------------------;
; Move single bit between two registers
;
;
do_op_inc:
- ldi temp,1
- add opl,temp
+ inc opl
+#if EM_Z80
in temp, sreg
+#endif
andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
ldpmx temp2, sz53p_tab, opl
or z_flags,temp2 ;
do_z80_flags_HP
ret
+do_op_inca:
+ inc z_a
+#if EM_Z80
+ in temp, sreg
+#endif
+ andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
+ ldpmx temp2, sz53p_tab, z_a
+ or z_flags,temp2 ;
+ do_z80_flags_HP
+ ret
+
;----------------------------------------------------------------
;|Mnemonic |SZHPNC|Description |Notes |
;----------------------------------------------------------------
;
;
do_op_dec:
- subi opl,1
+ dec opl
+#if EM_Z80
in temp, sreg
+#endif
andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
ldpmx temp2, sz53p_tab, opl
or z_flags,temp2 ;
do_z80_flags_set_N
ret
+do_op_deca:
+ dec z_a
+#if EM_Z80
+ in temp, sreg
+#endif
+ andi z_flags,(1<<ZFL_H)|(1<<ZFL_C) ; preserve C-, and H-flag
+ ldpmx temp2, sz53p_tab, z_a
+ or z_flags,temp2 ;
+ do_z80_flags_HP
+ do_z80_flags_set_N
+ ret
;----------------------------------------------------------------
;|Mnemonic |SZHPNC|Description |Notes |
;
;
do_op_sthl: ;store hl to mem loc in opl:h
- movw adrl,opl
+ movw xl,opl
#if DRAM_WORD_ACCESS
movw temp,z_l
rcall memWriteWord
#else
mov temp,z_l
rcall memWriteByte
- adiw adrl,1
+ adiw xl,1
mov temp,z_h
rcall memWriteByte
#endif
;
;
do_op_rmem16:
- movw adrl,opl
+ movw xl,opl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
;
;
do_op_rmem8:
- movw adrl,opl
+ movw xl,opl
rcall memReadByte
mov opl,temp
ret
;
;
do_op_push16:
- movw adrl,z_spl
- subi adrl,2
- sbci adrh,0
- movw z_spl,adrl
+ movw xl,z_spl
+ subi xl,2
+ sbci xh,0
+ movw z_spl,xl
#if DRAM_WORD_ACCESS
movw temp,opl
rcall memWriteWord
#else
mov temp,opl
rcall memWriteByte
- adiw adrl,1
+ adiw xl,1
mov temp,oph
rcall memWriteByte
#endif
;
;
do_op_pop16:
- movw adrl,z_spl
+ movw xl,z_spl
#if DRAM_WORD_ACCESS
rcall memReadWord
movw opl,temp
#else
rcall memReadByte
mov opl,temp
- adiw adrl,1
+ adiw xl,1
rcall memReadByte
mov oph,temp
#endif
.dw (FETCH_SP | OP_ADDHL | STORE_HL ) ; 39 ADD HL,SP
.dw (FETCH_DIR16| OP_RMEM8 | STORE_A ) ; 3A nn nn LD A,(nn)
.dw (FETCH_SP | OP_DEC16 | STORE_SP ) ; 3B DEC SP
-.dw (FETCH_A | OP_INC | STORE_A ) ; 3C INC A
-.dw (FETCH_A | OP_DEC | STORE_A ) ; 3D DEC A
+.dw (FETCH_NOP | OP_INCA | STORE_NOP) ; 3C INC A
+.dw (FETCH_NOP | OP_DECA | STORE_NOP) ; 3D DEC A
.dw (FETCH_DIR8 | OP_NOP | STORE_A ) ; 3E nn LD A,n
.dw (FETCH_NOP | OP_CCF | STORE_NOP) ; 3F CCF (Complement Carry Flag, gvd)
.dw (FETCH_B | OP_NOP | STORE_B ) ; 40 LD B,r