mirror of
https://github.com/Pecusx/jataricart.git
synced 2026-05-20 22:33:22 +02:00
multimemory lib done
This commit is contained in:
+193
-214
@@ -2,217 +2,138 @@
|
||||
; by JHusak , 04.01.2020
|
||||
; free to use.
|
||||
|
||||
; Nice to have procedures, because mads may exclude unused procedures (-x in cmdl)
|
||||
;.def STRIPPED
|
||||
FRAME_FEEDBACK=1
|
||||
|
||||
;.def FLASH_INCLUDE_ALL
|
||||
;FLASH_TYPE equ M_TYPE_28SF
|
||||
;FLASH_TYPE equ M_TYPE_29SF
|
||||
FLASH_TYPE equ M_TYPE_39SF
|
||||
;FLASH_TYPE equ M_TYPE_29F
|
||||
icl "lib_28sf0x0.asm"
|
||||
icl "lib_29f0x0.asm"
|
||||
icl "lib_39sf0x0.asm"
|
||||
num_mems = 3
|
||||
|
||||
; x - 0x0 or 0x40 - chip select;
|
||||
; a - $80 - format, $90 - enter id mode, $a0 - writebyte
|
||||
C_ID_MODE equ $90
|
||||
; CONSTANTS
|
||||
m_offsets
|
||||
softid_entry = 0
|
||||
softid_exit = 3
|
||||
flashoppreamble = 6
|
||||
flash_lockchip = 9
|
||||
flash_unlockchip = 12
|
||||
flash_wait_unit = 15
|
||||
flash_idstr = 18
|
||||
|
||||
M_TYPE_28SF equ $88
|
||||
M_TYPE_29SF equ $89
|
||||
M_TYPE_39SF equ $99
|
||||
M_TYPE_29F equ $09 ; used in MaxFlash BM29F040
|
||||
; rw section, may be moved to ZP if needed
|
||||
M_VECTOR .word 0
|
||||
tmpa .byte 0
|
||||
m_vendor .byte 0
|
||||
m_kind .byte 0
|
||||
m_iter .byte 0
|
||||
|
||||
M_SSIZE_28SF equ $0100 ; sector size
|
||||
M_SSIZE_29SF equ $0080 ; sector size
|
||||
M_SSIZE_39SF equ $1000 ; sector size
|
||||
M_SSIZE_29F equ $10000 ; sector size; MAXFlash, protocol compatible with 39sf0x0
|
||||
;Problems with writing:
|
||||
; 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
|
||||
; For flash recognition
|
||||
; 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 128 kbytes, read more -> if not ff, flash is 128k
|
||||
; - write additional 128KB, read more ->if not ff flash is 256kB, else is 512kb
|
||||
; - 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
|
||||
;
|
||||
; First detection is to read raw memory and id and compare results. Some issues may occur when no memory inserted.
|
||||
|
||||
;flash_detect_protocol:
|
||||
; lda #ID_MODE
|
||||
; jsr flashoppreamble_5555_2aaa
|
||||
; ??? c parameter as format/writebyte
|
||||
; ??? for compatibility, 5555_2aaa only
|
||||
|
||||
; c parameter as format/writebyte
|
||||
; for compatibility, 5555_2aaa only
|
||||
|
||||
.IF (FLASH_TYPE = M_TYPE_39SF) .or .def FLASH_INCLUDE_ALL
|
||||
TRIGGER_FORMAT equ $10
|
||||
C_FORMAT equ $80
|
||||
C_BYTE_PROG equ $a0
|
||||
flashoppreamble
|
||||
pha
|
||||
lda #C_BYTE_PROG
|
||||
scc
|
||||
lda #C_FORMAT ; only if c set
|
||||
sta command
|
||||
pla
|
||||
jmp @+
|
||||
flashoppreamble_acc ; 39sf0x0, 29F040
|
||||
sta command
|
||||
@ txa
|
||||
pha
|
||||
; when write byte x must be set to either 0 or 40 temporarily
|
||||
and #$40
|
||||
tax
|
||||
sta $d502,x
|
||||
mva #$aa $b555 ; $5555<$aa
|
||||
sta $d501,x
|
||||
mva #$55 $aaaa ; $2aaa<$55
|
||||
; $5555<$80
|
||||
sta $d502,x
|
||||
command equ *+1
|
||||
mva #$ff $b555; will become command: FORMAT/ID_MODE/BYTE_PROG
|
||||
cmp #C_FORMAT
|
||||
bne @+ ; if not FORMAT, procedure finishes
|
||||
; FORMAT part, more to write
|
||||
sta $d502,x
|
||||
mva #$aa $b555 ; $5555<$aa
|
||||
sta $d501,x
|
||||
mva #$55 $aaaa ; $2aaa<$55
|
||||
@ pla
|
||||
tax
|
||||
rts
|
||||
.endif
|
||||
.if (FLASH_TYPE=M_TYPE_29SF) .or .def FLASH_INCLUDE_ALL
|
||||
TRIGGER_FORMAT equ $10
|
||||
C_FORMAT equ $80
|
||||
C_BYTE_PROG equ $a0
|
||||
flashoppreamble
|
||||
pha
|
||||
lda #C_BYTE_PROG
|
||||
scc
|
||||
lda #C_FORMAT ; only if c set
|
||||
sta command
|
||||
pla
|
||||
jmp @+
|
||||
flashoppreamble_acc ; 29sf040
|
||||
sta command
|
||||
@ txa
|
||||
pha
|
||||
; when write byte x must be set to either 0 or 40 temporarily
|
||||
and #$40
|
||||
tax
|
||||
sta $d500,x
|
||||
mva #$aa $a555 ; $555<$aa
|
||||
mva #$55 $a2aa ; $2aa<$55
|
||||
; $555<command
|
||||
command equ *+1
|
||||
mva #$ff $a555; will become command: FORMAT/ID_MODE/BYTE_PROG
|
||||
cmp #C_FORMAT
|
||||
bne @+ ; if not FORMAT, procedure finishes
|
||||
; FORMAT part, more to write
|
||||
mva #$aa $a555 ; $555<$aa
|
||||
mva #$55 $a2aa ; $2aa<$55
|
||||
; PREPARE FOR SECTOR TO ERASE
|
||||
@ pla
|
||||
tax
|
||||
rts
|
||||
.endif
|
||||
|
||||
.if (FLASH_TYPE=M_TYPE_28SF) .or .def FLASH_INCLUDE_ALL
|
||||
TRIGGER_FORMAT equ $30
|
||||
C_FORMAT equ $30
|
||||
C_BYTE_PROG equ $10
|
||||
flashoppreamble
|
||||
pha
|
||||
lda #C_BYTE_PROG
|
||||
scc
|
||||
lda #C_FORMAT ; only if c set
|
||||
flashoppreamble_acc ; 28SF0x0
|
||||
sta $d500,x ; can be any address
|
||||
sta $a000; command: FORMAT/ID_MODE/BYTE_PROG, any address
|
||||
rts
|
||||
.endif
|
||||
.if FLASH_TYPE=M_TYPE_28SF
|
||||
flash_unlockchip
|
||||
sta $D500,x
|
||||
; read from 1823H, 1820H, 1822H, 0418H, 041BH, 0419H, 041AH
|
||||
lda $B823
|
||||
lda $B820
|
||||
lda $B822
|
||||
lda $A418
|
||||
lda $A41B
|
||||
lda $A419
|
||||
lda $A41A
|
||||
rts
|
||||
.endif
|
||||
.if (FLASH_TYPE=M_TYPE_29SF) .or (FLASH_TYPE=M_TYPE_39SF)
|
||||
flash_unlockchip
|
||||
rts
|
||||
.endif
|
||||
|
||||
.ifndef STRIPPED
|
||||
; flash size only needed in not stripped version for format result check.
|
||||
flash_size dta 0
|
||||
; as well as check_vendor procedure
|
||||
;
|
||||
; ------------------------------------------------------------------------
|
||||
; --------------------------
|
||||
; PROCEDURE
|
||||
; x = 0 or 0x40 - flash chip address.
|
||||
; returns c set -> failed
|
||||
; if c cleared, x=vendor, y=product code
|
||||
; there are some memories which need multiple read, but we do not abuse them.
|
||||
check_vendor
|
||||
lda #C_ID_MODE
|
||||
jsr flashoppreamble_acc
|
||||
ldx $a000 ; vendor
|
||||
ldy $a001 ; id
|
||||
mva #$f0 $a000 ; exit read_id
|
||||
mva #0 flash_size
|
||||
; stores proper vector table pointer if worked
|
||||
; this fails only when somebody stores vendor and product bytes
|
||||
; at the proper cells.
|
||||
;
|
||||
; then in the code we call lda #offset/jsr jsrtovectorproc
|
||||
check_type
|
||||
ldy #(2*(num_mems-1))
|
||||
?again
|
||||
sty m_iter
|
||||
; store default values
|
||||
jsr flashsetbank
|
||||
lda $a000
|
||||
sta m_vendor
|
||||
lda $a001
|
||||
sta m_kind
|
||||
|
||||
jsr jsrtosoftidentry
|
||||
|
||||
cpx #$BF; SST
|
||||
bne next1
|
||||
; nice to store that this is SST
|
||||
cpy #$B5
|
||||
bne @+
|
||||
lda #$0f
|
||||
@ cpy #$B6
|
||||
bne @+
|
||||
lda #$1f
|
||||
@ cpy #$B7
|
||||
bne @+
|
||||
lda #$3f
|
||||
@ sta flash_size
|
||||
clc
|
||||
rts
|
||||
next1
|
||||
.if 0
|
||||
lda #C_ID_MODE
|
||||
jsr flashoppreamble_acc
|
||||
ldx $a000 ; vendor
|
||||
ldy $a001 ; id
|
||||
mva #$f0 $a000 ; exit read_id
|
||||
mva #0 flash_size
|
||||
|
||||
cpx #$BF; SST
|
||||
bne cvexit
|
||||
; nice to store that this is SST
|
||||
cpy #$24
|
||||
bne @+
|
||||
lda #$1f
|
||||
@ cpy #$13
|
||||
bne @+
|
||||
lda #$3f
|
||||
@ sta flash_size
|
||||
clc
|
||||
rts
|
||||
.endif
|
||||
cvexit
|
||||
jsr flashsetbank
|
||||
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
|
||||
rts
|
||||
.endif
|
||||
?OK
|
||||
lda M_CHECK_VECS+1,y
|
||||
sta M_VECTOR+1
|
||||
lda M_CHECK_VECS,y
|
||||
sta M_VECTOR
|
||||
|
||||
jsrtosoftidexit
|
||||
lda #softid_exit
|
||||
jsr jsrtovectorproc
|
||||
lda $d013
|
||||
sta $3fa
|
||||
clc
|
||||
rts
|
||||
|
||||
jsrtosoftidentry
|
||||
lda M_CHECK_VECS+1,y ; first is softid entry
|
||||
pha
|
||||
lda M_CHECK_VECS,y ; first is softid entry
|
||||
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
|
||||
pha
|
||||
php
|
||||
rti
|
||||
|
||||
; --------------------------
|
||||
flashformatchip2
|
||||
@@ -227,11 +148,9 @@ flashformatchip
|
||||
|
||||
sei
|
||||
stx store_x
|
||||
lda #C_FORMAT
|
||||
jsr flashoppreamble_acc ; does not touch A
|
||||
sta $d502,x
|
||||
lda #TRIGGER_FORMAT
|
||||
sta $b555 ; FORMAT HERE TRIGGERED!
|
||||
sec ; will format flash!
|
||||
lda #flashoppreamble
|
||||
jsr jsrtovectorproc ; preserves A
|
||||
; not needed to mva $ff flashcmp
|
||||
jsr wait4flashcheckresult ; waits for format finished
|
||||
; then check number of banks for FFs
|
||||
@@ -262,12 +181,14 @@ flashformatsector
|
||||
; format 4kb evensector
|
||||
; strange form - easily maps to cartridge banks
|
||||
; to format bank, must format sector (x<<1) and (x<<1) +1
|
||||
; IT IS LONG because it has to be save, ie not format if formatted etc.
|
||||
|
||||
; first check if all ff
|
||||
; this is to avoid wear
|
||||
stx flashformatstorex
|
||||
sta flashformatstorea
|
||||
sei
|
||||
sta $d500,x
|
||||
jsr flashsetbank
|
||||
; store #$a0 or #$b0
|
||||
sta flashformataddrcheck + 2
|
||||
jsr flashchecksectorformatted
|
||||
@@ -276,9 +197,9 @@ flashformatsector
|
||||
flashformatstorex equ * + 1
|
||||
ldx #0 ; filled before
|
||||
; check least sector bit
|
||||
|
||||
lda #C_FORMAT
|
||||
jsr flashoppreamble_acc ; does not touch A,X
|
||||
sec
|
||||
lda #flashoppreamble ; does not touch A,X
|
||||
jsr jsrtovectorproc
|
||||
sta $D500,x
|
||||
; A must be either $A0 or $B0
|
||||
flashformatstorea equ * + 1
|
||||
@@ -296,7 +217,7 @@ flashtmpaddr equ *+1
|
||||
sta flashformataddrcheck+2
|
||||
|
||||
ldx flashformatstorex
|
||||
sta $d500,x
|
||||
jsr flashsetbank
|
||||
|
||||
; check if all data in sector is $ff
|
||||
flashchecksectorformatted
|
||||
@@ -309,10 +230,12 @@ flashformataddrcheck
|
||||
bne flashsectorformaterror
|
||||
inx
|
||||
bne flashformataddrcheck
|
||||
FEEDBACK
|
||||
inc flashformataddrcheck + 2
|
||||
dey
|
||||
bne flashformataddrcheck
|
||||
|
||||
FEEDBACKEND
|
||||
|
||||
flashsectorformatgood
|
||||
jsr flashcartoff
|
||||
clc
|
||||
@@ -323,7 +246,39 @@ flashsectorformaterror
|
||||
sec
|
||||
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
|
||||
lda #34
|
||||
sta sdmctl
|
||||
sta dmactl
|
||||
pla
|
||||
plp
|
||||
.endif
|
||||
.endm
|
||||
; ---------------------
|
||||
; PROCEDURE
|
||||
|
||||
@@ -346,8 +301,9 @@ byte_differs
|
||||
sta flashcmp
|
||||
sei
|
||||
pha
|
||||
lda #C_BYTE_PROG
|
||||
jsr flashoppreamble_acc ; preserves A,X
|
||||
clc ; byte program preamble
|
||||
lda #flashoppreamble ; preserves A,X
|
||||
jsr jsrtovectorproc
|
||||
pla
|
||||
; set right bank
|
||||
sta $D500,x
|
||||
@@ -356,10 +312,12 @@ byte_differs
|
||||
|
||||
wait4flashcheckresult ; sei mode
|
||||
mva #0 flashcnt
|
||||
ldy #1 ; first time wait short first turn to speed up byte write.
|
||||
bne @+
|
||||
sta flashcnt+1
|
||||
; ldy #1 ; first time wait short first turn to speed up byte write.
|
||||
beq @+
|
||||
|
||||
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
|
||||
@@ -369,26 +327,37 @@ flashwaitfordone
|
||||
; 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
|
||||
ldy#250
|
||||
@ dey
|
||||
nop
|
||||
bne @-
|
||||
; 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
|
||||
@
|
||||
;lda #flash_wait_unit
|
||||
;jsr jsrtovectorproc
|
||||
FEEDBACK
|
||||
;dey
|
||||
;bne @-
|
||||
|
||||
@ ldy #{ lda.w }
|
||||
@
|
||||
|
||||
ldy #{ lda.w }
|
||||
jsr flashprocessbyte
|
||||
sta flashval
|
||||
ldy #{ eor.w }
|
||||
jsr flashprocessbyte
|
||||
inc flashcnt
|
||||
bne @+
|
||||
sta $d580
|
||||
inc flashcnt+1
|
||||
bne @+
|
||||
jsr flashcartoff
|
||||
lda #$ff ; status
|
||||
rts
|
||||
@
|
||||
and #$40
|
||||
bne flashwaitfordone
|
||||
sta $d580
|
||||
jsr flashcartoff
|
||||
flashval equ *+1
|
||||
lda #0
|
||||
flashcmp equ *+1
|
||||
@@ -397,7 +366,7 @@ flashcmp equ *+1
|
||||
rts
|
||||
|
||||
flashcnt
|
||||
dta 0
|
||||
dta 0,0
|
||||
; ----------------------
|
||||
; PROCEDURE
|
||||
|
||||
@@ -411,6 +380,10 @@ flashbyteop
|
||||
sta $aaaa
|
||||
rts
|
||||
|
||||
flashend
|
||||
FEEDBACKEND
|
||||
rts
|
||||
|
||||
flashincaddr
|
||||
inw flashaddr
|
||||
rts
|
||||
@@ -420,6 +393,12 @@ flashsetaddr
|
||||
sty flashaddr+1
|
||||
rts
|
||||
|
||||
flashsetbank
|
||||
sta $d500,x
|
||||
lda $d013
|
||||
sta $3fa
|
||||
rts
|
||||
|
||||
flashcartoff
|
||||
pha
|
||||
sta $d580
|
||||
|
||||
@@ -1,371 +0,0 @@
|
||||
; flash eeprom library
|
||||
; by JHusak , 04.01.2020
|
||||
; free to use.
|
||||
|
||||
icl "lib_28sf0x0.asm"
|
||||
icl "lib_29f0x0.asm"
|
||||
icl "lib_39sf0x0.asm"
|
||||
num_mems = 3
|
||||
|
||||
; CONSTANTS
|
||||
m_offsets
|
||||
softid_entry = 0
|
||||
softid_exit = 3
|
||||
flashoppreamble = 6
|
||||
flash_lockchip = 9
|
||||
flash_unlockchip = 12
|
||||
flash_wait_unit = 15
|
||||
flash_idstr = 18
|
||||
|
||||
; rw section, may be moved to ZP if needed
|
||||
M_VECTOR .word 0
|
||||
tmpa .byte 0
|
||||
m_vendor .byte 0
|
||||
m_kind .byte 0
|
||||
m_iter .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 if worked
|
||||
; this fails only when somebody stores vendor and product bytes
|
||||
; at the proper cells.
|
||||
;
|
||||
; then in the code we call lda #offset/jsr jsrtovectorproc
|
||||
check_type
|
||||
ldy #(2*(num_mems-1))
|
||||
?again
|
||||
sty m_iter
|
||||
; store default values
|
||||
jsr flashsetbank
|
||||
lda $a000
|
||||
sta m_vendor
|
||||
lda $a001
|
||||
sta m_kind
|
||||
|
||||
jsr jsrtosoftidentry
|
||||
|
||||
jsr flashsetbank
|
||||
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
|
||||
rts
|
||||
?OK
|
||||
lda M_CHECK_VECS+1,y
|
||||
sta M_VECTOR+1
|
||||
lda M_CHECK_VECS,y
|
||||
sta M_VECTOR
|
||||
|
||||
jsrtosoftidexit
|
||||
lda #softid_exit
|
||||
jsr jsrtovectorproc
|
||||
lda $d013
|
||||
sta $3fa
|
||||
clc
|
||||
rts
|
||||
|
||||
jsrtosoftidentry
|
||||
lda M_CHECK_VECS+1,y ; first is softid entry
|
||||
pha
|
||||
lda M_CHECK_VECS,y ; first is softid entry
|
||||
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
|
||||
pha
|
||||
php
|
||||
rti
|
||||
|
||||
; --------------------------
|
||||
flashformatchip2
|
||||
ldx #$40
|
||||
dta { bit.w }
|
||||
flashformatchip1
|
||||
ldx #$0
|
||||
; --------------------------
|
||||
; PROCEDURE
|
||||
; x = 0 or 0x40 - flash chip address.
|
||||
flashformatchip
|
||||
|
||||
sei
|
||||
stx store_x
|
||||
sec ; will format flash!
|
||||
lda #flashoppreamble
|
||||
jsr jsrtovectorproc ; preserves A
|
||||
; not needed to mva $ff flashcmp
|
||||
jsr wait4flashcheckresult ; waits for format finished
|
||||
; then check number of banks for FFs
|
||||
lda #$3f ; this depends on flash size, $0f, $1f, $3f
|
||||
sta flashformatcounter
|
||||
flashbankloop sei
|
||||
ldx store_x
|
||||
flashformatcounter equ*+1
|
||||
sta $d5FF,x ; set chip (x) and bank
|
||||
; set pages count
|
||||
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 jmp flashcartoff ; preserves C
|
||||
store_x dta 0
|
||||
|
||||
; --------------------------
|
||||
; PROCEDURE
|
||||
flashformatsector
|
||||
; x - bank number 00 - 7f (even sector>>1)
|
||||
; a - erase 4KB from $B000 if A=$B0, FROM $A000 IF A=$A0
|
||||
; format 4kb evensector
|
||||
; strange form - easily maps to cartridge banks
|
||||
; to format bank, must format sector (x<<1) and (x<<1) +1
|
||||
; IT IS LONG because it has to be save, ie not format if formatted etc.
|
||||
|
||||
; first check if all ff
|
||||
; this is to avoid wear
|
||||
stx flashformatstorex
|
||||
sta flashformatstorea
|
||||
sei
|
||||
jsr flashsetbank
|
||||
; store #$a0 or #$b0
|
||||
sta flashformataddrcheck + 2
|
||||
jsr flashchecksectorformatted
|
||||
bcc flashsectorformatgood
|
||||
sei
|
||||
flashformatstorex equ * + 1
|
||||
ldx #0 ; filled before
|
||||
; check least sector bit
|
||||
sec
|
||||
lda #flashoppreamble ; does not touch A,X
|
||||
jsr jsrtovectorproc
|
||||
sta $D500,x
|
||||
; A must be either $A0 or $B0
|
||||
flashformatstorea equ * + 1
|
||||
lda #0 ; filled before
|
||||
sta flashtmpaddr+1
|
||||
sta flashformataddrcheck + 2
|
||||
|
||||
lda #$30
|
||||
flashtmpaddr equ *+1
|
||||
sta $a000 ; SECTOR FORMAT INVOKED HERE!
|
||||
jsr wait4flashcheckresult ;
|
||||
sei
|
||||
|
||||
lda flashformatstorea
|
||||
sta flashformataddrcheck+2
|
||||
|
||||
ldx flashformatstorex
|
||||
jsr flashsetbank
|
||||
|
||||
; check if all data in sector is $ff
|
||||
flashchecksectorformatted
|
||||
ldy #$10
|
||||
flashchecksectorformatted_bare
|
||||
lda #$ff
|
||||
ldx #0
|
||||
flashformataddrcheck
|
||||
cmp $a000,x
|
||||
bne flashsectorformaterror
|
||||
inx
|
||||
bne flashformataddrcheck
|
||||
inc flashformataddrcheck + 2
|
||||
dey
|
||||
bne flashformataddrcheck
|
||||
|
||||
flashsectorformatgood
|
||||
jsr flashcartoff
|
||||
clc
|
||||
rts
|
||||
|
||||
flashsectorformaterror
|
||||
jsr flashcartoff
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
; ---------------------
|
||||
; 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
|
||||
clc ; byte program preamble
|
||||
lda #flashoppreamble ; 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
|
||||
sta flashcnt+1
|
||||
ldy #1 ; first time wait short first turn to speed up byte write.
|
||||
bne @+
|
||||
|
||||
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
|
||||
@
|
||||
;lda #flash_wait_unit
|
||||
;jsr jsrtovectorproc
|
||||
inc colbaks
|
||||
lda colbaks
|
||||
sta colbak
|
||||
dey
|
||||
bne @-
|
||||
|
||||
@
|
||||
|
||||
ldy #{ lda.w }
|
||||
jsr flashprocessbyte
|
||||
sta flashval
|
||||
ldy #{ eor.w }
|
||||
jsr flashprocessbyte
|
||||
inc flashcnt
|
||||
bne @+
|
||||
inc flashcnt+1
|
||||
bne @+
|
||||
jsr flashcartoff
|
||||
lda #$ff ; status
|
||||
rts
|
||||
@
|
||||
and #$40
|
||||
bne flashwaitfordone
|
||||
jsr flashcartoff
|
||||
flashval equ *+1
|
||||
lda #0
|
||||
flashcmp equ *+1
|
||||
cmp #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
|
||||
flashaddr equ *+1
|
||||
flashbyteop
|
||||
sta $aaaa
|
||||
rts
|
||||
|
||||
flashincaddr
|
||||
inw flashaddr
|
||||
rts
|
||||
|
||||
flashsetaddr
|
||||
stx flashaddr
|
||||
sty flashaddr+1
|
||||
rts
|
||||
|
||||
flashsetbank
|
||||
sta $d500,x
|
||||
lda $d013
|
||||
sta $3fa
|
||||
rts
|
||||
|
||||
flashcartoff
|
||||
pha
|
||||
sta $d580
|
||||
lda $d013
|
||||
sta $3fa
|
||||
cli
|
||||
pla
|
||||
rts
|
||||
|
||||
@@ -0,0 +1,431 @@
|
||||
; flash eeprom library
|
||||
; by JHusak , 04.01.2020
|
||||
; free to use.
|
||||
|
||||
; Nice to have procedures, because mads may exclude unused procedures (-x in cmdl)
|
||||
;.def STRIPPED
|
||||
|
||||
;.def FLASH_INCLUDE_ALL
|
||||
;FLASH_TYPE equ M_TYPE_28SF
|
||||
;FLASH_TYPE equ M_TYPE_29SF
|
||||
FLASH_TYPE equ M_TYPE_39SF
|
||||
;FLASH_TYPE equ M_TYPE_29F
|
||||
|
||||
; x - 0x0 or 0x40 - chip select;
|
||||
; a - $80 - format, $90 - enter id mode, $a0 - writebyte
|
||||
C_ID_MODE equ $90
|
||||
|
||||
M_TYPE_28SF equ $88
|
||||
M_TYPE_29SF equ $89
|
||||
M_TYPE_39SF equ $99
|
||||
M_TYPE_29F equ $09 ; used in MaxFlash BM29F040
|
||||
|
||||
M_SSIZE_28SF equ $0100 ; sector size
|
||||
M_SSIZE_29SF equ $0080 ; sector size
|
||||
M_SSIZE_39SF equ $1000 ; sector size
|
||||
M_SSIZE_29F equ $10000 ; sector size; MAXFlash, protocol compatible with 39sf0x0
|
||||
;Problems 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
|
||||
; For flash recognition
|
||||
; - format,
|
||||
; - write 128 kbytes, read more -> if not ff, flash is 128k
|
||||
; - write additional 128KB, read more ->if not ff flash is 256kB, else is 512kb
|
||||
;
|
||||
; First detection is to read raw memory and id and compare results. Some issues may occur when no memory inserted.
|
||||
|
||||
;flash_detect_protocol:
|
||||
; lda #ID_MODE
|
||||
; jsr flashoppreamble_5555_2aaa
|
||||
|
||||
; c parameter as format/writebyte
|
||||
; for compatibility, 5555_2aaa only
|
||||
|
||||
.IF (FLASH_TYPE = M_TYPE_39SF) .or .def FLASH_INCLUDE_ALL
|
||||
TRIGGER_FORMAT equ $10
|
||||
C_FORMAT equ $80
|
||||
C_BYTE_PROG equ $a0
|
||||
flashoppreamble
|
||||
pha
|
||||
lda #C_BYTE_PROG
|
||||
scc
|
||||
lda #C_FORMAT ; only if c set
|
||||
sta command
|
||||
pla
|
||||
jmp @+
|
||||
flashoppreamble_acc ; 39sf0x0, 29F040
|
||||
sta command
|
||||
@ txa
|
||||
pha
|
||||
; when write byte x must be set to either 0 or 40 temporarily
|
||||
and #$40
|
||||
tax
|
||||
sta $d502,x
|
||||
mva #$aa $b555 ; $5555<$aa
|
||||
sta $d501,x
|
||||
mva #$55 $aaaa ; $2aaa<$55
|
||||
; $5555<$80
|
||||
sta $d502,x
|
||||
command equ *+1
|
||||
mva #$ff $b555; will become command: FORMAT/ID_MODE/BYTE_PROG
|
||||
cmp #C_FORMAT
|
||||
bne @+ ; if not FORMAT, procedure finishes
|
||||
; FORMAT part, more to write
|
||||
sta $d502,x
|
||||
mva #$aa $b555 ; $5555<$aa
|
||||
sta $d501,x
|
||||
mva #$55 $aaaa ; $2aaa<$55
|
||||
@ pla
|
||||
tax
|
||||
rts
|
||||
.endif
|
||||
.if (FLASH_TYPE=M_TYPE_29SF) .or .def FLASH_INCLUDE_ALL
|
||||
TRIGGER_FORMAT equ $10
|
||||
C_FORMAT equ $80
|
||||
C_BYTE_PROG equ $a0
|
||||
flashoppreamble
|
||||
pha
|
||||
lda #C_BYTE_PROG
|
||||
scc
|
||||
lda #C_FORMAT ; only if c set
|
||||
sta command
|
||||
pla
|
||||
jmp @+
|
||||
flashoppreamble_acc ; 29sf040
|
||||
sta command
|
||||
@ txa
|
||||
pha
|
||||
; when write byte x must be set to either 0 or 40 temporarily
|
||||
and #$40
|
||||
tax
|
||||
sta $d500,x
|
||||
mva #$aa $a555 ; $555<$aa
|
||||
mva #$55 $a2aa ; $2aa<$55
|
||||
; $555<command
|
||||
command equ *+1
|
||||
mva #$ff $a555; will become command: FORMAT/ID_MODE/BYTE_PROG
|
||||
cmp #C_FORMAT
|
||||
bne @+ ; if not FORMAT, procedure finishes
|
||||
; FORMAT part, more to write
|
||||
mva #$aa $a555 ; $555<$aa
|
||||
mva #$55 $a2aa ; $2aa<$55
|
||||
; PREPARE FOR SECTOR TO ERASE
|
||||
@ pla
|
||||
tax
|
||||
rts
|
||||
.endif
|
||||
|
||||
.if (FLASH_TYPE=M_TYPE_28SF) .or .def FLASH_INCLUDE_ALL
|
||||
TRIGGER_FORMAT equ $30
|
||||
C_FORMAT equ $30
|
||||
C_BYTE_PROG equ $10
|
||||
flashoppreamble
|
||||
pha
|
||||
lda #C_BYTE_PROG
|
||||
scc
|
||||
lda #C_FORMAT ; only if c set
|
||||
flashoppreamble_acc ; 28SF0x0
|
||||
sta $d500,x ; can be any address
|
||||
sta $a000; command: FORMAT/ID_MODE/BYTE_PROG, any address
|
||||
rts
|
||||
.endif
|
||||
.if FLASH_TYPE=M_TYPE_28SF
|
||||
flash_unlockchip
|
||||
sta $D500,x
|
||||
; read from 1823H, 1820H, 1822H, 0418H, 041BH, 0419H, 041AH
|
||||
lda $B823
|
||||
lda $B820
|
||||
lda $B822
|
||||
lda $A418
|
||||
lda $A41B
|
||||
lda $A419
|
||||
lda $A41A
|
||||
rts
|
||||
.endif
|
||||
.if (FLASH_TYPE=M_TYPE_29SF) .or (FLASH_TYPE=M_TYPE_39SF)
|
||||
flash_unlockchip
|
||||
rts
|
||||
.endif
|
||||
|
||||
.ifndef STRIPPED
|
||||
; flash size only needed in not stripped version for format result check.
|
||||
flash_size dta 0
|
||||
; as well as check_vendor procedure
|
||||
;
|
||||
; --------------------------
|
||||
; PROCEDURE
|
||||
; x = 0 or 0x40 - flash chip address.
|
||||
; returns c set -> failed
|
||||
; if c cleared, x=vendor, y=product code
|
||||
; there are some memories which need multiple read, but we do not abuse them.
|
||||
check_vendor
|
||||
lda #C_ID_MODE
|
||||
jsr flashoppreamble_acc
|
||||
ldx $a000 ; vendor
|
||||
ldy $a001 ; id
|
||||
mva #$f0 $a000 ; exit read_id
|
||||
mva #0 flash_size
|
||||
|
||||
cpx #$BF; SST
|
||||
bne next1
|
||||
; nice to store that this is SST
|
||||
cpy #$B5
|
||||
bne @+
|
||||
lda #$0f
|
||||
@ cpy #$B6
|
||||
bne @+
|
||||
lda #$1f
|
||||
@ cpy #$B7
|
||||
bne @+
|
||||
lda #$3f
|
||||
@ sta flash_size
|
||||
clc
|
||||
rts
|
||||
next1
|
||||
.if 0
|
||||
lda #C_ID_MODE
|
||||
jsr flashoppreamble_acc
|
||||
ldx $a000 ; vendor
|
||||
ldy $a001 ; id
|
||||
mva #$f0 $a000 ; exit read_id
|
||||
mva #0 flash_size
|
||||
|
||||
cpx #$BF; SST
|
||||
bne cvexit
|
||||
; nice to store that this is SST
|
||||
cpy #$24
|
||||
bne @+
|
||||
lda #$1f
|
||||
@ cpy #$13
|
||||
bne @+
|
||||
lda #$3f
|
||||
@ sta flash_size
|
||||
clc
|
||||
rts
|
||||
.endif
|
||||
cvexit
|
||||
sec
|
||||
rts
|
||||
.endif
|
||||
|
||||
|
||||
|
||||
; --------------------------
|
||||
flashformatchip2
|
||||
ldx #$40
|
||||
dta { bit.w }
|
||||
flashformatchip1
|
||||
ldx #$0
|
||||
; --------------------------
|
||||
; PROCEDURE
|
||||
; x = 0 or 0x40 - flash chip address.
|
||||
flashformatchip
|
||||
|
||||
sei
|
||||
stx store_x
|
||||
lda #C_FORMAT
|
||||
jsr flashoppreamble_acc ; does not touch A
|
||||
sta $d502,x
|
||||
lda #TRIGGER_FORMAT
|
||||
sta $b555 ; FORMAT HERE TRIGGERED!
|
||||
; not needed to mva $ff flashcmp
|
||||
jsr wait4flashcheckresult ; waits for format finished
|
||||
; then check number of banks for FFs
|
||||
lda #$3f ; this depends on flash size, $0f, $1f, $3f
|
||||
sta flashformatcounter
|
||||
flashbankloop sei
|
||||
ldx store_x
|
||||
flashformatcounter equ*+1
|
||||
sta $d5FF,x ; set chip (x) and bank
|
||||
; set pages count
|
||||
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 jmp flashcartoff ; preserves C
|
||||
store_x dta 0
|
||||
|
||||
; --------------------------
|
||||
; PROCEDURE
|
||||
flashformatsector
|
||||
; x - bank number 00 - 7f (even sector>>1)
|
||||
; a - erase 4KB from $B000 if A=$B0, FROM $A000 IF A=$A0
|
||||
; format 4kb evensector
|
||||
; strange form - easily maps to cartridge banks
|
||||
; to format bank, must format sector (x<<1) and (x<<1) +1
|
||||
; first check if all ff
|
||||
; this is to avoid wear
|
||||
stx flashformatstorex
|
||||
sta flashformatstorea
|
||||
sei
|
||||
sta $d500,x
|
||||
; store #$a0 or #$b0
|
||||
sta flashformataddrcheck + 2
|
||||
jsr flashchecksectorformatted
|
||||
bcc flashsectorformatgood
|
||||
sei
|
||||
flashformatstorex equ * + 1
|
||||
ldx #0 ; filled before
|
||||
; check least sector bit
|
||||
|
||||
lda #C_FORMAT
|
||||
jsr flashoppreamble_acc ; does not touch A,X
|
||||
sta $D500,x
|
||||
; A must be either $A0 or $B0
|
||||
flashformatstorea equ * + 1
|
||||
lda #0 ; filled before
|
||||
sta flashtmpaddr+1
|
||||
sta flashformataddrcheck + 2
|
||||
|
||||
lda #$30
|
||||
flashtmpaddr equ *+1
|
||||
sta $a000 ; SECTOR FORMAT INVOKED HERE!
|
||||
jsr wait4flashcheckresult ;
|
||||
sei
|
||||
|
||||
lda flashformatstorea
|
||||
sta flashformataddrcheck+2
|
||||
|
||||
ldx flashformatstorex
|
||||
sta $d500,x
|
||||
|
||||
; check if all data in sector is $ff
|
||||
flashchecksectorformatted
|
||||
ldy #$10
|
||||
flashchecksectorformatted_bare
|
||||
lda #$ff
|
||||
ldx #0
|
||||
flashformataddrcheck
|
||||
cmp $a000,x
|
||||
bne flashsectorformaterror
|
||||
inx
|
||||
bne flashformataddrcheck
|
||||
inc flashformataddrcheck + 2
|
||||
dey
|
||||
bne flashformataddrcheck
|
||||
|
||||
flashsectorformatgood
|
||||
jsr flashcartoff
|
||||
clc
|
||||
rts
|
||||
|
||||
flashsectorformaterror
|
||||
jsr flashcartoff
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
; ---------------------
|
||||
; 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 #C_BYTE_PROG
|
||||
jsr flashoppreamble_acc ; preserves A,X
|
||||
pla
|
||||
; set right bank
|
||||
sta $D500,x
|
||||
ldy #{ sta.w }
|
||||
jsr flashprocessbyte ; WRITE BYTE INVOKED !
|
||||
|
||||
wait4flashcheckresult ; sei mode
|
||||
mva #0 flashcnt
|
||||
ldy #1 ; first time wait short first turn to speed up byte write.
|
||||
bne @+
|
||||
|
||||
flashwaitfordone
|
||||
; 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
|
||||
ldy#250
|
||||
@ dey
|
||||
nop
|
||||
bne @-
|
||||
|
||||
@ ldy #{ lda.w }
|
||||
jsr flashprocessbyte
|
||||
sta flashval
|
||||
ldy #{ eor.w }
|
||||
jsr flashprocessbyte
|
||||
inc flashcnt
|
||||
bne @+
|
||||
sta $d580
|
||||
lda #$ff ; status
|
||||
rts
|
||||
@
|
||||
and #$40
|
||||
bne flashwaitfordone
|
||||
sta $d580
|
||||
flashval equ *+1
|
||||
lda #0
|
||||
flashcmp equ *+1
|
||||
cmp #0
|
||||
; when byte compare non zero = error
|
||||
rts
|
||||
|
||||
flashcnt
|
||||
dta 0
|
||||
; ----------------------
|
||||
; PROCEDURE
|
||||
|
||||
flashprocessbyte
|
||||
|
||||
; y - byteop for cpu to do with byte
|
||||
; flashaddr - stored address
|
||||
sty flashbyteop
|
||||
flashaddr equ *+1
|
||||
flashbyteop
|
||||
sta $aaaa
|
||||
rts
|
||||
|
||||
flashincaddr
|
||||
inw flashaddr
|
||||
rts
|
||||
|
||||
flashsetaddr
|
||||
stx flashaddr
|
||||
sty flashaddr+1
|
||||
rts
|
||||
|
||||
flashcartoff
|
||||
pha
|
||||
sta $d580
|
||||
lda $d013
|
||||
sta $3fa
|
||||
cli
|
||||
pla
|
||||
rts
|
||||
|
||||
Reference in New Issue
Block a user