diff --git a/README.md b/README.md index 192c570..fb1b4a0 100644 --- a/README.md +++ b/README.md @@ -1 +1,31 @@ -# jataricart \ No newline at end of file +# JatariCart + +This software is for use with my super simple flash cartridge (no gals, only 3 74xx elements and some caps and resistors). Top side is that without elements. + +The cartridge is driven by addresses D500-D580; write to D500 sets the first bank - this is boot bank. Write to D501 sets second bank etc. The max usable number with cart on is set by write to D51F; write to D580 switches off the cartridge. + +The internal construction of JatariCart allows utilise max 256kB of flash memory (32 banks) + +Remember to fool the Operating System not to hang up by cart on/off, by: + +carton (x - bank to switch) + pha + sta $D580,x + sta wsync ; needed for ntsc, no big difference in speed + sta wsync ; needed for ntsc + lda trig3 + sta gintlk + pla + rts + + + +flashwritelib.asx - 6502 code library for formatting flash/formatting sector and write byte. + +flashsrite.asx - 6502 code for generate flasher (when compiled, it contains either flash routines and cartridge image itself) + +crc16_v2.asm - crc16 library for fast checking every sector (when flash is damaged, it happens that write sector damages another) + +Compile (mads needed, http://mads.atari8.info): + +mads flashwrite.asx -o:flashwrite.xex diff --git a/atari.hea b/atari.hea new file mode 100644 index 0000000..66f9f53 --- /dev/null +++ b/atari.hea @@ -0,0 +1,290 @@ + opt l- + +.enum @dmactl + blank = %00 + narrow = %01 + normal = %10 + wide = %11 + missiles= %100 + players = %1000 + oneline = %10000 + dma = %100000 +.ende + +scr48 = @dmactl(wide|dma|players|missiles|oneline) ;screen 48b +scr40 = @dmactl(normal|dma|players|missiles|oneline) ;screen 40b +scr32 = @dmactl(narrow|dma|players|missiles|oneline) ;screen 32b + +.enum @pmcntl + missiles= %1 + players = %10 + trigs = %100 +.ende + +.enum @gtictl + prior0 = %0 + prior1 = %1 + prior2 = %10 + prior4 = %100 + prior8 = %1000 + ply5 = %10000 ; Fifth Player Enable + mlc = %100000 ; Multiple Color Player Enable + mode9 = %01000000 + mode10 = %10000000 + mode11 = %11000000 +.ende + + +.enum @antic + lms = $40 + hsc = $50 + vsc = $60 +.ende + +* --------------------------------------------------------------------------------------------- +* --- OS +* --------------------------------------------------------------------------------------------- + +ramlo = $04 ; (2) wektor RAM dla testu wielko?ci pami?ci + +warmst = $08 ; znacznik gor?cego startu +boot? = $09 ; znacznik odczytu wst?pnego +dosvec = $0A ; (2) wektor startowy programu dyskowego +dosini = $0C ; (2) wektor inicjacji po odczycie z dyskietki + +rtclok = $12 ; (3) zegar czasu rzeczywistego + +lmargin = $52 +rmargin = $53 +rowcrs = $54 ; wiersz kursora +colcrs = $55 ; (2) Kolumna kursora +savmsc = $58 ; (2) Adres pamięci obrazu + +keydef = $79 ; (2) tablica konwersji kod?w klawiatury na ATASCII + + +vdslst = $0200 ; (2) wektor przerwa? NMI listy displejowej +timcnt3 = $021C ; trzeci licznik systemu +vvblki = $0222 ; (2) wektor NMI natychmiastowego VBI +vvblkd = $0224 ; (2) wektor NMI op??nionego VBI +timflg3 = $022a ; znacznik wyzerowania licznika TIMCNT3 +sdmctl = $022f ; cień DMACTL +sdlstl = $0230 ; cień DLISTL +sdlsth = $0231 ; cień DLISTH + +colpf0s = $02C4 ; rejestr-cie? COLPF0 +colpf1s = $02C5 ; rejestr-cie? COLPF1 +colpf2s = $02C6 ; rejestr-cie? COLPF2 +colpf3s = $02C7 ; rejestr-cie? COLPF3 +colbaks = $02C8 ; rejestr-cie? COLBAK + +dsctln = $02D5 ; (2) Disk sector size register; default of 128 ($80) bytes +dvstat = $02EA ; (4) device status + +crsinh = $02F0 ; znacznik widoczno?ci kursora +chact = $02F3 ; rejestr cien CHRCTL +chbas = $02F4 ; rejestr cien CHBASE + +atachr = $02Fb ; numer koloru dla PLOT, DRAW (kod ATASCII znaku) +kbcodes = $02Fc ; kod ostatnio naci?ni?tego klawisza, $ff je?li ?aden nie zosta? naci?ni?ty (KBCODE) +fildat = $02Fd ; numer koloru dla FILL +chart = $02F3 ; cie? rejestru kontroli wy?wietlania znak?w (CHRCTL) + +ddevic = $0300 ; Device Control Block, identyfikator urz?dzenia +dunit = $0301 ; Numer urz?dzenia; w przypadku stacji dysk?w numer nap?du +dcmnd = $0302 ; Komenda dla urz?dzenia. +dstats = $0303 ; Przed wywo?aniem SIO nale?y ustawi? tu rodzaj operacji ($40 odczyt, $80 zapis, $C0 zapis i odczyt, $00 brak transferu danych). Po powrocie z systemu znajduje si? tu status operacji (kod b??du). +dbufa = $0304 ; (2) Adres bufora. Przy operacji zapisu i odczytu jednocze?nie (DSTATS = $C0) bufor na odczytywane dane znajduje si? w tym samym miejscu, co bufor danch przeznaczonych do zapisu. +dtimlo = $0306 ; Czas oczekiwania na pozytywn? odpowied? urz?dzenia, tzw. timeout, najczesciej = 7 +dunuse = $0307 ; Bajt nieu?ywany, zarezerwowany do przysz?ych zastosowa?. +dbyt = $0308 ; (2) Wielko?? bufora; musi by? zgodna z wielko?ci? transmitowanego bloku danych. Zero oznacza 64 kilobajty. +daux1 = $030A ; Pierwszy bajt pomocniczy. W operacjach dyskowych m?odszy bajt numeru sektora. +daux2 = $030B ; Drugi bajt pomocniczy. W operacjach dyskowych starszy bajt numeru sektora. +casflg = $030F ; When set to zero, the current operation is a standard SIO operation; when non-zero, it is a cassette operation. + +hatabs = $031A ; tabela wektor?w procedur obs?ugi + +iocb = $0340 ; IOCB 0..7 ($340, $350, $360 ...) +iocom = iocb+2 ; Komenda dla IOCB +ioadr = iocb+4 ; (2) Adres bufora dla IOCB +ioaux1 = iocb+10 ; Bajt pomocniczy 1 IOCB +ioaux2 = iocb+11 ; Bajt pomocniczy 2 IOCB + +icchid = $0340 +icdno = $0341 +iccmd = $0342 ; kod rozkazu operacji I/O +icstat = $0343 ; status operacji I/O +icbufa = $0344 ; (2) adres bufora danych dla operacji I/O +icputb = $0346 ; (2) adres procedury przesy?ania danych +icbufl = $0348 ; (2) d?ugo?? bufora danych dla operacji I/O +icax1 = $034A ; rejestr pomocniczy dla operacji I/O +icax2 = $034B ; rejestr pomocniczy dla operacji I/O +icax3 = $034C ; rejestr pomocniczy dla operacji I/O +icax4 = $034D ; rejestr pomocniczy dla operacji I/O +icax5 = $034E ; rejestr pomocniczy dla operacji I/O +icax6 = $034F ; rejestr pomocniczy dla operacji I/O + +casbuf = $0400 ; bufor magnetofonu +casben = $047F ; koniec bufora magnetofonu + +setvbv = $E45C +xitvbv = $E462 +ciov = $E456 ; Wektor do CIOMAIN +jsioint = $E459 ; Wektor do SIO +jdskint = $E453 ; Wektor do sterownika dyskowego + +* --------------------------------------------------------------------------------------------- +* --- KEY ($d209) +* --------------------------------------------------------------------------------------------- + +key_esc = 28 +key_space = 33 + +key_a = 63 +key_b = 21 +key_d = 58 +key_m = 37 +key_n = 35 +key_v = 16 +key_o = 8 +key_p = 10 +key_s = 62 +key_w = 46 + +* --------------------------------------------------------------------------------------------- +* --- GTIA +* --------------------------------------------------------------------------------------------- + +hposp0 = $D000 ; pozioma pozycja gracza 0 (Z) +hposp1 = $D001 ; pozioma pozycja gracza 1 (Z) +hposp2 = $D002 ; pozioma pozycja gracza 2 (Z) +hposp3 = $D003 ; pozioma pozycja gracza 3 (Z) +hposm0 = $D004 ; pozioma pozycja pocisku 0 (Z) +hposm1 = $D005 ; pozioma pozycja pocisku 1 (Z) +hposm2 = $D006 ; pozioma pozycja pocisku 2 (Z) +hposm3 = $D007 ; pozioma pozycja pocisku 3 (Z) +sizep0 = $D008 ; poziomy rozmiar gracza 0 (Z) +sizep1 = $D009 ; poziomy rozmiar gracza 1 (Z) +sizep2 = $D00A ; poziomy rozmiar gracza 2 (Z) +sizep3 = $D00B ; poziomy rozmiar gracza 3 (Z) +sizem = $D00C ; poziomy rozmiar pocisk?w (Z) +grafp0 = $D00D ; rejestr grafiki gracza 0 (Z) +grafp1 = $D00E ; rejestr grafiki gracza 1 (Z) +grafp2 = $D00F ; rejestr grafiki gracza 2 (Z) +grafp3 = $D010 ; rejestr grafiki gracza 3 (Z) +grafm = $D011 ; rejestr grafiki pocisk?w (Z) +colpm0 = $D012 ; rejestr koloru gracza i pocisku 0 (Z) +colpm1 = $D013 ; rejestr koloru gracza i pocisku 1 (Z) +colpm2 = $D014 ; rejestr koloru gracza i pocisku 2 (Z) +colpm3 = $D015 ; rejestr koloru gracza i pocisku 3 (Z) +colpf0 = $D016 ; rejestr koloru pola gry 0 (Z) +colpf1 = $D017 ; rejestr koloru pola gry 1 (Z) +colpf2 = $D018 ; rejestr koloru pola gry 2 (Z) +colpf3 = $D019 ; rejestr koloru pola gry 3 (Z) +colpf4 = $D01A +colbak = $D01A ; rejestr koloru t?a (Z) + +color0 = colpf0 +color1 = colpf1 +color2 = colpf2 +color3 = colpf3 + +kolm0pf = $D000 ; kolizja pocisku 0 z polem gry (O) +kolm1pf = $D001 ; kolizja pocisku 1 z polem gry (O) +kolm2pf = $D002 ; kolizja pocisku 2 z polem gry (O) +kolm3pf = $D003 ; kolizja pocisku 3 z polem gry (O) +kolp0pf = $D004 ; kolizja gracza 0 z polem gry (O) +kolp1pf = $D005 ; kolizja gracza 1 z polem gry (O) +kolp2pf = $D006 ; kolizja gracza 2 z polem gry (O) +kolp3pf = $D007 ; kolizja gracza 3 z polem gry (O) +kolm0p = $D008 ; kolizja pocisku 0 z graczem (O) +kolm1p = $D009 ; kolizja pocisku 1 z graczem (O) +kolm2p = $D00A ; kolizja pocisku 2 z graczem (O) +kolm3p = $D00B ; kolizja pocisku 3 z graczem (O) +kolp0p = $D00C ; kolizja gracza 0 z innym graczem (O) +kolp1p = $D00D ; kolizja gracza 1 z innym graczem (O) +kolp2p = $D00E ; kolizja gracza 2 z innym graczem (O) +kolp3p = $D00F ; kolizja gracza 3 z innym graczem (O) +trig0 = $D010 ; stan przycisku joysticka 0 (O) +trig1 = $D011 ; stan przycisku joysticka 1 (O) +trig3 = $D013 ; znacznik do??czenia cartridge-a (O) +pal = $D014 ; znacznik systemu TV (O) PAL = 1, NTSC = 15 + +gtictl = $D01B ; rejestr kontroli uk?adu GTIA +gtiactl = gtictl + +vdelay = $D01C ; licznik op??nienia pionowego P/MG +pmcntl = $D01D ; rejestr kontroli graczy i pocisk?w +hitclr = $D01E ; rejestr kasowania rejestr?w kolizji +consol = $D01F ; rejestr stanu klawiszy konsoli + +* --------------------------------------------------------------------------------------------- +* --- POKEY +* --------------------------------------------------------------------------------------------- + +irqens = $0010 ; rejestr-cie? IRQEN +irqstat = $0011 ; rejestr-cie? IRQST + +audf1 = $d200 ; cz?stotliwo?? pracy generatora 1 (Z) +audc1 = $d201 ; rejestr kontroli d?wi?ku generatora 1 (Z) +audf2 = $d202 ; cz?stotliwo?? pracy generatora 2 (Z) +audc2 = $d203 ; rejestr kontroli d?wi?ku generatora 2 (Z) +audf3 = $d204 ; cz?stotliwo?? pracy generatora 3 (Z) +audc3 = $d205 ; rejestr kontroli d?wi?ku generatora 3 (Z) +audf4 = $d206 ; cz?stotliwo?? pracy generatora 4 (Z) +audc4 = $d207 ; rejestr kontroli d?wi?ku generatora 4 (Z) + +audctl = $D208 ; rejestr kontroli generator?w d?wi?ku (Z) +stimer = $D209 ; rejestr zerowania licznik?w (Z) +kbcode = $D209 ; kod ostatnio naci?ni?tego klawisza (O) +skstres = $D20A ; rejestr statusu z??cza szeregowego (Z) +random = $D20A ; rejestr liczby losowej (O) +serout = $D20D ; szeregowy rejestr wyj?ciowy (Z) +serin = $D20D ; szeregowy rejestr wej?ciowy (O) +irqen = $D20E ; zezwolenie przerwa? IRQ (Z) +irqst = $D20E ; status przerwa? IRQ (O) +skctl = $D20F ; rejestr kontroli z??cza szeregowego (Z) +skstat = $D20F ; rejestr statusu z??cza szeregowego (O) + +* --------------------------------------------------------------------------------------------- +* --- PIA +* --------------------------------------------------------------------------------------------- + +porta = $D300 ; port A uk?adu PIA +portb = $D301 ; port B uk?adu PIA +pactl = $D302 ; rejestr kontroli portu A +pbctl = $D303 ; rejestr kontroli portu B + +* --------------------------------------------------------------------------------------------- +* --- ANTIC +* --------------------------------------------------------------------------------------------- + +dmactl = $D400 ; rejestr kontroli dost?pu do pami?ci +chrctl = $D401 ; rejestr kontroli wy?wietlania znak?w +dlptr = $D402 ; adres programu ANTIC-a +dlistl = $D402 +dlisth = $D403 +hscrol = $D404 ; znacznik poziomego przesuwu obrazu +vscrol = $D405 ; znacznik pionowego przesuwu obrazu +pmbase = $D407 ; adres pami?ci graczy i pocisk?w +chbase = $D409 ; adres zestawu znak?w +wsync = $D40A ; znacznik oczekiwania na synchronizacj? poziom? +vcount = $D40B ; licznik linii obrazu +lpenh = $D40C ; poziome po?o?enie pi?ra ?wietlengo +lpenv = $D40D ; pionowe po?o?enie pi?ra ?wietlnego +nmien = $D40E ; rejestr zezwole? na przerwania NMI +nmist = $D40F ; rejestr statusu przerwa? NMI (O) +nmires = $D40F ; (Z) + +* --------------------------------------------------------------------------------------------- +* --- HARDWARE +* --------------------------------------------------------------------------------------------- + +nmivec = $FFFA ; wektor przerwania NMI (6502) +resetvec= $FFFC ; wektor przerwania RESET +irqvec = $FFFE ; wektor przerwania IRQ + +nmivec16 = $FFEA ; wektor przerwania NMI (nativ 65816) +irqvec16 = $FFEE ; wektor przerwania IRQ + + opt l+ diff --git a/crc16_v2.asm b/crc16_v2.asm new file mode 100644 index 0000000..705930f --- /dev/null +++ b/crc16_v2.asm @@ -0,0 +1,57 @@ +/* + org $2000 + + mwa #$ffff crc16.crc + + lda #'B' + jsr crc16.updCRC + lda #'N' + jsr crc16.updCRC + lda #'E' + jsr crc16.updCRC + + jmp * +*/ + + +.proc crc16 + +crc equ $80 +tmpx equ $82 +tmpy equ $83 + + + +updCRC + stx tmpx + sty tmpy + EOR CRC+1 ; A contained the data + STA CRC+1 ; XOR it into high byte + LSR @ ; right shift A 4 bits + LSR @ ; to make top of x^12 term + LSR @ ; ($1...) + LSR @ + TAX ; save it + ASL @ ; then make top of x^5 term + EOR CRC ; and XOR that with low byte + STA CRC ; and save + TXA ; restore partial term + EOR CRC+1 ; and update high byte + STA CRC+1 ; and save + ASL @ ; left shift three + ASL @ ; the rest of the terms + ASL @ ; have feedback from x^12 + TAX ; save bottom of x^12 + ASL @ ; left shift two more + ASL @ ; watch the carry flag + EOR CRC+1 ; bottom of x^5 ($..2.) + TAY ; save high byte + TXA ; fetch temp value + ROL @ ; bottom of x^12, middle of x^5! + EOR CRC ; finally update low byte + STA CRC+1 ; then swap high and low bytes + STY CRC + ldx tmpx + ldy tmpy + RTS +.endp diff --git a/flashwrite.asx b/flashwrite.asx new file mode 100644 index 0000000..c3a47fe --- /dev/null +++ b/flashwrite.asx @@ -0,0 +1,340 @@ +; flash eeprom library +; by JHusak , 04.01.2020 +; free to use. + icl 'atari.hea' +BankNum equ $88 +Counter equ $89 +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 + jsr $f420 ; clrscr + lda portb + cmp #$fd + beq @+ + jsr print + dta c'Run with BASIC enabled and restart.',0 + jmp * +@ lda #$1 + sta 66 + ; waiting for cart to be inserted + jsr print + dta c'Insert cartridge...',0 +@ lda $D013 + lsr + bcc @- + jsr print + dta c' inserted.',$9b,0 + + ; cart inserted, fake it was not changed + lda $d013 + sta $3fa + + ;lda #$ff + ;sta $d301 + + jsr print + dta c'Press:',$9b + dta c'START - format cart and programm',$9b + dta c'SELECT - verify; repair bad blocks.',$9b + dta c'OPTION - verify only',$9b,0 +@ lda 53279 + cmp #7 + beq @- + sta operation + + cmp #select + beq VERIFYREPAIR + + cmp #option + beq CHECKONLY + ; start +FORMAT + jsr print + dta c'Formatting cart ...',0 + jsr flashformatchip + bcs formatfailed + jsr print + dta c'done:)',$9b,0 + rts +formatfailed + 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 + rts +crcsums + :128 dta 0,0 + +CHECKINIT + mwa #_SOURCE _csrc + mwa #_DEST _cdst + sei +CHECK + + mva #0 badcompare_counter + sta badcompare_counter+1 + ldx BankNum + sta $d500,x +checkloop +_csrc equ * + 1 + lda $6000 ; src +_cdst equ * + 1 + cmp $A000 ; dst + beq @+ + lda _csrc + ldx _csrc+1 + jsr BADCOMPARE +@ inw _csrc + inw _cdst + lda _csrc+1 + cmp #>_SOURCE+$20 + bne checkloop + cpw #0 badcompare_counter + beq @+ + sta $d580 + lda $d013 + sta $3fa + cli + jsr print + dta c'non-match byte#:',0 + lda badcompare_counter+1 + jsr printhex + lda badcompare_counter + jsr printhex + jsr printnl + sec + rts +@ sta $d580 + lda $d013 + sta $3fa + cli + lda #'o' + jsr outchar +@ clc +dmaon mva #34 dmactls + sta dmactl + rts +VERIFY + ;mwa #_SOURCE _csrc + ;mwa #_DEST _cdst + jsr CHECKINIT + bcc v_rts + lda #'f' + jsr outchar + ldx BankNum + lda #$a0 + jsr flashformatsector + ldx BankNum + lda #$b0 + jsr flashformatsector + jsr FORMATTED + dec Counter + bne VERIFY +v_rts jmp dmaon + +COMPARE_CRC16_DEST_ALL + lda BankNum + sta _tbanknum +@ sei +_tbanknum equ * + 1 + sta $D500 + clc + mva _tbanknum calccrc_bank + jsr CALCCRC_DEST + jsr status_crc + dec _tbanknum + bpl @- + sta $D580 + lda $d013 + sta $3fa + cli + rts +status_crc + php + jsr printBank_t + plp + php + sne + lda #'o' + plp + seq + lda #'!' + 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 +_tsrc equ * + 1 + lda $ffff + jsr crc16.updCRC + inw _tsrc + dew _tcnt + bne _tsrc -1 +calccrc_bank equ * +1 + lda #$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 @+ +printBank + jsr printnl + lda BankNum +@ pha + lda #'B' + jsr outchar + pla + jsr printhex + lda #':' + jmp outchar + +MAIN_PROCESS + ;mva #0 dmactls + ;sta dmactl + sec + mva BankNum calccrc_bank + jsr CALCCRC + mwa #_DEST flashaddr + jsr printBank + + lda operation + cmp #select + jeq VERIFY + + cmp #option + jeq CHECKINIT + +FORMATTED + mwa #_SOURCE _writeaddr + lda _writeaddr+1 + clc + adc #$20 + sta _cmpaddr + mwa #_DEST flashaddr + sec +formatted_next + ldx BankNum +formatted_next2 +_writeaddr equ *+1 + lda $ffff + jsr flashwritebyte + jsr flashincaddr + inw _writeaddr +_cmpaddr equ * + 1 + lda #$ff + cmp _writeaddr+1 + bne formatted_next2 + + jmp COMPARE_CRC16_DEST_ALL + +FINISH_PROCESS + jsr print + dta $9b,'Finished',0 + jmp * + rts +badcompare_counter dta 0,0 +BADCOMPARE + ldy 53279 + 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 +; ------- + icl 'flashwritelib.asx' + + icl 'crc16_v2.asm' + + ;jsr print + ;dta c'AlaMaKota.',$9b,0 + ;lda #$55 + ;jsr printhex + ;lda #$aa + ;jsr printhex + ;jmp * + icl 'print2.asx' + org $2e2 + dta a($2000) +; --------------------------------------- +; code generator for bank by bank programming. +; .rept number of cartridge banks of 8kb; set this for 8kb banks number: +; 256kb flash - 32 +; 128 kb flash - 16 +; 8 kb flash - 1 +;.rept 32, # +.rept 1, # + .print "A :1" + .local block:1 +;------------ + org BankNum + dta b(:1) + dta b(1) ; Counter +;------------ + org _SOURCE + ins "missile.bin",+:1*8192,8192 +;------------ + org $2e2 + dta a(MAIN_PROCESS) +;------------ + .endl + .endr +;------------ + org $2e2 + dta a(FINISH_PROCESS) diff --git a/flashwrite.xex b/flashwrite.xex new file mode 100644 index 0000000..003dcf0 Binary files /dev/null and b/flashwrite.xex differ diff --git a/flashwritelib.asx b/flashwritelib.asx new file mode 100644 index 0000000..8ae72e2 --- /dev/null +++ b/flashwritelib.asx @@ -0,0 +1,287 @@ +; flash eeprom library +; by JHusak , 04.01.2020 +; free to use. + +; x - bank to select on exit +; c - 1 - format, 0 - write + ;.print flashcnt +flashoppreamble + + ; $5555<$aa + sty $d502 + ldy #$aa + sty $b555 + ; $2aaa<$55 + sty $d501 + ldy #$55 + sty $aaaa + ; $5555<$80 + sty $d502 + ; sector format: carry set + scc + ldy #$80 ; sector erase + scs + ldy #$a0 ; byte programm + sty $b555 + bcc @+ + ; $5555<$aa + sty $d502 + ldy #$aa + sty $b555 + ; $2aaa<$55 + sty $d501 + ldy #$55 + sty $aaaa + + ; PREPARE FOR SECTOR TO ERASE + + ; set upper bank bits + +@ rts + +; -------------------------- +; PROCEDURE +flashformatchip + + sei + sec ; format preamble + jsr flashoppreamble ; does not touch A + sta $d502 + lda #$10 + sta $b555 + lda #$ff + sta flashcmp + jsr flashcheckresult + beq @+ + ; cart is off and cli +; sec ; error +; rts +@ lda #$1f + sta flashformatcounter +@ sei +flashformatcounter equ*+1 + sta $d51f + ldx #0 + ldy #$20 + lda #$a0 + sta flashformataddrcheck + 2 + lda #$ff + jsr flashformataddrcheck + bcs @+ ; format error + dec flashformatcounter + bpl @- +@ jmp flashcartoff ; preserves C + + +; -------------------------- +; PROCEDURE +flashformatsector +; x - even sector 00 - 1f +; 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 + sta flashformataddrcheck + 2 + jsr flashchecksectorformatted + bcc flashsectorformatgood + ;php + ;lda #'F' + ;jsr PRINTWHAT + ;plp + sei +flashformatstorex equ * + 1 + ldx #0 ; filled before +flashformatstorea equ * + 1 + lda #0 ; filled before +; check least sector bit + + sec ; format preamble + jsr flashoppreamble ; does not touch A,X + sta $D500,x + ; A must be either $A0 or $B0 + sta flashtmpaddr+1 + sta flashformataddrcheck + 2 + + lda #$30 +flashtmpaddr equ *+1 + sta $a000 ; Format! + jsr flashcheckresult + sei + + lda flashformatstorea + sta flashformataddrcheck+2 + + ldx flashformatstorex + sta $d500,x + + ; check if all data in sector is $ff +flashchecksectorformatted + ldx #0 + ldy #$10 + lda #$ff +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 +; flashaddr - addres in flash - must be a000-offset + ; do not programm byte if already good + sei + sta $D500,x + ldy #{ cmp.w } + jsr flashprocessbyte + bne @+ + sta $D580 + cli + clc + rts +@ sta flashcmp + + sei + clc ; write byte preamble + + jsr flashoppreamble ; preserves A,X + + sta $D500,x + + ldy #{ sta.w } + jsr flashprocessbyte + +flashcheckresult ; sei mode + mva #0 flashcnt + ldy #5 ; 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 + ldy #{ eor.w } + jsr flashprocessbyte + inc flashcnt + bne @+ + jsr flashcartoff + lda #$ff ; status + rts +@ + and #$40 + bne flashwaitfordone +; in acc will be mismatched byte + ldy #{ lda.w } + jsr flashprocessbyte + jsr flashcartoff ; preserves axy, not p +flashcmp equ *+1 + cmp #0 +; when non zero = error + rts + +flashcnt + brk +; ---------------------- +; 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 + +; PROCEDURE +; Y-char to write +PRINTWHAT + php + pha + txa + pha + tya + pha + jsr $f2b0 + pla + tay + pla + tax + pla + plp + rts +PRINTDOT + php + pha + txa + pha + tya + pha + lda #'.' + jsr $f2b0 + pla + tay + pla + tax + pla + plp + rts +; ----------------------- IINT +; org $2e2 +; dta a($600) diff --git a/missile.bin b/missile.bin new file mode 100644 index 0000000..bd532c9 Binary files /dev/null and b/missile.bin differ diff --git a/print2.asx b/print2.asx new file mode 100644 index 0000000..7be2175 --- /dev/null +++ b/print2.asx @@ -0,0 +1,66 @@ + + ; jsr print + ; dta c'Ala ma kota',$9b,0 + ; next instructions +print .proc + clc + pla + adc #$01 + sta ?strv + pla + adc #$00 + sta ?strv+1 + +?strv equ *+1 + lda $ffff + bne ?prt + lda ?strv+1 + pha + lda ?strv + pha + rts +?prt jsr $f2b0 + inw ?strv + bne ?strv-1 + rts + .endp + +printhex .proc + jsr lHex + sta ?printhextmp + txa + jsr $f2b0 + +?printhextmp equ * +1 + lda #$ff + jmp $f2b0 + .endp + +lHex .proc + +// po deklaracji procedury .PROC z parametrami, automatycznie wymuszone zostaje wykonanie +// makra @PULL, ktore zdejmie za nas parametry ze stosu programowego i umiesci je w pamieci +// od adresu @PROC_VARS_ADR, etykiecie parametru LOW zostaje przypisany adres @PROC_VARS_ADR + + pha + :4 lsr @ + + jsr HEX2INT + + tax ; wynik dzialania w regX + + pla + and #$0f + +HEX2INT SED + CMP #$0A + ADC #'0' + CLD + ; wynik dzialania w regA + rts + .endp + +printnl .proc + lda #$9b + jmp $f2b0 + .endp