Re: A86: browsing files...


[Prev][Next][Index][Thread]

Re: A86: browsing files...




Yeah, here it is...

; Link port routines for TI-8X E2 driver
; Portions stolen from linkport.h by Randy Gluvna

port	equ	$07		; Link port is port 7..

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Receives a block of data from E2 (serial flash EEPROM)	;
; Can't do more than 255+127 at once, cuz of firmware		;
; hl: pointer to destination					;
; page: page number to get (up to 15 bits)			;
; numba: number of bytes to send (less than 255+127)		;
; pstart: where to start on that page				;
;								;
; Handles paged memory gracefully (I think :)			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_sfe:
	di			;
	ld a,$52		; Get data op code
	call send_byte		; Send out the op code..
	call setup_e2rw		; Setup operation with firmware..

gsfe_loop:
	call rec_byte		; Get a byte...	
	ld (hl),a		; Copy to hl...
	inc hl			; Increase pointer..
	ld a,h			; Have we overflowed this RAM page
yet?
	cp $C0			;
	jr nz,resume_gsfe	; We don't want new page yet
	call next_ram_page	; Go to next RAM page...
resume_gsfe:
	dec bc			; Decrease byte counter
	ld a,b			; Is bc at 0 yet?
	or c			;
	jr nz,gsfe_loop		; If its not, continue
	ei			;
	ret			; Return when we're done...

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sends a block of data to E2					;
; Takes same parms as get_sfe.. only data is sent, not rec'd	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
send_sfe:
	di			;
	ld a,$82		; Receive data op code..
	call send_byte		; 
	call setup_e2rw		; Again, setup E2 the same way...
	ei			;
	ret			; Seperately callable

ssfe_loop:
	di			;
ssfe_lmain:
	ld a,(hl)		;
	call send_byte		;
	inc hl			;
	ld a,h			; -- 86 Only --
	cp $C0			;
	jr nz,resume_sfe	;
	call next_ram_page	; -- End 86 only --
resume_sfe:
	dec bc			;
	ld a,b			;
	or c			;
	jr nz,ssfe_lmain	;
	ei			;
	ret			;

next_ram_page:			;
	ld a,l			; If l!=00 too, don't do ram page
junk
	or a			; We will never need to read from
$c000
	ret nz			; but may from $c0f9; start of
textshadow
	ld h,$80		; l should be 0 (we went to $c000 from
$bfff
	in a,(6)		; Next ram page
	inc a			;
	out (6),a		;
	ret			;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Erase a page of SFE memory... used in format routine		;
; Very similar to two routines above				;
; Takes: page (page to erase)					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
erase_sfe:
	di			;
	ld a,$82		;
	call send_byte		; We'll be writing
	ld hl,page		;
	call LD_HL_MHL		;
	add hl,hl		;
	ld a,h			;
	call send_byte		;
	ld a,l			;
	call send_byte		;
	xor a			; Clear a...
	call send_byte		; (start at beginning of page)
	or $FF			; 255...
	call send_byte		;
	ld a,$09		; And 9 more, for total of 264
	call send_byte		;
	ld bc,$0108		; 264 bytes to do...
erasep_loop:
	or $FF			; Write page with all 1s...
	call send_byte		; Send it
	dec bc			;
	ld a,b			;
	or c			;
	jr nz,erasep_loop	;
	ei			;
	ret			;

erasep_ldi:
	di			;
	jr erasep_loop		;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sets up a send / receive... tells firmware how much, what page;
; and where to start						;
; (starting at other than 0 when SENDING is HIGHLY problematic!	;
; Driver never does start at 0, neither should you!		;
;								;
; Takes: pointer of where to begin in hl			;
; 	 Where to start in page:
pstart				;
;	 What page to start on: page				;
;	 Number of bytes to get: numba - LESS THAN 255+127!!	;
;		(Not a problem, page is only 264 bytes anyway)	;
;								;
; Returns: configured E2, numba in bc, pointer in hl		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
setup_e2rw:
	push hl
	ld hl,page		; Copy page address into hl
	call LD_HL_MHL		; page is now in hl...
	add hl,hl		; Shift left (free up b0 w/o data loss)
	ld a,h			; Send high byte first...
	call send_byte		;
	ld a,l			;
	call send_byte		; And then the low
	ld a,(pstart)		; Where to start (=<255, can't do
	call send_byte		; full page... (wouldn't need to
	ld hl,numba		;
	call LD_HL_MHL		; Number of bytes to get -> hl
	ld de,$0100		; 
	call CP_HL_DE		; Compare hl (if its hl<256, c)
	jr c,sete2_oneb		; Only send one byte.. hl < 256
	or $FF			; Set all bits on a (Get 255 bytes)
	call send_byte		; Send that...
	ld de,-$FF		; Subtract $FF
;	or a			;
	add hl,de		; This will always be at least 1
	ld a,l			; After above h -should- ALWAYS be
0
;	res 7,a			; Reset b7 just to make sure <128
;	and $7F			; (another way to do it)
	call send_byte		; Thats how we do it...
	jr sete2_done		; Get that data now...
sete2_oneb:			; We only want < FF bytes...
	ld a,l			; Its less than 256, so h is 0
	call send_byte		;
	ld a,$80		; Set bit 7 -- signalling no more
	call send_byte		; Firmware interprets this as just
<255
sete2_done:			; Messy, but no stack usage... safer
	ld hl,numba		;
	call LD_HL_MHL		; Number of bytes to get -> hl
	ld b,h			; 	(Its LIFO) ;-)
	ld c,l			; Put counter into bc
;	ld hl,page		;
;	call LD_HL_MHL		;
	pop hl			; Get back pointer...
	ret			; Return, we're done

; -- Miscellaneous E2 calls --

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Requests status of memory chip -- usually 1000000 on all the	;
; chips I've tested... does NOT follow AT45D041 datasheet :(	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;stat_req:
;	ld a,$57		; This is the status op code
;	jr send_rec_ret		;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Gets the E2/EuP's firmware revision				;
; =< 4 is an EuP, >= 5 is an E2					;
; Doesn't matter though, both work same way... only E2 has	;
; a module port however						;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ver_get:
	ld a,$FF		; Status get op code

; Just to save some code..
send_rec_ret:			;
	di			;
	call send_byte		;
	call rec_byte		;
	ei			;
	ret			;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Receives byte using TI protocol				;
; Returns with z set if errored out.. otherwise byte = a	;
; IT IS CRUCIAL THAT THE STACK IS CLEAN WHEN THIS IS CALLED	;
; BECAUSE IF IT ERRORS OUT IT'LL DO -TWO- RETs TO RETURN TO	;
; HIGHEST LEVEL API CALL					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
rec_byte:			;
	push bc			; Back 'em up... destroyed
	push de			;
	ld b,$08		; 8 bits..

r0:
	ld de,$FFFF		;
;	jr r2			;

r1:
	in a,(port)		;
	and $03			; Both low?
	jr z,linkerr		;  That's an instant error
	cp $03			; Both high?
	jr nz,r3		;  No... go to r3

;	in a,(port)		;
;	and $03			;
;	jr z,linkerr		;
;	cp $03			;
;	jr nz,r3		;
r2:
	dec de			; Decrease counter...
	ld a,d			; Is de at 0 yet?
	or e			;
	jr nz,r1		;
	jr linkerr		; Yes it is, return

r3:
	sub $02			; Which line is active?
	jr nc,r8		; Line 2 (bit 1)
	ld a,$D4		; Bit 0...
	out (port),a		;
	rr c			;
	ld de,$FFFF		;
;	nop
;	nop
;	nop
;	nop
r4:
	in a,(port)		;
	and $03			; Clear out everything but first
two
	cp $02			; Line 1 clear?
	jr z,r5			;
	dec de			; Line 2 is clear...
	ld a,d			;
	or e			;
	jr nz,r4		;
	jr linkerr		; Timeout...
r5:
	ld a,$C0		;
	out (port),a		;
	ld d,$04		;
;	nop
;	nop
;	nop
;	nop
r6:
	dec d			;
	jr z,r7			;
	in a,(port)		;
	and $03			;
	cp $03			;
	jr nz,r6		;
r7:
	djnz r0			;
	ld a,c			;
	jr linkok		;

r8:
	ld a,$E8		;
	out (port),a		;
	rr c			;
	ld de,$FFFF		;
;	nop
;	nop
;	nop
;	nop
r9:
	in a,(port)		;
	and $03			;
	cp $01			;
	jr z,r5			;
	dec de			;
	ld a,d			;
	or e			;
	jr nz,r9		; Errored out...

linkerr:			; Cheap stack tricks, but it works..
	ld sp,(spbak)		; Backup stack pointer... save us
	ld a,$C0		;
	out (port),a		;
	ld a,(varactive)	;
	or a			;
	jr z,disp_to		;
;	ld hl,buffer2-2		;
;	rst 20h			; Copy to op1
;	rst 10h			; Find sym
;	jr c,disp_to		; Not found, wierd but not found
;	call _delvar		; Delete variable, timed out...
	ld hl,$3045		; Display variable destroyed msg
	ld (_penCol),hl		;
	ld hl,vd		;
	call D_ZM_STR		;
disp_to:
	ld hl,$3030		; Setup for number display
	ld (_penCol),hl		;
	ld hl,to		; Display
	call D_ZM_STR		; Display time out string...
	jp exitpause		; Return to main menu

linkok:
	pop de			; Just get vars back and return
	pop bc			;
	ret			;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sends byte out using TI protocol				;
; Input: a							;
; Returns with z set if errored out...				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
send_byte:
	push bc			; Back up destroyed registers
	push de			;
	ld c,a
	ld b,$08		;
s0:
	ld de,$FFFF		;
	rr c			;
	jr nc,s1		; Send a 0
	ld a,$E8		; %11101000 -- Activate red wire
	jr s2			;
s1:
	ld a,$D4		; %11010100 -- Activate white wire
s2:
	out (port),a		;
;	nop
;	nop
;	nop
;	nop
s3:
	in a,(port)		;
	and $03			; Both low?
	jr z,s4			;

;	in a,(port)		;
;	and $03			;
;	jr z,s4			;

	dec de			;
	ld a,d			;
	or e			;
	jr nz,s3		;
	jr linkerr		; We've errored out
s4:
	ld a,$C0		; %110000000 -- Activate both wires?
	out (port),a		;
	ld de,$FFFF		;
;	nop
;	nop
;	nop
;	nop
s5:
	dec de			;
	ld a,d			;
	or e			;
	jr z,linkerr		;
	in a,(port)		;
	and $03			;
	cp $03			; Both high?
	jr nz,s5		;
	djnz s0			;
	jr linkok

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sends a string of data out via TI protocol... hl is pointer	;
; Stops when byte is 0.. will not use in E2 driver, but its	;
; here anyway							;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;send_str:
;	ld a,(hl)		;
;	or a			;
;	ret z			;
;	call send_byte		;
;	inc hl			;
;	jr send_str		;

___________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com/getjuno.html
or call Juno at (800) 654-JUNO [654-5866]


References: