-
Posts
65 -
Joined
-
Last visited
Content Type
Profiles
Forums
Blogs
Gallery
Events
Store
Community Map
Posts posted by JeffJetton
-
-
I had a quick question about DASM just now and Googled up the documentation.
Holy moly! What a huge difference! The current documentation is AMAZING, especially compared to the charmingly scruffy, but not-so-up-to-date, text file of yore.
Kudos to whomever has been doing what must be quite a bit of work. (Andrew, maybe?)
-
1
-
-
On 6/26/2020 at 10:03 AM, Karl G said:
I also like the green background version, but I think they both work just fine. Just go with what appeals to you best. ?
Another vote for green. Maybe gray if you want to give a B&W choice.
But having playing cards on a black background just seems... idiomatically incorrect for a VCS game. (Didn't Atari have a policy against black backgrounds for anything that wasn't a space game?)
-
I'm going to suggest something a lot simpler for your shuffle routine: Don't shuffle the cards in the first place. ?
Just start out with all the possible card values in a block of memory somewhere, in whatever order you want to generate them. Maintain a pointer that refers, at any given moment, to one of the cards. Every frame, increment (or decrement) that pointer. When it gets to the top (or bottom), bump it down (or up) to wherever the other end currently is*. So it's as if the game is constantly cycling through every remaining card, one after the other, all the time.
When the player starts the game with that first "fire", they get whatever card the pointer is currently pointing at. Remove that card from the "deck" and then remove the "memory hole" by copying values above it down one byte (or below it up one byte). Adjust references to the end of your memory block accordingly, or you could use a terminator value, such as zero, to signal the end (or beginning) of the block.
When they place that card with the fire button, you then "deal" then next card that's at whatever position the constantly-cycling pointer is at that point. There's no way a human can possibly time where the pointer is, so it is essentially random. Repeat the process of shifting memory to remove the "hole", waiting for the next "fire" to figure out what the next card is, etc.
This will appear, for all intents and purposes, as if you are dealing from the top of a randomly-shuffled deck. But really it's more like you're dealing a card from a randomly-selected place in an unshuffled deck each time, with the "randomness" supplied by the human player's own timing. The effect should be the same either way.
I did something similar on an Apple 1 game I wrote recently, although with dice roll outcomes rather than cards (and without needing to remove values each time like you will). It's also 6502 assembly, so feel free to take a look: https://github.com/JeffJetton/apple1-shut-the-box
* You might want to keep careful track of how many cycles the loop back to the bottom (or top) of the memory block takes when you reach the end, and then make sure that you take up the same number of cycles when you don't reach the end and instead just do the increment or decrement. This could be done by putting in one or more nop instructions or something like that. Otherwise, the card at the top (or bottom) will be slightly more likely to be dealt out, since the pointer will "linger" there slightly longer than on all the other cards.
-
On 2/11/2020 at 2:06 PM, SpiceWare said:
2) Sure, that's what Video Chess does when the computer makes its move.
And, as an aside, some computers like the ZX80 and (when in "fast" mode) the ZX81 would routinely drop the video signal logic when it came time for any sort of intensive calculations.
The Gigatron, a contemporary 8-bit computer without a microprocessor, finds a nice compromise by displaying black for a user-selected, alternating portion of the scan lines, depending on whether you want a slow program with a nice picture, or a faster program with a dimmer, striped/striated picture. Sort of similar to the "Venetian Blinds" trick used in Video Chess. Although Bob Whitehead used it there in order to display more objects, rather than to give the processor more time to think about game logic. (I don't think any carts ever used something like that to simply to provide more time for program logic, Gigatron-style, did they?)
Another option is to simply reduce the number of scanlines used for the visual part of the game, rather than get rid of them all together. That would give you more time in the overscan and/or vertical blank for "thinking", at the expense of a more "letterbox" image. Didn't a lot of carts use that trick?
-
Trying my code on Lillapojkenpåön's 88-row example yields the following. Hope it's correct! ?
0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0 0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0 0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0 0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0 0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0 0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,0,0 224,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0 0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0 0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,130,0,0 0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128 0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0 0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0 0,0,0,132,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0 0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0 0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0 0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0 132,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0 0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0 0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0 0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0 0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,128
-
On 3/6/2020 at 10:30 AM, carlsson said:
I made a small script in PHP which appears to do the job. It should be dynamic so it takes any amount of rows, but better test run it a couple of times. Before anyone says "UGGH! PHP!?!", go ahead and convert it to your preferred programming language.
Not that anyone asked, but... here's a stab at the problem using Python:
# Assumes each row has same number of columns INFILE = 'my_cool_level.txt' OUTFILE = 'leveldata.txt' BYTES_PER_OUTPUT_ROW = 64 EMPTY = '.' BYTE_SEPARATOR = ',' # Read in data, chopping off any newlines indata = [] with open(INFILE) as infile: for row in infile: indata.append(row.rstrip('\n')) # Build a list of output bytes outdata = [] for i in range(len(indata[0])): column = [] for j in range(len(indata)): if indata[j][i] == EMPTY: column.append('0') else: column.append('1') while len(column) > 0: if len(column) >= 8: byte = column[0:8] column = column[8:] else: byte = column + ['0'] * (8 - len(column)) column = [] byte = byte[::-1] byte = ''.join(byte) outdata.append(int(byte, 2)) # Write out the bytes with open(OUTFILE, 'w') as outfile: byte_counter = 0 for byte in outdata: outfile.write(str(byte)) byte_counter += 1 if byte_counter == BYTES_PER_OUTPUT_ROW: outfile.write('\n') byte_counter = 0 else: outfile.write(BYTE_SEPARATOR) print('Done!')
-
3
-
-
Depends on the game. As DirtyHairy points out above, not all games store/track the entire game state in RAM. So looking at the RAM will not give you all the important information. (I think Combat might be one of those games... maybe some of Video Olympics too?)
That is probably completely unlike just about every other computer system you might be familiar with. It certainly is for me.
It's sort of a holdover from the old days of video arcade games, which did not use a microprocessor and had no RAM in the traditional sense. Game state was stored all over the place, in a variety of counters, shift registers, various flip flops, and other hardware components. The Atari 2600 wound up being a bit of a hybrid machine, with the TIA chip (essentially a single-chip version of one of those old-school, discrete-component circuit boards) handling a lot of things all by itself, and the 6507 microprocessor being more of a coworker than a boss.
-
On 2/10/2020 at 4:22 PM, Andrew Davie said:
That is, the stack is living at the very top of zero-page memory. It MUST be in zero page on the Atari 2600 (hardwired), though on other machines it lives in other places.
As an aside, I've been digging into the memory map lately and found it interesting that, internally, the 6507 is actually "looking" for the stack in page one (from $01FF down to $0100). That's baked into the design of the 6502 (and therefore the 6507 too) and cannot be changed.
However address line A8 is not hooked up to the RIOT chip. So any attempt by the 6507 to read or write to anything in page one will have exactly the same effect as reading and writing to page zero (and the other way around). For example, when the 6507 tries to push a value onto the stack at $01FF (binary 0000 0001 1111 1111) the RIOT sees it as being no different from pushing it onto $00FF (binary 0000 0000 1111 1111), since the underlined bit is irrelevant.
Lines A10 and A11 are ignored by the RIOT in the same way, incidentally. So the 6507 could also access that same stack location at $0DFF (binary 0000 1101 1111 1111) or $08FF (binary 0000 1000 1111 1111), and so on.
And, of course, lines A13-A15 don't even come out of the chip in the first place, although the 6507 doesn't "know" that. So that same byte will also be accessible at, for example, $E5FF (binary 1110 0101 1111 1111), etc. That's 6 out of 16 bits that flat-out don't matter when you're accessing RIOT RAM!
-
On 1/18/2020 at 3:17 PM, JetSetIlly said:
I've been working a Atari 2600 emulator for the last year or so and thought AtariAge would like to see what I've been up to. I originally started it as a fun way to learn the Go language
Using "Go" to write an "Atari" emulator? How appropriate! ?
-
2
-
-
Oh, just saw that you're putting in issues. Thanks, Andrew! I'll work on making those tweaks. I really appreciate it!
-
Thanks! Yeah, sorry. That's supposed to link to the "documentation" for the code, which doesn't exist yet. ?
-
Hey MantaNZ, you might want to check out my beginning Atari programming notes that I've been (slowly) putting together. Actually, I'd really appreciate your feedback--I could use some guinea pigs!
https://github.com/JeffJetton/atari-examples
Still very much work-in-progress. I'm rethinking some of the later stuff, but I think the first section is pretty solid.
It's coming from the same angle as your C beginner's course idea. It's at the super-noob level* and explains a lot of the things that puzzled me early on but seem to get glossed over in a lot of other tutorials. It goes very slowly. (I'm certainly not an Atari assembly programming master myself, which I think actually helps!)
* Well, it does relate some things to higher-level programming concepts, and I don't really explain how binary and hex number systems work. But other than that, it's pretty noob-friendly!
-
2
-
-
Awesome! Congrats and good luck!
-
1
-
-
Awesome. Starred it! ⭐
-
On 11/23/2019 at 8:38 PM, Grant said:
It works! Using Windows 10 with dasm 2.20-11 and z26_407.
-The include file needs the path from dasm to the atari header files. Currently that is #include "Atari-2600\vcs.h" (for example).
Thank you so much.
-Grant
Other options include A) adding an incdir instruction before your includes to specify the directory all your include files are in, or B) specifying the include directory at compile-time using the -I option.
But yeah, it's probably easier to just copy the files over. They're small. ? -
On 11/13/2019 at 3:12 PM, DEBRO said:
Looking at his other work, I've come to Homerun and Boxing. Both of these store the sprites separated by n-number of bytes. As an example he would start the number fonts with the top of the zero sprite. Then the next byte would be the top of the one sprite. The next would would be the top of the two sprite...and so on.
Wait... so the sprite data is all interleaved together? Seems needlessly complicated... Is there any advantage to doing it that way?
I guess the offset of a number's sprite (from the beginning of the sprite data) would actually equal that very number, which might possibly be useful. Any other good reason for it?
-
Okay, I'm not actually writing an Atari 2600 program in Python as much as using Python to build a binary file of machine code instructions from hardcoded hex values.
Nothing really revolutionary about it, but I saw Ben Eater do something similar in a video (he flashed an EEPROM with a Python-created file of 6502 code) and thought it might be fun to do the same sort of thing. Reminded me a bit of when I was a kid and would try to write machine code on my Timex-Sinclair 1000 by POKEing bytes into memory using BASIC. ?
Here it is: https://github.com/JeffJetton/cart-maker
- Jeff
-
-
It's been a looooong wait, but part II is finally up! ?
In this one, he hooks the 6502 up to an EEPROM so it can actually execute a real sequence of instructions, and later adds another chip (a cousin of the Atari's RIOT, in turns out) to latch output data:
https://www.youtube.com/watch?v=yl8vPW5hydQ
I find this stuff really interesting, and it's giving me more insight on how the 2600 works.
-
Some of you might be familiar with Ben Eater. He famously posted a series of videos in which he built a basic, 8-bit computer from scratch using TTL components on a bunch of breadboards, clearly explaining the reasoning behind every step. (And when I say "from scratch", I mean he cobbled together the clock, the registers, the ALU... the whole shebang!)
Well now he's building a 6502-based computer. Not quite as far down to the bare metal as the previous project, I'd imagine, since he's using a microprocessor chip this time. But I suspect we'll wind up with more useful device when it's all done.
The first video in the series came out a few days ago, and it's fantastic:
(Most of us here will be able to guess why he used $EA for his data input value before he reveals the answer, of course. ? )
-
4
-
-
3 hours ago, easmith said:
The question is does this now also affect the frame 2 score which depends on frame 3 ??? If no, then my current scoring algorithm should work, if yes, then I am stuck .
I think the answer is that it does not , but not sure ....
I believe it does not also.
A strike gives you ten points, plus the score of your next two balls. It has nothing to do with the score in the next frame, per se.
https://slocums.homestead.com/gamescore.html
And yeah, I guess you would need to use some sort of array. Put a special "placeholder" in a location for strikes and spares. After each ball, scan for placeholders and update any that you now have enough throws to calculate a value for.
I was thinking you could use the stack, but that's a LIFO data structure, and bowling score placeholders are FIFO. ?
Disclaimer: I am not much of a bowler. And the last time I bowled, it was candlepin bowling, which is a whole 'nother kettle of fish...
-
11 hours ago, Swami said:
"The Atari Type Video Game System"?? ????
weird but cool.
Yeah, it's like something aliens would say while trying to pass themselves off as human:
Disguised Alien: "Hello! Would you like to join me, a perfectly normal human person, in competitive pursuits on the electronic display screen?"
Skeptical Invitee: "Uh, like, video games? Yeah, I guess. What sort of console do you have?"
Disguised Alien (beginning to panic): "It is... a... uh... Atari type video system!"
-
1 hour ago, AlexBel said:
I decided to assemble it myself
Wow! That's very cool. I hope you'll post about your progress on the forum as you go.
-
20 hours ago, nooob said:
thanks i guess i'll dig my spudger out!
Hey, this is a family-friendly forum. Let's keep it clean!
-
2
-


DASM - New home and new releases!
in Atari 2600 Programming
Posted
Yup. ? Just needed a refresher on which format number meant what.