Jump to content
IGNORED

my kernel


antron

Recommended Posts

It is for a smooth scrolling horizontal platformer.

 

A man (player) is made up of both player graphics side by side centered in the exact center of the screen. New player graphics are filled in every other scanline.

 

A missle is on the right and a missle is on the left. One missle is the monster, one is a wall.

 

The playfield is displayed every other scanline. The wall is also displayed every other scanline. The wall is used as a buffer to make the playfield look like it is scrolling horizontally one pixel at a time. The wall can change its position every other scanline, but only by the value that is in the memory location 'wallshft'. This can be used when the playfield staggers, or wants to incline.

 

The monster can be enabled and change its size and/or position every other scanline.

 

The ball can be enabled and change its position every other scanline.

 

The kernel provided is for the situation when the monster is on the left and the wall is on the right. But notice that the monster can be on the right provided that it is past 6502 cycle 54.

And the wall could be on the left provided that it is before cycle 45. I have a kernel for the reverse of all this too, but it is more trivial.

 

RAM usage:

1 byte for the color of the monster.

1 byte for the color of the wall.

1 byte for the value that the wall can be shifted by

2 bytes for sizes and movements each time that you want to use this two scanline kernel

2 bytes for player graphics each time that you want to use this two scanline kernel

6 bytes for the playfield that is displayed when this kernel is used.

 

I will have two versions of this kernel in a row. One that uses one set of playfield values, another that uses another 6 byte set. This way I can have the playfield stagger once while the man is being displayed. The wall will stagger with it with its hmove.

 

The color of the man must be in the Y register.

X register is the linecount.

 

The two bytes for sizes and movements are used as such:

mmisdata:

bit usage

0 must be 0 (not used)

1 enable monster?

2,3 monster size bits

4,5,6,7 monster hmove nibble

 

mlinedata

bit usage

0 is it time to end this kernal?

1 enable ball?

2 enable wall?

3 shift wall by the value in shftwall?

4,5,6,7 ball hmove nibble

 

MK1  lda mmisdata,x;4	70	load A with next monster data
sta HMM1   ;3      73      prepare to move monster next line
sta ENAM1  ;3      76


sta HMOVE  ;3     3	
asl              ;2   5    get monster size bits in position
asl              ;2	
sta NUSIZ1   ;3      10       set monster size for this line
inx              ;2      x needs to be incremented and inx fit here
txs              ;2  14   store linecount in S so X can be used later
lda #0         ;2  	
sta ENAM0   ;3         clear missle 0 (right) for this line
sta PF0        ;3	22	clear PF0 for this line
sta PF1        ;3   clear PF 1for this line
sta PF2        ;3	28	clear PF2 for this line
lda manL-1,x;4        -1 because inx was called early
sta GRP0     ;3	
lda manR-1,x;4
sta GRP1     ;3	42	load both player graphics 
sty COLUP0  ;3      *45*	color left side of man
sty COLUP1  ;3      *48*  	color rt side of man 
lda m1col     ;3
sta COLUP1  ;3      *54*	recolor for monster on left side (or right side past here)
lda pfm10L   ;3
sta PF0         ;3       load first left playfield
lda pfm11L    ;3
sta PF1         ;3  66     load second left playfield  
lda mlinedata-1,x;4     70        get ball and wall parameters for next line
sta HMBL       ;3	75	

sta ENAM0      ;3       2           enable wall (right side)
lsr                 ;2                   notice that bit 0 is in the carry!  don't erase it!
sta ENABL      ;3       7	enable ball for this line
and #%00000100;2	9
bne shftwl1    ;2(3)  test if wall is shifted
SLEEP 3
jmp noshft1    ;3   A is zero
shftwl1 lda wallshft  ;3                go get the walshift 
SLEEP 2	
noshft1	sta HMM0    ;3  18     shift wall 
lda pfm12L      ;3  	
sta PF2            ;3  24	load third left playfield  
lda pfm10R      ;3	
sta PF0            ;3	30	load first right playfield
ldx m1col        ;3      33	load monster (left) color early
lda pfm11R      ;3
sta PF1;3  	load second right playfield  
lda m0col         ;3      42	load wall (right) color early
sty COLUP0      ;3     *45*    recolor left side man
sty COLUP1      ;3     *48* color rt side of man after lt man begins but b4 rt side does
sta COLUP0      ;3     51 color missle on rt side after lt man ends but b4 rt side of man ends 
stx COLUP1      ;3      *54*  recolor for missle on left side (or right side past here)
lda pfm12R      ;3
sta PF2            ;3	60	load 3rd right pf
tsx                  ;2	62        get our line counter back
bcc MK1          ;2(3or4)    time for next kernal? this kernel is written for 4

Edited by antron
Link to comment
Share on other sites

post-4325-1119116529_thumb.png

 

The monster is the green. I am just changing its position once, but i could shift and change its size every other scanline. I realize that monster graphics will be limited.

 

The wall is the purple, but would normally be the same color as the wall, for scrolling.

 

The little man is the ball. It can only shift, not change size; parts of it are hiding behind the chair. It is being vertically delayed.

 

The wall and monster can go very deep into the vehicle before they get its color. Usually by then you can get a collision.

Edited by antron
Link to comment
Share on other sites

I'm working on a smooth side-scroller too, and I've found some of the same challenges (like the missile and player must share the same color :x )

 

Your kernel looks pretty tight, but I did see a place where you could free up 2 cycles using the BIT Absolute trick:

 

  bne shftwl1        ;2(3)  test if wall is shifted
  SLEEP 3
  jmp noshft1        ;3  00000100 is left in A
shftwl1 lda wallshft      ;3                go get the walshift
  SLEEP 2
noshft1 sta HMM0        ;3  18     shift ball

 

could be changed to

  bne shftwl1        ;2(3)  test if wall is shifted
  .byte 2C
shftwl1
  lda wallshft      ;3                go get the walshift
  noshft1 sta HMM0        ;3  18     shift ball

 

Though I could be wrong...

Link to comment
Share on other sites

Wow. I didn't know that one. I never even thought about eating opcodes like that. So, would need to have zero out in some ROM location depending on where wallshft is located in RAM?

 

 

also, my comment is wrong in the code you quoted. The A register was zero, obviously.

Edited by antron
Link to comment
Share on other sites

Wow.  I didn't know that one.  I never even thought about eating opcodes like that. So, would need to have zero out in some ROM location depending on where wallshft is located in RAM?

 

 

also, my comment is wrong in the code you quoted.  The A register was zero, obviously.

876678[/snapback]

No need to zero out anything... If you follow what the CPU is doing, when the bne wlshift1 is taken, the CPU sees LDA wallshft, if it's not taken, A remains zero and it sees LDX Absolute, and uses 6 cycles either way. It doesn't matter what gets loaded into X because you don't use X until you do LDX m1col below, which overwrites it anyway.

Link to comment
Share on other sites

Yep, I'm wrong... you need to preserve the carry bit.

BIT doesn't change the carry bit.

876707[/snapback]

Yes, you're right, my so called "correction" didn't correct anything :dunce: ... so I was right the first time. I thought it put bit 6 into the carry, turns out that is the V flag. You can tell I don't use that crazy BIT instruction too often. Looks like either 2C or AE will work, though 2C is the "normal" way to do this trick.

Edited by batari
Link to comment
Share on other sites

The only improvement I would like to make is to have the monster data loaded from ROM. That requires indirect indexed addressing with Y, but my linecount is in X.

 

If this loop is properly aligned the branch at the end is only 3 cycles, not 4. Using the 2 I free with the BIT gobble trick I have 3 to spare.

 

If I make X the man color, and Y the line count I can:

store the line count in RAM not S, 1 cycle

load the line count from RAM not S, 1 cycle

make an indirect indexed load, not an indexed, for the monster data, 1 cycle

 

so it fits. but it is not clear to me how it could be arranged with my other timing requirements (the ones in asterisks) i think i need to get the three cycles together.

Link to comment
Share on other sites

I'm working on a smooth side-scroller too, and I've found some of the same challenges (like the missile and player must share the same color  :x )

I was also working on a side-scroller; don't know if you guys saw it at the time. I stopped work on it when I ran into a couple of hurdles, though I am considering picking it up again.

 

The challenge of a 2600 side-scroller was irresistable to me! And to others, too, I guess. :D

Link to comment
Share on other sites

Hi there!

 

The challenge of a 2600 side-scroller was irresistable to me!  And to others, too, I guess.  :D

879657[/snapback]

 

Every once in a while I think about Ghosts'n'Goblins 2600. If allowed 30Hz flicker on everything, one could do an amazing 2600 conversion job here.

 

Greetings,

Manuel

Link to comment
Share on other sites

  • 2 weeks later...

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