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: