Wickeycolumbus, on Thu Jun 28, 2007 10:26 PM, said:
Ok... this is starting to make sense more! Thank you for all of your guyes help! I just have one more question that doesent have to do with this directly. I noticed that in some of the 2600 101 tutorials before the ORG command there is a SEG. What does this do?
Thanks
That's short for "segment." I haven't looked at the code you're referring to, but I'm going to guess that it's using a SEG.U command? SEG.U creates an *uninitialized* segment, meaning DASM doesn't try to output any values or code for that segment of memory-- it just "defines" it so to speak. This is handy for defining variables, especially RAM variables that are located outside of the cartridge memory range (i.e., in the Atari 2600's zero-page RAM, although they could also be in expansion RAM that's included in the cartridge-- e.g., in Superchip RAM).
For example, if you open up the "VCS.H" file, and chop out all of the comments, you'll be left with this:
VERSION_VCS = 105
IFNCONST TIA_BASE_ADDRESS
TIA_BASE_ADDRESS = 0
ENDIF
IFNCONST TIA_BASE_READ_ADDRESS
TIA_BASE_READ_ADDRESS = TIA_BASE_ADDRESS
ENDIF
IFNCONST TIA_BASE_WRITE_ADDRESS
TIA_BASE_WRITE_ADDRESS = TIA_BASE_ADDRESS
ENDIF
SEG.U TIA_REGISTERS_WRITE
ORG TIA_BASE_WRITE_ADDRESS
VSYNC ds 1
VBLANK ds 1
WSYNC ds 1
RSYNC ds 1
NUSIZ0 ds 1
NUSIZ1 ds 1
COLUP0 ds 1
COLUP1 ds 1
COLUPF ds 1
COLUBK ds 1
etc.
The first line simply defines a constant called "VERSION_VCS" and sets it to a value of 105, to identify that this is version 1.05 of the "VCS.H" file.
The next three lines say "IFNCONST TIA_BASE_ADDRESS" (i.e., if constant "TIA_BASE_ADDRESS" is *not* defined somewhere else within the program-- "If Not CONSTant"), then set it equal to 0 (i.e., to address $0000). That's because the TIA chip is connected to the 6507's address pins in such a way that the 6507 processor "sees" it at address $0000-- except that, like the cartridge slot, the TIA chip ends up being "mirrored" throughout the 64K address space. That means you can use any of the mirrors, and you'll still be addressing the TIA. At least one bankswitching scheme uses the beginning of the 64K address space for bankswitching purposes, in which case you can't address the TIA at those addresses or you'll end up switching banks-- so that bankswitching scheme uses the TIA mirror that's at address $40 (or $0040). DASM lets you set a constant called "TIA_BASE_ADDRESS" to specify where you'll be addressing the TIA registers, in case you want to write a program that uses that bankswitching scheme.
Likewise, the six lines after that let you define constants for the "TIA_BASE_READ_ADDRESS" and for the "TIA_BASE_WRITE_ADDRESS," so you can read the TIA "read registers" at one set of addresses, and write to the TIA "write registers" at another set of addresses. Normally, the TIA read and write registers are thought of as starting at $00 (or $0000), so if you haven't defined those two constants in your program, DASM will automatically set them equal to 0 (or $0000).
The next line-- "SEG.U TIA_REGISTERS_WRITE"-- says that we want to create an uninitialized segment that we'll call "TIA_REGISTERS_WRITE." Since it's an *uninitialized* segment, DASM won't create any actual code for it.
The next line-- "ORG TIA_BASE_WRITE_ADDRESS"-- says the uninitialized "TIA_REGISTERS_WRITE" segment will start at the address indicated by the "TIA_BASE_WRITE_ADDRESS" constant. Assuming we haven't set that constant to anything in particular, DASM will set it to 0 ($0000), in which case the uninitialized segment will start at $0000.
The next group of lines are the real "meat"-- they define where the TIA write registers are, what they'll be known as within the program, and how many bytes will be reserved for each one. For example, if the "TIA_REGISTERS_WRITE" segment is starting at address $0000, then the "VSYNC ds 1" line will define 1 byte at $0000, and associate it with the label "VSYNC." The next line-- "VBLANK ds 1"-- will define 1 byte at $0001, and associate it with the label "VBLANK."
You can use this same technique to create variables in zero-page RAM, as in this example:
SEG.U My_Zero_Page_RAM_Variables
ORG $80; or $0080, the start of zero-page RAM
An_8_Byte_Array DS 8
A_1_Byte_Variable DS 1
A_2_Byte_Pointer DS 2
In this example, the label "An_8_Byte_Array" will be associated with address $80 (or $0080).
The label "A_1_Byte_Variable" will be associated with address $88 (or $0088), because 8 bytes were set aside for "An"8_Byte_Array," starting at $0080, therefore the next available address is $0088, see?
Now, I said that 8 bytes were "set aside" for "An_8_Byte_Array," but that doesn't stop you from using other labels for those bytes, if you define the other labels somewhere else in your program.
Another way to do this same thing would like this:
An_8_Byte_Array = $80
A_1_Byte_Variable = $88
A_2_Byte_Pointer = $89
However, this second method can be tedious and tricky, because you have to keep track of where you want the next label to go, it's a hassle to relocate the variables, and it's easier to make a mistake as you locate or relocate the variables. For example, suppose you typed this by mistake:
An_8_Byte_Array = $80
A_1_Byte_Variable = $81
A_2_Byte_Pointer = $82
Oops, you actually wanted to use addresses $80 through $87 for "An_8_Byte_Array," but the above lines will make "A_1_Byte_Variable" and "A_2_Byte_Pointer" overlap with "An_8_Byte_Array."
Anyway, if you want to declare space for variables using the "DS" statement, then you need to also use the "SEG.U" statement if the variables are going to be outside of the 4K cartridge area, otherwise DASM will create the binary file too large. For example:
ORG $80
An_8_Byte_Array DS 8
A_1_Byte_Variable DS 1
A_2_Byte_Pointer DS 2
ORG $F000
START
; my program goes here...
ORG $FFFC
WORD START
WORD START
The above code will cause DASM to create a binary file that's 65408 bytes long (starting at $0080 and ending at $FFFF), which is not good. On the other hand, the following is okay:
SEG.U My_Variables
ORG $80
An_8_Byte_Array DS 8
A_1_Byte_Variable DS 1
A_2_Byte_Pointer DS 2
SEG My_Program
ORG $F000
START
; my program goes here...
ORG $FFFC
WORD START
WORD START
This will create an uninitialized segment starting at $0080, so DASM won't output anything for that segment, but then it will create an initialized segment starting at $F000--- so DASM will create a binary file that's 4K (from $F000 through $FFFF).
If you want to know all of the options and commands that are available with DASM, there's a text file named "DASM.TXT" that comes with DASM, which describes them all.
I hope this wasn't too confusing.
Michael
Edited by SeaGtGruff, Thu Jun 28, 2007 9:58 PM.