Quantcast
Channel: nesdev.org
Viewing all articles
Browse latest Browse all 785

Funny mistake helping me figuring out my calculations. NES PAINT

$
0
0
:D :P

Sounds crazy, but i was trying to align my tile index detector, then this happen:



it began writing tiles behing my player on demande!!! at the coordinates from my adress calculation routine ! It also allows me to debug the namtable changes
Untitled.png
NINTENDO PAINT baby :DiTS ACtually drawing tiles on demand, ( almost ). I had to show this one.

Now I have a problem:

1. Trying to figure out the mistake in my ppu calculations routine. As you can see the tiles drawn when moving are drawn at 5 places(or should be ):
X
X P1 X
X
Also behind p1, sprite 1 ( the top left sprite ).
This is what Im trying to do. Its a little offset always. Maybe its the time i call the routine ? but i call it every nmi. hmmm.

Here is the calculation routine so far:

Code:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CalculatePPUAddress:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     lda #$00               ; Clear A (start accumulator at 0)    sta HIGHB             ; Clear high byte    sta LOWB              ; Clear low byte    lda SPRITE_Y_P1     ; Load SPRITE_Y_P1 (C0 = 192)    sta temp                ; Store it in temp    ; Divide temp by 8 (192 >> 3 = 24)    lsr                 ; Shift right (divide by 2)    lsr                 ; Divide by 4    lsr                 ; Divide by 8    sta temp        ; Store result in temp (temp = 24)    ; Multiply temp by 32      lda temp    asl ;times 2 (can't overflow)    asl ;times 4 (can't overflow)    asl ;times 8 (can't overflow)    asl ;times 16 (might overflow)    rol HIGHB ;propagate bit to high byte    asl ;times 32 ;(might overflow)    rol HIGHB ;propagate bit to high byte    sta LOWB ; LOWB and HIGHB now hold the result;Add SPRITE_X_P1 to the result       lda SPRITE_X_P1     ; Load SPRITE_Y_P1 (C0 = 192)    ; Divide temp by 8 (192 >> 3 = 24)    lsr                 ; Shift right (divide by 2)    lsr                 ; Divide by 4    lsr                 ; Divide by 8    sta temp            ; Store result in temp (temp = 24)    lda LOWB            ; Load the low byte    clc                 ; Clear carry    adc temp     ; Add SPRITE_X_P1 to the low byte    sta LOWB            ; Store the new low byte    bcc :+      ; If no overflow, skip incrementing the high byte    inc HIGHB           ; Increment high byte if there's overflow:; this is the scrolling offset, following the background movement.lda offset_value sta templda temp        lsr                 ; Shift right (divide by 2)        lsr                 ; Divide by 4        lsr                 ; Divide by 8sta tempclclda LOWBadc tempsta LOWBbcc :+inc HIGHB:lda HIGHBclcadc #$20sta HIGHB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;store into main variable  TILE_INDEX_MAIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lda LOWB          ; Load LOWB    sta LOWB_MAIN     ; Store it into LOWB_MAIN    lda HIGHB         ; Load HIGHB    sta HIGHB_MAIN    ; Store it into HIGHB_MAIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Calculate the adress of the tile top of the player, 32 bytes earlier;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lda LOWB       ; Load LOWB    sta tempL      ; Transfer LOWB to tempL    lda HIGHB      ; Load HIGHB    sta tempH      ; Transfer HIGHB to tempH    lda tempL      ; Load tempL    sec            ; Set carry for subtraction    sbc #$20       ; Subtract 32 bytes    sta tempL      ; Store result back in tempL    bcs :+         ; If no underflow, skip decrementing tempH    dec tempH      ; If underflow, decrement tempH:                   ; Label for skipping decrement;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;store highb and lowb for TILE_INDEX_TOP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lda tempL          ; Load LOWB    sta LOWB_TOP     ; Store it into LOWB_MAIN    lda tempH         ; Load HIGHB    sta HIGHB_TOP    ; Store it into HIGHB_MAIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Now we do the bottom, same process but 32 bytes later, one row ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lda LOWB       ; Load LOWB    sta tempL      ; Transfer LOWB to tempL    lda HIGHB      ; Load HIGHB    sta tempH      ; Transfer HIGHB to tempH    lda tempL      ; Load tempL    clc            ; Clear carry for addition    adc #$20       ; Add 32 bytes    sta tempL      ; Store result back in tempL    bcc :+         ; If no overflow, skip incrementing tempH    inc tempH      ; If overflow, increment tempH:                   ; Label for skipping increment;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Store highb and lowb for TILE_INDEX_BOTTOM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lda tempL          ; Load LOWB    sta LOWB_BOTTOM  ; Store it into LOWB_MAIN    lda tempH         ; Load HIGHB    sta HIGHB_BOTTOM  ; Store it into HIGHB_MAIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Now we do left, one byte BEFORE for TILE_INDEX_LEFT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    lda LOWB       ; Load LOWB    sta tempL      ; Transfer LOWB to tempL    lda HIGHB      ; Load HIGHB    sta tempH      ; Transfer HIGHB to tempH    lda tempL      ; Load tempL    sec            ; Set carry for subtraction    sbc #$01       ; Subtract 1 byte    sta tempL      ; Store result back in tempL    bcs :+         ; If no underflow, skip decrementing tempH    dec tempH      ; If underflow, decrement tempH:                   ; Label for skipping decrement               ; Label for skipping increment;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;store into main variable;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lda tempL          ; Load LOWB    sta LOWB_LEFT    ; Store it into LOWB_MAIN    lda tempH         ; Load HIGHB    sta HIGHB_LEFT    ; Store it into HIGHB_MAIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Now we do right, one byte BEFORE for TILE_INDEX_LEFT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    lda LOWB       ; Load LOWB    sta tempL      ; Transfer LOWB to tempL    lda HIGHB      ; Load HIGHB    sta tempH      ; Transfer HIGHB to tempH    lda tempL      ; Load tempL    clc            ; Set carry for subtraction    adc #$01       ; add 1 byte    sta tempL      ; Store result back in tempL    bcc :+         ; If no underflow, skip decrementing tempH    dec tempH      ; If underflow, decrement tempH:              ; Label for skipping decrement               ; Label for skipping increment;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;store into main variable;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lda tempL          ; Load LOWB    sta LOWB_RIGHT    ; Store it into LOWB_MAIN    lda tempH         ; Load HIGHB    sta HIGHB_RIGHT    ; Store it into HIGHB_MAIN   rts
After that routine I tried to get the corresponding tile index for each addresss. This is my first draft, thats where the magic is happenning :D

Code:

CALL_CHECK_TILE_INDEX:; Increment the frame counter    lda frame_flag    clc    adc #$01    sta frame_flag;do it every lets say 6 nmi for now     cmp #$02               bne END_CHECK_TILE         ; If not 60, skip the operation    ; Reset the counter    lda #$00    sta frame_flag; Check if VBlank is active, if not, passCheckVBlank:    lda $2002             ; Read PPU status register    and #$80              ; Mask out all bits except the VBlank flag (bit 7)    beq SkipTileUpdate    ; If VBlank flag is not set, skip the tile update    ; Write TILE_INDEX_MAIN    lda HIGHB_MAIN        ; Load the high byte of the address    sta $2006             ; Store it in $2006 (PPU address high byte)    lda LOWB_MAIN         ; Load the low byte of the address    sta $2006             ; Store it in $2006 (PPU address low byte)    ldx TILE_INDEX_MAIN   ; Load the tile index for the main section    stx $2007             ; Write the tile index to PPU memory    ; Write TILE_INDEX_TOP    lda HIGHB_TOP         ; Load the high byte of the address    sta $2006             ; Store it in $2006 (PPU address high byte)    lda LOWB_TOP          ; Load the low byte of the address    sta $2006             ; Store it in $2006 (PPU address low byte)    ldx TILE_INDEX_TOP    ; Load the tile index for the top section    stx $2007             ; Write the tile index to PPU memory    ; Write TILE_INDEX_BOTTOM    lda HIGHB_BOTTOM      ; Load the high byte of the address    sta $2006             ; Store it in $2006 (PPU address high byte)    lda LOWB_BOTTOM       ; Load the low byte of the address    sta $2006             ; Store it in $2006 (PPU address low byte)    ldx TILE_INDEX_BOTTOM ; Load the tile index for the bottom section    stx $2007             ; Write the tile index to PPU memory    ; Write TILE_INDEX_LEFT    lda HIGHB_LEFT        ; Load the high byte of the address    sta $2006             ; Store it in $2006 (PPU address high byte)    lda LOWB_LEFT         ; Load the low byte of the address    sta $2006             ; Store it in $2006 (PPU address low byte)    ldx TILE_INDEX_LEFT   ; Load the tile index for the left section    stx $2007             ; Write the tile index to PPU memory    ; Write TILE_INDEX_RIGHT    lda HIGHB_RIGHT       ; Load the high byte of the address    sta $2006             ; Store it in $2006 (PPU address high byte)    lda LOWB_RIGHT        ; Load the low byte of the address    sta $2006             ; Store it in $2006 (PPU address low byte)    ldx TILE_INDEX_RIGHT  ; Load the tile index for the right section    stx $2007             ; Write the tile index to PPU memorySkipTileUpdate:           ; Skip tile update if not in VBlank    ; Continue with other code...END_CHECK_TILE:LDA toggle_flag    ; Load the value of nametable toggle_flag    BEQ FIX_NAMETABLE_TILES     ; the multiples writes to $2006 changed the base nametable value; therefor we have to put back in $2000 right base nametable    LDA #%10010000;enable nmi on vblanks, nametable 1STA PPU_CTRL            ; Update PPU control registerJMP DONE_FIX_NAMETABLE_TILES           ;FIX_NAMETABLE_TILES:LDA     #%10010011    ; Enable NMI on vblank's(Bit 7 set), nametable 4STA     PPU_CTRL         ; Write to PPU Control Register $2000DONE_FIX_NAMETABLE_TILES:RTS    ; Continue with the rest of the NMI routine
I am just supposed to do that for each adresses, instead of fetching I ended up WRITING , so tired I am lol :wink: :

Code:

 ; Perform the operation once every 2 time per sec.    lda $2002    lda HIGHB_MAIN    sta $2006    lda LOWB_MAIN    sta $2006    ldx $2007    Ldx $2007    stx TILE_INDEX_MAIN

Statistics: Posted by v.depatie — Fri Jan 24, 2025 10:58 pm — Replies 3 — Views 125



Viewing all articles
Browse latest Browse all 785

Latest Images

Trending Articles



Latest Images