Assembler directives: #data Including C Source Files: #data#data <name>,<start>,<size>
This directive declares an area of ram to be used for variables etc. Assembler directives: #data Including C Source Files: #data#data behaves much like Assembler directives: #code Including C Source Files: #code#code, except that the contents of this segment is not stored into the output file. The segment is used merely to define Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabels, presumably in ram.
For a simple rom written entirely in assembler you probably need only one data segment, or even no data segment at all, Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif you just define the variables' addresses with the Pseudo instructions 8080 Assembler: 8080 pseudo instructionspseudo instruction Pseudo instructions: equ Types of labels: Named values Labels: EQUequ.
The name can be chosen freely, but must be a valid Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel name. zasm generates a Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabel for the start address, the Pseudo instructions: end, .end 8080 pseudo instructions: ENDend address and the size of each segment (since 4.0.24). Names for segments are case sensitive like all Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabels, except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif Differences from v3 to v4: Command line options Command Line Options Command Line Options: Command line optionscommand line option --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefoldcasefold was used.
Assembler directives: #data Including C Source Files: #data#data DATA, 100, 1000
will define these Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabels:
DATA = $0064 = 100
DATA_end = $044C = 1100
DATA_size = $03E8 = 1000
Typically the assembler instruction 'defs' alias 'Pseudo instructions: defs, ds, .ds, .block, .blkb and data 8080 pseudo instructions: DSds' is used to allocate space in a data segment. You cannot use instructions which actually try to store bytes into this segment – only gaps.
In addition the assembler instruction 'data' is allowed in a data segment, which just does the same.
Also allowed are org and align, because they also just insert space, they're just different in how they calculate the gap size.
The following #insert: Examples: #assert: Example: incbin: Examples: #assert: Example:example might be used Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif you include c source:
It defines two data segments named _DATA and _INITIALIZED, which is where the c compiler stores uninitialized and initialized variables. In this #insert: Examples: #assert: Example: incbin: Examples: #assert: Example:example these segments are fittet into the 'printer buffer' of the ZX Spectrum, a mostly unused area (except for printing) of 256 bytes.
The segment _INITIALIZED is defined with address '*' which means that it's start address will be directly appended to the previous segment's Pseudo instructions: end, .end 8080 pseudo instructions: ENDend, and the equation for the size makes sure that the combined size of both segments is exactly 256 bytes and allocating more variables will be detected by the assembler and raise an error.
Assembler directives: #data Including C Source Files: #data#data _DATA, printer_buffer ; uninitialized data
Assembler directives: #data Including C Source Files: #data#data _INITIALIZED, *, 256 - (_INITIALIZED-_DATA) ; data initialized from _INITIALIZER
Assembler directives: #data Including C Source Files: #data#data _HEAP, code_end ; heap:
__sdcc_heap_start: ; --> sdcc _malloc.c
Pseudo instructions: defs, ds, .ds, .block, .blkb and data 8080 pseudo instructions: DSds ram_end-$-1 ; add all unused memory to the heap
__sdcc_heap_end: ; --> sdcc _malloc.c
Pseudo instructions: defs, ds, .ds, .block, .blkb and data 8080 pseudo instructions: DSds 1
A data segment can be re-entered by using the Assembler directives: #data Including C Source Files: #data#data directive with the name only or by using the .area pseudo opcode:
Assembler directives: #data Including C Source Files: #data#data _DATA ; following code will be stored in data segment _DATA
.area _DATA ; following code will be stored in segment _DATA (sdcc syntax)
You can switch between segments whenever you need to allocate storage space for variables in your source.
...
Assembler directives: #data Including C Source Files: #data#data _DATA ; switch context to data segment _DATA
foo defs 4
bar defs 2
fuzzy defs $20
;
Assembler directives: #code Including C Source Files: #code#code _CODE ; switch context back to code segment _CODE
...
The c compiler uses the code segment _INITIALIZER to store the initial data of initialized variables. These are copied during system initialization to the location of _INITIALIZED. (Actually the c compiler doesn't do this. It is your job to add some code in the _GSINIT segment to copy the initializer data!) So you can switch between these segments to allocate the variable in ram and add init data in rom:
...
Assembler directives: #data Including C Source Files: #data#data _INITIALIZED
foo defs 2 ; allocate space in ram
Assembler directives: #code Including C Source Files: #code#code _INITIALIZER
defw 4711 ; store init data in rom. SIZE AND POSITION MUST MATCH!
Assembler directives: #code Including C Source Files: #code#code _CODE
...
|