Jump to content

Cybearg

Recommended Posts

Does "if pulse then goto 10" have any actual cycle advantage over "if pulse <> 0 then goto 10"? Because if not, I'd like to keep things as unobtuse as possible.

 

I'd be able to save even more cycles here:


if flicker = 0 && temp4{0} then goto 110
if flicker = 1 && temp4{1} then goto 110
if flicker = 2 && temp4{2} then goto 110
if flicker = 3 && temp4{3} then goto 110
if flicker = 4 && temp4{4} then goto 110
if flicker = 5 && temp4{5} then goto 110
if flicker = 6 && temp4{6} then goto 110
if flicker = 7 && temp4{7} then goto 110

 

and here:

 


if temp4{0} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[0]: temp3 = temp3 + 1
if temp4{1} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[1]: temp3 = temp3 + 1
if temp4{2} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[2]: temp3 = temp3 + 1
if temp4{3} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[3]: temp3 = temp3 + 1
if temp4{4} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[4]: temp3 = temp3 + 1
if temp4{5} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[5]: temp3 = temp3 + 1
if temp4{6} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[6]: temp3 = temp3 + 1
if temp4{7} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[7]: blkcount = blkcount - 1

 

... if you know of a way for me to refer to a bit operation with a variable, such as:

 

if temp4{temp3} &&  temp2 >= colorodds[temp3]  then a[temp1] = blkc[temp3]: temp3 = temp3 + 1

 

Anyway, there are probably ways for me to improve my code, but I have as many weeks of programming experience as you can count on one bird-flip, so it's unlikely that I'm going to catch everything.

Link to comment
Share on other sites

That part where you are looping back to 105 seems to be the main thing eating up most of your time. If you put a REM before goto 105, run the program in Stella, then hit alt + L on your keyboard, you'll notice how it mostly stays at 262.

Link to comment
Share on other sites

105
rem increment flicker
flicker = flicker + 1 & 7

rem determines if a color is being used
if setbits[flicker] & temp4 then goto 110
goto 105

data screen_add
$02, $02, $07, $0F, $17, $1F, $27, $2A, $2A, $29, $25, $1C, $14, $0C, $05, $01
end

data block_bit
$80, $08, $01, $08, $10, $08, $01, $08, $80, $10, $01, $04, $08, $04, $01, $10
end

data setbits
$01, $02, $04, $08, $10, $20, $40, $80
end

110
rem cycle through pfpixels, turning them on if they are equal to the color being drawn
temp6 = base : temp4 = blkc[flicker]
for temp5 = 0 to 15
if a[temp6] = temp4 then temp2 = screen_add[temp5] : $A4[temp2] = $A4[temp2] | block_bit[temp5]
temp6 = temp6 + 1 & 15
next

rem set playfield to current color
COLUPF = temp4

Edited by bogax
  • Like 2
Link to comment
Share on other sites

Wow, thanks a lot! That works fantastically!

 

... I have to say I don't understand it, though. It's drawing pfpixels without referencing the pfpixel locations data set I made before and without even saying "pfpixel." How is that?

 

it writes it directly to memory instead of passing the info to the

pfpixels routine and having it do it (the screen is at $A4)

Link to comment
Share on other sites

If no one else is going to step up to the plate, then I can write the kernel. It wouldn't be tonight though. Once the kernel is done then you probably won't have to worry about setting the playfield pixels at all. The kernel would simply look at the color of the block, and if the color was black it wouldn't draw that block. In other words you could off-load all the pixel set up to the kernel, and simply deal with the colors.

 

 

The kernel would greatly simplify things. No flicker, and pixel perfect hardware collisions.

  • Like 4
Link to comment
Share on other sites

If no one else is going to step up to the plate, then I can write the kernel. It wouldn't be tonight though. Once the kernel is done then you probably won't have to worry about setting the playfield pixels at all. The kernel would simply look at the color of the block, and if the color was black it wouldn't draw that block. In other words you could off-load all the pixel set up to the kernel, and simply deal with the colors.

 

 

The kernel would greatly simplify things. No flicker, and pixel perfect hardware collisions.

Ahem...

 

Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you! Thank you!

 

My appreciation knows no bounds! No rush, but I'm massively curious, so if you do make progress, please do pop in and say a thing or two about how it's going. Again, thanks much! I was starting to panic that no one would be willing/able to do it.

Link to comment
Share on other sites

If you use the code below to clear the visible screen instead of pfclear, you should be able to safely use the hidden row of playfield variables (var44 = 0 : var45 = 0 : var46 = 0 : var47 = 0).

 

  rem  ****************************************************************
  rem  *
  rem  *  Clears the screen.
  rem  *
  rem  ````````````````````````````````````````````````````````````````
  rem  `
  playfield:
  ................................
  ................................
  ................................
  ................................
  ................................
  ................................
  ................................
  ................................
  ................................
  ................................
  ................................
end

  • Like 1
Link to comment
Share on other sites

 

 

it writes it directly to memory instead of passing the info to the

pfpixels routine and having it do it (the screen is at $A4)

Nice. Now just where is the location to do this in DPC+?

I know the display bank is copied to RAM, I just wish I knew how to manipulate it directly.

I'll keep on learning.

Link to comment
Share on other sites

If you use the code below to clear the visible screen instead of pfclear, you should be able to safely use the hidden row of playfield variables (var44 = 0 : var45 = 0 : var46 = 0 : var47 = 0).

Niiiice. I loves me some extra variables! These function just like any other but I guess the names are set at var 44/45/46/47?

Link to comment
Share on other sites

Niiiice. I loves me some extra variables! These function just like any other but I guess the names are set at var 44/45/46/47?

 

No you can use them to make aliases. Same for lifecolor, statusbarlength, and lives.

 

On a similar subject, I forgot to tell you that I added dim rand16 = lifecolor to the version of your program that I PMed you, so your random numbers would be more random:

 

  rem  ****************************************************************
  rem  ****************************************************************
  rem  *
  rem  *  VARIABLE ALIASES
  rem  *
  rem  ****************************************************************
  rem  `
  rem  `  (You can have more than one alias for each variable.)
  rem  `
  rem  ````````````````````````````````````````````````````````````````
  rem  `
  dim _Base = q
  dim _Block_Count = r
  dim _Level = s
  dim _Cool_Down = t
  dim _Anglevar = u
  dim _Pulse_Counter = v
  dim _Flicker = w
  dim _Offset = x
  dim _Ball_Color = y
  dim _Heart_Color = z
  dim rand16 = lifecolor

 

www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#rand

 

 

On a different subject, this isn't anything like your game, but when I saw your game, I was faintly reminded of the circular Space Invaders game called The Attack of the Green Smelly Aliens from Planet 27b/6 that I played on the Amiga in the early 1990s. I thought you might want to see it:

 

http://www.youtube.com/watch?v=Umz8ELy77Ug

Link to comment
Share on other sites

I don't see what makes them so smelly.

 

Neat, though! Yeah, I can certainly see why you'd think of it. And I'll add that rand16 in there--I know that I seemed to roll up the same direction multiple times quite often, it seemed.

 

I've attached the latest version (not that there have been a whole lot of changes--mostly just a few tweaks here and there with some additions and suggestions).

heartbreak.bas

heartbreak.bas.bin

Link to comment
Share on other sites

On a similar subject, I forgot to tell you that I added dim rand16 = lifecolor to the version of your program that I PMed you, so your random numbers would be more random

 

I was thinking something similar

here's a scatter plot previous value v current value for

a combined PRNG

http://postimage.org/image/xt2hiwf0p/

the LCG is seed * 17 + 103 iirc

 

The bB RNG is a 16 bit LFSR I believe (but not the one

used for the picture)

 

in bB it would be something like

myrnd = myrnd * 4 + myrnd +103
r = rand ^ myrnd

ie it wouldn't cost much and it looks (to me)

much more random.

Edited by bogax
Link to comment
Share on other sites

According to z26, the flicker resulting from that 272 scanline count really isn't so bad, though it may get worse (or better?)

 

 

You should really be using Stella. I would guess a good 95% of us do, for the awesome debugger, amongst other things. Aside from NUSIZx weirdness (like in Meltdown) I dare say Stella is by far the most accurate emulator out there for the 2600. Also you might want to check out its TV effects. ;)

 

 

The kernel is done, but work has to be done to integrate it. I took an older version of the game and hacked it in to test it. So you have to try and and break out an assembly kernel from BB kernel like RevEng did.

 

Some things to know:

 

- ORG statements are being used in the assembly kernel right now. They hard code an address for the compiler to put the assembly kernel in. You can change those if you want, or play around with ALIGN statements.

- "Unused" play field ram is being used for temporary ram in the assembly kernel.

- Register $FA is being used to even out the cycles in skipdraw. It should always remain with a value of 0. It will get trashed if you do a triple nested jump to subroutine though. Currently they subroutines seem to be only 2 deep, so that is okay. $FA is an illegal NOP opcode as well. I could potentially also use TSX as well, but it gets a little more messy as I'm using JSR's.

- At the end of the assembly kernel, I'm doing a hard-coded jump back into the bb kernel. I don't think this will shift, but you never know.

 

Here's the old rom I hacked into. The title screen doesn't show up because I hacked it to jump directly to the assembly kernel. Just press fire as normal and the assembly kernel will display. This is just meant as a demo. Remember it is an older version too. From what I've seen the assembly kernel should be compatible with the newer versions.

 

hb(demo).bin

 

Here's the assembly. Right now it's just over 2 pages by about 10 bytes or so. It probably could be made to fit 2 pages exactly, but I have to go out right now and it probably be good enough as is. You must add all the statements to include it in BB. I think that is "asm" or something. You might also need to include vcs.h if it can't find it. Anyhow see if you can get this going.

 

HeatASM.zip

Link to comment
Share on other sites

Thank you SO MUCH! That demo looks great!

 

This asm file is meant to be either included directly (as you say above) or chopped into pieces and added to batariBasic in asm statements, correct? It would be very helpful if it wasn't necessary to search for and replace/add to stuff on every new bB iteration.

 

What kind of set-up for the colors is necessary with the kernel? Since it doesn't use flickering, all those flicker statements should be removed, I assume, but then what would the structure of the color calls look like? Or does this assembly code replace that part?

 

Is there any risk of me accidentally using register $FA? Is it something that I'm liable to make be not equal to 0 or are you just informing me about that?

 

Also, can the scope of this kernel extend beyond the limits of Heartbreak in particular? What is its actual full potential and what all can be done with it?

 

EDIT: I have no experience with this and can't truly read assembly, though I sorta-kinda-maybe get the gist of what that new kernel is doing, kinda?

 

Anyway, since I don't know how a new kernel like this is supposed to join together with the existing stuff, I tried making a tweaked includes file and added this line to the start of heartbreak.bas:

 

  includesfile heartbreak.inc

 

The includes file is just the standard include with a mention of heartkern.asm thrown in there after all the standard kernels are loaded. That's apparently wrong, since heartbreak.bas won't compile through bB due to:

 

heartbreak.bas.asm (421): error: Unknown Mnemonic 'rtsstart'.

 

I hate to bother Omega with having to explain all this to a complete newbie, so if anyone else can clue me in as to how these puzzle pieces fit together, that'd be much appreciated. :)

 

Since I can't upload the .inc file type, this is what heartbreak.inc looks like:

 


;
; Inclues go below - order is crucial, since this is also the order in which
; they will appear in the generated assembly file
;


; header file
2600basicheader.asm


; standard kernel: two players, two missiles, a ball and an asymmetric playfield.
std_kernel.asm

; standard startup routine.
startup.asm


; below are collections of subroutines and functions
; if you have any more to add, put them immediately below this line.

pf_drawing.asm
pf_scrolling.asm
std_routines.asm
heartkern.asm

; The overscan routine goes below.  it sets up sprites for the std_kernel.
; if you have any routines that will not run until the overscan period,
; put them immediately below this line.
std_overscan.asm


; below is the generated batari Basic file

bB.asm


; score graphics.
score_graphics.asm

; below is the footer, which contains the score digits and startup vectors.
; If you want to create your own custom score digits, you may hack the file below,
; but first you should rename it to something else.

2600basicfooter.asm

heartbreak.bas

heartkern.asm

Link to comment
Share on other sites

Before I look at what you did... yes, the kernel is meant to inserted. In BB I think you use ASM, then put in the assembly code, and finally terminate it with END. Not 100% sure since I don't use BB, just going off memory here.

 

You don't have to do anything special to set up the colors. They have already been set up in certain locations in ram. As long as you don't change those ram locations it will work, and if you do change those locations you just update the locations assigned for what I called "colBlock1" to "colBlock16" in the file.

 

As a short explanation, you used some of BB's variables. BB variables have been mapped to certain locations in the RIOT ram by the BB kernel. If you start your game, and get to the playing screen, use the "~" key in the Stella emulator to open the debugger. Once there you will see where your colors are stored.

 

With the $FA, if you overwrite it you will know immediately. When you take a shot some garbage will show up on the screen. I'm just using it to even out cycles, but in reality we might not even have to even out the cycles. I haven't tested that to see. I wouldn't worry too much about it.

 

If you are having trouble compiling it could be a few reasons. Maybe try to put Processor 6502 and include vcs.h at the top of the assembly file. Also make sure you have a copy of vcs.h in the same folder as the assembly file or map the path. I'd just put a copy in the folder and see if it compiles with or without it there.

Edited by Omegamatrix
Link to comment
Share on other sites

Looking at the above includes in your post, I'm not sure that is the way to include this file. I haven't looked at what RevEng did. In the demo I made I put it before the score and after the BB kernel. You might try putting ORG $FD00 before the heartkernel.asm, and make sure it is after BB kernel. Then see if it will compile in. If it does it still won't work yet as we haven't told it to jump there when it is in the playing screen, and go to the regular BB kernel when it's the title screen.

Link to comment
Share on other sites

Well, instead of trying to include it with a .inc file, I tried just dropping it in asm ... end before everything else. It compiles with 94 bytes to spare on the ROM, which is great!

 

... Though nothing seems to happen. That may be because I... need to go back and delete out all the stuff about the flickering? From what you said, the kernel takes the color values directly from the memory addresses of the first sixteen variables, though keep in mind that those variables always have some value. If a block is dead, the color "2" is written to it. Why not black? Because there are black blocks in later levels and I needed a way to distinguish a black block from a dead block. That wasn't the case in the version you made the kernel for.

 

If it draws the pfpixels directly through the kernel without the aid of the color flicker code:

 


rem ==============
rem COLOR FLICKER
rem ==============

100

rem first, set levelcolor[level] into another variable for bitwise operations
temp4 = levelcolors[level]

105
rem increment flicker
flicker = flicker + 1 & 7

rem determines if a color is being used
if setbits[flicker] & temp4 then goto 110
goto 105

data screen_add
2, 2, 7, 15, 23, 31, 39, 42, 42, 41, 37, 28, 20, 12, 5, 1
end

data block_bit
128, 8, 1, 8, 16, 8, 1, 8, 128, 16, 1, 4, 8, 4, 1, 16
end 

data setbits
1, 2, 4, 8, 10, 32, 64, 128
end

110
rem cycle through pfpixels, turning them on if they are equal to the color being drawn
temp6 = base
for temp5 = 0 to 15
if a[temp6] = blkc[flicker] then temp2 = screen_add[temp5] : $A4[temp2] = $A4[temp2] | block_bit[temp5]
temp6 = temp6 + 1 & 15
next

rem set playfield to current color
COLUPF = blkc[flicker]

 

... Which I only partially understand since bogax's brilliant reworking, will it still be able to account for that kind of thing?

 

Currently, I just get a black screen, but I'm likely doing something wrong or maybe the COLOR FLICKER code needs to be removed in order to get it to all work together.

heartbreak.bas

Link to comment
Share on other sites

Changed the 2 to a 1. When you say

 

You have to jump into the routine with BB.

... Do you mean jump into the subroutine? Because the compiler doesn't recognize DrawKernel as a valid subroutine since it's not defined outside of the asm ... end code.

 

Gah, sorry for the annoyance of all the questions for simple stuff.

 

EDIT: Oh, wait... Just looked at this, which explains how this sort of thing is supposed to work.

 

From what I can tell, the .nameHere parts of Assembly are the actual subroutines, not the big DrawKernel: stuff, so I need to call one of those .nameHere parts.

 

So which subroutine is meant to be called to begin the whole draw process? I see one for .storeShot (do I need to call that when the ball is generated?) .storeblock 1-16 (which I assume I need to call for each of the blocks being generated?) and then things like .loopThreeBlocks and .loopTwoCloseBlocks, etc., which I'm not sure how they would be called correctly.

 

Also, I included the .asm file at the end of everything rather than the beginning, like so:

 


rem end loop
800 goto draw_loop

asm
include "heartkern.asm"
end

Link to comment
Share on other sites

Changed the 2 to a 1. When you say

 

[/font][/color]

... Do you mean jump into the subroutine? Because the compiler doesn't recognize DrawKernel as a valid subroutine since it's not defined outside of the asm ... end code.

 

Gah, sorry for the annoyance of all the questions for simple stuff.

 

Try putting a dot in front of it in the assembly kernel, and call it the same thing in BB. Also, you might be able to put it before the area where you include the assembly file, or even better just use a new label.

 

The way I set it up, you might to use a goto instead of a jump to subroutine. I'm going to get my haircut right now, and I won't be back for a few hours. So someone else might be able to help you in the meantime. Good luck, I want to see this working too! :)

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