This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

New pal only glitch?

New pal only glitch?
by on (#43021)
As I said in my pong thread:
Quote:
Now more important. I played this on my famicom but took it to school today and played it on my pal nes. For some reason my pal nes the up button got shifted to start. A pal only glitch perhaps. I'd like to see if theres more info on this.


I doubt its the dmpc glitch since it doesnt happen on my famicom and I dont even have audio.

by on (#43023)
Can't help much without source code. Best to first try building a test program that just reads the controller and prints the byte returned, and see if that still exhibits the problem. If not, you know the cause is in your other code.

by on (#43024)
It's on my laptop. I"ll upload the code later. I used an inefficient way of reading the pads. But it works on ntsc machines so its really weird.

by on (#43026)
PAL does have a slower CPU than NTSC, would that contribute at all?

by on (#43027)
I dont see how......it reads the controller basicly by latching it.

by on (#43029)
Ok this is fucked up. I did some more testing.
first of all all controllers work on all units with other games like dpad hero.
Heres all tests with my game:
dogbone (famicom) on pal nes: works
pal controller on pal nes: doesnt work (tried 2)

pal controller on famicom: works
dogbone controller on famicom works to.

This is f-ed up

by on (#43050)
Are you masking out open bus/gamepad unused bits?

by on (#43066)
Code:
        .inesprg    1
        .ineschr    1
        .inesmir    1
        .inesmap    0

   .org $8000
   .bank 0


paddle_y = $0200
paddle_x = $0203
paddle2_y = $020c
paddle2_x = $020f
ball_y = $0218
ball_x = $021b
score_1 = $0221
score_2 = $021d
direction = $304

reset:
    sei        ; ignore IRQs
    cld        ; disable decimal mode
    ldx #$40
    stx $4017  ; disable APU frame IRQ
    ldx #$ff
    txs        ; Set up stack
    inx        ; now X = 0
    stx $2000  ; disable NMI
    stx $2001  ; disable rendering
    stx $4010  ; disable DMC IRQs
 
    ; Optional (omitted):
    ; Set up mapper and jmp to further init code here.
 
    ; First of two waits for vertical blank to make sure that the
    ; PPU has stabilized
vblankwait1: 
    bit $2002
    bpl vblankwait1
 
    ; We now have about 30,000 cycles to burn before the PPU stabilizes.
    ; Use it to clear RAM.  X is still 0...
    txa
clrmem:
    sta $000,x
    sta $100,x
    sta $200,x
    sta $300,x
    sta $400,x
    sta $500,x
    sta $600,x
    sta $700,x  ; Remove this if you're storing reset-persistent data
    inx
    bne clrmem
 
vblankwait2:
    bit $2002
    bpl vblankwait2

ldpalletadr:
   lda #$3F
   sta $2006
   lda #$10
   sta $2006
   ldx #$00

palletloop:
  LDA palette, x        ;load palette byte
  STA $2007             ;write to PPU
  INX                   ;set index to next byte
  CPX #$20           
  BNE palletloop  ;if x = $20, 32 bytes copied, all done

preploadscreen:
  lda $2002
  lda #$20
  sta $2006
  lda #$20
  sta $2006
  ldx #$00
  lda #$01

loadscreen:
  sta $2007
  inx
  cpx #$20
  bne loadscreen

preloadscreen2:
  lda $2002
  lda #$23
  sta $2006
  lda #$00
  sta $2006
  ldx #$00
  lda #$01

loadscreen2:
  sta $2007
  inx
  cpx #$20
  bne loadscreen2
 

set2006:
  lda #$00
  sta $2006
  sta $2006

drawscore1:
   lda #$c7
   sta $021C
   lda #$04
   STA $021d
   lda #$00
   sta $021e
   lda #$50
   sta $021f

drawscore2:
   lda #$c7
   sta $0220
   lda #$04
   STA $0221
   lda #$00
   sta $0222
   lda #$A7
   sta $0223
   
drawpaddle:
   lda #$48 ;first sprite
   sta paddle_y ;store y position
   lda #$03
   sta $0201 ;store sprite number
   lda #%00000000
   sta $0202 ;store no flipping ect.
   lda #$08
   sta paddle_x ;store x position
   lda #$50 ;second sprite
   sta $0204
   lda #$01
   sta $0205
   lda #$00
   sta $0206
   lda #$08
   sta $0207
   lda #$58 ;third sprite
   sta $0208
   lda #$03
   sta $0209
   lda #%10000000
   sta $020A
   lda #$08
   sta $020B ;end third sprite

drawpaddle2:
   lda #$48 ;first sprite
   sta paddle2_y ;store y position
   lda #$03
   sta $020d ;store sprite number
   lda #$00
   sta $020e ;store no flipping ect.
   lda #$f0
   sta paddle2_x ;store x position
   lda #$50 ;second sprite
   sta $0210
   lda #$01
   sta $0211
   lda #$00
   sta $0212
   lda #$f0
   sta $0213
   lda #$58 ;third sprite
   sta $0214
   lda #$03
   sta $0215
   lda #%10000000
   sta $0216
   lda #$f0
   sta $0217 ;end third sprite
   lda #$02
   sta $4014

drawball:
   lda #$50 ;sprite
   sta ball_y ;store y position
   lda #$02
   sta $0219 ;store sprite number
   lda #$00
   sta $021a ;store no flipping ect.
   lda #$7b
   sta ball_x ;store x position

setbalv:
   lda #$01
   sta $301
   lda #$02
   sta $300

generate:
   lda #%10000000
   sta $2000

turnon:
   lda #%00011110
   sta $2001

setscore:
   lda #$04
   sta score_1
   sta score_2
 
loop:
 
   jmp loop

reverse:
   Lda direction
   eor #$00000001
   sta direction
   rts

nmi:

   pha    ; Push A on the stack (which were the contents in A)
   txa    ; transfer X to A
   pha    ; Push A on the stack (which were the contents in X)
   tya    ; transfer Y to A
   pha    ; Push A on the stack (which were the contents in Y)



checkscore1:
   ldx ball_x
   cpx #$F7
   bcc checkscore2
   lda score_2
   clc
   cmp #$07
   bne scorelol1
   jmp reset

scorelol1:
   lda #$7b
   sta ball_x
   lda #$50
   sta ball_y
   ldx score_2
   inx
   stx score_2
   jsr reverse
   

checkscore2:
   ldx ball_x
   cpx #$08
   bcs checkdirection
   lda score_1
   clc
   cmp #$07
   bne scorelol2
   jmp reset

scorelol2:
   lda #$7b
   sta ball_x
   lda #$50
   sta ball_y
   ldx score_1
   inx
   stx score_1
   jsr reverse


checkdirection:
   ldx direction
   cpx #$00
   bne checkballpaddle2


checkballpaddle1:
   lda paddle2_x
   clc
   adc #$08
   clc
   cmp ball_x
   bcc checkbounce       ;If the left edge of the enemy is farther than the Player's Right edge, there is could be no collision.

   lda ball_x
   clc
   adc #$08
   clc
   cmp paddle2_x
   bcc checkbounce       ;If the Player's Left edge is beyond the enemy's right, there's no way there could be a collision.

   lda paddle2_y
   clc
   adc #$15
   clc
   cmp ball_y
   bcc checkbounce       ;If the Player's Bottom Border is above the top of the enemy, there is no way for collision.

   lda ball_y
   clc
   adc #$08
   clc
   cmp paddle2_y
   bcc checkbounce       ;If the player's Top edge is below (Greater than) the enemy's bottom edge, there can be no collision.

reverseball:
   jsr reverse

checkballpaddle2:
   lda paddle_x
   clc
   adc #$08
   clc
   cmp ball_x
   bcc checkbounce       ;If the left edge of the enemy is farther than the Player's Right edge, there is could be no collision.

   lda ball_x
   clc
   adc #$08
   clc
   cmp paddle_x
   bcc checkbounce       ;If the Player's Left edge is beyond the enemy's right, there's no way there could be a collision.

   lda paddle_y
   clc
   adc #$15
   clc
   cmp ball_y
   bcc checkbounce       ;If the Player's Bottom Border is above the top of the enemy, there is no way for collision.

   lda ball_y
   clc
   adc #$08
   clc
   cmp paddle_y
   bcc checkbounce       ;If the player's Top edge is below (Greater than) the enemy's bottom edge, there can be no collision.

reverseball2:
   jsr reverse
 
checkbounce:
   ldx ball_y
   cpx #$10
   beq checkbounce2

reversey:
   lda $303
   eor #$00000001
   sta $303

checkbounce2:
   ldx ball_y
   cpx #$b8
   beq updatebally1

reversey2:
  lda $303
  eor #$00000001
  sta $303

updatebally1:
   lda $303
   and #$01
   bne updatebally2
   lda ball_y
   clc
   adc $300
   sta ball_y
   jmp updateballx1

updatebally2:
   lda ball_y
   sec
   sbc $300
   sta ball_y

updateballx1:
   lda direction
   and #%00000001
   bne updateballx2
   lda ball_x
   clc
   adc $301
   sta ball_x
   jmp check1

updateballx2:
   lda ball_x
   sec
   sbc $301
   sta ball_x


checkcheck1:
   ldx ball_x
   cpx #$EF
   bcc checkcheck2
   jmp finish

checkcheck2:
   ldx ball_x
   cpx #$10
   bcs check1
   jmp finish
     
   
check1:
   ldx paddle_y ;see if paddle is at top
   cpx #$10
   beq check2
   lda #$01 ; start latch
   sta $4016
   lda #$00
   sta $4016 ;latch the controller
   lda $4016
   lda $4016
   lda $4016
   lda $4016 ;ignore everything till up and down
   lda $4016
   and #%00000001
   beq check2 ;if up pressed go up
   ldx paddle_y
   dex
   stx paddle_y ;first sprite
   ldx $0204
   dex
   stx $0204 ;second
   ldx $0208
   dex
   stx $0208 ;third
   
check2:
   ldx $0208 ;see if paddle is at bottom
   cpx #$b8
   beq check3
   lda #$01 ; start latch
   sta $4016
   lda #$00
   sta $4016 ;latch the controller
   lda $4016
   lda $4016
   lda $4016
   lda $4016 ;ignore everything till up and down
   lda $4016
   lda $4016
   and #%00000001
   beq check3 ;yaya
   ldx paddle_y
   inx
   stx paddle_y ;first
   ldx $0204
   inx
   stx $0204 ;second
   ldx $0208
   inx
   stx $0208 ;third.

check3:
   ldx paddle2_y ;see if paddle is at top
   cpx #$10
   beq check4
   lda #$01 ; start latch
   sta $4016
   lda #$00
   sta $4016 ;latch the controller
   lda $4017
   lda $4017
   lda $4017
   lda $4017 ;ignore everything till up and down
   lda $4017
   and #%00000001
   beq check4 ;if up pressed go up
   ldx paddle2_y
   dex
   stx paddle2_y ;first sprite
   ldx $0210
   dex
   stx $0210 ;second
   ldx $0214
   dex
   stx $0214 ;third

check4:
   ldx $0214 ;see if paddle is at bottom
   cpx #$b8
   beq finish
   lda #$01 ; start latch
   sta $4016
   lda #$00
   sta $4016 ;latch the controller
   lda $4017
   lda $4017
   lda $4017
   lda $4017 ;ignore everything till up and down
   lda $4017
   lda $4017
   and #%00000001
   beq finish ;yaya
   ldx paddle2_y
   inx
   stx paddle2_y ;first
   ldx $0210
   inx
   stx $0210 ;second
   ldx $0214
   inx
   stx $0214 ;third.
   
   

finish:
   lda #$02
   sta $4014
   pla     ; Pull A off of the stack (which were the contents in Y)
   tay     ; transfer A to Y
   pla     ; Pull A off of the stack (which were the contents in X)
   tax     ; transfer A to X
   pla     ; Pull A off of the stack (which were the contents in A)
   rti     ; return from NMI interrupt


     

        palette:
          .db $0F,$30,$30,$30,   $0F,$30,$30,$30,   $0F,$30,$30,$30,   $0F,$30,$30,$30
          .db $0F,$30,$30,$30,   $0F,$30,$30,$30,   $0F,$30,$30,$30,   $0F,$30,$30,$30 

       .bank 1
   .org   $FFFA
   .dw      nmi ;(NMI_Routine)
   .dw      reset ;(Reset_Routine)
   .dw      0 ;(IRQ_Routine)

    .bank 2
    .org    $0000
    .incbin "pong.chr"  ;gotta be 8192 bytes long


My code in its entirety.

by on (#43072)
Try adding a NOP between the consecutive $4016/$4017 reads. I doubt that will fix it, but I don't know what else to suggest (unless the bug is somewhere else).

by on (#43073)
Kev told me pal pads are different. But I dont see why the pal pads would work on my famicom fine then.

by on (#43075)
Yeah, looks to be that it can't be read that quickly. Perhaps capacitance on the input. Any reason you aren't using a normal controller read loop?

by on (#43076)
meh this was one of the first things I worked on. And it was when I first started nesdev. Thats the reason for the non standard controller read loop. However it might be good to make note of this.