mirror of
https://github.com/Pecusx/jataricart.git
synced 2026-05-20 22:33:22 +02:00
e6dc1ff925
updated flasher to handle all chip configuration.
530 lines
9.4 KiB
Plaintext
530 lines
9.4 KiB
Plaintext
; flash eeprom library
|
|
; by JHusak , 04.01.2020
|
|
; free to use.
|
|
|
|
FRAME_FEEDBACK=1
|
|
|
|
icl "lib_28sf0x0.asm"
|
|
icl "lib_29f0x0.asm"
|
|
icl "lib_39sf0x0.asm"
|
|
num_mems = 3
|
|
|
|
; CONSTANTS
|
|
m_offsets
|
|
; jump table
|
|
softid_entry = 0
|
|
softid_exit = 3
|
|
flash_formatchip = 6
|
|
flash_formatsector = 9
|
|
flash_writebyte = 12
|
|
flash_lockchip = 15
|
|
flash_unlockchip = 18
|
|
flash_wait_unit = 21
|
|
; data table
|
|
; 1 byte
|
|
flash_sectorsizeMSB = 24
|
|
; var bytes 0 terminated
|
|
flash_idstr = 25
|
|
|
|
; rw section, may be moved to ZP if needed
|
|
M_VECTOR .word 0
|
|
m_vendor .byte 0
|
|
m_kind .byte 0
|
|
|
|
; ro section again
|
|
; Protocols for known kinds of memory:
|
|
; 28sf0x0 protokol unlock/write
|
|
; 39sf0x0 protokol 5555/AA;2aaa/55
|
|
; 29f0x0 protokol 555/AA;2aa/55
|
|
; Working scan order; scanning from the end;
|
|
M_CHECK_VECS .word M_VECTORS_39SF, M_VECTORS_29F, M_VECTORS_28SF
|
|
|
|
; --------------------------------------------------------------------
|
|
;Problems to solve with writing:
|
|
; - check flash presence
|
|
; - flash protocol
|
|
; - size of flash 1,2
|
|
; - size of sector in some cases
|
|
; - number of flashes (easy, they do not overlap)
|
|
; All can be read by erasing memory, writing several bytes and reading them;
|
|
; But we will rely rather on user's choice not to wear memory
|
|
|
|
; First detection is to read raw memory and id and compare results. However, we do not want to keep all those ids to recognise.
|
|
; Second detection is to compare contents. But not very reliable as contents may repeat.
|
|
; And ome issues may occur when no memory inserted.
|
|
; Eventually, for flash recognition
|
|
; - format,
|
|
; - write 128k-1 byte, read 2*128k-1 -> if not ff flash is 128k
|
|
; - write 256k-1 byte, read 2*256k-1 -> if not ff flash is 256kB, else is 512kb
|
|
;
|
|
|
|
; ??? c parameter as format/writebyte
|
|
; ??? for compatibility, 5555_2aaa only
|
|
|
|
; ------------------------------------------------------------------------
|
|
; --------------------------
|
|
; PROCEDURE
|
|
; x = 0 or 0x40 - flash chip address.
|
|
; stores proper vector table pointer
|
|
; this fails only when somebody stores vendor and product bytes
|
|
; at the proper cells.
|
|
; The second case is that there is no mem at all.
|
|
; Then two cases are possible: random number OR fixed ff.
|
|
;
|
|
; then in the code we call lda #offset/jsr jsrtovectorproc
|
|
.if 0
|
|
check_type
|
|
ldy #(2*(num_mems-1))
|
|
?again
|
|
sty m_iter
|
|
?again_loop
|
|
; store default values
|
|
jsr flashsetbank0
|
|
; load real values, may be random if no chip.
|
|
lda $a000
|
|
sta m_vendor
|
|
lda $a001
|
|
sta m_kind
|
|
|
|
jsr jsrtosoftidentry
|
|
|
|
jsr flashsetbank0
|
|
lda $a000 ; vendor
|
|
cmp m_vendor
|
|
sta m_vendor
|
|
beq ?next
|
|
lda $a001 ; id
|
|
cmp m_kind
|
|
sta m_kind
|
|
beq ?next
|
|
bne ?OK
|
|
?next
|
|
ldy m_iter
|
|
dey
|
|
dey
|
|
bpl ?again
|
|
; error
|
|
sec ; failed, no chip
|
|
rts
|
|
|
|
?check_again
|
|
; if zero, decrement check_bad_counter
|
|
sne
|
|
dec check_bad_counter
|
|
dec check_counter
|
|
bne ?again_loop
|
|
lda check_bad_counter
|
|
cmp #CNTINIT
|
|
; if check_counter is 0 and check_bad_counter is CNTINIT then ok, else
|
|
; go to ?next
|
|
bne ?next
|
|
.endif
|
|
|
|
|
|
|
|
check_type
|
|
ldy #(2*(num_mems-1))
|
|
?again
|
|
sty ?m_iter
|
|
|
|
lda #0
|
|
sta ?or_val
|
|
sta ?or_val+1
|
|
sta ?c_iter
|
|
lda #$ff
|
|
sta ?and_val
|
|
sta ?and_val+1
|
|
?repeat
|
|
jsr flashsetbank0
|
|
jsr jsrtosoftidentry
|
|
|
|
lda $A000
|
|
sta ?_id_m
|
|
lda $A001
|
|
sta ?_id_m+1
|
|
|
|
jsr jsrtosoftidexit
|
|
|
|
lda $A000
|
|
sta ?_no_m
|
|
lda $A001
|
|
sta ?_no_m+1
|
|
|
|
lda ?_id_m
|
|
and:sta ?and_val
|
|
|
|
lda ?_id_m+1
|
|
and:sta ?and_val+1
|
|
|
|
lda ?_id_m
|
|
ora:sta ?or_val
|
|
|
|
lda ?_id_m+1
|
|
ora:sta ?or_val+1
|
|
|
|
|
|
dec ?c_iter
|
|
bne ?repeat
|
|
;@
|
|
; lda #$ff
|
|
; sta $d01a
|
|
; lda #0
|
|
; sta $d01a
|
|
; jmp @-
|
|
cpw ?and_val ?or_val
|
|
bne ?next_chip ; empty slot, random values, no chip, check next chip
|
|
cpw ?and_val ?_no_m
|
|
beq ?next_chip ; the came content, stable values, no response so no chip, check next chip
|
|
|
|
?OK
|
|
lda ?_id_m
|
|
sta m_vendor
|
|
lda ?_id_m+1
|
|
sta m_vendor+1
|
|
lda M_CHECK_VECS+1,y
|
|
sta M_VECTOR+1
|
|
lda M_CHECK_VECS,y
|
|
sta M_VECTOR
|
|
clc
|
|
rts
|
|
|
|
?next_chip
|
|
php ; store zero flag
|
|
pla
|
|
ldy ?m_iter
|
|
dey
|
|
dey
|
|
jpl ?again
|
|
pha ; restored zero flag
|
|
plp
|
|
sec
|
|
rts
|
|
|
|
?or_val dta 0,0
|
|
?and_val dta 0,0
|
|
?_id_m dta 0,0
|
|
?_no_m dta 0,0
|
|
?c_iter .byte 0
|
|
?m_iter .byte 0
|
|
|
|
jsrtosoftidexit
|
|
lda #softid_exit
|
|
jsr jsrtovectorproc
|
|
lda $d013
|
|
sta $3fa
|
|
clc
|
|
rts
|
|
|
|
|
|
|
|
jsrtosoftidentry
|
|
lda M_CHECK_VECS+1,y ; first is softid entry
|
|
sta M_VECTOR+1
|
|
pha
|
|
lda M_CHECK_VECS,y ; first is softid entry
|
|
sta M_VECTOR
|
|
pha
|
|
php
|
|
rti ; jsr to tabled func
|
|
|
|
; PROCEDURE
|
|
; performs jump to vector table at offset in A provided
|
|
; y passed to the procedure called
|
|
jsrtovectorproc
|
|
php ; preserve C
|
|
clc
|
|
adc M_VECTOR
|
|
sta tmpa
|
|
lda M_VECTOR+1
|
|
adc #0
|
|
plp ; restore C
|
|
pha
|
|
lda tmpa:#0
|
|
pha
|
|
php
|
|
rti
|
|
; a - vector value offset
|
|
; returns y-LSB A-MSB
|
|
getvectorvalue
|
|
clc
|
|
adc M_VECTOR
|
|
tay
|
|
lda M_VECTOR+1
|
|
adc #0
|
|
rts
|
|
; --------------------------
|
|
flashformatchip2
|
|
ldx #$40
|
|
dta { bit.w }
|
|
flashformatchip1
|
|
ldx #$0
|
|
; --------------------------
|
|
; PROCEDURE
|
|
; x = 0 or 0x40 - flash chip address.
|
|
flashformatchip
|
|
; first check if not formatted
|
|
stx store_x
|
|
jsr flashcheckempty
|
|
bcc flashformatexit
|
|
sei
|
|
ldx store_x
|
|
lda #flash_formatchip
|
|
jsr jsrtovectorproc ; preserves A
|
|
; not needed to mva $ff flashcmp
|
|
jsr wait4flashcheckresult ; waits for format finished
|
|
; then check number of banks for FFs
|
|
flashcheckempty
|
|
lda #$3f ; this depends on flash size, $0f, $1f, $3f
|
|
sta flashformatcounter
|
|
flashbankloop sei
|
|
ldx store_x
|
|
sta flashformatcounter:$d5FF,x ; set chip (x) and bank
|
|
; set pages count, 8kB
|
|
ldy #$20
|
|
; reset address
|
|
lda #$a0
|
|
sta flashformataddrcheck + 2
|
|
; check whole sector against 0xff
|
|
jsr flashchecksectorformatted_bare ; destroys x
|
|
bcs flashformatexit ; format error if c set
|
|
dec flashformatcounter
|
|
bpl flashbankloop
|
|
flashformatexit
|
|
flashcartoff ; preserves C
|
|
pha
|
|
sta $d580
|
|
lda $d013
|
|
sta $3fa
|
|
cli
|
|
pla
|
|
rts
|
|
|
|
flashchecksectorformatted
|
|
ldy #$10
|
|
flashchecksectorformatted_bare
|
|
lda #$ff
|
|
ldx #0
|
|
flashformataddrcheck
|
|
cmp $a000,x
|
|
bne flashsectorformaterror
|
|
inx
|
|
bne flashformataddrcheck
|
|
FEEDBACK
|
|
inc flashformataddrcheck + 2
|
|
dey
|
|
bne flashformataddrcheck
|
|
FEEDBACKEND
|
|
clc
|
|
rts
|
|
flashsectorformaterror
|
|
jsr flashcartoff
|
|
sec
|
|
rts
|
|
|
|
; --------------------------
|
|
store_x dta 0
|
|
|
|
; --------------------------
|
|
; PROCEDURE
|
|
flashformatsector
|
|
; x - bank number 00 - 7f (even sector>>1)
|
|
; a - page number in 128byte units $0-$3f
|
|
; erase sector containing address bank number * $2000 + page number * 128
|
|
|
|
stx flashformatstorex
|
|
sei
|
|
; calculate lower 13 bits of sector
|
|
; (address in 8kb bank)
|
|
ldx #0
|
|
; convert page in A to cartridge a000-bfff address flashtmpaddr
|
|
; 0,1 -> 0 ; 2,3 -> 256 ; 4,5 -> 512 etc
|
|
lsr
|
|
ora #$A0
|
|
tay
|
|
|
|
jsr flashsetaddr ;(x/y) store address for write byte to format sector
|
|
;
|
|
ldx flashformatstorex:#0 ; filled before, 8k bank number
|
|
|
|
lda #flash_formatsector ; does not touch A,X?
|
|
jsr jsrtovectorproc
|
|
|
|
ldy #{ sta.w }
|
|
jsr flashprocessbyte ; format sector INVOKED !
|
|
|
|
|
|
jsr wait4flashcheckresult ;
|
|
;sei
|
|
|
|
ldx flashformatstorex
|
|
jsr flashsetbank0
|
|
|
|
cli
|
|
; check if all data in sector is $ff
|
|
|
|
flashsectorformatgood
|
|
;jsr flashcartoff
|
|
clc
|
|
rts
|
|
|
|
.macro FEEDBACK
|
|
.if (FRAME_FEEDBACK)>=1
|
|
php
|
|
pha
|
|
.if (FRAME_FEEDBACK&1)==1
|
|
inc colbaks
|
|
lda colbaks
|
|
sta colbak
|
|
.endif
|
|
.if (FRAME_FEEDBACK&2)==2
|
|
lda #0
|
|
sta dmactl
|
|
sta sdmctl
|
|
.endif
|
|
pla
|
|
plp
|
|
.endif
|
|
|
|
.endm
|
|
.macro FEEDBACKEND
|
|
.if FRAME_FEEDBACK>=1
|
|
php
|
|
pha
|
|
lda #0
|
|
sta colbaks
|
|
sta colbak
|
|
.if (FRAME_FEEDBACK&2)==2
|
|
lda #34 ; ???
|
|
sta sdmctl
|
|
sta dmactl
|
|
.endif
|
|
pla
|
|
plp
|
|
.endif
|
|
.endm
|
|
; ---------------------
|
|
; PROCEDURE
|
|
|
|
flashwritebyte
|
|
|
|
; a - byte to write
|
|
; x - 8kb bank to switch, $00 to $7f, also chip select
|
|
; flashaddr - addres in flash - must be a000-offset
|
|
; do not programm byte if already good
|
|
sei
|
|
sta $D500,x ; select bank, chip
|
|
ldy #{ cmp.w }
|
|
jsr flashprocessbyte
|
|
bne byte_differs
|
|
sta $D580
|
|
cli
|
|
clc
|
|
rts
|
|
byte_differs
|
|
sta flashcmp
|
|
sei
|
|
pha
|
|
lda #flash_writebyte ; preserves A,X
|
|
jsr jsrtovectorproc
|
|
pla
|
|
; set right bank
|
|
sta $D500,x
|
|
ldy #{ sta.w }
|
|
jsr flashprocessbyte ; WRITE BYTE INVOKED !
|
|
|
|
wait4flashcheckresult ; sei mode
|
|
mva #0 flashcnt ; reset counter
|
|
sta flashcnt+1
|
|
; ldy #1 ; first time wait short first turn to speed up byte write.
|
|
beq skipwsync
|
|
|
|
flashwaitfordone
|
|
; WARNING! 29f040 erases even 10 seconds!
|
|
; approx 100ms in overall for chip erase:
|
|
; as many cycles needed, as 256*cycles >100ms * (1+epsilon)
|
|
; 100 ms is 180000 cycles
|
|
; so max 256 rough loops must last longer
|
|
; 180000 / 256 = 703
|
|
; 700 cycles by 6 cycles loop lasts = 116.
|
|
; so flipipng values, and adding margin,
|
|
; we count 128*6 cycles in inner loop.
|
|
; max sector erase by datasheet: 25 ms
|
|
; max chip erase by datasheet: 100 ms 39sf040
|
|
; max chip erase by datasheet: 20 ms 28sf040
|
|
; max chip erase by datasheet: 10000 ms 29f040
|
|
|
|
;ldy#250
|
|
sta WSYNC
|
|
skipwsync
|
|
;lda #flash_wait_unit
|
|
;jsr jsrtovectorproc
|
|
FEEDBACK
|
|
;dey
|
|
;bne @-
|
|
|
|
ldy #{ lda.w }
|
|
jsr flashprocessbyte
|
|
sta flashval
|
|
ldy #{ eor.w }
|
|
jsr flashprocessbyte
|
|
inc flashcnt
|
|
bne cont
|
|
inc flashcnt+1
|
|
bne cont
|
|
jsr flashcartoff
|
|
FEEDBACKEND
|
|
lda #$ff ; status
|
|
rts
|
|
cont
|
|
and #$40
|
|
bne flashwaitfordone
|
|
jsr flashcartoff
|
|
FEEDBACKEND
|
|
lda flashval:#0
|
|
cmp flashcmp:#0
|
|
; when byte compare non zero = error
|
|
rts
|
|
|
|
flashcnt
|
|
dta 0,0
|
|
; ----------------------
|
|
; PROCEDURE
|
|
|
|
flashprocessbyte
|
|
|
|
; y - byteop for cpu to do with byte
|
|
; flashaddr - stored address
|
|
sty flashbyteop
|
|
flashbyteop
|
|
sta flashaddr:$aaaa
|
|
rts
|
|
|
|
flashend
|
|
FEEDBACKEND
|
|
rts
|
|
|
|
flashincaddr
|
|
inw flashaddr
|
|
rts
|
|
|
|
flashsetaddr
|
|
stx flashaddr
|
|
sty flashaddr+1
|
|
rts
|
|
|
|
flashunlockchip
|
|
lda #flash_unlockchip
|
|
jmp jsrtovectorproc
|
|
flashlockchip
|
|
lda #flash_lockchip
|
|
jmp jsrtovectorproc
|
|
|
|
flashsetbank0
|
|
sta $d500,x
|
|
pha
|
|
lda $d013
|
|
sta $3fa
|
|
pla
|
|
rts
|
|
|