|
Assembler directives: #code Including C Source Files: #code#code <name>,<start>,<size> [,FLAG=<flagbyte>] [,SPACE=<fillbyte>]
Assembler directives: #code Including C Source Files: #code#code <name>,<start>,<size> [,<flags>] ; old syntax
Assembler directives: #code Including C Source Files: #code#code <name>,<start>,<size>
This defines a code segment where the generated code will be stored. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf the assembler directive Assembler directives: #target Including C Source Files: #target#target has been used then at least one Assembler directives: #code Including C Source Files: #code#code segment must be defined. Depending on the desired target your source must consist of multiple Assembler directives: #code Including C Source Files: #code#code segments. See the section about target files.
Arguments may be left unspecified from right to left. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf you need to specify the size but not the address, you can use '*' to mark an argument as unspecified, e.g.:
Assembler directives: #code Including C Source Files: #code#code BLOCK1, *, 0x400 ; appended to the previous code block, size = 1kB; no flag
Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf you define more than one code segment, then the segments (and thus the code therein) will be appended in the output file in the sequence of definition. Typically you define all used segments at the start of your source file in the sequence they shall be appended to the output file and then later re-enter the segments as required. The following is an #insert: Examples: #assert: Example: incbin: Examples: #assert: Example:example as it might be used Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif you also include c sources:
Assembler directives: #code Including C Source Files: #code#code _BOOT,0x0000 ; segment with Reset, RST and NMI vectors
Assembler directives: #code Including C Source Files: #code#code _GSINIT ; init code: the compiler adds some code here and there as required
Assembler directives: #code Including C Source Files: #code#code _HOME ; code that must not be put in a bank switched part of memory.
Assembler directives: #code Including C Source Files: #code#code _CODE ; most code and const data go here
Assembler directives: #code Including C Source Files: #code#code _INITIALIZER ; initializer for initialized data in ram
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, Pseudo instructions: end, .end 8080 pseudo instructions: ENDend address and length (since 4.0.24) of each segment. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf you include c source, then the c compiler requires the above code segments to be defined. 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: #code Including C Source Files: #code#code FOO, 100, 1000
will define these Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labelslabels:
FOO = $0064 = 100
FOO_end = $044C = 1100
FOO_size = $03E8 = 1000
The start address is required for the first segment only or it will default to 0. Following segments will be automatically assigned start addresses without gap Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif no address is defined.
The start address should define the 'physical' address for the segment, the address where it is visible to the cpu. It also Pseudo instructions: defl, set and '=' Labels: SETsets the 'logical' address (the org) for the code which can be 'shifted' with .phase and .dephase.
Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf a start address is given and does not exactly match the Pseudo instructions: end, .end 8080 pseudo instructions: ENDend address of the previous code segment, then the following segments is still appended without gap in the output file. It is assumed that the code will be moved to this address before it is executed.
Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf the code is written to a .hex or .s19 file, then it depends on the Assembler directives: #target Including C Source Files: #target#target, how exactly this 'gap' is handled, because these formats also store the destination address of the contained code.
You can use the start address Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif you have a rom which is paged into the Command Line Options: --z80 Pseudo instructions: .z80, .z180 and .8080 Targets: #target Z80Z80 address space, e.g. a 32k rom which consists of 2 pages might be defined like this:
#target rom
Assembler directives: #code Including C Source Files: #code#code PAGE1,0,0x4000 ; boot rom
Assembler directives: #code Including C Source Files: #code#code PAGE2,0,0x4000 ; basic rom
Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf given, the size defines the size for this segment. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf you store less bytes in it, then the segment will be padded up to this size with the default #code: Fill Byte #code: Fill Bytefillbyte: 0xff for rom and 0x00 for any other target. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf your code exceeds the size, then the assembler will generate an error.
Since version 4.4.2 it is also possible to define a custom #code: Fill Byte #code: Fill Bytefillbyte for code segments by appending a key/value pair SPACE=<value> after the size. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf you want to leave the size unspecified, use '*'.
Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifIf no size is defined, then the segment is exactly as long as the code stored into it.
The 3rd argument is not required and actually not allowed in most cases. But some targets require a flag for the code segment, e.g. Assembler directives: #target Including C Source Files: #target#target tap requires a #code: Flag Byte #code: Flag Byteflag byte for each tape block.
Since version 4.4 it is recommended to define the #code: Flag Byte #code: Flag Byteflag byte using a key/value pair FLAG=<value>.
Assembler directives: #code Including C Source Files: #code#code HEADER, 0, 17, FLAG = 0x00
Since version 4.4.2 it is possible to define a custom #code: Fill Byte #code: Fill Bytefillbyte for code segments by appending a key/value pair SPACE=<value> after the segment size. This #code: Fill Byte #code: Fill Bytefill byte is used to fill the gap in 'defs' and 'org' Pseudo instructions 8080 Assembler: 8080 pseudo instructionspseudo instructions, and for the padding at the Pseudo instructions: end, .end 8080 pseudo instructions: ENDend of the segment, Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endifif a fixed size was specified.
Assembler directives: #code Including C Source Files: #code#code _INITIALIZER, *, *, SPACE = 0x00
The above #insert: Examples: #assert: Example: incbin: Examples: #assert: Example:example might be used in a rom which incorporates a segment with global data initializers, so that parts of variables, which are Pseudo instructions: defl, set and '=' Labels: SETset with 'defs' are Pseudo instructions: defl, set and '=' Labels: SETset to 0x00.
A code segment can be re-entered by using the Assembler directives: #code Including C Source Files: #code#code directive with the name only or by using the .area pseudo opcode:
Assembler directives: #code Including C Source Files: #code#code _HOME ; following code will be stored in code segment _HOME
.area _CODE ; following code will be stored in segment _CODE (sdcc syntax)
You can switch between code segments whenever you like in your source. A typical application is initialization code:
You define a segment for init code, e.g. _GSINIT and a segment for most other code, e.g. _CODE. Then at any point in your source where you have some data which need initialization you temporarily switch to the _GSINIT segment and add the init code. This is what the c compiler does for initialized variables.
| |