-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