diff options
Diffstat (limited to 'basics')
| -rw-r--r-- | basics/chr-ram.s | 37 | ||||
| -rw-r--r-- | basics/flicker.s | 14 | ||||
| -rw-r--r-- | basics/input.s | 23 | ||||
| -rw-r--r-- | basics/persist.s | 16 | ||||
| -rw-r--r-- | basics/sprite.s | 26 | ||||
| -rw-r--r-- | basics/unrom.s | 18 |
6 files changed, 69 insertions, 65 deletions
diff --git a/basics/chr-ram.s b/basics/chr-ram.s index 20e1b30..bb2186e 100644 --- a/basics/chr-ram.s +++ b/basics/chr-ram.s @@ -29,7 +29,8 @@ .segment "BANK0" -chr: .incbin "../assets/basic.chr" +chr: + .incbin "../assets/basic.chr" .segment "BANK1" .byte $00 @@ -56,33 +57,18 @@ chr: .incbin "../assets/basic.chr" .segment "FIXED" ;;; -;; Bank switching code as with `basics/unrom.s`. Not used here. - -banktable: - .byte $00, $01, $02, $03, $04, $05, $06 - -m_current_bank = $00 - -bankswitch: - sty m_current_bank -bankswitch_nosave: - tya - sta banktable, y - rts - -;;; ;; From here on the code is basically the same as `basics/sprite.s`, but with a ;; special twist that will be commented in. For comments on the rest of the code ;; just check `basics/sprite.s`. -reset: +.proc reset sei cld - ldx #$40 + ldx #$FF stx $4017 - ldx #$ff + ldx #$FF txs inx stx $2000 @@ -139,6 +125,7 @@ reset: bne @palettes_reset_loop jmp main +.endproc ;;; ;; Transfer the CHR data from PRG-ROM into RAM. @@ -166,17 +153,17 @@ reset: ;; - x contains the number of 256-byte pages to copy. ;; - y will index within the page ($00-$FF). ldx #32 -loop: +@loop: ;; First part of the loop: copy each byte of the current page. lda ($00), y sta $2007 iny - bne loop + bne @loop ;; Go to the next page and repeat the first part of the loop. inc $01 dex - bne loop + bne @loop rts .endproc @@ -274,7 +261,7 @@ initial_sprite_data: .byte $B0, $00, %01000000, $82 .endproc -nmi: +.proc nmi bit $20 bpl @next @@ -305,6 +292,8 @@ nmi: pla @next: rti +.endproc -irq: +.proc irq rti +.endproc diff --git a/basics/flicker.s b/basics/flicker.s index 8db03e8..2522cb2 100644 --- a/basics/flicker.s +++ b/basics/flicker.s @@ -61,7 +61,6 @@ jmp @main_game_loop .endproc - ;;; ;; NOTE: this is the actual meat of the example :D .proc apply_flicker @@ -135,7 +134,7 @@ ;;; ;; NOTE: and from here on stuff that is not relevant for sprite flickering. -nmi: +.proc nmi bit $20 bpl @next @@ -168,15 +167,16 @@ nmi: pla @next: rti +.endproc -reset: +.proc reset sei cld ldx #$40 stx $4017 ; APU Frame Counter - ldx #$ff + ldx #$FF txs inx @@ -201,7 +201,7 @@ reset: inx bne @ram_reset_loop ; if x overflows back to #00, then we are done. - lda #$ef + lda #$EF @sprite_reset_loop: sta $200, x inx @@ -229,9 +229,11 @@ reset: bne @palettes_reset_loop jmp main +.endproc -irq: +.proc irq rti +.endproc .proc init_sprites NUM_SPRITES = 20 diff --git a/basics/input.s b/basics/input.s index b773fd7..df49a66 100644 --- a/basics/input.s +++ b/basics/input.s @@ -13,12 +13,10 @@ ;; which brings some other considerations when reading from controllers. That ;; is, the algorithm shown below is not entirely "safe" due to a hardware bug ;; which might give unreliable inputs on some spikes. -;;; ;;; ;; You can safely ignore all of this up until the `ReadController` subroutine. ;; This is boilerplate that is explained on the `sprite.s` example. -;;; .segment "HEADER" .byte 'N', 'E', 'S', $1A @@ -34,17 +32,23 @@ .segment "CODE" -nmi: -irq: - rti +;; Unused +.proc nmi + rti +.endproc + +;; Unused +.proc irq + rti +.endproc -reset: +.proc reset sei cld ldx #$40 stx $4017 - ldx #$ff + ldx #$FF txs inx @@ -75,6 +79,7 @@ reset: bpl @vblankwait2 jmp main +.endproc .proc ReadController ;; The status of the eight buttons fits into a single byte. We start the whole @@ -117,7 +122,7 @@ reset: ;; `rol` instruction. At this point, we have already read the full byte. read_loop: lda $4016 - lsr a + lsr rol $20 bcc read_loop @@ -166,8 +171,6 @@ pressed: ;; There and back again. jmp loop - - rts .endproc .segment "CHARS" diff --git a/basics/persist.s b/basics/persist.s index 3e7c439..e7dfb07 100644 --- a/basics/persist.s +++ b/basics/persist.s @@ -43,19 +43,24 @@ .segment "BANK1" ;; Unused -nmi: -irq: - rti +.proc nmi + rti +.endproc + +;; Unused +.proc irq + rti +.endproc ;; Check `basics/sprite.s` for a deeper look on the logic below. I have only ;; added comments to MMC1-specific stuff. -reset: +.proc reset sei cld ldx #$40 stx $4017 - ldx #$ff + ldx #$FF txs inx @@ -165,6 +170,7 @@ reset_mmc1: ;; Loop forever, there's nothing to be done here. @loop: jmp @loop +.endproc ;; Unused .segment "CHR0" diff --git a/basics/sprite.s b/basics/sprite.s index 1892ce5..6fcdad3 100644 --- a/basics/sprite.s +++ b/basics/sprite.s @@ -23,7 +23,6 @@ ;; basic identification, it defines some relevant things like PRG and CHR sizes, ;; plus mapping if desired. See https://www.nesdev.org/wiki/NES_2.0#Header for ;; documentation on this, or also: https://www.nesdev.org/neshdr20.txt. -;;; .segment "HEADER" ;; The first thing to do is to define the magic "NES\0" string identifier ;; ($1A is the ASCII that MS-DOS wanted as end of string). Some people write @@ -82,7 +81,6 @@ ;; actually removes this segment in its linker configuration down the road). ;; This is also removed by the configuration provided in `config/nrom.cfg`, ;; which is the one being used in the end for this example. -;;; ;; .segment "STARTUP" .segment "CODE" @@ -94,8 +92,7 @@ ;; NesDev wiki which is pretty much followed by everyone as I could see. The ;; main idea is to leave the hardware in a known state and then jump into the ;; main game subroutine. -;;; -reset: +.proc reset ;; We first instruct the NES to disable everything. That is, we don't want ;; any pesky interrupt to make us jump into the `nmi` section, for example, ;; before we have configured everything. @@ -200,10 +197,10 @@ reset: ;; ;; "Resetting sprites" is just a matter of giving them a value which will ;; not bother us in the future. One way to do this is to set each value to - ;; $ef, which will give each "sprite" off-screen Y-coordinates. How any of + ;; $EF, which will give each "sprite" off-screen Y-coordinates. How any of ;; this is the case will be shown whenever we deal with loading proper ;; sprites below. - lda #$ef + lda #$EF @sprite_reset_loop: sta $200, x inx @@ -217,7 +214,7 @@ reset: ;; the byte given at the OAMADDR, thus XX = #$00; and N = 2 (see `lda ;; #$02`). Therefore, we are telling the PPU to start the DMA process from ;; $200. The PPU will assume that the following 256 bytes of memory are the - ;; ones to be copied, resulting in a DMA copy of $200-$2ff, right where we + ;; ones to be copied, resulting in a DMA copy of $200-$2FF, right where we ;; stored the sprite data in advance. lda #$00 sta $2003 ; OAMADDR @@ -238,7 +235,7 @@ reset: ;; stored. Palettes are the answer from old systems like the NES to: how can ;; you display this amount of colors on screen without taking too much ;; memory? The NES allows developers to store eight palettes (four - ;; background, four foreground), and each palette group four colors. This + ;; background, four foreground), and each palette groups four colors. This ;; way, whenever we want to draw a sprite or a piece of background, we don't ;; specify which colors to pick for each pixel, but we rather apply a ;; palette to a sprite or background tile definition. @@ -268,12 +265,12 @@ reset: ;; jump into our main subroutine and start loading sprites, palettes, etc.; ;; and start the game proper. jmp main +.endproc ;;; ;; This is our main subroutine. At this point we can assume that the hardware ;; has already been set to a proper and defined state. So now we can load all ;; the data we need for our game and enter the main game loop. -;;; .proc main ;; Before starting the game loop proper we initialize all our assets: load ;; the palettes, nametables and sprites for this game. @@ -341,7 +338,7 @@ reset: .proc init_palettes ;; Remember these four instructions? That's what we also did when resetting ;; palettes on the reset code. That is, we are preparing the PPU to write - ;; data starting from $3f00. + ;; data starting from $3F00. lda #$3F sta $2006 ; PPUADDR lda #$00 @@ -500,7 +497,7 @@ palettes: ;; This is tied to the number of sprites stored in the `initial_sprite_data` ;; section. Remember that this can be 64 *maximum*: 64 sprites * 4 bytes per ;; sprite = 256 bytes; which is the reserved space in memory we have for - ;; sprites: $0200-$02ff. + ;; sprites: $0200-$02FF. NUM_SPRITES = 2 ;; The loading is quite straight-forward. We just store whatever is on @@ -551,8 +548,7 @@ initial_sprite_data: ;; we ought to keep things as simple and fast as possible. You can take a look ;; at the examples from `scroll` for more complex NMI code that have to handle ;; stuff like VRAM buffering or setting other PPU registers. -;;; -nmi: +.proc nmi ;; As mentioned on the `main` subroutine, rendering will be skipped until ;; the proper flag is set. bit $20 @@ -601,6 +597,7 @@ nmi: pla @next: rti +.endproc ;;; ;; Interrupt Requests handler. This is triggered by the NES' sound processor @@ -608,8 +605,9 @@ nmi: ;; mapper). In our case we don't have to do anything here, so we just return ;; from the interrupt. ;;; -irq: +.proc irq rti +.endproc ;;; ;; Include into this all the data that needs to go into the CHR ROM. One typical diff --git a/basics/unrom.s b/basics/unrom.s index b6deb4d..eb49b17 100644 --- a/basics/unrom.s +++ b/basics/unrom.s @@ -101,32 +101,37 @@ banktable: ;; Variable containing the bank we are currently in. It's useful to keep track ;; of the bank so the NMI handler can restore it if it does some bank switching ;; of its own. -m_current_bank = $00 +zp_current_bank = $00 ;; Perform a bankswitch by using the value on the `y` register. Note that you ;; can use the `bankswitch_nosave` variant, which is useful if you just want to ;; perform a temporary bankswitch (e.g. on NMI code). bankswitch: - sty m_current_bank + sty zp_current_bank bankswitch_nosave: tya sta banktable, y rts ;; Unused -nmi: -irq: +.proc nmi rti +.endproc + +;; Unused +.proc irq + rti +.endproc ;; Check `basics/sprite.s` for a deeper look on the logic below. I have only ;; added code after configuration/reset is done. -reset: +.proc reset sei cld ldx #$40 stx $4017 - ldx #$ff + ldx #$FF txs inx @@ -178,3 +183,4 @@ reset: ;; Loop forever, there's nothing to be done here. @loop: jmp @loop +.endproc |
