Jump to content

ZackAttack

Members
  • Content Count

    785
  • Joined

  • Last visited

Everything posted by ZackAttack

  1. If only the internal A15 had been wired to the pin for A12.

    1. Keatah

      Keatah

      Maybe somebody could make a mod? Or an adapter to use a real 6502?

  2. Through some experimentation I confirmed that allowing the PC to go from $1FFF to $2000 will result in the address at $0000 being read. So it would seem that only 4KB of ROM space can be accessed before the 6507 is given a JMP $1000 instruction. So it looks like it's not possible to send a full frames worth of register updates without having a few JMP instructions sprinkled throughout. Is there some clever way to avoid having to issue a JMP instruction in order to keep the PC in the ROM address space?
  3. Here's the solution that I came up with. It uses collision detection with PF too, which as I already mentioned introduces some issues. Papa's solution would probably run a little faster because it doesn't use any gosubs. The downside to his solution is that it's harder to read and maintain, and it doesn't properly handle when you jump off a ledge and continue to hold the fire button. A nice enhancement to either solution would be to add a lookup table so the player slows at the peak of the jump and then gains speed again as he starts falling. rem Generated 6/12/2015 11:34:52 PM by Visual bB Version 1.0.0.548 rem ********************************** rem *<filename> * rem *<description> * rem *<author> * rem *<contact info> * rem *<license> * rem ********************************** ;alias variables a so it's easier to read the code ;It's best to alias them all in one place so you can keep track of which variable have been used already dim jumpState = a dim jumpHeightRemaining = b ;define constants for each state, again this will help readability const jumping = 0 const falling = 1 const standing = 2 ;How many pixels to jump vertically before you start falling const JumpHeight = 20 const JumpVelocity = 1 const FallVelocity = 1 ;initialize state machine to standing. jumpState = standing player0x = 50 player0y = 28 main2 COLUP0=28 COLUBK=02 playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ................................ ...........................XXXXX ......................XXXXXX.... ................XXXXXX.......... .........XXXXXXX................ XXXXXXXXX....................... ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end player0: %00011000 %00011000 end drawscreen ;TODO use var0-var43 to determine if player0 is adjacent to the playfield horizontally if joy0right then player0x = player0x + 1 if joy0left then player0x = player0x - 1 on jumpState gosub OnJump OnFall OnStand goto main2 OnJump ;Output condition logic player0y = player0y - JumpVelocity jumpHeightRemaining = jumpHeightRemaining - JumpVelocity ;Next state conditioning logic if !joy0fire || jumpHeightRemaining{7} then jumpState = falling return OnFall ;Next state conditioning logic ;TODO use var0-var43 to determine if player0 is adjacent to the playfield vertically if collision(player0,playfield) then jumpState = standing : return ;Output condition logic player0y = player0y + FallVelocity return OnStand ;Output condition logic ;Next state conditioning logic if joy0fire then gosub StartJump if !collision(player0,playfield) then jumpState = falling return StartJump jumpHeightRemaining = JumpHeight jumpState = jumping return
  4. This wouldn't compile for me. Perhaps the formatting got messed up because you forgot to enclose it in code tags?
  5. Don't forget that using collision detection is going to have some issues to work out. Like jumping under a platform and hitting your head on it. You don't want the player getting their head stuck to platforms. Post you bas file and I'll see if I can help you out later. Btw, there's a sub-forum dedicated to batari basic. You'll get more/better responses if you post basic questions there.
  6. It would be cool if vwBasic forces the programmer to name all their variables. It always annoyed me that bB gives you defaults of a-z. Everybody just uses them because it's easier and then the programs are harder to read than they should be. A proper if/then/else/endif implementation would be nice too. You should be able to construct an if statement without using goto.
  7. I'd create a state machine with the states jumping falling and onplatform. You can use on gosub to easily implement one. Google Finate State Machine (FSM) if you're not familiar with them.
  8. Forgot all about the FCC. Thanks for bringing that up and linking to one that's certified.
  9. I just stumbled upon the ESP8266 which is a small IC with wifi support that only costs about 5 bucks USD. I'm thinking it would be a good idea to plan for a wifi expansion to the C++ cart in the future. That could allow for network play, easier updates, and maybe even an app store for the 2600.
  10. You write better English than a lot of people I've dealt with here in the states. If I understand what this macro is for, you have created a rough equivalent of variable scope. Normal dasm variables are global and overlay variables can have local scopes which allow non-overlapping scopes to share the same location in memory. So assuming that's what you've done here. I think it would be good to have an example with at least 2 separate functions which rely on both global and local memory in order to demonstrate how the overlay would enhance that. Maybe a display algorithm and an AI algorithm for a very basic demo/game. I'm sure you'd have some meaningful labels and names at that point which would make things that much clearer.
  11. My guess would be that STA would cause bus contention on real hardware and possibly damage or crash the system. But, that's just a guess.
  12. This is a great idea. A lot better than my approach of adding the comment ";This is a bad idea..." I think you'll get a better adoption rate if the example were a little more practical though. It's not really clear what Level1 and "level 1a" are supposed to represent. If you had a small demo project that consumed overlay.h and used actual variable names to accomplish a small display task it would be a lot easier to understand the intended use of this. Thanks for releasing this to the public forum.
  13. Cool game idea. I would have never guessed that's what the random bit patterns you asked about were for. Since only the taller sections of walls can protect you it makes me wish I was able to duck when pressing down. Also, since it's a sniper shooting at you, it might be more appropriate to have a single head shot instead of a blanket of bullets. To make it more pronounced you could add blood to that animation. Might be neat to have just that one use of color.
  14. That's a neat idea. I think you'd still need multiple kernels in order to handle moving P0 independent of P1. Maybe that's why CAA has 3.
  15. With a little more effort I think it would be possible to have the P1 sprites (bees) travel across the screen in a sine wave pattern. The challenge there would be keeping the updates for the second copy in between the two copies. It would probably require a few different kernels to be switched as the sprites traveled across the screen.
  16. If you want to control the probability you could always bitwise and multiple rand values. The more you and together, the less chance a bit has of being set. Using rand is fairly expensive since it produces a subroutine call and performs some calculations each time. For extremely sparse outputs you could just randomly choose which bit to enable. Randomly choose a byte and then randomly choose a bit in that byte. Then you only have 2 rand calls to produce a 1/32nd probability of bits being set. The major drawback to this approach is that you lose some of the randomness feel. I've created a small test program that uses the first approach to randomly set the bits in the first 10 rows of the playfield. Up and Down on joystick 0 will change the sparseness between 4 different levels. The indicator on the bottom left shows which sparseness level is currently in use. The level wraps around in both directions. This should take up less CPU time and possibly less rom space than calling rand for each bit. sparse.bas sparse.bin sparse.lst
  17. Keep in mind that setting a variable to a random value is the same thing as setting each bit randomly. Also, realize that the behavior of the top row describes the behavior of a bit-wise AND. You should be able to do something like this for each byte in the rows. BottomRowByte = rand TopRowByte = rand & BottomRowByte
  18. I modified the fpga code a bit to try to reduce changes to the data bus output. To make it easy to experiment I wired up two groups of 8 switches to configure the delay before updating data out and how long to keep updating it once the delay expired. A few clocks of the 50MHz clock was enough delay to produce a significant reduction in noise. I tried to take a video to show the difference but my camera seems to amplify the little bit of noise that's left and it ends up looking the same. Based on these results I think I can ignore any remaining noise issues until I finish out the functionality and get the first pcb prototype. I think adjustments to the fpga code will allow for most of the signal issues to be resolved. Here's the latest vhdl code: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; ---------------------------------------- entity Light is port( CLOCK_50: in std_logic; SW: in std_logic_vector(17 downto 0); LEDR: out std_logic_vector (17 downto 0); LEDG: out std_logic_vector (7 downto 0); GPIO_0: inout std_logic_vector (28 downto 0); FL_WE_N: out std_logic; FL_CE_N: out std_logic; FL_OE_N: out std_logic; FL_RST_N: out std_logic; FL_DQ: in std_logic_vector(7 downto 0); FL_ADDR: out std_logic_vector(21 downto 0) ); end Light; ---------------------------------------- architecture behv1 of Light is signal prevAddr: std_logic_vector(12 downto 0); signal count: unsigned(7 downto 0); begin process(CLOCK_50) begin if(CLOCK_50'event and CLOCK_50 = '1') then --Enable reading from flash memory FL_WE_N <= '1'; FL_RST_N <= '1'; FL_OE_N <= '0'; FL_CE_N <= '0'; --Only using the lowest 4KB block of flash memory FL_ADDR(21 downto 12) <= "0000000000"; if GPIO_0(28) = '1' then --Fetch a byte from ROM and throw it on the data bus FL_ADDR(11 downto 0) <= GPIO_0(27 downto 16); if (prevAddr = GPIO_0(28 downto 16)) then count <= count + 1; else count <= x"00"; end if; if(count > unsigned(SW(7 downto 0)) and count < unsigned(SW(17 downto 10))) then GPIO_0(7 downto 0) <= FL_DQ; end if; else --Stuff in values on switches when PF1 is written to if GPIO_0(28 downto 16) = "0000000001110" then GPIO_0(7 downto 0) <= SW(7 downto 0); else --Disable data bus driver since this is outside of ROM address space GPIO_0(7 downto 0) <= "11111111"; end if; end if; --Snoop value of SWCHA and display it on green LEDs if GPIO_0(28 downto 16) = "0001010000000" then LEDG <= GPIO_0(15 downto ; end if; prevAddr <= GPIO_0(28 downto 16); end if; end process; end behv1; ------------------------------------------
  19. Adding the 1K resistors to the data bus helped a little, but it breaks bus-stuffing. Adding them to the address bus also helped a little. After staring at the TV for a while it occurred to me that the noise appears to be the worst on cpu cycles where the ROM address space is read from. I reviewed the VHDL code and believe the problem may be there. if GPIO_0(28) = '1' then --Fetch a byte from ROM and throw it on the data bus FL_ADDR(11 downto 0) <= GPIO_0(27 downto 16); GPIO_0(7 downto 0) <= FL_DQ; else --Disable data bus driver since this is outside of ROM address space GPIO_0(7 downto 0) <= "11111111"; end if; Anytime the CPU is in the ROM address space I'm sending the address to the flash memory on the dev board and sending back the flash memory data bus back to the Atari. I think I may be picking up some transient address values due to variance in the resistors that do the level translation. Since the fpga and flash memory operate much faster than the Atari it could potentially throw multiple values on the data bus in a very short period of time. If this is indeed what's causing the problem that would be great. Once the command management vhdl is done the fpga will know which address value comes next and only change its data output once the next address value is detected. I could also build in a small delay to prevent it from thrashing. Maybe I'll attempt to modify the existing fpga code to limit how often a new data output can occur so I can test the hypothesis sooner.
  20. lol, maybe next time only click post once It's amazing that websites still have this issue in 2015
  21. ZackAttack

    ORB

    Sure thing. I didn't post more details about the actual debugging because I didn't find a good way to leverage stella for this one. In the end I just reviewed the code and monitored the SP using the method I mentioned above.
  22. ZackAttack

    ORB

    Dividing the problem into many small sub-routines is a good thing. The problem here is that you have inadvertently created a recursive function. main->...->gameover->gameset->main->..keeps repeating. The best way to avoid this is at the architectural level. You can have a single main loop via a goto. Inside that main loop you can check a state variable and act accordingly. The the gameover routine would update the state variable instead of jumping straight to the new game itself. Since you've already written so much code and it would difficult to modify the overall architecture at this point, I have developed a simple work around that will allow you to reset the stack when gameset is called. This prevents the stack overflow and should resolve the weird issues you've been seeing. Simply add this assembly code to the beginning of the gameset routine: asm STX $FF LDX #$FF TXS LDX $FF end
  23. Thanks for tip about the resistors. After reading your post about the noise I watched the video again and noticed that the signal is only messed up for the portion of the frame where the 6502 is active. So it probably is related to switching noise. I'll try the extra resistors and post another video if it helps.
  24. ZackAttack

    ORB

    I think RT is correct about the gosub. If you look at the stack pointer register (SP) inside the debugger you will see that it decrements by 2 each game. Eventually the stack overflows into memory that is being used by the game/kernel and causes lots of bad stuff to happen. The symptoms are so varied because of the random way the memory is corrupted. You can test whether or not this issues has been resolved by simply watching the value of SP after the second game is started. If SP is decreasing by 2 each game the issue has not been resolved. If you provided the source code I would be happy to debug this issue and post the steps that I took so that it can serve as a learning experience for all of us. If you do not wish to share the source with everyone, you may send it to me via PM and I will limit my results to only showing the few lines of code that are relevant. Hit ~ to toggle between running mode and debug mode. Once in debug mode the value of SP is displayed on the top right. Here is a screenshot from stella showing how SP has been reduced to $F3 after several games were played. At this point I started to see some really interesting behavior.
  25. Yeah, I was wondering about what to do with SECAM. Maybe there's a variation in the hardware that can be detected. Regarding the menu, I'd only show it for pal since nstc can be correctly identified. It also seems like a good setting to save in the arm eeprom so you only have to choose once. That could probably be done with the encore too.
×
×
  • Create New...