; 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 . ; 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)