$8E19> LDA $2002 ; Clear the $2005/$2006 latch
$8E1C> LDA $0778 ; Load the buffer of PPU #1
$8E1F> ORA #$10 ; Set bit 4 and zeroes bits 0-3
$8E21> AND #$f0 ; (bkg pattern table at $1000 and increment by 1)
$8E23> JSR $8EED ; Update PPU #1 and $0778
$8E26> LDA #$24 ;
$8E28> JSR $8E2D ; First work with name table 1 at $2400
$8E2B> LDA #$20 ; After then, clean name table 0
$8E2D> STA $2006 ;
$8E30> LDA #$00 ;
$8E32> STA $2006 ; Final result: $2400 the first time, $2000 the second one
$8E35> LDX #$04 ;
$8E37> LDY #$c0 ;
$8E39> LDA #$24 ;
$8E3B> STA $2007 ; fill the proper Name Table (#1 or #0)
; with #$24 (black tile) for C0+3*100 times
$8E3E> DEY ;
$8E3F> BNE $8E3B ;
$8E41> DEX ;
$8E42> BNE $8E3B ; end fill Name Table
$8E44> LDY #$40 ;
$8E46> TXA ;
$8E47> STA $0300 ;
$8E4A> STA $0301 ;
$8E4D> STA $2007 ; fill the attribute table with 00
$8E50> DEY ;
$8E51> BNE $8E4D ; end fill attribute table
$8E53> STA $073F ; $2005 buffer 1
$8E56> STA $0740 ; $2005 buffer 2
$8E59> JMP $8EE6 ; Reset $2005In SMB the background is scrolling during the game and to do that we need to use two Name Tables (with their Attribute Tables). The memory mirroring in the cartridge is set as vertical, so the Name Table #0 will start at $2000 and the #1 at $2400. This two Name Tables will be initialized using empty tiles.As I said before, this code contains several buffered registers:
- $0778 buffer for PPU #1 ($2000)
- $073F and $0740 buffer for $2005, the scrolling register
- $0300 and $0301 will be explained in another post
To cleaning the two Name Tables the programmer decided to use an interesting algorithm: the high byte of the first Name Table (#$24) is loaded into the accumulator, then a JSR is used to skip the next line, that would have loaded the accumulator with the high byte of the second Name Table (#$20). The next three instructions after the jump set the VRAM address to $2400, then a loop fills the first Name Table with the value #$24 (a black tile in the Pattern Table) and another loop zeroes the relative Attribute Table. When the subroutine reaches the ending RTS, the flow goes back to the instruction we skipped before that sets the VRAM address to $2000. The program continue as before with the two loops until he reaches another time the RTS instruction and this time he really exit the subroutine.
Actually, the final instruction of this subroutine is a simple JMP that goes to the end of another subroutine that we will see very likely in the next post. This is the instructions after the jump:
$8EE6> STA $2005
$8EE9> STA $2005
$8EEC> RTSSo this is just a little trick used to save some bytes. After the program returns to the Reset part, it simply enable the NMI (by ORing the $0778 buffer and calling the $8EED subroutine we saw earlier) and then it starts a forever loop.The presence of a forever loop means that all the actual game is done during the NMI. This will be where the funny begins! So stay tuned!




No comments:
Post a Comment