From d6851d6f406f985eaec740624ddc9469f96400ea Mon Sep 17 00:00:00 2001 From: RochesterX Date: Sat, 14 Feb 2026 18:08:10 -0500 Subject: [PATCH] Initial --- -game.o | Bin 0 -> 22249 bytes background.chr | Bin 0 -> 4096 bytes game.cfg | 19 ++ game.nes | Bin 0 -> 40976 bytes game.o | Bin 0 -> 20057 bytes game.s | 530 +++++++++++++++++++++++++++++++++++++++++++++++++ run | 5 + sprite.chr | Bin 0 -> 4096 bytes temp.png | Bin 0 -> 1373 bytes 9 files changed, 554 insertions(+) create mode 100644 -game.o create mode 100644 background.chr create mode 100644 game.cfg create mode 100644 game.nes create mode 100644 game.o create mode 100644 game.s create mode 100755 run create mode 100644 sprite.chr create mode 100644 temp.png diff --git a/-game.o b/-game.o new file mode 100644 index 0000000000000000000000000000000000000000..1bc57f71896ea87af505f48054657e7b1e18631d GIT binary patch literal 22249 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 literal 0 HcmV?d00001 diff --git a/game.cfg b/game.cfg new file mode 100644 index 0000000..8342b4d --- /dev/null +++ b/game.cfg @@ -0,0 +1,19 @@ +MEMORY { + ZP: start = $00, size = $0100, type = rw, file = ""; + OAM: start = $0200, size = $0100, type = rw, file = ""; + RAM: start = $0300, size = $0500, type = rw, file = ""; + HDR: start = $0000, size = $0010, type = ro, file = %O, fill = yes, fillval = $00; + PRG: start = $8000, size = $8000, type = ro, file = %O, fill = yes, fillval = $00; + CHR: start = $0000, size = $2000, type = ro, file = %O, fill = yes, fillval = $00; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp; + OAM: load = OAM, type = bss, align = $100; + BSS: load = RAM, type = bss; + HEADER: load = HDR, type = ro; + CODE: load = PRG, type = ro, start = $8000; + RODATA: load = PRG, type = ro; + VECTORS: load = PRG, type = ro, start = $FFFA; + TILES: load = CHR, type = ro; +} diff --git a/game.nes b/game.nes new file mode 100644 index 0000000000000000000000000000000000000000..eb36e6c83a1883607aeea56cddda9a3b061dffa1 GIT binary patch literal 40976 zcmeI$PiP}m90%~pz>DM1?aP(-j`(VT9pQab6e(&ErZ$J}KW&{yE1lInk2;xbuCGe*BzJ{3-nzQ9vKjfQ$i&0m%Vn z29zC8Zb12Qawkdyu8A>6^857ro4j1J-K}rccj_VClg)7_GI|t>L^h8*`ywgwj)n^8 zn&5sw*QJVtzu-iA;!UBVSNxp1p5reJDdXqW_)u-11avIFd~!&VYvX^UygHWK2UId}G|Z??z(Q=bd*NjYdK74m*$N z=;gPvdG5J7D7FgY?cXlQy-|7l zPE`HZbl$fn50aBf-b{Yvbu&R}x|qH3=4SGXYn^-MMXOM$S;m>CEGjKq_R@;AP<_FA z;@Ow1vrj)i|CJ&`00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|c$fljb*S@G=fNG)S^U@dyndSd-S{r|`tNwd zTX$1htJ-#TjZW*cr+CN_rw^`+J_H~D0SG_<0uX=z1Rwwb2tWV=4`0BG`@>;B_Gs1P zSf!=9$x-)~FPAvpBU*iXy?EX`J;?ebh!!S6^!nw}X_22iMWU^<>lHbrN4Mi2zB`)y z6X1vwd4k9^xh^spJ@L{d-CmqMUZnPVvz?ii^w>PoG>-Kjwb$14XP&(@9*ss0z5IbB zl3#l(daA0ftW-Jl2A)1l+vDt9afphK+V-k)sAxS#Vo|wVL_h!n5P$##AOHafKmY;| LfB*#k_X2+bTG4dn literal 0 HcmV?d00001 diff --git a/game.o b/game.o new file mode 100644 index 0000000000000000000000000000000000000000..40e7c175a939f4d851f56e701e9e1a7a573d3e53 GIT binary patch literal 20057 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 JGrGGm{|O|){WAan literal 0 HcmV?d00001 diff --git a/game.s b/game.s new file mode 100644 index 0000000..b96ad37 --- /dev/null +++ b/game.s @@ -0,0 +1,530 @@ +.segment "HEADER" + +INES_MAPPER = 0 +INES_MIRROR = 1 +INES_SRAM = 0 + +.byte 'N', 'E', 'S', $1A +.byte $02 +.byte $01 +.byte INES_MIRROR +.byte (INES_MAPPER & %11110000) +.byte $0, $0, $0, $0, $0, $0, $0, $0 + + +.segment "TILES" +.incbin "background.chr" +.incbin "sprite.chr" + + +.segment "VECTORS" +.word nmi +.word reset +.word irq + + +.segment "CODE" +reset: + sei + lda #0 + sta $2000 + sta $2001 + sta $4015 + sta $4010 + lda #40 + sta $4017 + cld + ldx #$FF + txs + + bit $2002 + : + bit $2002 + bpl :- + + lda #0 + ldx #0 + : + sta $0000, X + sta $0100, X + sta $0200, X + sta $0300, X + sta $0400, X + sta $0500, X + sta $0600, X + sta $0700, X + inx + bne :- + + lda #255 + ldx #0 + : + sta oam, X + inx + inx + inx + inx + bne :- + + : + bit $2002 + bpl :- + + lda #%10001000 + sta $2000 + jmp main + + +.segment "ZEROPAGE" +nmi_lock: .res 1 +nmi_count: .res 1 +nmi_ready: .res 1 +nmt_update_len: .res 1 +scroll_x: .res 1 +scroll_y: .res 1 +scroll_nmt: .res 1 +temp: .res 1 + +.segment "BSS" +nmt_update: .res 256 +palette: .res 32 + +.segment "OAM" +oam: .res 256 + +.segment "CODE" +nmi: + pha + txa + pha + tya + pha + + lda nmi_lock + beq :+ + jmp @nmi_end + + : + lda #1 + sta nmi_lock + + lda nmi_ready + bne :+ + jmp @ppu_update_end + + : + cmp #2 + bne :+ + lda #%00000000 + sta $2001 + ldx #0 + stx nmi_ready + jmp @ppu_update_end + + : + ldx #0 + stx $2003 + lda #>oam + sta $4014 + + lda #%10001000 + sta $2000 + lda $2002 + lda #$3F + sta $2006 + stx $2006 + ldx #0 + : + lda palette, X + sta $2007 + inx + cpx #32 + bcc :- + + ldx #0 + cpx nmt_update_len + bcs @scroll + @nmt_update_loop: + lda nmt_update, X + sta $2006 + inx + lda nmt_update, X + sta $2006 + inx + lda nmt_update, X + sta $2007 + cpx nmt_update_len + bcc @nmt_update_loop + + lda #0 + sta nmt_update_len +@scroll: + lda scroll_nmt + and #%00000011 + ora #%10001000 + sta $2000 + lda scroll_x + sta $2005 + lda scroll_y + sta $2005 + + lda #%00011110 + sta $2001 + + ldx #0 + stx nmi_ready +@ppu_update_end: + lda #0 + sta nmi_lock +@nmi_end: + pla + tay + pla + tax + pla + rti + + +.segment "CODE" +irq: + rti + + +.segment "CODE" +ppu_update: + lda #1 + sta nmi_ready + : + lda nmi_ready + bne :- + + rts + +ppu_skip: + lda nmi_count + : + cmp nmi_count + beq :- + + rts + +ppu_off: + lda #2 + sta nmi_ready + : + lda nmi_ready + bne :- + + rts + +ppu_address_tile: + lda $2002 + tya + lsr + lsr + lsr + ora #$20 + sta $2006 + tya + asl + asl + asl + asl + asl + sta temp + txa + ora temp + sta $2006 + rts + +ppu_update_tile: + pha + txa + pha + ldx nmt_update_len + tya + lsr + lsr + lsr + ora #$20 + sta nmt_update, X + inx + tya + asl + asl + asl + asl + asl + sta temp + pla + ora temp + sta nmt_update, X + inx + pla + sta nmt_update, X + inx + stx nmt_update_len + rts + +ppu_update_byte: + pha + tya + pha + ldy nmt_update_len + txa + sta nmt_update, Y + iny + pla + sta nmt_update, Y + iny + pla + sta nmt_update, Y + iny + sty nmt_update_len + rts + + +PAD_A = $01 +PAD_B = $02 +PAD_SELECT = $04 +PAD_START = $08 +PAD_U = $10 +PAD_D = $20 +PAD_L = $40 +PAD_R = $80 + +.segment "ZEROPAGE" +gamepad: .res 1 + +.segment "CODE" +; gamepad_poll: this reads the gamepad state into the variable labelled "gamepad" +; This only reads the first gamepad, and also if DPCM samples are played they can +; conflict with gamepad reading, which may give incorrect results. +gamepad_poll: + ; strobe the gamepad to latch current button state + lda #1 + sta $4016 + lda #0 + sta $4016 + ; read 8 bytes from the interface at $4016 + ldx #8 + : + pha + lda $4016 + ; combine low two bits and store in carry bit + and #%00000011 + cmp #%00000001 + pla + ; rotate carry into gamepad variable + ror + dex + bne :- + sta gamepad + rts + + +.segment "RODATA" +example_palette: +.byte $0F,$15,$26,$37 ; bg0 purple/pink +.byte $0F,$09,$19,$29 ; bg1 green +.byte $0F,$01,$11,$21 ; bg2 blue +.byte $0F,$00,$10,$30 ; bg3 greyscale +.byte $0F,$18,$28,$38 ; sp0 yellow +.byte $0F,$14,$24,$34 ; sp1 purple +.byte $0F,$1B,$2B,$3B ; sp2 teal +.byte $0F,$12,$22,$32 ; sp3 marine + +.segment "ZEROPAGE" +velocities: .res 8 + +cursor_x: .res 1 +cursor_y: .res 1 +temp_x: .res 1 +temp_y: .res 1 +var_m: .res 1 +var_n: .res 1 +var_o: .res 1 +var_p: .res 1 + +frame_counter: .res 1 + +.segment "CODE" +main: + ldx #0 + : + lda example_palette, X + sta palette, X + inx + cpx #32 + bcc :- + + jsr setup_background + jsr ppu_update + + lda #$40 + sta cursor_x + sta cursor_y + + lda #0 + sta frame_counter + + jsr init_objects +@loop: +@draw: + jsr draw + jsr ppu_update + + lda frame_counter + clc + adc #1 + sta frame_counter + jmp @loop + +init_objects: + lda #0 + sta var_n + ldx #0 + : + lda var_n + clc + adc #8 + sta var_n + + sta oam+0, X ; Set Y position + sta oam+3, X ; Set X position + + txa + lsr + lsr + sta oam+1, X + + tay + lda #0 + sta velocities, Y + + inx + inx + inx + inx + cpx #(8*4) + bne :- + + rts + +draw: + lda frame_counter + and #1 + cmp #0 + bne @end + + ldx #0 + ldy #0 + : + lda velocities, Y + clc + adc #1 ; Add 2 to velocity + sta velocities, Y + + lda oam+0, X + clc + adc velocities, Y + sta oam+0, X + + cmp #200 + bmi :+ + lda #245 + sta velocities, Y + : + + inx + inx + inx + inx + + iny + cpy #8 + bne :-- +@end: + rts + +setup_background: + lda $2002 ; reset latch + lda #$20 + sta $2006 + lda #$00 + sta $2006 + ; empty nametable + lda #0 + ldy #30 ; 30 rows + : + ldx #32 ; 32 columns + : + sta $2007 + dex + bne :- + dey + bne :-- + ; set all attributes to 0 + ldx #64 ; 64 bytes + : + sta $2007 + dex + bne :- + ; fill in an area in the middle with 1/2 checkerboard + lda #1 + ldy #8 ; start at row 8 + : + pha ; temporarily store A, it will be clobbered by ppu_address_tile routine + ldx #8 ; start at column 8 + jsr ppu_address_tile + pla ; recover A + + ldx #8 + : + sta $2007 + eor #$3 + inx + cpx #(32-8) + bcc :- + eor #$3 + iny + cpy #(30-8) + bcc :-- + + lda #$24 + sta $2006 + lda #$00 + sta $2006 + lda #$00 + ldy #30 + : + ldx #32 + : + sta $2007 + clc + adc #1 + and #3 + dex + bne :- + clc + adc #1 + and #3 + dey + bne :-- + + lda #0 + ldy #4 + : + ldx #16 + : + sta $2007 + dex + bne :- + + clc + adc #%01010101 + dey + bne :-- + + rts + diff --git a/run b/run new file mode 100755 index 0000000..762473a --- /dev/null +++ b/run @@ -0,0 +1,5 @@ +#!/bin/bash +ca65 game.s -o game.o +ld65 game.o -C game.cfg -o game.nes +fceux game.nes + diff --git a/sprite.chr b/sprite.chr new file mode 100644 index 0000000000000000000000000000000000000000..6847b198b711e293b26e4350a505931984f3d4bb GIT binary patch literal 4096 zcmeH@zY4-I5Ql%X9SRmK=pYW#!NJk7Ly#gJ92|Uv4vrO^#37u|(T5QWc?L&u=!3*N z|MVf`K9c;7TtdP}uDMfZZ|eds0w_z)Dt> zaQN=&9{0`*9S0}?;+XqE6v_F+LDu?P*0AN)MxU1K{qWv7nXv1%j9-#>ZQB-DT|ywd zQ7%`rd7jT1d4S|ImN<)Z0VIRT#AF4M;RwMjtGKDC0X3io)PNdL18P7Gr~x&g2GoEW H_Px#3{Xr|MFj-~Pft&+t*!t6{+w*E%m4rY0b)x>L;#2d9Y_EG010qNS#tmY3ljhU z3ljkVnw%H_000McNliru+5!^+9Uy|;7#jcp1jR|G?w&$cy0T+H@E0v+58DPxI*G0gP0+yY?4brY=jPo6WTN&Q409U`1k@qJCjkub^y@<3C(gY zIE&a&>|}~^K>>76&VwvC2A^h7!YPngvLp=3*hRz9(VX2$@-8K(;g#UP_{kU}UCNm9 z;4TNW6QmGr3a~_cx7a2(3|Mf0aR3jQ1?eqVve1@olex%ZZ~)4-vxz2i;j=*SS;UCW ze8}R0W=TKlq^HZqxpNY`vJ*Zmx{y8dMafGD0H1OSfCt*-Rmv!Mj!gJVy;OpnzUZgvSNsowF5*#`Wvo~6rh7ch=2Ajs0Sr&KFFdb(t^S8rEv6| z54fyyWC{ow=FkJg6eNFJt|Cnvodt@-xOMlg2_n-W(cBdbVQm>IDh~BPA^{(;FBk?e zS8{yzRO)dk7;gbn3w)xnLSF z0DBOXbJY^&XB%f5b-EaM^(VLhqC#{s5Y)so25~ z*6v+aY7WFQ0n?AV_P3LfyVDCUhWdPceoyPqhyMDy0@L3TaJbv*obJALbbJRWgtPiu z-MJY0^6H!i9!<4Q3DDbjfI?_pSJzz@SCsk;S~P?24;h%&`T!IM5z_qU&kt{bX5hwh z%l;aGoDQ|yS8Hq`dgpez)%jp|L~kzi=Hil|3Tykd{iDZ6kNX0zH&?GQaIBAY zU*OH=>L={t*~YVtzQBX#>c_ON_P6%8`v1(Sk%wA$ySv>N_(iE12JYRzcfZiZ%KXaw zbAYcF3w0piX`v1enkzGfI&c<+I&c<+I&c<+I;6mJb>J8Zb-1t%j8@8NKYyM{21cuC z&8c$Q9pvW;^fTsuNoj3hBH?a871B3RDtn;RuD^+>>=FN)tam!?# zH+iH&Zpg)lA%1xfh&WCz#%DY4c|td!q#MX1L&N$ToX~oS`i|Q#>2(;<8cPn` zOz5w&H0=9&1_)Xx>AN&;CQ@r!TPu(0P#&euHOjv_#-pe=U|dzkSdVd44O-I%rPY8= z1%_0G0Gg{hj{&ICVuco~^!B@D7_ZX220R8}eI15jw87)p@Dhyi+__&5fS!QT5|7k} f8)1!a6K?u1+B(Kw5`b@%00000NkvXXu0mjf>Zf!M literal 0 HcmV?d00001