X-Git-Url: http://cloudbase.mooo.com/gitweb/avrcpm.git/blobdiff_plain/94175893adca548862102caa29fd8c998d7d0e67..8b13b36c6542ac4fac3a69ae45f7e296f7754bdb:/remainders.asm diff --git a/remainders.asm b/remainders.asm index 2af7532..a1372a6 100644 --- a/remainders.asm +++ b/remainders.asm @@ -182,1040 +182,16 @@ printstr_end: pop zl pop zh ret - -; ---------------- Virtual peripherial interface ---------------- - -;The hw is modelled to make writing a CPM BIOS easier. -;Ports: -;0 - Con status. Returns 0xFF if the UART has a byte, 0 otherwise. -;1 - Console input, aka UDR. -;2 - Console output -;3 - "UART" status: bit 0=rx, bit 1 = tx -;4 - "UART" data register, no wait -;15 - Disk select -;16,17 - Track select -;18 - Sector select -;20 - Write addr l -;21 - Write addr h -;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 - .equ BOOT_FUNC = 5 - .equ HOME_FUNC = 4 - - - -;***************************************************** -;* 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 - .equ hostblk = hostsize/128 ;CP/M sects/host buff -; .equ CPMSPT = hostblk*hostspt;CP/M sectors/track - .equ CPMSPT = 26 ; - .equ SECMSK = hostblk-1 ;sector mask - .equ SECSHF = log2(hostblk) ;sector shift - -;***************************************************** -;* BDOS constants on entry to write * -;***************************************************** - .equ WRALL = 0 ;write to allocated - .equ WRDIR = 1 ;write to directory - .equ WRUAL = 2 ;write to unallocated - .equ WRTMSK= 3 ;write type mask - - - .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) -hostparttbltop: -hostdsk: .byte 1 ;host disk number -hostlba: .byte 3 ;host sector number (relative to partition start) - -unacnt: .byte 1 ;unalloc rec cnt -unadsk: .byte 1 ;last unalloc disk -unatrk: .byte 2 ;last unalloc track -unasec: .byte 1 ;last unalloc sector - -erflag: .byte 1 ;error reporting -wrtype: .byte 1 ;write operation type -dmaadr: .byte 2 ;last dma address -hostbuf: .byte hostsize ;host buffer (from/to SD-card) + + .dseg .cseg -conStatus: - lds temp,rxcount - cpse temp,_0 - ldi temp,0xff - ret - -conInp: - rjmp uartgetc - -dbgOut: - printnewline - printstring "Debug: " - rcall printhex - ret - -conOut: - rjmp uartputc - -uartstat: - clr temp - lds temp2,rxcount - cpse temp2,_0 - sbr temp,0x01 - lds temp2,txcount - cpi temp2,TXBUFSIZE - breq uartst_1 - sbr temp,0x02 -uartst_1: - ret - -uartout: - lds temp2,txcount - cpi temp2,TXBUFSIZE - breq uartout_1 - rjmp uartputc -uartout_1: - ret - -uartin: - clr temp - lds temp2,rxcount - cpse temp2,_0 - rjmp uartgetc - ret - -;Called with port in temp2. Should return value in temp. -portRead: - cpi temp2,0 - breq conStatus - cpi temp2,1 - breq conInp - cpi temp2,3 - breq uartstat - cpi temp2,4 - breq uartin - - cpi temp2,15 - breq dskDiskCheck - cpi temp2,22 - breq dskErrorRet - - cpi temp2,TIMER_MSECS - brlo pr_noclock - cpi temp2,TIMER_MSECS+6 - brsh pr_noclock - rjmp clockget - -pr_noclock: - ldi temp,0xFF - ret - -;Called with port in temp2 and value in temp. -portWrite: - cpi temp2,0 - breq dbgOut - cpi temp2,2 - breq conOut - cpi temp2,4 - breq uartout - - cpi temp2,15 - breq dskDiskSel - cpi temp2,16 - breq dskTrackSel_l - cpi temp2,17 - breq dskTrackSel_h - cpi temp2,18 - breq dskSecSel - cpi temp2,20 - breq dskDmaL - cpi temp2,21 - breq dskDmaH - - cpi temp2,22 - breq dskDoIt - - cpi temp2,TIMERPORT - brlo pw_noclock - cpi temp2,TIMER_MSECS+6 - brsh pw_noclock - rjmp clockput - -pw_noclock: - ret - - -dskDiskCheck: - lds temp2,seekdsk - cpi temp2,RAMDISKNR - brsh dsk_dchrd ;maybe ramdisk - -; Check if selected disk # is less then # of disks. - - lds temp,ndisks - tst temp - brne dsk_dchpart1 - -; Need to init - - rcall dsk_partinit - cbr temp,0x80 - lds temp2,seekdsk - -dsk_dchpart1: - cp temp2,temp - brsh dsk_dcher - -dsk_dchend: - ldi temp,0 - ret - -dsk_dchrd: -#if RAMDISKCNT - cpi temp,RAMDISKNR+RAMDISKCNT - brlo dsk_dchend -#endif -dsk_dcher: - ldi temp,0xff ;error return - ret - - - - -dskErrorRet: - lds temp,erflag - ret - -dskDiskSel: - sts seekdsk,temp - ret - -dskTrackSel_l: - sts seektrk,temp - sts seektrk+1,_0 - ret - -dskTrackSel_h: - sts seektrk+1,temp - ret - -dskSecSel: - sts seeksec,temp - ret - -dskDmal: - sts dmaadr,temp - ret - -dskDmah: - sts dmaadr+1,temp - ret - -dskDoIt: -.if DISK_DEBUG - push temp - sbrc temp,READ_FUNC - rjmp dskdbgr - sbrc temp,WRITE_FUNC - rjmp dskdbgw - rjmp dskdbge - -dskdbgr: - printnewline - printstring "Disk read: " - rjmp dskdbg1 -dskdbgw: - printnewline - printstring "Disk write: " -dskdbg1: - lds temp,seekdsk - subi temp,-('A') - rcall uartputc - printstring ": track " - lds temp2,seektrk+1 - lds temp,seektrk - rcall printhexw - printstring ", sector " - lds temp,seeksec - rcall printhex - printstring ", dma-addr " - lds temp2,dmaadr+1 - lds temp,dmaadr - rcall printhexw - pop temp - push temp - sbrs temp,WRITE_FUNC - rjmp dskdbge - printstring " wrtype " - andi temp,3 - rcall printhex -dskdbge: - pop temp -.endif - ;See what has to be done. - sbrc temp,READ_FUNC - rjmp dsk_read - sbrc temp,WRITE_FUNC - rjmp dsk_write - sbrc temp,HOME_FUNC - rjmp dsk_home - sbrc temp,BOOT_FUNC - rjmp dsk_boot - - printstring "DISK I/O: Invalid Function code: " - rcall printhex - rjmp haltinv - -dsk_boot: - sts ndisks,_0 ;no active partitions -dsk_cboot: - cbi flags,hostact ;host buffer inactive - sts unacnt,_0 ;clear unalloc count - ret - -dsk_home: - sbis flags,hostwrt ;check for pending write - cbi flags,hostact ;clear host active flag - ret - - -dsk_read: - - sbi flags,readop ;read operation - ;RAM disk? - lds temp2,seekdsk -#if RAMDISKCNT - cpi temp2,RAMDISKNR - brlt PC+2 - rjmp rdskDoIt -#endif - sts unacnt,_0 - sbi flags,rsflag ;must read data - ldi temp,WRUAL ;write type - sts wrtype,temp ;treat as unalloc - rjmp dsk_rwoper ;to perform the read - - -dsk_write: - ;write the selected CP/M sector - - cbi flags,readop ;not a read operation - - ;RAM disk? - lds temp2,seekdsk -#if RAMDISKCNT - cpi temp2,RAMDISKNR - brlt PC+2 - rjmp rdskDoIt -#endif - andi temp,WRTMSK - sts wrtype,temp ;save write type - - cpi temp,WRUAL ;write unallocated? - brne dsk_chkuna ;check for unalloc - -; write to unallocated, set parameters - ldi temp,blksize/128 ;next unalloc recs - sts unacnt,temp - lds temp,seekdsk ;disk to seek - sts unadsk,temp ;unadsk = sekdsk - lds temp,seektrk - sts unatrk,temp ;unatrk = sectrk - lds temp,seektrk+1 - sts unatrk+1,temp ;unatrk = sectrk - lds temp,seeksec - sts unasec,temp ;unasec = seksec -; -dsk_chkuna: - ;check for write to unallocated sector - lds temp,unacnt ;any unalloc remain? - tst temp - breq dsk_alloc ;skip if not - -; more unallocated records remain - dec temp ;unacnt = unacnt-1 - sts unacnt,temp - lds temp,seekdsk ;same disk? - lds temp2,unadsk - cp temp,temp2 ;seekdsk = unadsk? - brne dsk_alloc ;skip if not - -; disks are the same - lds temp,unatrk - lds temp2,unatrk+1 - lds temp3,seektrk - lds temp4,seektrk+1 - cp temp,temp3 ;seektrk = unatrk? - cpc temp2,temp4 - brne dsk_alloc ;skip if not - -; tracks are the same - lds temp,seeksec ;same sector? - lds temp2,unasec - cp temp,temp2 ;seeksec = unasec? - brne dsk_alloc ;skip if not - -; match, move to next sector for future ref - inc temp2 ;unasec = unasec+1 - sts unasec,temp2 - cpi temp2,CPMSPT ;end of track? (count CP/M sectors) - brlo dsk_noovf ;skip if no overflow - -; overflow to next track - sts unasec,_0 ;unasec = 0 - lds temp,unatrk - lds temp2,unatrk+1 - subi temp, low(-1) ;unatrk = unatrk+1 - sbci temp2,high(-1) - sts unatrk,temp - sts unatrk+1,temp2 -; -dsk_noovf: - cbi flags,rsflag ;rsflag = 0 - rjmp dsk_rwoper ;to perform the write -; -dsk_alloc: - ;not an unallocated record, requires pre-read - sts unacnt,_0 ;unacnt = 0 - sbi flags,rsflag ;rsflag = 1 - -;***************************************************** -;* Common code for READ and WRITE follows * -;***************************************************** - -dsk_rwoper: - ;enter here to perform the read/write -.if DISK_DEBUG - printstring ", flags: " - in temp,flags - rcall printhex -.endif - sts erflag,_0 ;no errors (yet) - - ;Convert track/sector to an LBA address (in 128byte blocks) - - lds xl,seeksec ; - ldi xh,0 ; - ldi yl,0 ; - lds temp3,seektrk ; - lds temp4,seektrk+1 ; - ldi temp,CPMSPT ; - mul temp3,temp ; - add xl,r0 ; - adc xh,r1 ; - mul temp4,temp ; - add xh,r0 ;yl:xh:xl := sec + trk * SectorsPerTrack - adc yl,r1 ; - - mov temp,xl - andi temp,SECMSK ;mask buffer number - push temp ;save for later - - ;Convert from CP/M LBA blocks to host LBA blocks - ldi temp,SECSHF -dsk_sh1: - lsr yl - ror xh - ror xl - dec temp - brne dsk_sh1 - ;yl:xh:xl = host block to seek -; active host sector? - in _tmp0,flags ;host active flag - sbi flags,hostact ;always becomes 1 - sbrs _tmp0,hostact ;was it already? - rjmp dsk_filhst ;fill host if not - -; host buffer active, same as seek buffer? - lds temp,seekdsk - lds temp2,hostdsk ;same disk? - cp temp,temp2 ;seekdsk = hostdsk? - brne dsk_nomatch - -; same disk, same block? - 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 - 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,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: - - ;copy data to or from buffer - ldiw z,hostbuf - ldi temp,128 - pop temp2 ;get buffer number (which part of hostbuf) - mul temp2,temp - add zl,r0 ;offset in hostbuf - adc zh,r1 -.if DISK_DEBUG > 2 - push r0 - push r1 - printstring "; host buf adr: " - pop temp2 - pop temp - rcall printhexw -.endif - - 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: - mem_read - st z+,temp - adiw xl,1 - dec temp3 - brne dsk_wmove - rjmp dsk_rwmfin - -dsk_rmove: - ld temp,z+ - mem_write - adiw xl,1 - dec temp3 - brne dsk_rmove -dsk_rwmfin: -; data has been moved to/from host buffer - lds temp,wrtype ;write type - cpi temp,WRDIR ;to directory? - breq dsk_wdir - ret ;no further processing -dsk_wdir: -; clear host buffer for directory write - lds temp,erflag - tst temp ;errors? - breq dsk_wdir1 - ret ;skip if so -dsk_wdir1: - rcall dsk_writehost ;clear host buff - cbi flags,hostwrt ;buffer written - ret -;***************************************************** - -; hostdsk = host disk #, (partition #) -; hostlba = host block #, relative to partition start -; Read/Write "hostsize" bytes to/from hostbuf -dsk_hostparam: - ldiw z,hostparttbl - lds temp,hostdsk -.if HOSTRW_DEBUG - push temp - subi temp,-('A') - rcall uartputc - printstring ": " - 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 - printstring "lba: " - 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 - printstring ", max: " - 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 - printstring " " -.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 yl,temp3 - adc yh,_0 -.if HOSTRW_DEBUG - printstring ", abs:" - 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 - printstring " " -.endif - ori temp,255 -dsk_hpex: - ret - -;***************************************************** -;* WRITEhost performs the physical write to * -;* the host disk, READhost reads the physical * -;* disk. * -;***************************************************** - -dsk_writehost: -.if HOSTRW_DEBUG - printnewline - printstring "host write " -.endif - rcall dsk_hostparam - breq dsk_rdwr_err - - rcall mmcWriteSect - tst temp - breq dsk_rdwr_ok - - rcall dsk_partinit - cbr temp,0x80 - breq dsk_rdwr_err - - rcall dsk_hostparam - breq dsk_rdwr_err - rcall mmcWriteSect - tst temp - brne dsk_rdwr_err - rjmp dsk_rdwr_ok - - -dsk_readhost: -.if HOSTRW_DEBUG - printnewline - printstring "host read " -.endif - rcall dsk_hostparam - breq dsk_rdwr_err - - rcall mmcReadSect - tst temp - breq dsk_rdwr_ok - - rcall dsk_partinit - cbr temp,0x80 - breq dsk_rdwr_err - - rcall dsk_hostparam - breq dsk_rdwr_err - rcall mmcReadSect - tst temp - brne dsk_rdwr_err - -dsk_rdwr_ok: - sts erflag,_0 - ret - -dsk_rdwr_err: - sts erflag,_255 - ret - -;*************************************************************************** - -#if RAMDISKCNT - -; ----------------- RAM disk ----------------- - - .dseg -rdskbuf: - .byte 128 - - .cseg -;---------------------------------------------- - -rdsk_adr: - ldi xl,0 - lds xh,seeksec - lds temp2,seektrk - - lsr xh - ror xl ;Col 0..7 - - mov temp,temp2 - andi temp,0x0f - swap temp - or xh,temp ;Row 0..7 - - ldiw z,rdskbuf - ldi temp3,128 - DRAM_SETADDR xh, ~0,(1< 1 - mov temp,xh - rcall printhex - printstring " " - mov temp,xl - rcall printhex - printstring " " -.endif - ret - -;---------------------------------------------- - -rdskDoIt: - sts erflag,_0 - sbis flags,readop - rjmp rdsk_wr - -.if DISK_DEBUG > 1 - printnewline - printstring "rd-adr: " -.endif - rcall rdsk_adr -rdsk_rdl: - DRAM_SETADDR xl, ~(1< 1 - printnewline - printstring "wr-adr: " -.endif - lds xl,dmaadr - lds xh,dmaadr+1 - ldiw z,rdskbuf - ldi temp3,128 -rdsk_wrldl: - mem_read - st z+,temp - adiw x,1 - dec temp3 - brne rdsk_wrldl - - ldi temp2,RAM_DQ_MASK | (1<