Jump to content

ZackAttack

Members
  • Posts

    853
  • Joined

Everything posted by ZackAttack

  1. 95 is my best so far. The longer delays when the frog watches you really make for some nail-biting moments. I'm not even mad at him for eating me just before I broke into triple digits.
  2. Looks like the changes to the supercharger support in the standard firmware could be made in UCA pretty easily. I'll try to send you a new UCA build to test in the next week or so.
  3. I have some other work in progress that I want to complete before we release a new version. Unless you're seeing glitches/crashes there isn't much point in upgrading.
  4. Correct, currently it makes use of opcodes $84, $85, $86, and $87 It polls for the zero-page address that's being stuffed and puts the value on the bus right away. The value is stuffed until the next address is put on the address bus. Only 6 of 8 bits are stuffed. The other 2 are determined by which opcode is used and what the register values are.
  5. Has anyone considered how to handle the carts/games that do bus-stuffing yet? I think it would be possible to handle with a few extra ICs between the pi3 and the cart. When putting a new address on the bus, the data that may potentially be overridden by the cart is latched to an open collector buffer. Then read in the value from the cart just as you would from a ROM access. If no bus stuffing is taking place, you'll just read back the value you latched. Otherwise, the cart has free reign to pull additional bits low. If the pi3 was replaced with something that has a higher GPIO count, the data bus could be split so that 8 IOs are always outputting to the open collector and 8 IOs are always inputting the resulting bus value.
  6. Not difficult, but it shouldn't be necessary. The upgraders for firmwares only work for their own type. If you're on legacy/standard firmware v17 you can run v18 updater just fine, but you can't run any of the UCA updaters. If you're on a version of the UCA firmware you can run any of the UCS updaters, but you can't run any of the legacy/standard firmware updaters directly. To switch between the two types of firmware you should use the binaries I posted here. 17to2.3.14.bin is to convert any cart on v17 or higher of the standard/legacy firmware to UCA. UnifiedToLegacy17.ace is to convert any cart on UCA back to the standard/legacy firmware. After running either of those to switch which firmware you are using, you can then run the corresponding updates to get to the latest version.
  7. Would you be able to increase the capture rate and/or zoom in? I think you need to be on a scale of 50ns or less to really see what's going on. As far as writing the data bus too early. There is a required hold time where the data bus must remain valid for a short period after the address bus has already changed. If you're not holding for the required time, it would definitely cause problems.
  8. It's been so long, you probably just forgot about it. I got a little sidetracked with hardware development in my quest to make these ARM enhanced games publishable to carts, and then further sidetracked trying to make them support both 2600 and 7800. But thanks to recent collaborations there's been huge progress made and there should be some playable demos coming out later this year.
  9. Ironically, it's been the opposite for me. I tend to spend way more time than I should on the display kernels because this tech allows you to squeeze more out of the TIA. This is a huge understatement. I use Gopher 99% of the time and only bother testing on real hardware when I'm going to share a build with other pluscart users. How about compiling the game and emulator to webassembly and running it in web browsers? It might just be crazy enough to work.
  10. I think it could be helpful to test the timing of only polling for A12. Could you try the following and post the results? A logic analyzer on A12, D0, and A0-A5 would be ideal. If the logic analyzer shows the proper execution of the "lda ($b1),y" instructions, we can start adding in the remaining functionality one piece at a time. That will greatly simplify debugging because you can isolate each change and commit every time the test passes. #define A12_MASK 0x4000 #define MANGLE_DATA(data) ((data & 0b00011111) << 1 | (data & 0b11100000) << 3) static void Test() { // Be sure IRQ disabled __disable_irq(); // Preload data for Data Bus // Leave LDA ($b1),Y on the bus to create a nop-sled. Reset vector will be 0xb1b1 which provides some cycles to collect some timing data. // Eventually the PC will roll over and the Atari will crash. So logic analyzer and/or oscilliscope should trigger on the // First A12 rising edge after the Atari is powered on GPIOA->ODR = MANGLE_DATA(0xB1); // Bus Polling Loop while (1) { // Wait for A12 high while ((GPIOB->IDR & A12_MASK) == 0) ; // Drive Data Bus GPIOA->MODER = 0xa8150554; // 0b10101000000101010000010101010100; // Wait for A12 low while ((GPIOB->IDR & A12_MASK) != 0) ; // Release Data Bus GPIOA->MODER = 0xa0000000; // 0b10101000000000000000000000000000; } }
  11. I've done something similar with the Chameleon Cart. It's using a STM32G0. If you can point me to the code I could take a look and see if anything stands out. Embedding a 4k rom as a const uint8_t[4096] and a small while loop to service the bus should be all you need to get something running. Some things to check based on the pain of developing the Chameleon Cart: Disable IRQ. I've been burnt so many times by enabling them for something and forgetting to disable them again. Avoid initialization of large variables to keep boot time minimal. __attribute__((section(".noinit"))) static uint8_t playfieldBuffer[192*5]; It's fine to leave the 4k binary in flash memory. It's never been a problem for me. static const int8_t rom[4096]= {...}; The code that services the bus should be executed from RAM. The whole zerowaitstate flash gimmick works 99.9% and that .1% will crash ruin your day. Here's what I use when I want to do a quick check with 4K rom. __attribute__((long_call, section(".RamFunc"))) static void Emulate4K() { __disable_irq(); while (1) { if((GPIOB->IDR & 0x1000) != 0) // Assumes A0-A12 are wired to GPIOB0-12 respectively { GPIOA->MODER = DATA_OUT_MODER; // Masked with 0xfff to stay in 4kb array bounds. Can cast to int8/char if your hardware has better alignment GPIOA->ODR = ((int16_t)rom[GPIOB->IDR & 0xfff]) << 6; // Shift value depends on which GPIO pins are wired to data bus } else { GPIOA->MODER = DATA_IN_MODER; } } } Be aware that having the SWDIO/CLK pins on the same GPIO port as your Address Bus inputs can be problematic if you don't mask them away.
  12. Each track (ttt file) will have its own instruments and percussion. They can and should use both channels, but the second channel will be overridden with sound effects as needed.
  13. Yes, to swap in a new ttt file you would need to place a copy of the new ttt file in the assets/sound/ folder and replace 'glafouk - Miniblast.ttt' in source/parse_assets.py with the new file name. Then you should be able to run make to build it with the new music. That would be great. There's support for multiple ttt files in the same project, so all contributions are welcome and appreciated!
  14. @8bitPoet and I have been collaborating on a new game called Mattress Monkeys and could use some help with the background music. We only have a few remaining tasks before we can release a playable demo and would really like to have some original music to go with it. The audio engine is TIA Tracker based and there is a huge amount of storage space for audio data. Please let me know if you'd like to help out. Thanks! Perks include: Access to the latest build of the game Inclusion in credits screen A copy of the finished game cart Forum Topic: Fluid simulation for new 2600 game concept - Atari 2600 Programming - AtariAge Forums Code Repo: mattress-monkeys-2600 Recent Screen Shot:
  15. I assume you'd want a couple assembled PCBs in hand before you'd attempt this. Would it make sense to design the PCB to be as small as possible and fit inside a standard cart? But try to position the ports close to the top and side so there's the possibility of creating a 3d printable shell which exposes the ports? The only downside to this would be the 3d shell having a non standard shape and size. Maybe that would just make it more interesting.
  16. I quoted the front and back with https://craftcloud3d.com/ for FDM ABS with the cheapest options it works out to about $4/cart plus $20 shipping. So, buying at least 20 at a time should work out to around $5 a cart. I assume they won't be as pretty as the injection molded shells. I think it's worth it to have the ports exposed though. jlcpcb has a 3d printing service too. They quote about $5 each plus $20 shipping. But that's for SLA resin with sanded finish and it may be possible to combine shipping if the assembled PCBs are included in the order. If we have a design with only the front and back halves it might be viable.
  17. Does anyone know approximately how much a 3d printed cart costs per unit? If it's comparable to the injection molded ones, wouldn't it be easier to go that route and let the USB, SD, and Reset button all be accessible? It's just a matter of setting a few pointers in the firmware. No problem at all. ACE and ELF based games should be using those pointers and will work without any modification to the game rom itself. Sounds like it might be best to always power the board from the Atari card edge connector. It requires less routing and prevents user error from potentially breaking something. Assuming they all have Wifi equipped, the USB connection wouldn't be that useful. Everything we could do with USB could be done wirelessly via WiFi. Will it really be idiot-proof though? Won't they just leave the USB cable connected and then wonder why the cart isn't working still? Using a microswitch would have the benefit of automatically reverting back to normal boot as soon as they release the button. I don't think either approach is more right or wrong than the other. You should choose whichever you like better. Yeah, surface mount for sure. It will be nice to have a design that's easy to order fully assembled. The ESP-WROOM and family have flexible I/O, but there are some pins that are better suited for SPI than others. Also, some I/O is already in use by the module because it has external SPI flash built in. Something to keep in mind. Agreed. For the higher pin count parts, I prefer surface mounted because you can do many pins at the same time.
  18. Won't that require destroying the label to get to the ports inside the cartridge? Would it be better to keep the hole, but place the ports on the edge of the cartridge and modify the cartridge to add the necessary holes for the ports?
  19. All your notes are super helpful. I'm looking forward to seeing where you take this. Assuming the GPIO assignments are compatible with everything we want to include I see no reason not to go with such an approach. Yes, that's what we were discussing before. I have concerns that extra traces could interfere with bus-stuffing. There's no need to retain compatibility with the older UnoCart firmware. UCA is the one that will be getting all the new features. It really doesn't matter which GPIO are used for 6507 Address and Data bus connections. The only requirements are: Data bus is byte aligned Address bus is uint16 aligned GPIO 13-15 of the address bus are either grounded or NC. We don't want the performance hit of masking the address values. I second this. The need to have USB and SD ports already makes the PCB incompatible with an original, unmodified cart shell. If this were a stand-alone cart for publishing games, it would be a different story. Agreed. .1 inch pin header would be ideal. (right angle for clearance) I vote for including nRST. In theory it can help with programming if you accidentally change the SWDIO/SWCLK pins to GPIO or alt functions. It would also be handy for communicating directly with the ESP32. I do think it would be good to have a power pin for the initial firmware programming. Though, in my designs I've always brought 5V to the connector because I didn't think it would be good to connect a 3v3 power source to the output of the VREG. Perhaps 3v3 should be replaced with 5V? Pin jumper or micro switch would be fine. BOOT0 would only be used for initial firmware flashing and unbrinking. I think a micro switch that's accessible via a paper clip sized hole would be the most professional looking option. Wouldn't it be needed for USB-OTG? I'm not that familiar with USB-OTG either. It seems like we would need to have the ability to switch power to the USB VBUS from the MCU. Maybe there's an application note for this? This all sounds good to me. USB-OTG is certainly the lowest priority of everything we've discussed. If it's a lot of effort, we can do without. This could be solved in software. We could have a region override file in the root of the SD or something if this ever becomes an issue. I think the application note would be the best authority on this. This would be a good reason to use the larger SMD components. We may need to hand solder new resistors onto the first prototypes if we find they are out of spec. Chameleon cart uses W25Q128JVSIQ, plain vanilla 8-pin SPI flash that's cheap and easy to obtain. I think a separate SPI would be preferable. I think it would be possible to restrict the design to only SMD components. The ESP-01S could easily be replaced with an ESP32-WROOM or similar. The pin header can be placed over a cart edge connector, making the pin header optional. Another benefit of switching to the ESP32 is that we could add an SPI connection to it as well. My rough estimate is that a buad rate of 15MBit would be necessary to feed the Maria DMA in 7800 mode. If the ESP32 has a dedicated SPI connection it would easily hit that baud rate. Then we could put micropython on it and use the STM32 as a level converter for the ESP32. Being able to write Atari 2600/7800 games in python would be pretty cool.
  20. Directly from ST: The STM32F405xx and STM32F407xx family is based on the high-performance Arm® Cortex®-M4 32-bit RISC core operating at a frequency of up to 168 MHz. The Cortex-M4 core features a Floating point unit (FPU) single precision which supports all Arm single-precision data-processing instructions and data types. It also implements a full set of DSP instructions and a memory protection unit (MPU) which enhances application security. That said, I have been targeting arm-v6 in all my projects because that leaves the option of using the stm32g0 when publishing individual games. I'm hoping the esp-01s can be used as a sort of GPU/co-processor eventually. Great!
  21. I wasn't aware such a cart existed. If you need a quick fix you could just switch them back to internal for now. We can cross the HSE bridge later when USB is brought into the mix.
  22. Here's my best attempt to answer all your questions. Hope this helps. The WIP in the UCA github repo doesn't have an external oscillator and will need to have it added in order for USB to work properly. I designed a standalone cart that's intended to be used for publishing games that are based on the new elf format and other modern schemes. This cart includes a 16MB SPI flash. Since the cost difference is insignificant, I think it would be wise to include it in the multi-cart. In theory we could use the SD card to emulate the SPI flash, but that would require much more effort than adding it to the PCB. Exactly. Capacitor placement. Trace widths and spacing. Should you decide to take on this project, I would be happy to look everything over before do a run of boards. My preference is to keep the USB connector. Having the ability to unbrick without an st-link is nice for less tech savvy users. There's also the possibility of using USB-OTG in the future. Yes. 5V tolerance is mandatory. Also, be careful when checking for 5V tolerance. Most STM32 chips have a mix of tolerances and which pins are 5V tolerant can change depending on the pin count. The Chameleon cart uses weird pin assignments because some of the GPIOA pins are only rated for 3.3v when using the higher pin count parts. This was tested and the result was a 192MHz minimum for /Public ROMs/PlusROMs/sokoboo Plus.bin and 144MHz minimum for /Public ROMs/PlusROMs/C.A.V.E. Apocalypse/C.A.V.E. Apocalypse NTSC.bin Currently the latest version of the UCA firmware has the stm32f407 clocked at 216MHz. I believe there are some ACE files created by @MarcoJ that make use of the FPU in the M4F. jlcpcb has had these in stock every time I've ever checked. They also have a parts bin feature which lets you purchase parts ahead of time so you can be sure you'll have the parts you need in the future. I think the supply issue is more relevant to the discovery boards used in the DIY builds.
  23. I just created a PR to add the WIP to Al-Nafuur/United-Carts-of-Atari (github.com) so it's available for anyone to work on. I had planned on working this once the basic 7800 support is finished, but if someone else wants to work on the PCB before then that would be great. It still needs the external crystal oscillator, SPI flash, and other refinements to bring it in line with the ST hardware design guidelines.
  24. Yeah, that's why I combined them. That way the game code never puts itself in a position where it can get the two out of sync. However, I could add set_input_type() and get_last_input() functions and implement them so they don't directly interface with the 6507. No, it's a valid point. I was thinking it would be useful to prefix everything in a way that it makes auto-completion work well. blit_pf_into_asym_pf() is more readable. If we assume each kernel will reside in its own header/source files, then it should be easy enough to find the available functions for a specific kernel. It's probably better to favor more readable names.
  25. I am building a stackable kernel framework that will make it easier to take advantage of the new elf file support in the UCA based carts. The idea is to have a json file that specifies how to parse all the asset files. Each asset can specify 2600 and 7800 variations. A python script will parse the json file, then parse the png files and generate all the asset code for you. Then you simply pass the asset id to the various display kernel functions. Each game can have one or more frames. Each frame can be composed of one or more display kernels. Frames and kernels would be created once at the start. Each kernel will have a set of functions that can be used to change its appearance. For example, you can call a function to change the text displayed by the text kernel. The kernels would stack vertically to produce a full 192+ lines of visible screen. Here is some pseudocode to demonstrate what it would look like. Is this easy enough to read and understand? Is this a good approach? game() { // puts atari in known state and configures display kernels for the current system type (2600,7800, NTSC, PAL) init_display_kernels(); // Set the type of controller we want to use set_controller_type(controller_type_joystick); // make some display kernels char36 status_line = create_char36(lines, color_blue, color_white); asym_pf play_area = create_asym_pf(height, color_wall, color_black, color_monkey, color_banana); asym_pf_blit_p0(play_area, asset_tree, 0, x, y); // Set this now since it doesn't change // make a frame composed of the display kernels display_kernel frame_lv1[2] = { status_line, play_area }; // define some variables for our game to use input_joystick joystick_state; int p0_score = 0; int p1_score = 0; char score[5]; while (1) { // *** Update display kernels based on game state *** // Update the text that char36 will display for both player scores int_to_str(p0_score, score, 5); char36_write(status_line, 0, 0, 5, score); int_to_str(p1_score, score, 5); char36_write(status_line, 31, 0, 5, score); // Move and animate sprites asym_pf_blit_pf(play_area, asset_clouds, frame_index, x, y); asym_pf_blit_p1(play_area, asset_monkey_jumping, frame_index, x, y); // *** Feed instructions and/or DMA data to Atari during visible screen *** // Draw a single frame and capture user input draw_frame(frame_lv1); // *** Update game state based on user inputs and previous state // Handle user input move_player(prev_joy0, joy0, p0); move_player(prev_joy1, joy1, p1); // Time based stuff if ((frame_count & 0xf) == 0) { frame_index++; } } } Edit: 2023-01-25 Incorporated some of the changes suggested by @splendidnut
×
×
  • Create New...