Files
jataricart/lib/flashwrite.asx
2025-01-27 18:31:35 +01:00

580 lines
9.1 KiB
Plaintext

; JatariCart flasher
; by Jakub Husak , 04.01.2020
; All Rights Reserved.
;
; JatariCart is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; JatariCart is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with JatariCart256. If not, see <http://www.gnu.org/licenses/>.
;
icl 'atari.hea'
; flash image is included at the end of file
; uncomment when flashing all cart or want to check all blocks written so far.
;.def compareall
BankNum equ $88
operation equ $8a
start equ 6 ; format chip and program
select equ 5 ; ferify and format sectors
option equ 3 ; verify
outchar equ $F2B0
memtop equ $2e5
dmactls equ $22f
_SOURCE equ $6000
_DEST equ $A000
; test code
org $2000
FINISH_PROCESS_JMP
.print "#define FINISH_PROCESS_JMP 0x",*
jmp FINISH_PROCESS
MAIN_PROCESS_JMP
.print "#define MAIN_PROCESS_JMP 0x",*
jmp MAIN_PROCESS
.print "#define STARTFLASHWRITE 0x",*
STARTFLASHWRITE
mva #$A0 ramtop
jsr opened
lda rtclok+2
@ cmp rtclok+2
beq @-
@ lda #$1
sta critic
; waiting for cart to be inserted
jsr print
.print "#define TITLE 0x",*-$2000+6
TITLE+128
dta $9b,c'JatariCart/MaxFlash flasher'
dta $9b
dta c'by JHusak, version 26.01.2025'
dta $9b
dta c'JatariCart of size '
.print "#define CARTSIZE1 0x",*-$2000+6
CARTSIZE+128
dta c' kB needed',$9b,$9b
dta c'Insert JatariCart of '
.print "#define CARTSIZE2 0x",*-$2000+6
CARTSIZE+128
dta c' kB...',0
lda #$00
sta nmien
sta $d500
?wloop lda trig3
lsr
bcc ?wloop
; cart inserted, fake it was not changed
jsr accept_bank_change
lda #$40
sta nmien
ldx #$25
?lloop ; wait 0.5 sec after inserting
@ bit VCOUNT
bmi @-
@ bit VCOUNT
bpl @-
dex
bne ?lloop
jsr print
dta $9b,c'Inserted.',$9b,0
ldx #0 ; chip address
stx numgoodchipsneeded
_check_chips
stx _storex
jsr check_type
bcc ?chip_ok
beq ?unrecog2
?unrecog1
jsr print
dta c'no chip #'
?chipign1
dta c'1, ignoring... ',0
clc
bcc ?common
?unrecog2
jsr print
dta c'unknown chip #'
?chipign2
dta c'1 protocol, ignoring...',0
?common
lda #0
sta m_vendor
sta m_kind
jmp ?exit
?chip_ok
lda numgoodchipsneeded
ora goodchipsmask
sta numgoodchipsneeded
jsr print
dta c'chip #'
?chipno
dta c'1' ; will be incremented if TWOCHIPS defined
dta c' vend/prod: ',0
lda m_vendor
jsr printhex
lda m_kind
jsr printhex
jsr print
dta c' code: ',0
; print memory type
lda M_VECTOR
clc
adc #flash_idstr ; will print flashmem text id
sta ?taddr
lda M_VECTOR+1
adc #0
sta ?taddr+1
ldy #0
?loop ; write string onscreen, 0-ended
lda ?taddr:$ffff,y
beq ?exit
sty st_y
jsr outchar
ldy st_y:#0
iny
bne ?loop
?exit
jsr printnl
ldx _storex
asl goodchipsmask
cpx #$40
beq menu
lda m_vendor
sta t_vendor
lda m_kind
sta t_kind
inc ?chipno
inc ?chipign1
inc ?chipign2
ldx #$40
jmp _check_chips
menu
lda numgoodchipsneeded
.if .def TWOCHIPS
cmp #3 ; two chips needed
.else
and #1
cmp #1 ; at least first chip needed
.endif
beq ?cont
; FAIL and loop forever
jsr print
dta $9b
dta c'Sorry, recognized chip configuration',$9b
dta c'does not suit your binary.',$9b
dta c'Your cart needs '
.if .def TWOCHIPS
dta c'two chips.',$9b
.else
dta c'at least first chip.',$9b
.endif
dta c'Please reboot.',$9b,0
jmp *
?cont
jsr printnl
;lda #$ff
;sta $d301
jsr print
dta c'Press:',$9b
dta c'START - cartridge format and flash!',$9b
;dta c'SELECT - verify; repair bad blocks.',$9b
dta c'OPTION - verify',$9b,0
?wloop lda consol
cmp #7
beq ?wloop
sta operation
cmp #select
beq ?wloop
cmp #option
jeq CHECKONLY
cmp #start
beq FORMAT
bne ?wloop
; start
FORMAT
jsr printformatting
jsr print
dta c'1...',0
jsr flashformatchip1
bcs formatfailed
jsr flashend ; restores display etc. preserves all
.print "#define TWO_CHIPS_SWITCH 0x",*-$2000+6+1
.print "#define TWO_CHIPS_SWITCH_ADDR 0x",*+1
.if .def TWOCHIPS
lda #1
.else
lda #0
.endif
beq ?exit2
jsr printdone
jsr printformatting
jsr print
dta c'2...',0
jsr flashformatchip2
bcs formatfailed
?exit2
jsr flashend ; restores display etc. preserves all
printdone jsr print
dta c'done:)',$9b,0
jmp eraseSRC_FF
printformatting
jsr print
dta c'Formatting cart chip ',0
rts
formatfailed
jsr flashend
jsr print
dta c'failed:(',$9b,'Waiting for reboot...',$9b,0
jmp *
VERIFYREPAIR
jsr print
dta c'Verify and ',0
CHECKONLY
jsr print
dta c'Compare.',$9b,0
jsr eraseSRC_FF
rts
t_vendor .byte 0
t_kind .byte 0
numgoodchipsneeded .byte 0
goodchipsmask .byte 1
_storex .byte 0
crcsums
:128 .word 0
opened
ldx #0
lda #12
jsr icio
mwa #name icbufa,x
mva #$0c icax1,x
mva #$0 icax2,x
lda #3
icio sta iccmd,x
jmp ciov
name dta 'E:',$9b
CHECKINIT
mwa #_SOURCE _csrc
mwa #_DEST _cdst
sei
CHECK
mva #0 badcompare_counter
sta badcompare_counter+1
jsr GetBankNumToX
sta $d500,x
checkloop
lda _csrc:$6000 ; src
cmp _cdst:$A000 ; dst
beq _byte_ok
lda _csrc
ldx _csrc+1
jsr BADCOMPARE
_byte_ok
inw _csrc
inw _cdst
lda _csrc+1
cmp #>_SOURCE+$20
bne checkloop
cpw #0 badcompare_counter
beq _all_bytes_ok
; several differences found...
; cart off
jsr cartoff_and_accept_bank_change
cli
; print status
jsr print
dta 253,c'non-match byte#:',0
lda badcompare_counter+1
jsr printhex
lda badcompare_counter
jsr printhex
jsr print
dta c' (START-cont)',0
lda #7
cmp CONSOL ; wait for consol
req
jsr printnl
jsr eraseSRC_FF
sec
rts
_all_bytes_ok
jsr cartoff_and_accept_bank_change
jsr eraseSRC_FF
cli
lda #'o'
jsr outchar
@ clc
dmaon mva #34 dmactls
sta dmactl
rts
cartoff_and_accept_bank_change
sta $d5ff
accept_bank_change
lda trig3
sta gintlk
rts
eraseSRC_FF
mwa #_SOURCE e_csrc
e_loop_init
lda #$FF
e_loop
sta e_csrc:$ffff ; src
inc e_csrc
bne e_loop
inc e_csrc+1
lda e_csrc+1
cmp #>_SOURCE+$20
bne e_loop_init
rts
VERIFY
;mwa #_SOURCE _csrc
;mwa #_DEST _cdst
jsr CHECKINIT
bcc v_rts
lda #'f'
jsr outchar
jsr GetBankNumToX
lda #$a0
jsr flashformatsector
jsr GetBankNumToX
lda #$b0
jsr flashformatsector
jsr FORMATTED
v_rts jmp dmaon
COMPARE_CRC16_DEST_ALL
jsr GetBankNumToX
stx _tbanknum
@ sei
_tbanknum equ * + 1
sta $d500
clc
mva _tbanknum calccrc_bank
jsr CALCCRC_DEST
jsr status_crc
.ifdef compareall
dec _tbanknum
bpl @-
.endif
jsr cartoff_and_accept_bank_change
cli
rts
status_crc
php
jsr printBank_t
plp
php
sne
lda #'o'
plp
seq
lda #'!'+128
jsr outchar
lda #','
jmp outchar
CALCCRC_DEST
php
mwa #_DEST _tsrc
bne crccont
CALCCRC ; c=1 - write; c=0 - check
php
mwa #_SOURCE _tsrc
mwa #$2000 _tcnt
crccont mwa #$ffff crc16.crc
lda _tsrc:$ffff
jsr crc16.updCRC
inw _tsrc
dew _tcnt
bne _tsrc -1
lda calccrc_bank:#$ba ;nk number
asl
tax
plp
bcc crccheck
mwa crc16.crc crcsums,x
rts
_tcnt :2 dta 0
crccheck
cpw crc16.crc crcsums,x
rts
printBank_t
lda _tbanknum
bpl skip
printBank
jsr printnl
jsr GetBankNumToX
txa
skip pha
lda #'B'
jsr outchar
pla
jsr printhex
lda #':'
jmp outchar
MAIN_PROCESS
;mva #0 dmactls
;sta dmactl
sec
jsr GetBankNumToX
stx calccrc_bank
jsr CALCCRC
mwa #_DEST flashaddr
;ldx #<_DEST
;ldy #>_DEST
;jsr flashsetaddr
jsr printBank
lda operation
;cmp #select
;jeq VERIFY
cmp #option
jeq CHECKINIT
; START (was CONSOL & !OPTION, so START)
FORMATTED
mwa #_SOURCE _writeaddr
lda _writeaddr+1
clc
adc #$20
sta _cmpaddr ; only hi byte
mwa #_DEST flashaddr
; sec
formatted_next
jsr GetBankNumToX
jsr flashunlockchip
formatted_next2
lda _writeaddr:$ffff ; this is source address
jsr flashwritebyte
jsr flashincaddr
inw _writeaddr
lda _cmpaddr:#$ff ; this is the page to end
cmp _writeaddr+1
bne formatted_next2
jsr flashend
jsr flashlockchip
jsr COMPARE_CRC16_DEST_ALL
jmp eraseSRC_FF
FINISH_PROCESS
jsr print
dta $9b,'Finished',0
jmp *
rts
badcompare_counter dta 0,0
BADCOMPARE
ldy consol
cpy #7
beq @+
pha
txa
pha
lda #'!'
jsr outchar
pla
jsr printhex
pla
jsr printhex
lda #':'
jsr outchar
mwa _csrc badcompare_tmp1
badcompare_tmp1 equ * +1
lda $ffff
jsr printhex
lda #'/'
jsr outchar
mwa _cdst badcompare_tmp2
badcompare_tmp2 equ * +1
lda $ffff
jsr printhex
jsr printnl
@ inw badcompare_counter
sec
jmp dmaon ; rts inside dmaon
; -------
icl 'flashwritelib.asx'
icl 'crc16_v2.asm'
icl 'print2.asx'
bank_order_tab
.if .not .def BANK_ORDER
.rept 128
.byte .R
.endr
.else
BANK_ORDER
.endif
GetBankNumToX
ldx BankNum
lda bank_order_tab,x
tax
rts
.print "#define END_OF_MAIN_CODE 0x",*-$2000+6+6
org $2e2
dta a(STARTFLASHWRITE)
; ---------------------------------------
; blocks for every 8kb bank
.rept BANKS, #
.print "A :1"
.local block:1
;------------
org BankNum
dta b(:1)
;------------
org _SOURCE
BANKS_FILE :1
;------------
org $2e2
dta a(MAIN_PROCESS_JMP)
;------------
.endl
.endr
;------------
.if .def CUSTOM_CART_LAYOUT
CUSTOM_CART_LAYOUT
.endif
org $2e2
dta a(FINISH_PROCESS_JMP)