1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
; xex.inc - easy way to generate an atari 8-bit executable with ca65,
; without dealing with ca65's linker scripts and segments.
; see xex.rst (or xex.html) for full documentation.
.macro xex_failtarget target
.ifdef target
.fatal "must assemble with '-t none'"
.endif
.endmacro
xex_failtarget __APPLE2__
xex_failtarget __APPLE2ENH__
xex_failtarget __ATARI2600__
xex_failtarget __ATARI5200__
xex_failtarget __ATARI__
xex_failtarget __ATARIXL__
xex_failtarget __ATMOS__
xex_failtarget __BBC__
xex_failtarget __C128__
xex_failtarget __C16__
xex_failtarget __C64__
xex_failtarget __CBM__
xex_failtarget __CBM510__
xex_failtarget __CBM610__
xex_failtarget __CX16__
xex_failtarget __GEOS__
xex_failtarget __GEOS_APPLE__
xex_failtarget __GEOS_CBM__
xex_failtarget __LUNIX__
xex_failtarget __LYNX__
xex_failtarget __NES__
xex_failtarget __OSIC1P__
xex_failtarget __PET__
xex_failtarget __PLUS4__
xex_failtarget __SIM6502__
xex_failtarget __SIM65C02__
xex_failtarget __SUPERVISION__
xex_failtarget __VIC20__
.ifndef RUNAD
.include "atari.inc"
.endif
.ifndef xex_verbose
xex_verbose=1
.endif
.ifndef xex_warnings
xex_warnings=1
.endif
xex_api_called .set 0
xex_segcount .set 1
xex_old_org .set -1
.macro xex_vprint arg
.if xex_verbose
.out .concat("xex.inc: ",arg)
.endif
.endmacro
.macro xex_warn arg
.if xex_verbose
.warning .concat("xex.inc: ",arg)
.endif
.endmacro
.macro xexstart startaddr, endaddr
.if xex_api_called = 0
.fatal "xex.inc: don't call xexstart directly, use xex_org."
.endif
xex_api_called .set 0
.if xex_old_org > -1
xex_endseg
.endif
.org 0 ; can be anything really...
.ifndef xex_ffff_emitted
.byte $ff,$ff
xex_ffff_emitted=1
xex_vprint .sprintf("starting segment %d at $%04x (with ffff header)", xex_segcount, startaddr)
.else
xex_vprint .sprintf("starting segment %d at $%04x", xex_segcount, startaddr)
.endif
.word startaddr
.word endaddr-1
.org startaddr
; we don't need a label here really, but define it so it shows up in
; the VICE label file created by -Ln.
.ident(.sprintf("xex_startaddr_%d", xex_segcount)):
xex_segcount .set xex_segcount + 1
.endmacro
.macro xex_org startaddr,limit
xex_api_called .set 1
xexstart startaddr,.ident(.sprintf("xex_endaddr_%d", xex_segcount))
xex_old_org .set startaddr
.ifblank limit
xex_limit .set $10000 ; impossibly high
.else
xex_limit .set limit
.endif
.endmacro
.macro xex_endseg
.local endaddr
endaddr = * - 1
.if xex_old_org < 0
xex_warn "xex_endseg called when not in a segment; harmless but redundant."
.exitmacro
.endif
.if endaddr < xex_old_org
.fatal .sprintf("cannot create an empty segment (start $%04x, end $%04x)", xex_old_org, endaddr)
.endif
.ident(.sprintf("xex_endaddr_%d", xex_segcount-1)):
xex_vprint .sprintf(" ending segment %d at $%04x, length $%04x", xex_segcount-1, endaddr, endaddr-xex_old_org+1)
xex_old_org .set -1
.assert .not (endaddr >= xex_limit), error, .sprintf("xex.inc: segment %d exceeds user-requested limit $%04x, by $%04x bytes", xex_segcount-1, xex_limit, endaddr - xex_limit + 1)
xex_limit .set $10000
.endmacro
.macro xex_run runaddr
xex_org RUNAD
.word runaddr
xex_endseg
xex_vprint .sprintf(" run address: $%04x", runaddr)
.ifndef xex_run_addr
xex_run_addr .set runaddr
.else
xex_warn .sprintf("multiple run addresses (previous was $%04x)", xex_run_addr)
xex_run_addr .set runaddr
.endif
.endmacro
.macro xex_init initaddr
xex_org INITAD
.word initaddr
xex_endseg
xex_vprint .sprintf(" init address: $%04x", initaddr)
.endmacro
.macro xex_incbin addr, filename, offset, length
.local o
.ifblank offset
o = 0
.else
o = offset
.endif
xex_org addr
.ifblank length
.incbin filename, o
.else
.incbin filename, o, length
.endif
xex_endseg
.endmacro
;;; THIS DOESN'T WORK!
.if 0
.macro xex_include addr, filename
xex_org addr
.out .sprintf("before include %s: %04x", filename, *)
.include filename
.out .sprintf("after include: %04x", *)
xex_endseg
.endmacro
.endif
|