Jump to content







Photo

Cycle73 Positioning

Posted by Mord, 07 June 2009 · 36 views

While I posted this in the programming forums for others to use, I figure it'll be easier for me to find it later in my own blog if I need a backup of this thing or something. Right now it takes too many lines to position an object since I have the actual HMOVE separated from the positioning but it's at least a start. I guess the next thing I'll be doing is trying to integrate the hmove into the equation while keeping the time used constant. I'm guessing this is where the real pain starts for this kind of thing.

As an overview of what's happening in the picture, the solid yellow strip is where the cycle 73 positioning is going on. The red dot is P0, the 4 bars is P1. P1 is being positioned regularly with a standard hmove during the VBLANK. P0 is being positioned during the yellow strip. Both are getting their X position from the variable Xpos and thus should always line up. Moving left and right is limited in range from 0-159.

Attached Thumbnails

  • Attached Image

Attached Files






I think it's typical for in-kernel cycle 73/74 HMOVEs to occur on the line following the RESPx. You can do useful stuff in that second line - it just means that you need a gap of a few lines between sprites. It's actually not a huge compromise, IMO.

Trying to place the HMOVE in the same line as the RESPx is going to be a difficult.

It is possible, as I believe the Juno First kernel does just that, but it requires a dozen or so mini-kernels and a way to jump between them (such as indirect jumps to RAM.) The advantage to the Juno First approach is that it does useful work during repositioning instead of a divide-by-15 loop in the middle of the kernel that wastes a whole line. The disadvantage is that, as I understand, the kernel takes up nearly an entire bank.

I can think of a simpler way to do it without using any RAM for a jump table, but you can't do useful work during repositioning. You can place a series of compares and branches to 13 alternative kernels and each mini-kernel will start with a RESPx and then have enough NOPs to fill in time until the HMOVE, then a JMP back to the main kernel.
  • Report

batari, on Sun Jun 7, 2009 3:59 PM, said:

Trying to place the HMOVE in the same line as the RESPx is going to be a difficult.

Depends how far over the sprite needs to go. If it doesn't have to go too far to the right, one could do something like:
 ; X holds position
  lda #255
  sbx #15
  bcs *+7
  sta RESPx
  ldy postbl-241,x
  sbx #15
  bcs *+7
  sta RESPx
  ldy postbl-241,x
  ...
  sbx #15
  bcs *+7
  sta RESPx
  ldy postbl-241,x
  sty HMPx
  sta HMOVE
Provided the position value is within range, and postbl is located so the loads will always wrap or never wrap, the total execution time should be constant.
  • Report

supercat, on Fri Jun 12, 2009 12:45 AM, said:

batari, on Sun Jun 7, 2009 3:59 PM, said:

Trying to place the HMOVE in the same line as the RESPx is going to be a difficult.

Depends how far over the sprite needs to go. If it doesn't have to go too far to the right, one could do something like:
I was thinking of something like this, actually, which didn't quite work until I saw your idea about SBX for subtracting:
  sbx #15
  bcc .1
  sbx #15
  bcc .2
  sbx #15
  bcc .3
  sbx #15
  bcc .4
...
  sbx #15
  bcc .11

; fallthough for far right:

  nop
  lda postable2,x; positive index into page-wrap table that doesn't wrap
  sta RESPx
  sta HMPx
  sta HMOVE

...
.1
  sta RESPx
  .byte $DD; effectively skips the next instruction by doing CMP $1x85,X, which will always wrap a page and take 5 cycles
.2
  sta RESPx
  .byte $DD
...
.11
  sta RESPx
  lda postable,x; always page-wraps for 5 cycles
  sta HMPx
  sta HMOVE
  • Report

May 2012

S M T W T F S
  12345
6789101112
13141516171819
20 21 2223242526
2728293031