Jump to content
IGNORED

Playfield anomoly


Recommended Posts

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?

 

post-48311-0-13868000-1523540123.png

 

playfield.asm

Link to comment
Share on other sites

If you step through Stella's debugger you'll see you're updating PF1 a tad too late:

post-3056-0-47822000-1523541722_thumb.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
Link to comment
Share on other sites

As a developer you need to turn on Developer Mode in Stella. Hit TAB to bring up the in-game menu:

post-3056-0-14443700-1523542775_thumb.png

 

then click on Developer Settings...

post-3056-0-97458700-1523542778_thumb.png

 

When you do things go crazy:

post-3056-0-73583700-1523542816_thumb.png post-3056-0-84950700-1523542819_thumb.png post-3056-0-19994600-1523542823_thumb.png post-3056-0-68739600-1523542826_thumb.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:

post-3056-0-86442200-1523544107.png

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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. :-)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...