Jump to content

Photo

Playfield anomoly


7 replies to this topic

#1 Karl G ONLINE  

Karl G

    Dragonstomper

  • 601 posts

Posted Thu Apr 12, 2018 7:36 AM

I've done bits of ASM mixed with Batari BASIC, but this is my first time diving in deeper and attempting to write my own kernel, so please be kind.  :-D

Anyway, I decided to make my first ASM project a 1 or 2 player game of whack-a-mole using the keyboard controllers.  I've gotten as far as drawing a playfield, but I noticed there is one playfield pixel missing on the first line, left side only (I am using a mirrored playfield).  My first thought was that I was going over my HBLANK cycles for the first line, but moving initialization code over to VBLANK didn't seem to help.  Any thoughts?

 

playfield.png

 

Attached File  playfield.asm   4.2KB   18 downloads



#2 SpiceWare ONLINE  

SpiceWare

    Draconian

  • 12,491 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu Apr 12, 2018 8:10 AM

If you step through Stella's debugger you'll see you're updating PF1 a tad too late:
Screen Shot 2018-04-12 at 8.54.45 AM.png
 
The small white square in the upper left is where the electron beam is currently at - it's already drawn half of the first PF1 pixel when the STA PF1 finishes.
 
Quick fix is to move when the WSYNC is strobed:
; 192 scanlines
    ldx #0
ScanLoop
    sta WSYNC
    cpx pfstart
    bcc ____skip_read_playfield
    bne ____skip_playfield_start
    lda #$80
    sta PF0
____skip_playfield_start
    ldy Count
    lda playfield_left,y
    sta PF1
    lda playfield_right,y
    sta PF2
    iny
    sty Count
____skip_read_playfield
    ; sta WSYNC ; WSYNC doesn't care what value is stored
    inx
    cpx #192
    bcc ScanLoop


#3 SpiceWare ONLINE  

SpiceWare

    Draconian

  • 12,491 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu Apr 12, 2018 8:11 AM

As a developer you need to turn on Developer Mode in Stella. Hit TAB to bring up the in-game menu:
Screen Shot 2018-04-12 at 8.51.36 AM.png
 
then click on Developer Settings...
Screen Shot 2018-04-12 at 8.51.40 AM.png
 
When you do things go crazy:
Screen Shot 2018-04-12 at 9.19.06 AM.png  Screen Shot 2018-04-12 at 9.19.51 AM.png  Screen Shot 2018-04-12 at 9.19.53 AM.png  Screen Shot 2018-04-12 at 9.19.54 AM.png
 
 
Which tells you that you've most likely made the common mistake of leaving out a # in an Immediate Mode instruction:
; 192 scanlines
	ldx #0
ScanLoop
    sta WSYNC
    cpx pfstart
 
should be:
; 192 scanlines
	ldx #0
ScanLoop
    sta WSYNC
    cpx #pfstart
 
what was happening was instead of comparing the value of 43, you're comparing the contents of zero-page location 43, which is a mirror TIA register INPT3. If you check that debugger screenshot above you'll see that Stella pointed that out:
Screen Shot 2018-04-12 at 8.54.45 AM.png

#4 SpiceWare ONLINE  

SpiceWare

    Draconian

  • 12,491 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu Apr 12, 2018 8:32 AM

Next thing you need to do is add cycle counts to your code.  While you don't have to do this everywhere, you must do it for your kernel. Reference something like this 6502 opcode listing:
 
LDA (LoaD Accumulator)
 
Affects Flags: S Z
 
MODE           SYNTAX       HEX LEN TIM
Immediate     LDA #$44      $A9  2   2
Zero Page     LDA $44       $A5  2   3
Zero Page,X   LDA $44,X     $B5  2   4
Absolute      LDA $4400     $AD  3   4
Absolute,X    LDA $4400,X   $BD  3   4+
Absolute,Y    LDA $4400,Y   $B9  3   4+
Indirect,X    LDA ($44,X)   $A1  2   6
Indirect,Y    LDA ($44),Y   $B1  2   5+
 
+ add 1 cycle if page boundary crossed
 
the LEN column is how many bytes, the TIM value is how many cycles.

; 192 scanlines
    ldx #0
ScanLoop
    sta WSYNC                       ;    0
    cpx #pfstart                    ; 2  2
    bcc ____skip_read_playfield     ; 2  4 (3 5)
    bne ____skip_playfield_start    ; 2  6 (3 7)
    lda #$80                        ; 2  8
    sta PF0                         ; 3 11 @0-22
____skip_playfield_start
    ldy Count                       ; 3 14
    lda playfield_left,y            ; 4 18
    sta PF1                         ; 3 21 @71-28
    lda playfield_right,y           ; 4 25
    sta PF2                         ; 3 28 @66-39
    iny                             ; 2 30
    sty Count                       ; 3 33
____skip_read_playfield
    inx                             ; 2 35
    cpx #192                        ; 2 37
    bcc ScanLoop                    ; 2 39 (3 40)
 
The @ comments are for time-critical updates to let you know when they need to occur. That way if you make a change and see this after updating the cycle counts for the kernel:
    sta PF0                         ; 3 23 @0-22
 
you'll know the update is 1 cycle too late.

#5 SpiceWare ONLINE  

SpiceWare

    Draconian

  • 12,491 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu Apr 12, 2018 8:43 AM

note: I see you're currently reading the replies. I just added some thing to the end of reply #3, so scroll back up and review it ;)

#6 Karl G ONLINE  

Karl G

    Dragonstomper

  • Topic Starter
  • 601 posts

Posted Thu Apr 12, 2018 8:57 AM

Got it.  :)  I follow the difference between specifying a memory address and a literal number in that case.  Just so I understand, adding WSYNC to the top of my look would mean that I'm starting my drawing one scanline later than I was before, right?

 

Anyway, thanks for the detailed reply.  Keeping track of exact cycles makes sense so I'm not constantly chasing after ghosts like this.  I don't know how one finds time to do player objects, etc, but I'll cross that bridge when I get that far.  :-)



#7 SpiceWare ONLINE  

SpiceWare

    Draconian

  • 12,491 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Thu Apr 12, 2018 9:15 AM

Most likely - you could take a screenshot and compare the before/after to see if it shifted.

 

No problem.  Start off by counting down instead of up in your kernel, I cover that when I explain why the graphics are upside down.



#8 Karl G ONLINE  

Karl G

    Dragonstomper

  • Topic Starter
  • 601 posts

Posted Thu Apr 12, 2018 1:20 PM

I also realized that since I'll be drawing the moles, etc in the cells, I won't have to update the playfield registers at the same point as I'm drawing player graphics anyway.

I'm beginning to see why people enjoy the challenge of writing a kernel.




0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users