+SpiceWare Posted April 4, 2015 Share Posted April 4, 2015 (edited) For the past couple of months I've been blogging an Advanced Atari 2600 series on DPC+ ARM Development. It goes over how to utilize the ability of DPC+1 to offload processing to the ARM chip found in the Harmony and Melody cartridges. This allows for the creation of more advanced games such as Space Rocks and Stay Frosty 2. With the most recent entry, which is the first2 to have code to produce a valid3 2600 program, I've decided to end each post with a new bit called Task for you. The blog comments don't allow for the attachment of files, so I decided to start this companion topic for the series. It's intended to be used as a place for y'all to upload what you did (source, bin, and screenshot if the change is visual). Some of what's uploaded here will feed back into the series as it progresses. TIP: Make sure to mention which Part of the series your upload is for. 1 By DPC+ I mean the enhanced version of David Crane's DPC coprocessor used in Pitfall II, not the batari Basic DPC+ Kernel option which utilizes DPC+. 2 The prior entries cover things like setting up the C compiler that generates the ARM code. 3 While it doesn't do much, it does generate a valid 262 scanline NTSC/PAL60 display that changes in reaction to the joystick. Edited April 4, 2015 by SpiceWare Quote Link to comment Share on other sites More sharing options...
Joe Musashi Posted April 4, 2015 Share Posted April 4, 2015 Great idea with the DPC+ ARM Development series!!! I'm looking forward for part 8. Actually, why not write the entries here in the Programming forums like the "Porgamming for Newbies" workshop? I haven't solved the task from part 7 as my current project only supports one player . But I made me some defines to make the source a bit more (human) readable. // SWCHA bits #define P0_RIGHT 0x80 #define P0_LEFT 0x40 #define P0_DOWN 0x20 #define P0_UP 0x10 // INPT4 bits #define P0_BUTTON 0x80 #define JOY0_LEFT_PRESSED (!(SWCHA & P0_LEFT) ) #define JOY0_LEFT_RELEASED ( SWCHA & P0_LEFT ) #define JOY0_RIGHT_PRESSED (!(SWCHA & P0_RIGHT) ) #define JOY0_RIGHT_RELEASED ( SWCHA & P0_RIGHT ) #define JOY0_UP_PRESSED (!(SWCHA & P0_UP) ) #define JOY0_UP_RELEASED ( SWCHA & P0_UP ) #define JOY0_DOWN_PRESSED (!(SWCHA & P0_DOWN) ) #define JOY0_DOWN_RELEASED ( SWCHA & P0_DOWN ) #define JOY0_BUTTON_PRESSED (!(INPT4 & P0_BUTTON)) #define JOY0_BUTTON_RELEASED ( INPT4 & P0_BUTTON ) 1 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 4, 2015 Author Share Posted April 4, 2015 Thanks! A few reasons, though mostly because all of my other technical series have been done in my blog. I'd only recently decided to make this series more interactive by wrapping up each post with a Task for you, so up until then the inability to add comment attachments wasn't an issue. Part 8's almost done, might even be posted tonight if I get my taxes done early enough. The outline (section headers with a few notes on what to cover) for part 9's also done, and its task will build upon the one in part 8. The results of those tasks will feed back into parts 10 and beyond. Nice defines! I tend to put player processing in a loop like this, so would need to use a variation of them: int joystick; int fire; int player; joystick = SWCHA; fire = INPT4; for (player = 0; player < 2; player++) { if (!(joystick & 0x80)) SpriteX[player]++; if (!(joystick & 0x40)) SpriteX[player]--; if (!(joystick & 0x20)) SpriteY[player]++; if (!(joystick & 0x10)) SpriteY[player]--; if (!(fire & 0x80)) ShootMissile(player); joystick <<=4; fire = INPT5; } Quote Link to comment Share on other sites More sharing options...
Joe Musashi Posted April 23, 2015 Share Posted April 23, 2015 Sorry for being off-topic again. I was lazy and haven't done the "Task(s) for you" , though I would have some contribution to Part 8, which might be worth sharing. I also ran into the problem of having to keep the defines of the 6507 and ARM code bases in sync, so I was looking for a method to do this a bit more automated. A simple way is to use the .sym file that DASM outputs and generate a C header file from it. This can even be done from within a makefile. The relevant part of my current project makefile looks like: build = @$(DASM) $(PROJECT).asm \ -o$(PROJECT).bin \ -l$(PROJECT).lst \ -s$(PROJECT).sym \ -DTV_EXTERN=$(1) \ -f3 headers = grep DD_ $(PROJECT).sym \ | awk '{printf "\#define %-24s 0x%s\n", $$1, $$2}' \ | sort \ > ./ARM/displaydata.h $(PROJECT): @$(call build) > /dev/null @$(call headers) @$(MAKE) -C ./ARM TV_EXTERN=0 @$(call build,0) So what does this do? When the PROJECT target is executed, first DASM is run (by calling the build function). Since the ARM code has not been compiled at this point, this does not generate a binary, but still a useable .sym file. The second function call then generates the C header file. It greps for symbols starting with DD_ then uses awk to extract the first and second columns and prints them as C defines (the sort is optional). For example, spites are defined in the display data portion of my 6507 code like: RORG $0000 DD_Crown_HEIGHT = 20 DD_Crown_GRP: BYTE %01111110 ; | XXXXXX | 19 BYTE %00100100 ; | X X | 18 BYTE %01011010 ; | X XX X | 17 BYTE %11011011 ; |XX XX XX| 16 BYTE %01011010 ; | X XX X | 15 BYTE %00100100 ; | X X | 14 BYTE %01111110 ; | XXXXXX | 13 BYTE %00111100 ; | XXXX | 12 BYTE %01011010 ; | X XX X | 11 BYTE %01011010 ; | X XX X | 10 BYTE %10111101 ; |X XXXX X| 9 BYTE %01011010 ; | X XX X | 8 BYTE %00000000 ; | | 7 BYTE %00000000 ; | | 6 BYTE %00101000 ; | X X | 5 BYTE %00000000 ; | | 4 BYTE %01010100 ; | X X X | 3 BYTE %00000000 ; | | 2 BYTE %00010000 ; | X | 1 BYTE %00000000 ; | | 0 DD_Crown_COL: BYTE $3E ; |FCBC74| 19 BYTE $1E ; |FCFC54| 18 BYTE $48 ; |D65C5C| 17 BYTE $4A ; |E46F6F| 16 BYTE $48 ; |D65C5C| 15 BYTE $3E ; |FCBC74| 14 BYTE $1E ; |FCFC54| 13 BYTE $3E ; |FCBC74| 12 BYTE $1E ; |FCFC54| 11 BYTE $3E ; |FCBC74| 10 BYTE $0E ; |ECECEC| 9 BYTE $1E ; |FCFC54| 8 BYTE $00 ; |000000| 7 BYTE $00 ; |000000| 6 BYTE $0E ; |ECECEC| 5 BYTE $00 ; |000000| 4 BYTE $0E ; |ECECEC| 3 BYTE $00 ; |000000| 2 BYTE $0E ; |ECECEC| 1 BYTE $00 ; |000000| 0 Grep and awk will then generate: #define DD_Crown_COL 0x0014 #define DD_Crown_GRP 0x0000 #define DD_Crown_HEIGHT 0x0014 The resulting .h file can then be included when compiling the ARM C code (third function call). 2 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 23, 2015 Author Share Posted April 23, 2015 I have been rather disappointed about the lack of response, both in this topic and comments to the blog entries themselves. It's had me wondering if aren't that interested in the series, or that I've gone over their heads and they're afraid to ask questions. So thanks for posting this! It's quite clever. The code changes for part 10 are done, still working up the blog entry. There is a new #define that might pose a problem for your automated method. I added a font in bank 4 that the C code references. Because of the RORG the address ends up being $Fxxx in the symbol file, but the C code needs to see it as $4xxx. The echo statement converts it by removing the leading $F and replacing it with $4: echo "#define FONT ", [[Font & $fff] + $4000]d Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted April 23, 2015 Share Posted April 23, 2015 (edited) I have been rather disappointed about the lack of response, both in this topic and comments to the blog entries themselves. It's had me wondering if aren't that interested in the series, or that I've gone over their heads and they're afraid to ask questions. You should consider that some may not need a full blown tutorial and will simply use the blog as a reference. So the lack of response may not be an accurate indicator of how many developers have benefited by your efforts. I'd also guess that there is limited interest due to the extra effort required to develop for both systems simultaneously. The DPC+ bB kernel has a much bigger impact of graphics quality and very little complexity, whereas native DPC+ requires more effort to take full advantage of it. Personally I doubt I would ever develop a DPC+ game because it seems silly to me to have to write any assembly when there's a ARM CPU available to do all the work, but I'll still review your blog and learn from it. So thanks for all you effort! Edited April 24, 2015 by ZackAttack Quote Link to comment Share on other sites More sharing options...
iesposta Posted April 24, 2015 Share Posted April 24, 2015 You should consider that some may not need a full blown tutorial and will simply use the blog as a reference. So the lack of response may not be an accurate indicator of how many developers have benefited by your efforts. I'd also guess that there is limited interest due to the extra effort required to develop for both systems simultaneously. The DPC+ bB kernel has a much bigger impact of graphics quality and very little complexity, whereas native DPC+ doesn't requires more effort to take full advantage of it. Personally I doubt I would ever develop a DPC+ game because it seems silly to me to have to write any assembly when there's a RISC CPU available to do all the work, but I'll still review your blog and learn from it. So thanks for all you effort! SpiceWare, I appreciate your blog, although I am not at a point to use it or follow along yet. It is nice to know it is there. Zack, your post isn't clear in the middle. And the 3rd sentence seems you don't understand what the DPC+ does. You can't just make a 2600 game using the ARM. The DPC+ is the hardware (emulated also in the ARM) that lets ARM code logic (optional), music (optional) and graphics communicate with the Atari's 6507 which must run an assembly kernel to display anything. if it all ran with C code in the Arm and output from the cart, that wouldn't be a 2600 game, but a 2600 powering a computer not to mention you couldn't use the Atari switches or controllers. Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted April 24, 2015 Share Posted April 24, 2015 Sorry, the second doesn't was a typo. I meant to say "native DPC+ requires more effort to take full advantage of it." My point is that there will never be a huge developer base for DPC+ because of the extra complexity it adds. I understand that the ARM just emulates DPC+ but afaik the harmony/melody boards are the only boards that implement DPC+ and they both use ARM to do it. So to me DPC+ => ARM, but that's just my opinion. Quote Link to comment Share on other sites More sharing options...
iesposta Posted April 24, 2015 Share Posted April 24, 2015 Ah yes I agree. The DPC+ adds complexity to assembly games, then add to that using the leftover ARM cycles to do game things you need to add C language to all of it. Next we will have "Bus Stuffing" kernels to do even more thing per scan line, with or without DPC+. Even without DPC+ unthinkable games are made like Boulder Dash and the upcoming Star Castle's Arcade just using Assembly and added cart RAM and/or non-violatile memory to save Star Castle's scores. Every extra hardware seems to have a different way of programming it. Like the Supercharger. It requires a whole lot of input / output coding, and writing to RAM is odd. Very few programs were written homebrew for Supercharger which I saw great potential with multi-loading making unique games. Only multi-loading Dragonstomper and Escape from the Mindmaster worked well, Swords of Soros and Survival Island suffered from being rushed and unpolished. Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 24, 2015 Share Posted April 24, 2015 Darrell, I have bookmarked your valuable information (BIG thanks for that). So if I start developing using DPC+ I know where to look. Then for sure you will get some feedback and questions. Just not now. Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted April 24, 2015 Author Share Posted April 24, 2015 It just seems odd that there's been 50 downloads of the source in part 8, but no comments or feedback. In looking back at the Collect series, I should have been expecting it. It was written in June & July but it wasn't until January that somebody asked questions about the code. Quote Link to comment Share on other sites More sharing options...
Joe Musashi Posted April 24, 2015 Share Posted April 24, 2015 (edited) The code changes for part 10 are done, still working up the blog entry. There is a new #define that might pose a problem for your automated method. I added a font in bank 4 that the C code references. Because of the RORG the address ends up being $Fxxx in the symbol file, but the C code needs to see it as $4xxx. The echo statement converts it by removing the leading $F and replacing it with $4: echo "#define FONT ", [[Font & $fff] + $4000]d Yes, address translation would require a modified awk "script". In the case above something like: awk '{printf "\#define %-24s 0x4%s\n", $$1, substr($$2,2)}' It just takes a substring of the input address and prints '4' in front. This simple solution will also translate constants, so these would have to be handled differently, for example by using special prefixes "DD_CONST_" and "DD_ADDR_" to grep for. Of course, for more complicated cases one could use a fullblown awk script (or any other text processing tool). But I agree that for few labels the echo method is probably quicker. I'm a bit surprised not more people are using DPC+/ARM. When working only in your spare time, making an assembler game can take years (at least for me). Being able to program in C can be a huge time saver. Of couse, this is all just for fun, so eveybody should choose the programming environment which is most enjoyable for oneself. Edited April 24, 2015 by Joe Musashi Quote Link to comment Share on other sites More sharing options...
Yosikuma Posted June 9, 2016 Share Posted June 9, 2016 Don't get discouraged. Aspiring programmers like me find this to be valuable information -- even if we're not quite at that point to be taking this on! 1 Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted February 16, 2017 Share Posted February 16, 2017 It's not technically a "task for you" assignment, but I just completed the first 5 parts of the series. Pretty sure your blog just saved me hours of cursing at Linux and gnu 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.