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: