Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

182 Excellent

About JeremiahK

  • Rank
  • Birthday 05/18/1996

Profile Information

  • Gender
  • Location
    Indiana, USA
  • Interests
    I was born in 1996, and played on my dad's Atari 2600 a bit as a kid. I enjoy making 3D graphics, running, working on my custom computer, and programming.
  • Currently Playing
  1. Excellent! Thank you stephana. I had thought it was some sort of bug in my code, because I think it had worked in an earlier version awhile back.
  2. Yes, INTIM is what you are looking for. It's not located in the zeropage, and none of the registers for setting the timer are either, so even after clearing the zeropage, it is still unknown.
  3. It's been a long time... This week is my vacation from work, my first since getting my job almost 18 months ago. I have been slowly working on this project when I have the chance, but I am going to be spending a lot of time on it this week. I didn't feel the need to post an update until now. I have finished the music engine for the game, as well as the intro music. I took a lot of time to make sure the tempo was correct, and it works in both 50Hz and 60Hz. Holding Game Reset on startup will force 50Hz mode, and the COLOR/BW switch selects the color palette. This will allow for both PAL50 and PAL60. (I cut the size to 4K for this demo, so if you press Game Select, it restarts. Stella doesn't seem to be auto-detecting PAL properly, but the timing works on a real system.) I only need minor tweaks from here, such as syncing the animation to the music. And allowing to mute the sound with the difficulty switches. The plan is to have the animated stars scrolling past until you press fire, which is when the game detects if you are using a joystick or paddle. Initially, the game title will be displayed above the cat, and after a game is played, score information will be displayed instead. Below the cat will be a scrolling menu, with 3 lines visible at a time. I have already finished the code for displaying the text, I just need to make it do what I want... 😎 nyancat.bin
  4. Posting this here in a new thread. I saw the topic of RAM management mentioned in another thread, but I didn't want to hijack it. Obviously there are many ways to skin a cat, to each their own. I wanted to share how I like to do it. I would love to hear how the rest of you do this, as well. For my projects, RAM typically falls into 1 of 3 categories, global, local, or temporary: Global RAM: Exactly what it sounds like. This is everything that needs to be accessible throughout the project. Your global frame counter should be here, current score, high score, etc. Local RAM: These are variables that are specific to a particular game mode, display kernel, menu, etc. They only need to be used in one area of code, and they can be recycled elsewhere. Temporary RAM: Technically, this shouldn't normally be needed. Each set of local variables should probably define their own temporary variables. But if you want to create subroutines that can be accessed from multiple areas, for example, a text display kernel, it may be best to define a space in RAM that is known to be available, regardless of the current local variables. The way I implement this is by defining each section of RAM in a separate file, for organization. First, I define all the global variables: filename: ram_global.asm RamGlobal ; start of global RAM Frame ds 1 Variation ds 1 Score ds 6 Rand16 ds 2 RamLocal ; start of local RAM Next, I define local variables in separate files: filename: ram_game.asm RORG RamLocal ; reset RAM position to local RAM SomePointer ds 2 PlayerColor ds 1 BallPosX ds 1 BallPosY ds 1 Temp ds 1 And I tie it all together in another file: filename: variables.asm SEG.U VARS ; create a segment of labels that isn't output into the binary RORG $80 include ram_global.asm include ram_menu.asm include ram_game.asm include ram_credits.asm include ram_temp.asm
  5. My thoughts exactly, would love to see what others are using
  6. Here is a slightly modified version of the routine, I was using an extra temp variable before. This version uses 32 bytes of RAM, the earlier one used 33. 8_char_routine.asm
  7. While planning my Nyan Cat game, I decided I wanted the main menu to allow up to 8 characters per line. This could easily be done with each word hard coded into the ROM, but I wanted to allow each character to be set on-the-fly. This takes less ROM when a lot of messages are needed, but it also allows this kernel to be used for 8-digit scores, if desired. I am considering remaking the score display for my game to utilize this. I have been working on this display for quite a while now, and I am glad to say it is finished! It uses 3 pre-shifted graphics tables for the font. I am using a font that is 7 pixels high, allowing 36 unique characters to fit in each page. This works perfectly for me, as I am using 10 numbers, plus 25 letters (letter-O is shared with zero), plus a space, but this could be adjusted as necessary. If this was only used as a score display, all 3 graphics tables would easily fit within a single page. The kernel and pre-kernel subroutines take up a total of 235 bytes. I split them into 2 separate routines so that I could more easily utilize them in different areas of my game, but there is no reason why they couldn't be combined. 32 bytes of RAM are used in this routine, 8 for pointers, 21 for graphics buffers, and 3 for temp variables. The graphics tables are all upside-down. Any bits not used are cleared. XXXXX___ Table #0 has the data shifted to the far left. XXX___XX Table #1 has the first 2 bits shifted to the far right, and the last 3 bits shifted to the far left (so it "wraps" around the end of the byte to the beginning). __XXXXX_ Table #2 has the data shifted almost all the way to the right. Edit: As-is, the code looks for a label FontGfx0, which would be Table #0. It assumes that Table #1 and #2 are in the following 2 pages. The way text is selected for the routine is by loading Y with the offset of the first of the 8 characters to display. You would set up a table as such: Table HEX ## ## ## ## ## ## ## ## HEX ## ## ## ## ## ## ## ## HEX ## ## ## ## ## ## ## ## The reason for this is that you can save some ROM by overlapping messages with each other. Edit: As-is, the code assumes this table is called FontText. Actually using these routines would look like this: sta WSYNC SLEEP 3 ldy #0 ; start with character #0 jsr CharLoad ; prepare for kernel jsr CharKernel ; draw kernel SLEEP 9 ; or change color, for example ldy #8 ; start with character #8 jsr CharLoad ; prepare for kernel jsr CharKernel ; draw kernel I have included both routines, as well as an example binary. 8_char_display.bin 8_char_routine.asm
  8. I believe that post was the original inspiration for me, then one day in the shower I figured out how to put it all together, haha. That would be interesting, although it would require a bit of ROM.
  9. Not that I know of, but I had wondered that as well. I know there was a color-test cart made that I thought simply rendered a typical test screen. After looking up the video, though, it looks a bit more complex than that. WARNING: Mute the sound!
  10. Thanks guys! I was hoping the game would be under 512 bytes, but it would have to be drastically stripped down. Doing simple things without RAM takes a lot more ROM... I would like to do a 128-byte RAM game someday. Probably as a 256-byte cart that does initialization, pushes the code to RAM, and jumps into it. The inspiration for the gameplay was taken from this video:
  11. You need to be some sort of masochist to code for the VCS, because the system is so limiting. One of its most well-known limitations is the mere 128 bytes of RAM on board. Programmers have spent ages seeing what is possible using these 1024 bits of information. So, I thought, why not limit myself to the extreme? I challenged myself to make a complete game using absolutely NONE of the on-board RAM. And I did it! It took a lot longer to actually finish than I had anticipated, but I have a fully-functional 2-player pong clone using none of the RAM, namely without addressing anything within $80-$FF or any of its mirrors, neither reading nor writing. This should work perfectly on a system with the RAM disabled or otherwise re-routed. Since I am not using RAM, I am only using the CPU registers for storing information. I can only use X and the stack pointer for storage, though, while A and Y take on more temporary roles. I used T1024T and INTIM to temporarily store data while swapping X with the SP, which is neccessary twice per frame. The SP normally holds the scores (both values from 0-10) encrypted into 7 bits, with the high bit controlling the vertical speed of the ball. The X register normally holds the vertical position of the ball (0-95), with the high bit controlling the vertical direction of the ball. X is also used to trigger "score mode", where a sound is played for about half a second before switching to "serve mode". These are simply special X values that cannot occur during a rally. The Interrupt flag is used to control the horizontal direction of the ball. Since there is no way to test the value of this flag, I am using the stack to push the CPU state to NUSIZ0. GRP0 is used for the score graphics, and since it never moves, I can use a simple collision detection against the playfield to determine what the Interrupt flag is. The ball's horizontal position is not stored, as it is moved with HMOVE. All other game mechanics are done with either checking the bounds of the data, or checking collisions between objects. If you disable different graphics objects, strange things will happen! In attract mode, the screen color cycles, and if you have the BW/COLOR switch set to COLOR, it keeps the color on game reset, otherwise it resets to black and white. This also just happens to fit within 1K of space. I could probably squeeze a few more bytes out to maybe add changeable paddle sizes using the difficulty switches, but I like it as it is. ramless_pong.bin ramless_pong.asm
  12. Exactly. Everything must be drawn at the same time, playfield, players, missiles, and ball. Some games like Asteroids drew all the asteroids on one frame, and the player on the next, only drawing one or the other. This causes flickering, which is not fun to look at, and should be avoided at all costs.
  13. Instead of using X for the line counter, you could store it in RAM. To decrement it, use DEC instead of DEX: LDA #96 STA $90 ; This is in RAM. It should be replaced with a label, so its less confusing. ; I havent seen your RAM variables, so this address might already be used somewhere else in your code. KernelLoop ; Preload Colors LDX $90 LDA Screen_1_BKColor-1,X LDY Screen_1_PFColor-1,X ; BK/PF Colors STA WSYNC STA COLUBK STY COLUPF ; Prepare X for playfield LDA $90 ; First, load A with the line counter (1-96) LSR ; This divides A by 2... TAX ; ...and then transfers the result to X (1-48) ; Draw Playfield LDA Screen_1_PF0-1,X STA PF0 LDA Screen_1_PF1-1,X STA PF1 LDA Screen_1_PF2-1,X STA PF2 ; Skip Lines STA WSYNC DEC $90 ; Decrement the line counter BNE KernelLoop RTS
  14. This will be my last post on here. If that is your final decision, I will respect it. But once again, I say that your idea is quite different than mine. The only reason why I referenced mine was because I thought it might help you to see how I coded my kernel, because it might give you ideas on how you would implement yours. This community doesn't play favorites. There aren't a lot of people writing code for 2600 games, so all projects are appreciated and encouraged. Regardless of what you decide to do, I wish you the best in your next endeavor! This forum is always open to you, and willing to help any issues you run into!
  • Create New...