aboutsummaryrefslogtreecommitdiff
path: root/Makefile
blob: 36f950f0391f2df4ea17ce944d0a511f07abc66c (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# Makefile for Atari 800 Taipan, by B. Watson
# Written for GNU make, but seems to work with BSD make (though
# I don't test BSD make every time I change anything).

# cl65 binary:
CC=cl65

# System cl65 will compile for. Don't expect this to work if you change it
# (though possibly atarixl might work, with newer cc65s)
SYS=atari

# Optimization flags for cc65.
#COPT=-Oirs
COPT=-O

# This is used for embedding the date and git info in the game binary.
# It'll appear on the title screen.
VER=0.99alpha
TODAY=`date +%Y%m%d`
#BRANCH=`( git branch 2> /dev/null || echo ' NOGIT' )| cut -d' ' -f2`
REV=`git rev-parse --short HEAD 2>/dev/null || echo UNKNOWN`
#VERSION="v$(VER)-$(TODAY)-$(BRANCH)-$(REV)"
VERSION="v$(VER)-$(TODAY)-$(REV)"

# Memory layout. Controlled by the Makefile from now on, no longer
# hardcoded addresses in various scripts. These are in hex. If any
# of them are changed, you *must* run 'make clean'.

# Font.
FONT_ADDR=0x2000

# Title screen data will be decompressed to this address.
TITLE_DATA_ADDR=0x2400

# Title display list, decompression code, and menu code. Should be
# TITLE_DATA_ADDR plus 0x1744.
TITLE_CODE_ADDR=0x3b44

# Main game start address. All the code in TAIMAIN_C_SRC and
# TAIMAIN_ASM_SRC loads here. We get this address by looking for
# 'C code can load at' message when making newtitle.xex. It's the
# next byte after the end of the display list.
#TAIMAIN_ADDR=0x3d00
TAIMAIN_ADDR=0x3cc7

# Size of cc65 parameter stack in bytes.
STACK_SIZE=0x200

# for older cc65, we need a custom linker file.
#CFLAGS=-t $(SYS) -C custom.cfg -I. -L. $(COPT)

# for recent git cc65, we can reserve memory on the command line.
# -D__RESERVED_MEMORY__=1056 because cc65's default end of memory
# is $BC20, and we want it to end just below our font, which starts
# at $B800. cc65's runtime stack starts just below this, and is
# 2K in size (bottom is at 0xb000).
# -D__SYSTEM_CHECK__=1 stops cl65 from prepending a bit of code that
# checks to make sure there's enough memory. Older cc65 didn't do this,
# and I never missed it.
# The meaning of the -l flag is different between cc65-2.13.3
# and the later github cc65, so it's been removed here.
#CFLAGS=-t $(SYS) -T -I. -L. -Wl -D__SYSTEM_CHECK__=1 -Wl -D__RESERVED_MEMORY__=1056 $(COPT)

CFLAGS=-t $(SYS) -T -I. -L. -Wl -D__SYSTEM_CHECK__=1 -DFONT_ADDR=$(FONT_ADDR) --start-addr $(TAIMAIN_ADDR) -Wl -D__STACKSIZE__=$(STACK_SIZE) $(COPT) $(EXTRACFLAGS)

AS=ca65
ASFLAGS=
AR=ar65

# C compiler for host system. Currently only used for building convfont.
HOSTCC=gcc
HOSTCFLAGS=-Wall

# A few files have no make rules here. LORCHA.DAT is generated as a
# side-effect of generating taifont.xex. It's a 49-byte (7x7) blob of
# Atari "internal" screen codes.

# LORCHA.DAT, and PORTSTAT.DAT aren't deleted by a
# 'make clean'.

# romfont is the 1K font extracted from the Atari 800 OS, with a
# command like:
# dd if=atariosb.rom of=1 bs=256 skip=8 count=4
# ...where atariosb.rom comes from e.g. the PC-Xformer 2.5 zip file.

# The game binary:
XEX=taipan.xex

# All the C and asm sources for taimain.xex:
TAIMAIN_HDRS=sounds.h
TAIMAIN_C_SRC=taipan.c
TAIMAIN_ASM_SRC=rand.s draw_lorcha.s timed_getch.s portstat.s console.s ultostr.s soundasm.s explosion.s

# Comment these lines out to build without big number support.
# This will stop being possible at some point.
BIGNUM_SRC=bigfloat.s
BIGNUM_HDRS=bignum.h bigfloat.h
BIGNUM_CFLAGS=-DBIGNUM=BIGFLOAT

# Uncomment these for experimental int48 big numbers
#BIGNUM_SRC=bigint48.c
#BIGNUM_HDRS=bignum.h bigint48.h
#BIGNUM_CFLAGS=-DBIGNUM=BIGINT48

# Default rule for plain 'make' command is to build the binary.
all: $(XEX) tags

# I have F10 in my editor bound to 'make test', so:
test: all
	atari800 -nobasic $(XEX)

# ctags. I forgot it can handle cc65 asm source. One wrinkle: C
# identifiers get prepended with an underscore from the POV of assembly
# code, and asm identifiers need a leading underscore to be used from
# C. There's probably a clever way to get ctags to handle this, but I
# don't know it, so I wrote a perl script to do the job.
tags:
	@ctags $(TAIMAIN_C_SRC) $(TAIMAIN_ASM_SRC) 2>/dev/null && perl fixtags.pl tags || true

# The above is fast & easy, but from time to time it's necessary
# to test slow loading, make sure the title screen stuff works OK.
dos2: all
	cp dos2.atr.in dos2.atr
	cp taipan.xex TAIPAN
	axe -w TAIPAN dos2.atr
	rm -f TAIPAN
	atari800 -nobasic -nopatch dos2.atr

fenders: all
	cp taipan.xex TAIPAN
	cp fenders.atr.in fenders.atr
	axe -w TAIPAN fenders.atr
	rm -f TAIPAN
	atari800 -nopatch fenders.atr

mydos: all
	cp taipan.xex TAIPAN
	cp mydos.atr.in mydos.atr
	axe -w TAIPAN mydos.atr
	rm -f TAIPAN
	atari800 -nopatch mydos.atr


# The game binary is a multi-part binary load file. This rule
# depends on all the pieces, and just concatenates them.
$(XEX): checkmem.xex taimain.xex taifont.xex newtitle.xex comptitle.xex
	perl multixex.pl checkmem.xex comptitle.xex newtitle.xex taifont.xex taimain.xex > $(XEX)
	perl size.pl $(TAIMAIN_ADDR) $(STACK_SIZE)

# Bitmap data for the title screen, 256x184 = 47104 pixels, 8 bits
# per pixel, or 5888 bytes. Displayed in ANTIC mode F (aka GR.8),
# using GTIA narrow playfield. The original title screen for the Apple
# is a 280x192 bitmap with a few blank lines at the top & bottom. I
# squished it horizontally to 256 pixels and got rid of the blank lines,
# to save load time. Note that titledata.dat is not built into
# the game binary as-is: it's now used as input for creating
# comptitle.xex, the compressed title screen.
titledata.dat: newtitle.pl newtitle.png
	perl newtitle.pl > titledata.dat

# compressed title, for faster loading. see titlecompression.txt
# for gory details.
comptitle.xex: titledata.dat titlecomp.pl comptitle.s.in
	perl titlecomp.pl 133 < titledata.dat
	cl65 -l comptitle.lst -o comptitle.xex -t none --asm-define destination=$(TITLE_DATA_ADDR) comptitle.s

# tiny 1-sector memory checker, aborts the laod if a cart is present.
checkmem.xex: checkmem.s
	cl65 -o checkmem.xex -t none checkmem.s

# Init segment that loads after the title screen data. It sets up
# a custom display list and sets the GTIA for narrow playfield,
# then waits for a keypress. Afterwards, it restores the OS's
# display list and sets the GTIA back to normal, then exits.
# Notice this is built with "-t none" instead of "-t atari",
# since it's a lot easier to homebrew an init segment than it is
# to get cc65 to build an init segment (would need a custom linker
# script at least).
newtitle.xex: newtitle.s ver.dat help.dat
	cl65 -l newtitle.lst -m newtitle.map -o newtitle.xex -t none --asm-define screendata=$(TITLE_DATA_ADDR) --asm-define origin=$(TITLE_CODE_ADDR) newtitle.s

# Version number in Atari screen-data form
ver.dat: text2screen.pl
	echo "$(VERSION)" | perl text2screen.pl > ver.dat

# Help text for the title screen
help.dat: help.txt text2screen.pl
	perl text2screen.pl < help.txt > help.dat

#ver.dat: mkver.pl
#	perl mkver.pl $(VERSION) > ver.dat

# The main executable. All the C and asm code goes here, except the init
# segment in newtitle.s.
taimain.xex: $(TAIMAIN_C_SRC) $(TAIMAIN_ASM_SRC) $(TAIMAIN_HDRS) $(BIGNUM_SRC) $(BIGNUM_HDRS)
	cl65 -m taipan.map $(CFLAGS) $(BIGNUM_CFLAGS) -o taimain.xex $(TAIMAIN_C_SRC) $(TAIMAIN_ASM_SRC) $(BIGNUM_SRC)

#cl65 --mapfile taipan.map $(CFLAGS) -o taimain.xex taipan.c sounds.c rand.s draw_lorcha.s timed_getch.s jsleep.s portstat.s console.s

# With newer cc65s, I have to do this to get an assembly listing of just
# taipan.c. This rule not used as part of the main build, it's only for
# debugging.
taipan.lst: taipan.c
	cl65 -m taipan.map $(CFLAGS) -c -o /dev/null -l taipan.lst -T taipan.c

# Another such rule for sounds.c:
sounds.lst: sounds.c sounds.h
	cl65 -m sounds.map $(CFLAGS) -c -o /dev/null -l sounds.lst -T sounds.c

# The font gets loaded into RAM, in the area reserved by the
# -D__RESERVED_MEMORY__ option to cl65. To actually use the font,
# taimain.xex contains code that sets CHBAS ($02f4).
# Not mentioned in any make rule: convfont also creates LORCHA.DAT,
# which draw_lorcha.s depends on (so we touch draw_lorcha.s here).
taifont.xex: convfont romfont font
	cat romfont font | ./convfont -x > taifont.xex
	touch draw_lorcha.s

# Not part of the game binary. This just builds the font without the
# Atari 6-byte binary load header, for eyeballing it in bitmapdump.pl
# or converting to other formats.
taifont: convfont romfont font
	cat romfont font | ./convfont > taifont

# PORTSTAT.DAT gets incbin'ed directly in portstat.s. It's screen-code
# data for the static part of the port status screen, which ends up in
# an array that the C code can memcpy() into screen RAM as needed.
# This make rule actually runs atari800. For it to work, you'll need
# the H: device enabled, pointed at the current directory, and set
# to writable.
PORTSTAT.DAT: mkportstats.xex
	atari800 -nobasic mkportstats.xex
	touch portstat.s

# Host tool that builds our custom font from the data ripped out of
# the Apple version, plus the Atari OS ROM. Also, all the custom
# characters for the enemy ships are defined here (as hex data. Yes,
# I converted them manually from eyeballing a screenshot of the Apple
# combat screen).
convfont: convfont.c
	$(HOSTCC) $(HOSTCFLAGS) -DFONT_ADDR=$(FONT_ADDR) -o convfont convfont.c

# Cartridge-related targets. Build as a cart isn't really supported yet.

# mkcart turns a raw binary into an atar800 .cart image with 16-byte header.
mkcart: mkcart.c
	$(HOSTCC) $(HOSTCFLAGS) -o mkcart mkcart.c

# cc65 doc atari.html explains how to produce a raw binary file.
# we build it for $03ff because cc65-produced atari binaries always
# have an RTS as the first byte (for compatibility with SpartaDOS).
# the "tail -c+2" stuff removes the first byte, so we end up with
# a romable_taimain.raw that's ready to be copied to $0400 and run
# via "JSR $0400".
romable_taimain.raw: $(TAIMAIN_C_SRC) $(TAIMAIN_ASM_SRC) $(TAIMAIN_HDRS)
	rm -f taimain.xex
	$(MAKE) TAIMAIN_ADDR=0x3ff EXTRACFLAGS="-Wl -D__AUTOSTART__=1 -Wl -D__EXEHDR__=1 -DCART_TARGET=1 --asm-define CART_TARGET=1" taimain.xex
	tail -c+2 taimain.xex > romable_taimain.raw
	rm -f taimain.xex

# 512 bytes of $ff filler, for the last page of each code bank.  wasting
# this little bit of space simplifies the copying code in bank7.s, and
# guarantees I don't accidentally end up with a 0 in the "cart present"
# byte of the cart trailer.
fill512:
	perl -Mbytes -e 'print chr(0xff) x 512' > fill512

# 8192 bytes of $ff filler, for unused banks. Possibly these will be
# used for something like an interactive game manual/tutorial.
blankbank:
	perl -Mbytes -e 'print chr(0xff) x 8192' > blankbank

splitrom.raw.0:
splitrom.raw.1:
splitrom.raw.2:
splitrom.raw.3:
	split -b 7680 -a 1 -d romable_taimain.raw splitrom.raw.

bank0: splitrom.raw.0 fill512
	cat splitrom.raw.0 fill512 > bank0

bank1: splitrom.raw.1 fill512
	cat splitrom.raw.1 fill512 > bank1

bank2: splitrom.raw.2 fill512
	cat splitrom.raw.2 fill512 > bank2

bank3: splitrom.raw.3 bank3.s taifont
	cl65 -l bank3.lst -m bank3.map -t none -o bank3 bank3.s

bank7: bank7.s titledata.dat
	cl65 -l bank7.lst -m bank7.map -t none -o bank7 bank7.s

taipan.rom: bank0 bank1 bank2 bank3 bank7 blankbank
	cat bank0 bank1 bank2 bank3 blankbank blankbank blankbank bank7 > taipan.rom

cart: taipan.cart

taipan.cart: taipan.rom mkcart
	./mkcart -otaipan.cart -t13 taipan.rom
	./mkcart -ctaipan.cart

# Rules for building various file types with the cc65 toolchain.
.s.o:
	$(AS) $(ASFLAGS) -o $@ $<

.c.o:
	$(CC) $(CFLAGS) -c -o $@ $<

%.xex: %.c
	$(CC) --mapfile map $(CFLAGS) -o $@ $<

# Obligatory clean and distclean rules.
clean:
	rm -f *.o *.lst convfont *.xex AUTORUN.SYS taipan.atr ver.dat help.dat tags cartmsg.dat

distclean: clean
	rm -f *~ core .*.swp 1.* 2.* 1 2 3 map map.* *.map a b c foo bar baz comptitle.s comptitle.dat

push:
	sh push.sh

size: clean all
	perl size.pl $(TAIMAIN_ADDR) $(STACK_SIZE)

# Cruft. Was used for testing the enemy ship animation.
lorchatest: lorchatest.c draw_lorcha.s taifont.xex
	cl65 -t atari -O -T -o lorchatest1.xex lorchatest.c draw_lorcha.s
	cat taifont.xex lorchatest1.xex > lorchatest.xex
	atari800 -nobasic lorchatest.xex

#### cruft, from when I was planning to use a 32K cart:
# this was a blind alley: zlib is too slow to decompress, plus there's
# no need to compress taimain.xex since I'm able to use a 64K cart.

# gzip2deflate downloaded from https://github.com/pfusik/zlib6502
# I could have used deflator.c that ships with cc65's source, but
# it's deprecated by its own upstream (same author as gzip2deflate).
gzip2deflate: gzip2deflate.c
	$(HOSTCC) $(HOSTCFLAGS) -o gzip2deflate gzip2deflate.c

zlibtest.xex: gzip2deflate zlibtest.c zlibtestdata.s romable_taimain.raw
	gzip -9c < romable_taimain.raw | ./gzip2deflate > rom.dfl
	$(CC) -t atari -m zlibtest.map -l zlibtest.lst -Wl -D__SYSTEM_CHECK__=1 --start-addr 0x7000 -o zlibtest.xex zlibtest.c zlibtestdata.s
romable_taimain.xex: $(TAIMAIN_C_SRC) $(TAIMAIN_ASM_SRC) $(TAIMAIN_HDRS)
	rm -f taimain.xex
	$(MAKE) TAIMAIN_ADDR=0x3ff EXTRACFLAGS="-DCART_TARGET=1 --asm-define CART_TARGET=1"
	mv taimain.xex romable_taimain.xex

###

soundtest: sounds.c
	cl65 -DTESTXEX -t atari -o sounds.xex sounds.c
	atari800 -nobasic sounds.xex

# former textmode title screen, was generated by TITLE.LST. Replaced
# by graphical title screen.
#title.xex: TITLE.DAT
#	perl title.pl TITLE.DAT > title.xex

# old title
#$(XEX): taimain.xex taifont.xex title.xex
#	cat taifont.xex title.xex taimain.xex > $(XEX)