Re: TI-H: empeg player
[Prev][Next][Index][Thread]
Re: TI-H: empeg player
>well if you feel like waiting a month or so......
>ours will be done... available in kit form maybee,
>the design and source code will be free to the public.
>Its mostly college proffesors and such working on it.
>there are quite of few of us so It should move quickly...
>It will have an IDE interface ... and USB.
The 68k series does NOT directly interface to IDE drives, but I guess
you'll find that out soon. :) It takes a bunch of code just to handle
fat. Better rethink the whole thing. :)
Don't waste your time. Here is a driver I made a while back.
* DOS Notes:
*
* Find-free _writes_ the FAT map, not fmapalloc!!! To update a file's
* allocations, do either a fflush (fat flush) or fclose!
* This DOS does NOT support access of the HD by other tasks that do not
* restore the LBA, sector counts, etc....
*
* DOS Essentials:
*
* Keep file prev_ent and next_ent fields coordinated!!!! -So files don't
* get trashed by closing them out of order.
*
*
* DOS Ideas:
* Keep eof buffer addresses for data buf, ext buf, etc. precalculated to
* reduce recalculations.
* Modify all routines to set flags, to eliminate d0 tests.
* Modify FORTH-executable routines like shdbuf, fhdbuf, and slba for assembly
* entry points, to eliminate stack-thrashing (accept params in d0).
*
*
hd_size EQU 332800
map_siz EQU hd_size/8
map_spc EQU (map_siz/512)+1
* The additional one is there if it doesn't come out evenly
m_sz_sc EQU 82
num_fil EQU 8
read EQU 0
write EQU -1
buf_siz EQU 1560
entry EQU 0
ent_ext EQU 512
dat_buf EQU 1024
ent_lba EQU 1536
ext_lba EQU 1540
dat_lba EQU 1544
lba_ptr EQU 1548 ; points to current allocation point for LBA's
dat_ptr EQU 1552 ; points to next byte within data buffer
mode EQU 1556 ; mode ( R:0 W:-1 )
; Offsets into file entry buffer
fname EQU 0 ; name of file/directory
prv_ent EQU 16 ; LBA of prev file (0 for first file, dirs: always 0)
nxt_ent EQU 20 ; LBA of next file (0 for last file) (dirs: 1st file)
size EQU 24 ; size in bytes (dirs: prev_dir, 0 for root)
chksum EQU 28 ; check-sum or CRC (dirs: next_dir, 0 for only dir )
date EQU 32 ; date of creation/last update
fflags EQU 36 ; flags and permissions
type EQU 40 ; contents of file code (0 for dir/-1 for file)
fst_blk EQU 44 ; start of blocks (file-- not used currently)
prv_dir EQU 44 ; previous dir (root: 0)
fst_fil EQU 48 ; first file LBA (0 for no files)
; Offset into extension block buffer/header block buffer
linkf EQU 508 ; link to next extension block
* SI section
org $300800
SI DC.B '_HDT'
DC.L hdcon
DC.B ' '
DC.L 0
hdcon DC.L initfmp
DC.L freesec
DC.L fndfree
DC.L fsflush
DC.L fmpaloc
DC.L fflush
DC.L rtinit
DC.L ghandle
DC.L nxtlink
DC.L lstlink
DC.L fndfile
DC.L fopenwr
DC.L fputc
DC.L fopenrd
DC.L fgetc
DC.L fclose
DC.L fdel
DC.L fcpy
DC.L mkdir
DC.L rmdir
DC.L chdir
DC.L cdup
DC.L cdroot
DC.L initdos
DC.L _hdbuf
DC.L _ffbuf
DC.L _frebuf
DC.L _tbuf
DC.L _tmp1
DC.L _tmp2
DC.L _bptr
DC.L _secptr
DC.L _bitptr
DC.L _cur_dir
DC.L _datptr
DC.L hdt
org $300900
tmpx1 DC.L 0
tmpx2 DC.L 0
hdt move.l 4(a7),tmpx2 ; handle
move.l #$100000,tmpx1
wrlp move.l #1,-(a7)
move.l tmpx2,-(a7)
bsr fputc
adda.l #08,a7
subq.l #01,tmpx1
bne wrlp
rts
_datptr move.l #dat_ptr,d0
rts
_tmp1 move.l #tmp1,d0
rts
_tmp2 move.l #tmp2,d0
rts
_bptr move.l #bptr,d0
rts
_secptr move.l #secptr,d0
rts
_bitptr move.l #bitptr,d0
rts
_cur_dir move.l #cur_dir,d0
rts
_freptr move.l #freptr,d0
rts
_hdbuf move.l #hdbuf,d0
rts
_ffbuf move.l #ffbuf,d0
rts
_frebuf move.l #frebuf,d0
rts
_tbuf move.l #tbuf,d0
rts
* ------Init-FAT-Map
* ------Returns 0 if ok, -3 if error
initfmp move.l a0,-(a7)
movea.l #ffbuf+512,a0
clrbf clr.l -(a0)
cmpa.l #ffbuf,a0
bne clrbf
movea.l (a7)+,a0 ; restore a0
move.l d1,-(a7) ; save d1
move.l #0,d1
clrfat move.l d1,-(a7)
jsr slba
move.b #1,hd1+5 ; set count to 1 sector
move.l #ffbuf,-(a7) ; stick blanked buffer addr on stack
jsr shdbuf
adda.l #8,a7
tst.l d0
bne imwerr
addq.l #1,d1
cmp.l #map_spc,d1 ; done all sectors?
bne clrfat
bsr initdos ; reset pointers, reload ffbuf
bmi imret
move.l #map_spc,d1
fillfat bsr fmpaloc ; reserve sectors for FAT map
bmi imret
subq.l #1,d1
bne fillfat
bsr fflush ; write new map to hd
move.l (a7)+,d1
rts
imwerr move.l #-3,d0 ; write error code
imret move.l (a7)+,d1
rts
* ------Free-Sector----------------------------------
* ------Returns 0 if ok, -1/-2/-3 if error
freesec bsr fflush ; flush ffbuf in case anything has changed
move.l #-1,secptr ; invalidate ffbuf ptr
move.l 4(a7),d0 ; get sec number
cmp.l #hd_size-1,d0
bgt toobig
divu #8,d0
swap d0 ; swap remainder to lower word
move.l d1,-(a7) ; save d1
moveq.b #01,d1 ; init inverse mask
tst.b d0 ; see if remainder=0
beq skiprot ; if it's 0, skip rotate
lsl.b d0,d1 ; shift 1 out the remainder times
skiprot not.b d1 ; invert result
swap d0 ; put quotient in lower word again
andi.l #$ffff,d0 ; get rid of remainder
move.l d0,tmp2 ; save number/8
andi.l #511,tmp2 ; trim off high bits (used as an offset in buffer)
lsr.l #8,d0 ; divide by 512 to get LBA of alloc sector
lsr.l #1,d0
cmp.l freptr,d0 ; does frebuf contain sector already?
beq skipld
move.l d0,-(a7) ; save d0 a sec
bsr fsflush ; flush (will only flush if buffer changed/valid)
tst.l d0
bne fwrerr
move.l (a7)+,d0 ; restore it
move.l d0,freptr ; load with new pointer
move.l d0,-(a7) ; push lba of alloc map sector
jsr slba
move.b #1,hd1+5 ; set count to 1 sector
move.l #frebuf,-(a7)
jsr fhdbuf
adda.l #8,a7 ; lose lba, pushed addr of free-sector buf
tst.l d0
bne frderr
skipld move.l a0,-(a7)
movea.l #frebuf,a0
move.l tmp2,d0 ; get offset in buf
and.b d1,0(a0,d0) ; and off the bit in the buf
move.b #-1,frchg ; indicate buffer changed
movea.l (a7)+,a0 ; restore a0
move.l (a7)+,d1 ; restore d1
move.l #0,d0 ; set result=0 (ok)
tst.l d0
rts
toobig move.l #-1,d0 ; set result=-1 (lba too big)
tst.l d0
rts
frderr move.l (a7)+,d1 ; restore d1
move.l #-2,d0 ; ""=-2 (read error)
tst.l d0
rts
fwrerr adda.l #4,a7 ; drop stacked d0
move.l (a7)+,d1 ; restore d1
move.l #-3,d0 ; ""=-3 (read error)
tst.l d0
rts
* ------Free-Sec-Flush
* ------Writes current fat map sector in free buff to drive and returns 0/-3
fsflush tst.b frchg ; if nothing has changed, skip it
beq skipfrf
move.l freptr,-(a7)
jsr slba
move.b #1,hd1+5 ; set count 1 sector
move.l #frebuf,-(a7)
jsr shdbuf
adda.l #8,a7
tst.l d0
bne fsfwerr
clr.b frchg
move.l #-1,freptr
skipfrf move.l #0,d0
rts
fsfwerr move.l #-3,d0 ; couldn't write to FAT map!
rts
* ------Find-free---------------------------------------
* -----( -- LBA/-1/-2/-3/-4 )
* -----Returns LBA if ok, -X if error
fndfree bsr fsflush ; make sure no sectors freed since last call
move.l a0,-(a7)
move.l d1,-(a7)
move.l bptr,d0 ; load with last saved values
tst.l secptr ; make sure ffbuf contains valid data
bmi ldff ; if not, load it!
ldret move.l secptr,d1
movea.l #ffbuf,a0
cmp.b #-1,0(a0,d0) ; if no bits free at current byte, reset bitptr
beq rstbp
fflp cmp.b #-1,0(a0,d0)
bne ffree ; found a bit at 0
addq.l #01,d0
cmp.l #512,d0 ; at end of buffer?
beq nxtsec
bra fflp
ldff move.l #0,secptr
move.l #0,-(a7)
jsr slba
move.b #1,hd1+5
move.l #ffbuf,-(a7)
jsr fhdbuf
adda.l #8,a7
tst.l d0
beq ldret
bra ffwrerr
rstbp move.l #0,bitptr
bra fflp
ffree move.l d1,secptr ; save lba
move.l d0,bptr ; save buffer offset pointer
lsl.l #8,d1 ; convert to bit # in alloc map (multiply by 4096)
lsl.l #4,d1 ; (4 from prev to total 12)
lsl.l #3,d0 ; convert to bit # (ptrx8)
add.l d0,d1 ; sum for current bit number
move.l d1,tmp1 ; save it!
move.l bptr,d0 ; restore byte offset pointer
move.l bitptr,d1 ; restore bit pointer
tstlp btst.b d1,0(a0,d0)
beq bitfree ; if not 1, calculate LBA
addq.l #01,d1 ; next bit...
cmp.b #08,d1 ; make sure we haven't tested all bits
bne tstlp
move.l #-4,d0 ; otherwise return FUBAR error code
bra ffret ; and return...
* WARNING!!!!!!!!!! TRICK IN PROGRESS!!!
* ONLY 2 things (d1,a0) must be stacked when bitfree is called!!!!!!!!!
bitfree cmp.l #fmret,8(a7) ; is fmapalloc calling us ?
beq btalloc ; (look at return address)
btaret move.l tmp1,d0 ; get saved LBA
move.l d1,bitptr ; save bit pointer to free bit
add.l d1,d0 ; add in bit number
bra ffret ; and return...
btalloc bset.b d1,0(a0,d0)
move.b #-1,ffchg ; indicate ffbuf has been changed
bra btaret
nxtsec bsr fflush
tst.l d0 ; error?
bne ffwrerr
addq.l #01,d1 ; next sector...
cmp.l #hd_size,d1
beq nofree ; at end? --no sectors free
move.l d1,-(a7) ; push next LBA on stack
jsr slba ; set it
move.b #1,hd1+5 ; set count to 1 sector
move.l #ffbuf,-(a7)
jsr fhdbuf ; load with next sector in alloc map
adda.l #8,a7 ; drop stacked data
tst.l d0
bne ffrderr
clr.l d0
bra fflp
ffwrerr move.l #-3,d0
bra ffret
ffrderr move.l #-2,d0
bra ffret
nofree move.l #-1,d0
ffret move.l (a7)+,d1
movea.l (a7)+,a0
rts
* ------FAT-map-Flush
* ------Writes current fat map sector to drive and returns 0/-3
fflush tst.b ffchg
beq skipfl ; skip flush if there's no change to buffer
* move.b #02,d0
* jsr putc ; !!!!!!!!!!!!!!!!!!!!
move.l secptr,d0
* bsr print ; !!!!!!!!!!!!!!!!!!!!!!!
move.l secptr,-(a7)
jsr slba
* bsr print ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!
move.b #1,hd1+5 ; set count 1 sector
move.l #ffbuf,-(a7)
jsr shdbuf
adda.l #8,a7
tst.l d0
bne fflwerr
* bsr lba ; !!!!!!!!!!!!!!!!!!!!111
clr.b ffchg ; indicate nothing new in buffer now
skipfl move.l #0,d0
rts
fflwerr move.l #-3,d0 ; couldn't write to FAT map!
rts
* ------FAT-Map-Allocate
* ------Allocates next free bit in alloc map and returns LBA
* ------( -- LBA/-1/-2/-3/-4)
fmpaloc bsr fndfree ; get first free sector
* Note: because find-free looks at the return address, we simply call
* it and it will automagically allocate a bit
fmret tst.l d0 ; set CC to reflect d0's value
rts ; if <0 return code, error!
* ------RootInit
* ------Initializes root directory entry, returns 0/-3
rtinit bsr initfmp ; clear allocation table
tst.l d0
bmi rtiwe2
move.l a5,-(a7)
move.l a4,-(a7)
movea.l 12(a7),a5 ; get root name pointer
move.l 16(a7),d0 ; get root name length
movea.l #tbuf,a4
jsr Strcpyn ; copy name into buffer
clr.l prv_ent(a4) ; no previous entry
clr.l prv_dir(a4) ; no previous dir (root)
clr.l fst_fil(a4) ; no files
clr.l nxt_ent(a4) ; no next entry
clr.l size(a4) ; 0 size
clr.l date(a4) ; no date
move.l #-1,fflags(a4) ; wide open permissions
clr.l chksum(a4) ; none
clr.l type(a4) ; directory type
clr.l fst_blk(a4) ; no blocks (directory)
bsr fmpaloc ; allocate space
bmi rtiret
move.l d0,-(a7)
jsr slba ; set LBA
move.l a4,-(a7) ; stick tbuf addr on stack
move.b #1,hd1+5 ; set count 1 sector
jsr shdbuf
adda.l #8,a7
tst.l d0
bne rtiwerr
bra rtiret
rtiwe2 rts
rtiwerr move.l #-3,d0
rtiret movea.l (a7)+,a4
movea.l (a7)+,a5
rts
* ------Get-Handle
* ------Returns either addr within hdbuf or -1 (no handle free)
ghandle move.l a0,-(a7)
movea.l #hdbuf,a0
move.l #num_fil,d0
mulu #buf_siz,d0
adda.l d0,a0 ; get addr of 1st byte, last entry+1 in buf
ghlp suba.l #buf_siz,a0 ; skip back one buffer
tst.b (a0)
beq fndhnd
cmpa.l #hdbuf,a0 ; have we looked at all entries?
bne ghlp
movea.l (a7)+,a0
move.l #-1,d0 ; no handle free
tst.l d0
rts
fndhnd move.l a0,d0 ; return handle
movea.l (a7)+,a0
tst.l d0
rts
* ------Next-link
* ------Returns next link's LBA in link chain (0 if no file next), -2 if error
nxtlink move.l 4(a7),d0 ; get LBA specified
move.l d0,-(a7)
jsr slba
move.b #01,hd1+5 ; set count 1 sectors
move.l #tbuf,-(a7)
jsr fhdbuf ; get entry spec'd
adda.l #8,a7 ; drop data stacked
tst.l d0
bne nlrder
move.l 4(a7),d0 ; get lba again
cmp.l cur_dir,d0 ; are we reading the current dir entry?
beq get_fsf ; if equal, get first_file info, not nxt_ent
move.l tbuf+nxt_ent,d0
rts
get_fsf move.l tbuf+fst_fil,d0
rts
nlrder move.l #-2,d0
rts
* ------Last-link
* ------Returns LBA of last file in link chain, LBA of dir if no files in dir
lstlink move.l cur_dir,-(a7)
bsr nxtlink
adda.l #4,a7 ; drop data stacked
tst.l d0
bmi llret ; if negative, read error (return)
beq no_file ; no files (return)
llnlp move.l d0,-(a7) ; stack current link's LBA
bsr nxtlink
adda.l #4,a7 ; drop data stacked
tst.l d0
bmi llret ; if negative, read error (return)
bne llnlp ; keep going until d0=0
move.l -4(a7),d0 ; restore last link's LBA
tst.l d0
rts
no_file move.l cur_dir,d0
llret tst.l d0
rts
* ------Find-file
* ------Returns LBA of file in current dir, or -1 if not found, -2 if error
fndfile move.l a5,-(a7)
move.l a4,-(a7)
movea.l 12(a7),a5 ; get string pointer
move.l 16(a7),tmp1 ; get length
move.l cur_dir,-(a7)
bsr nxtlink
adda.l #4,a7 ; drop data stacked
tst.l d0
bmi fflret ; if negative, read error (return)
beq fflret ; no files (return)
ffllp move.l d0,-(a7) ; stick next LBA on stack
move.l d0,tmp3 ; save lba
bsr nxtlink
adda.l #4,a7 ; drop data stacked
tst.l d0
bmi fflret ; if negative, read error (return)
move.l d0,tmp2 ; save next LBA
movea.l #tbuf,a4 ; get pointer to name
move.l tmp1,d0 ; get length
jsr Strncmp
beq fffnd ; found a match...
move.l tmp2,d0
tst.l d0 ; any more files?
bne ffllp ; fall through if no more files...
move.l #-1,d0
fflret movea.l (a7)+,a4
movea.l (a7)+,a5
tst.l d0
rts
fffnd move.l tmp3,d0 ; retrieve LBA
bra fflret
* ------File-Open (write mode)
* ------Returns handle if ok, -1 if no handle free,-2/-3/-4 (no space)
fopenwr move.l a5,-(a7)
move.l a4,-(a7)
movea.l 12(a7),a5 ; get name pointer
move.l 16(a7),tmp1 ; get name length
bsr ghandle ; get handle
tst.l d0
bmi fowret ; if no handle available, abort...
movea.l d0,a4 ; point a4 to buffer allocated
move.l tmp1,d0 ; restore length
jsr Strcpyn ; copy name into buffer
bsr fmpaloc ; get some space for header
bmi fowret
move.l #-1,mode(a4) ; set mode to -1 (write)
move.l d0,ent_lba(a4) ; save LBA of header
bsr lstlink
move.l d0,prv_ent(a4) ; previous entry (dir LBA if none)
clr.l nxt_ent(a4) ; no next entry
clr.l size(a4) ; 0 size
clr.l date(a4) ; no date
move.l #-1,fflags(a4) ; wide open permissions
clr.l chksum(a4) ; none
move.l #1,type(a4) ; file type
bsr fmpaloc ; get some space for first extension block
bmi fowret
move.l d0,ext_lba(a4) ; extension block LBA
move.l d0,linkf(a4) ; link to first extension block
pea dat_buf(a4)
move.l (a7)+,dat_ptr(a4) ; pointer within data block
bsr fmpaloc ; get some space for first data block
bmi fowret
move.l d0,ent_ext(a4) ; save first data LBA to ext block
move.l d0,dat_lba(a4) ; data block LBA
pea.l ent_ext+4(a4) ; get address of second block in hdbuf
move.l (a7)+,lba_ptr(a4) ; point to extension block
clr.l ent_ext+linkf(a4) ; no link-field
move.l ent_lba(a4),-(a7)
jsr slba ; set LBA
move.l a4,-(a7) ; stick buf addr on stack
move.b #1,hd1+5 ; set count 1 sector
jsr shdbuf
adda.l #8,a7
tst.l d0
bmi fowret ; abort if error
move.l prv_ent(a4),-(a7) ; previous entry
jsr slba
move.b #1,hd1+5 ; set count 1 sector
move.l #tbuf,-(a7)
jsr fhdbuf ; get prev entry
adda.l #8,a7
tst.l d0
bmi fowret
move.l cur_dir,d0 ; get current directory
cmp.l prv_ent(a4),d0 ; if previous is current dir entry, save to...
beq svtoff ; first_file location, not nxt_ent
move.l ent_lba(a4),tbuf+nxt_ent ; save current LBA to nxt_ent
svtffrt move.b #1,hd1+5 ; set count 1 sector
move.l #tbuf,-(a7)
jsr shdbuf ; save it!
adda.l #4,a7
tst.l d0
move.l a4,d0 ; return handle
fowret movea.l (a7)+,a4
movea.l (a7)+,a5
rts
svtoff move.l ent_lba(a4),tbuf+fst_fil ; update current dir's entry with ...
bra svtffrt ; first file's LBA
* ------File-Put-Character ( handle c -- flag )
* ------Returns -3 if write fails
fputc move.l a0,-(a7)
move.l a1,-(a7)
movea.l 12(a7),a0 ; get handle
movea.l dat_ptr(a0),a1 ; get data pointer
move.b 19(a7),(a1)+ ; save data
addq.l #01,size(a0) ; increment size
move.l a0,d0
add.l #dat_buf+512,d0 ; get eof buffer addr
cmp.l a1,d0 ; end of buffer?
beq nxtdsec ; if so, save and start next sector
move.l a1,dat_ptr(a0) ; otherwise save pointer
movea.l (a7)+,a1
movea.l (a7)+,a0
clr.l d0
rts
nxtdsec move.l dat_lba(a0),-(a7)
jsr slba
move.b #1,hd1+5
pea.l dat_buf(a0)
jsr shdbuf ; save data sector
adda.l #8,a7
tst.l d0
bne fpcret
pea dat_buf(a0)
move.l (a7)+,dat_ptr(a0) ; reset pointer within data block
bsr fmpaloc ; get a new sector
bmi fpcret
move.l d0,dat_lba(a0) ; save new lba
movea.l lba_ptr(a0),a1
move.l d0,(a1)+ ; save new lba
move.l a1,lba_ptr(a0) ; save pointer
move.l a0,d0
add.l #ent_ext+508,d0
cmp.l a1,d0 ; any more space for data lba's?
beq nxtext ; if not allocate a new one
clr.l d0
bra fpcret
Follow-Ups:
References: