Pascal's code can be improved by using segments to declare variables. It's easier to read and it won't give you a chance to make a mistake and screw up your variables by declaring them wrong.
(This code is for asmx. It's probably very similar or even identical in other assemblers, but not having used them, I don't really know.)
Instead of this:
Code: Select all
vtimer equ $ff0000 ; long
ballx equ vtimer+4 ; word
bally equ ballx+2 ; word
ballpx equ bally+2 ; word
ballpy equ ballpx+2 ; word
x1 equ ballpy+2 ; word
y1 equ x1+2 ; word
x2 equ y1+2 ; word
y2 equ x2+2 ; word
Write this:
Code: Select all
seg globals
org $ff0000
vtimer ds 4
ballx ds 2
bally ds 2
ballpx ds 2
ballpy ds 2
x1 ds 2
y1 ds 2
x2 ds 2
y2 ds 2
seg
Isn't that a whole lot prettier?
If you want a byte, use "ds 1", a word, use "ds 2", and a longword, "ds 4". Easy. Just be careful to keep your words and longwords aligned to 16-bit boundaries (use "even" before 16/32-bit variables if you're not sure whether they'll be aligned or not).
The "seg" at the end tells the assembler that the globals segment has ended, at least for now, and you're back to writing ROM code.
You can also have multiple "globals" blocks. Let's get some terminology clear, to distinguish between blocks and segments. I'm using the word "block" to mean a "seg globals ... seg" block of code. A "segment" is a place in memory where code or variables go. So you may have multiple blocks, but as long as you name each one the same thing (in this case "globals"), they are all the same segment. The assembler just combines the blocks of a segment together in order as if they were written as one big block in the first place.
When using multiple blocks, in the first and ONLY the first block, you must use "org $ff0000". This tells the assembler that these variables go in RAM (which begins at FF0000) rather than ROM, which is the point of using the segment.
Being able to use multiple blocks is good because you could, say, have a globals block in your main file, and then have another one in, say, video.inc that contains globals specific to video routines, and the assembler will correctly merge the blocks together in a single segment, as long as you do that "org $ff0000" the first and only the first time. You don't even have to include any variables the first time if you don't want to define any before including your other files; you can just do this:
Code: Select all
; Set up the globals segment for your include files
seg globals
org $ff0000
seg
; blah1.inc and blah2.inc have their own globals blocks,
; and now they don't have to worry about using org $ff0000
include blah1.inc
include blah2.inc
; Now the globals for your main file
seg globals
var1 ds 2
var2 ds 2
seg
One thing to be careful about is that words and longwords need to be on 16-bit boundaries. If your globals block doesn't end on such a boundary, the next block won't begin on one. For that reason I prefer to end my segments with "even" just before "seg", which forces the next block to begin on a 16-bit boundary. Alternatively, you can always begin them with "even" instead. It doesn't matter which as long as you either always choose the beginning or always choose the end.
Whew, this was a long and exhausting post to write.

Hope it helps.
- Kef