+Random Terrain Posted April 22, 2011 Share Posted April 22, 2011 (edited) I think all those WSYNC's look ugly so I thought I'd share this with the class [snip/snip] Z26 must default to PAL because it's not using the whole screen I changed 192 to 242 and it works fine but does the vertical blank and overscan need to be adjusted? I welcome questions - after all, this is supposed to be an interactive tutorial/forum. I tried to make the code sample as UNDERSTANDABLE as possible. It is certainly not the most efficient code - for it uses too many bytes of ROM to achieve its effect. But we're learning, and what's important right now is understanding how things work. It's as good a time as any to explain a little bit about the assembler - DASM. As you have probably gathered by now, we make our changes to the source code - which is meant to be a human-readable form of the program. We feed that source code to the assembler - and provided the assembler doesn't find any errors in the format of the code, it will convert the human-readable format into a binary format which is directly runnable on the '2600 (burn it to an EPROM, plug the EPROM into a cartridge, and plug the cartridge into a '2600) or on an emulator (just load the binary into the emulator). Consider the following snippet of code... sta WSYNC sta WSYNC sta WSYNC That's 3 scanlines of 6502-halting. DASM has a nice feature where it can output a listing file which shows both our original source code, but also the binary numbers it replaces that code with. We'll have a close look at this feature later (and how to 'drive' DASM) - but those wishing to look through the DASM documentation should look for the "-l" switch. When the above code fragment (from our original kernel) is assembled, the listing file contains the following... 25 f008 85 02 sta WSYNC 26 f00a 85 02 sta WSYNC 27 f00c 85 02 sta WSYNC The leftmost number is the line-number in our original source. The next 4-digit hexadecimal number is the address in ROM of the code. Don't worry too much about that now - but do notice that each line of code is taking 2 bytes of ROM. That is, the first line starts at F008 and the next line starts at F00A (2 bytes different). That's because the "sta WSYNC" assembles to two bytes - $85 and $02. In fact, there's a 1:1 correspondence here between the mnemonic ("abbreviation") of our instruction - the human readable form - and the binary - the machine-readable form. The "sta" instruction (which stands for store-accumulator) has an opcode of $85. Whenever the 6502 fetches an instruction from ROM, and that instruction opcode is $85, it will execute the "store accumulator" instruction. The above code fragment, then, shows three consecutive "$85 $02" pairs, corresponding exactly to our three consecutive "sta WSYNC" pairs. Can you guess the actual address of the TIA WSYNC register? If you need a clue, load up the "vcs.h" file and see what you can find in there. It should be clear to you that the assembler has simply replaced the WSYNC with an actual numerical value. To be exact, after assembling the file, it has decided that the correct value for WSYNC is 2 - and replaced all occurences of WSYNC with the number 2 in the binary image. OK, so that was pretty straightforward - now let's do what HappyDood did, and insert that "REPEAT" thingy... REPEAT 3 sta WSYNC REPEND This does do exactly the same thing, as he has surmised - but not, I suspect, quite in the way that he thinks. Let's have a look at the listing file for this one... 31 f008 REPEAT 3 32 f008 85 02 sta WSYNC 31 f008 REPEND 32 f00a 85 02 sta WSYNC 31 f00a REPEND 32 f00c 85 02 sta WSYNC 33 f00e REPEND If you look carefully, you can see in the source code at right, we still have exactly 3 lines of code - the "sta WSYNC" code - and in the middle, we still have 3 pairs of "$85 $02" bytes in our binary. All that has changed, really, is that our source code was smaller and easier to write (especially if we're considering dozens of lines of "sta WSYNC"s. DASM is a pretty good assembler - and it is loaded with features which make writing code easier. Happy has used one of these features to simplify the writing of the code. That feature is the "repeat" construct. Wrap any code with "REPEAT n" (where n is a number > 0), and "REPEND" and the assembler will automatically duplicate the surrounded code in the binary n times. Note, we're not saving ROM, we're just having an easier time writing the code in the first place. So this highlights, I hope, that it is possible to include things in your source code which are directions to the assembler - basically a guide to the assembler about how to interpret the code. REPEAT is one of those. There are several others, and we will no doubt learn about these in future sessions. I won't introduce too much more 6502 at this stage - but what HappyDood was striving to do was simplify the code. The repeat structure was a way to do that visually, but it does not reduce ROM usage. One way (of several) to do that is to incorporate the "sta WSYNC" into a loop, which iterates 37 times. Here's a teaser... ; 37 scanlines of vertical blank... ldx #0 VerticalBlank sta WSYNC inx cpx #37 bne VerticalBlank Remember, the 6502 has three "registers" named "X", "Y", and "A". In the code above, we initialise one register to the value 0 through "ldx #0", then we do the halt "sta WSYNC" which will halt the 6502 until the TIA finishes the current scanline. Then we increment the x-register "inx" by one, then we compare the x-register with 37 "cpx #37". This is in essence asking "have we done this 37 times yet". The final line "bne VerticalBlank" transfers control of the program back to the line "VerticalBlank" if the comparison returned (in effect) "no". The actual listing file for that code contains the following... 41 f012 a2 00 ldx #0 42 f014 85 02 VerticalBlank sta WSYNC 43 f016 e8 inx 44 f017 e0 25 cpx #37 45 f019 d0 f9 bne VerticalBlank If we count the number of bytes in the binary output we can see that this code takes just 9 bytes of ROM. If we had 37 "sta WSYNC" instructions, at two bytes each, that's 74 bytes of ROM. Using the REPEAT structure, as noted, will still take 74 bytes of ROM. So looping is a much more efficient way to do this sort of thing. There are even MORE efficient ways, but let's not get ahead of ourselves. We are a bit ahead of ourselves here, so don't panic. Just remember, though, that DASM is a tool designed to aid us humans. It is full of things which make the code more readable (less "ugly") but taking lines of code out does not necessarily mean our code is more efficient - or uses less ROM Does anyone familiar with the sessions know if the above info is covered in one of the sessions or does it need to be added? Edited April 22, 2011 by Random Terrain Quote Link to comment Share on other sites More sharing options...
TerryMasters Posted January 26, 2012 Share Posted January 26, 2012 (edited) Hey everyone. Firstly let me say I am absolutely loving the guide. It's one of the few I can actually understand. So far everything was going great until I tried to compile this source code - the process went smoothly but the program itself runs with artifacts so to speak. I'm not sure if dasm/z26 was updated or if I'm screwing up somehow, but copying that source and compiling it with dasm atarit.asm -f3 -oatarit.bin (new and old) gives me this: The end result spits out a thick green bar at the top, followed by a thin green bar at the bottom. For whatever reason, not even the example Andrew compiled himself seems to run properly in StellaX - no idea why but here's what I get: Edit- This is what it says with -v5: START OF PASS: 1 ---------------------------------------------------------------------- SEGMENT NAME INIT PC INIT RPC FINAL PC FINAL RPC f000 f000 RIOT [u] 0280 0280 TIA_REGISTERS_READ [u] 0000 0000 TIA_REGISTERS_WRITE [u] 0000 0000 INITIAL CODE SEGMENT 0000 ???? 0000 ???? ---------------------------------------------------------------------- 3 references to unknown symbols. 0 events requiring another assembler pass. --- Symbol List (sorted by symbol) 0.FREE_BYTES 0000 AUDC0 0015 AUDC1 0016 AUDF0 0017 AUDF1 0018 AUDV0 0019 AUDV1 001a COLUBK 0009 (R ) COLUP0 0006 COLUP1 0007 COLUPF 0008 CTRLPF 000a CXBLPF 0006 CXCLR 002c CXM0FB 0004 CXM0P 0000 CXM1FB 0005 CXM1P 0001 CXP0FB 0002 CXP1FB 0003 CXPPMM 0007 ENABL 001f ENAM0 001d ENAM1 001e GRP0 001b GRP1 001c HMBL 0024 HMCLR 002b HMM0 0022 HMM1 0023 HMOVE 002a HMP0 0020 HMP1 0021 INPT0 0008 INPT1 0009 INPT2 000a INPT3 000b INPT4 000c INPT5 000d INTIM 0284 NUSIZ0 0004 NUSIZ1 0005 PF0 000d PF1 000e PF2 000f REFP0 000b REFP1 000c RESBL 0014 Reset f000 (R ) RESM0 0012 RESM1 0013 RESMP0 0028 RESMP1 0029 RESP0 0010 RESP1 0011 RSYNC 0003 StartOfFrame f000 (R ) SWACNT 0281 SWBCNT 0283 SWCHA 0280 SWCHB 0282 T1024T 0297 TIA_BASE_ADDRESS 0000 (R ) TIA_BASE_READ_ADDRESS 0000 (R ) TIA_BASE_WRITE_ADDRESS 0000 (R ) TIM1T 0294 TIM64T 0296 TIM8T 0295 TIMINT 0285 VBLANK 0001 (R ) VDELBL 0027 VDELP0 0025 VDELP1 0026 VERSION_MACRO 006a VERSION_VCS 0069 VSYNC 0000 (R ) WSYNC 0002 (R ) --- End of Symbol List. Edited January 26, 2012 by TerryMasters Quote Link to comment Share on other sites More sharing options...
Pioneer4x4 Posted January 27, 2012 Share Posted January 27, 2012 Looks like it is being displayed as PAL in the second image. Quote Link to comment Share on other sites More sharing options...
PiXL Posted February 15, 2016 Share Posted February 15, 2016 (edited) Greetings, I am new to the Atari 2600 and Assembly. I have been following this awesome tutorial but I came across an issue from using this tutorial's code and I am not sure how to fix it. I get this: START OF PASS: 1Warning: Unable to open 'vcs.h'Warning: Unable to open 'macro.h'----------------------------------------------------------------------SEGMENT NAME INIT PC INIT RPC FINAL PC FINAL RPC f000 f000INITIAL CODE SEGMENT 0000 ???? 0000 ????----------------------------------------------------------------------458 references to unknown symbols.458 events requiring another assembler pass. - Expression in mnemonic not resolved.--- Unresolved Symbol ListCOLUBK 0000 ???? (R )VBLANK 0000 ???? (R )VSYNC 0000 ???? (R )WSYNC 0000 ???? (R )--- 4 Unresolved SymbolsSTART OF PASS: 2Warning: Unable to open 'vcs.h'Warning: Unable to open 'macro.h'----------------------------------------------------------------------SEGMENT NAME INIT PC INIT RPC FINAL PC FINAL RPC f000 f000INITIAL CODE SEGMENT 0000 ???? 0000 ????----------------------------------------------------------------------458 references to unknown symbols.458 events requiring another assembler pass. - Expression in mnemonic not resolved.--- Unresolved Symbol ListCOLUBK 0000 ???? (R )VBLANK 0000 ???? (R )VSYNC 0000 ???? (R )WSYNC 0000 ???? (R )--- 4 Unresolved Symbols--- Unresolved Symbol ListCOLUBK 0000 ???? (R )VBLANK 0000 ???? (R )VSYNC 0000 ???? (R )WSYNC 0000 ???? (R )--- 4 Unresolved SymbolsFatal assembly error: Source is not resolvable. Can anyone point me in the right direction? Edited February 15, 2016 by PiXL Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted February 15, 2016 Author Share Posted February 15, 2016 START OF PASS: 2 Warning: Unable to open 'vcs.h' Warning: Unable to open 'macro.h' Can anyone point me in the right direction? These two files (vcs.h and macro.h) are distributed with DASM, and contain code and equates that are needed to get your program working. Simply put, the assembler can't "see" those files when it's looking for them. Copy them from the DASM directory to the same directory as your source file and this should fix it. If you don't have them, they should be easy enough to find - try the sourceforge DASM repository, for example. Essentially it's a path problem - can't find the files as they're not on the search path, or they don't exist. Fix that! Quote Link to comment Share on other sites More sharing options...
PiXL Posted February 15, 2016 Share Posted February 15, 2016 (edited) These two files (vcs.h and macro.h) are distributed with DASM, and contain code and equates that are needed to get your program working. Simply put, the assembler can't "see" those files when it's looking for them. Copy them from the DASM directory to the same directory as your source file and this should fix it. If you don't have them, they should be easy enough to find - try the sourceforge DASM repository, for example. Essentially it's a path problem - can't find the files as they're not on the search path, or they don't exist. Fix that! Ah! So that's what it meant! Silly me! Indeed the files seem to be missing. I'll keep you updated EDIT: I forgot to specify that the DASM I downloaded came from https://sourceforge.net/projects/dasm-dillon/It only came with dasm.Darwin.x86, dasm.exe and dasm.Linux.x86. I can't seem to find the dasm repository on SourceForge Edited February 15, 2016 by PiXL Quote Link to comment Share on other sites More sharing options...
PiXL Posted February 15, 2016 Share Posted February 15, 2016 (edited) Sorry for the double post but I thought of posting this little bit of info if anyone else runs into the same issue. I managed to find the missing files on http://khryssun.free.fr/programming_code.htmland copy them into my DASM folder. The tutorial's code seems to work properly now. Edited February 15, 2016 by PiXL Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted February 15, 2016 Share Posted February 15, 2016 Ah! So that's what it meant! Silly me! Indeed the files seem to be missing. I'll keep you updated EDIT: I forgot to specify that the DASM I downloaded came from https://sourceforge.net/projects/dasm-dillon/It only came with dasm.Darwin.x86, dasm.exe and dasm.Linux.x86. I can't seem to find the dasm repository on SourceForge You can find those header files in the source. On that page click on files then drill down to the latest source. After unarchiving the source you'll find them in directory machines/atari2600. Quote Link to comment Share on other sites More sharing options...
KrazyKattapilla Posted August 17, 2019 Share Posted August 17, 2019 Hi, Does the "END" on the last line of the kernel have a special purpose? I seem to be able to compile and run things successfully without it so I'm guessing it's more of an aide-memoir. Simon Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted August 17, 2019 Author Share Posted August 17, 2019 20 minutes ago, KrazyKattapilla said: Hi, Does the "END" on the last line of the kernel have a special purpose? I seem to be able to compile and run things successfully without it so I'm guessing it's more of an aide-memoir. Simon Funny, I never even noticed it. My current game has it there. It appears to be superfluous. Quote Link to comment Share on other sites More sharing options...
KrazyKattapilla Posted August 18, 2019 Share Posted August 18, 2019 12 hours ago, Andrew Davie said: It appears to be superfluous Super - thank you. 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.