+Karl G Posted April 12, 2018 Share Posted April 12, 2018 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. 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.asm Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 12, 2018 Share Posted April 12, 2018 If you step through Stella's debugger you'll see you're updating PF1 a tad too late: 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 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 12, 2018 Share Posted April 12, 2018 As a developer you need to turn on Developer Mode in Stella. Hit TAB to bring up the in-game menu: then click on Developer Settings... When you do things go crazy: 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: Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 12, 2018 Share Posted April 12, 2018 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. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 12, 2018 Share Posted April 12, 2018 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 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted April 12, 2018 Author Share Posted April 12, 2018 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. :-) Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 12, 2018 Share Posted April 12, 2018 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. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted April 12, 2018 Author Share Posted April 12, 2018 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.