+SpiceWare Posted December 17, 2019 Share Posted December 17, 2019 Stella has excellent support for developers, you can read about it in the Stella documentation in the sections: Integrated Debugger Developer Options/Integrated Debugger Developer Keys in TIA mode Developer Commands for the Command Line Stella does not directly support the debugging of ARM code; however, we can use the extra cartridge tabs to view information before and after the ARM code has run, which can be helpful to track down problems. Note: I'm only going to show Stella's Debugger as it pertains to CDFJ, if you're unfamiliar with using it then read over these to help get you up to speed: Reply 9 - use Stella to create a disassembly Reply 12 - use Stella to help with cycle counts Reply 2 - Fixed Debug Colors mode Video tutorial by @tschak909 Reply 86 Reply 87 additional info from me in Reply 91 if you know of a helpful resource not listed then add a comment with a link Cartridge CDFJ tab Just a brief overview of the CDFJ bank switching scheme. Games using the original CDF spec, such as Draconian and Super Cobra Arcade, will have slightly different text to denote they're using an older version of the scheme. States tab Status of the various CDFJ registers. Before your initialization routine runs the values will not be valid: An example after the values have been initialized. Like the CartridgeCDFJ tab, the States tab will be slightly different for older CDF games. Cartridge RAM tab The Cartridge RAM tab shows the entire 8K of RAM that's available in the Harmony/Melody. The first 2 K contain the CDFJ driver, so should be ignored. The first 2K also contain the various registers, but those are much easier to view on the States tab. You can scroll down Description box for a little more info: Display Data As mentioned in Part 1, ARM RAM begins at 0x40000000 and Display Data begins at 0x40000800. Stella's debugger drops off the leading 0x4000 so if we scroll down to 08xx we'll be at the start of Display Data RAM: The initial values in Display Data RAM are random, so the 6507 InitSystem routine will call our C function Initialize() to zero it out so we have a known starting state: In the 6507 code the first part of Display Data is defined as this: _DS_TO_ARM: _RUN_FUNC: ds 1 ; function to run _SWCHA: ds 1 ; joystick directions to ARM code _SWCHB: ds 1 ; console switches to ARM code _INPT4: ds 1 ; left firebutton state to ARM code _INPT5: ds 1 ; right firebutton state to ARM code _DS_FROM_ARM: ; ARM OverScan routines return value for MODE _MODE: ; $00 = splash, $01 = menu, $80 = game _BALL_X: ds 1 ; ARM VerticalBLank routines do not return MODE, instead _M1_X: ds 1 ; theyreturn values for the 5 X positions _M0_X: ds 1 _P1_X: ds 1 _P0_X: ds 1 ; Splash screen datastreams _SPLASH0: ds 192 ... If we look into the symbol file collect3.sym we can find the values for each label: _BALL_X 0005 _DS_FROM_ARM 0005 _DS_TO_ARM 0000 (R ) _INPT4 0003 _INPT5 0004 _M0_X 0007 _M1_X 0006 _MODE 0005 _P0_X 0009 _P1_X 0008 _RUN_FUNC 0000 _SPLASH0 000a _SWCHA 0001 _SWCHB 0002 To see them in the CartridgeRAM tab just add 0x0800 to the value. If we advance a single frame we'll see the RAM starting at 0x0800 change: So we can see the following values in RAM are: 05 = _RUN_FUNC ff = _SWCHA 3f = _SWCHB 8c = _INPT4 8d = _INPT5 Advance a few more frames until we see SPLASH in the TIA Display in the upper-left: From here we can see: _P1_X at address 08 has the value of 48 _P0_X at address 09 has the value of 40 _SPLASH0 staring at address 0a is filled in with the graphics to show SPLASH down the screen. If we switch to the TIA tab on the left we can see the positions of the players: P0 Pos# = 64 P1 Pos# = 72 At first glance those look incorrect, but the Pos# values are shown in decimal while the RAM values are shown in hexadecimal. 64 = $40 and 72 = $48, so they do match. C Variables and Stack C Variables and Stack begin at 0x40001800 Global variables are those defined outside of functions. In Collect 3 those are currently: unsigned int frame; unsigned char player_x[2]; unsigned char player_y[2]; unsigned short int player_shape[2]; We can use the Map file to find their RAM address. The Map file for Collect 3 is main/bin/testarm.map At the start of the map file we will find a list of the variables and their sizes: Common symbol size file player_y 0x2 main.o frame 0x4 main.o player_x 0x2 main.o player_shape 0x4 main.o Their addresses can be found towards the end of the file: COMMON 0x0000000040001808 0xe main.o 0x0000000040001808 player_y 0x000000004000180c frame 0x0000000040001810 player_x 0x0000000040001812 player_shape The ARM uses LSB order so looking at the table we see our frame counter is at 180c which contains the bytes de 02 00 00 which is the value $000002de or 734 The values for the 2 byte array player_x are at 1810 and contain the bytes 24 and 74, which are 36 and 116 respectively. If we switch to the TIA tab we can see the Pos # for P0 and P1 match. If we switch to the I/O tab we can check the joystick positions then click the Frame +1 button to advance a frame. We'll see the values for player_x and player_y both changed: However, when we look at the TIA tab the Position numbers have not yet changed: That's because the values for player_x and player_y were changed in Overscan and we've not yet run Vertical Blank which is when the positioning of the players occurs. Click Frame +1 again and the positions will change. The 4 bytes at 1800-1803 are from the random number generator. It uses a static variable within the function: unsigned int getRandom32() { // using a 32-bit Galois LFSR as a psuedo random number generator. // http://en.wikipedia.org/wiki/Linear_feedback_shift_register#Galois_LFSRs static unsigned int random = 0x02468ace; return random = (random >> 1) ^ (unsigned int)(-(random & 1u) & 0xd0000001u); } which for some reason it does not appear in the Map file. 1 1 Link to comment Share on other sites More sharing options...
Omegamatrix Posted May 24, 2020 Share Posted May 24, 2020 On 12/17/2019 at 6:37 AM, SpiceWare said: The ARM uses LSB order so looking at the table we see our frame counter is at 180c which contains the bytes de 02 00 00 which is the value $000002de or 734 It would be a useful feature if Stella allowed you to highlight 1, 2, or 4 bytes in the Cartridge Ram, and it displayed the the result in MSB order for both hex and decimal. The debugger has also changed format with the latest release so it is shorter in height, and the "label", "dec", and "bin" are gone on the cartridge ram. However I think something like I mocked below could work. What do you guys think? I suppose the length of the box for decimal would need to increase, but that shouldn't be a show stopper. 1 Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted May 26, 2020 Share Posted May 26, 2020 The missing elements are still there. Just increase the debugger's screen size in the developer options. Link to comment Share on other sites More sharing options...
Recommended Posts