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
|
; bank 7 of the cartridge image, to be built with -t none.
; this bank is the fixed bank, always mapped at $a000-$bfff, in
; the "left cartridge" area.
.macpack atari ; for scrcode (screen code) macro
.include "atari.inc"
; zero page temporaries
destptr = FR0
srcptr = FR1
; where the romable_taimain code was org'ed.
codedest = $0400
; address of the font, which lives in bank 3 of the cart.
font = $9c00
; cc65's atari.inc fails to define this standard Atari label.
CCNTL = $d500
; cart_trailer is my name for what the OS calls CARTLOC.
; cc65's atari.inc doesn't define it either.
cart_trailer = $bffa
.org $a000 ; left cartridge
screendata:
; uncompressed title screen bitmap, $1700 bytes
.incbin "titledata.dat"
.res $44, $ff ; fudge factor, keep the DL from crossing a 1K boundary
; newtitle.s is the display list and menu code. CART_TARGET is used
; for conditional assembly (to make it work from ROM).
CART_TARGET = 1
.include "newtitle.s"
; copy_31_pages:
; copy 7936 bytes from $8000-$9dff to (destptr).
; on exit, destptr points to the next 7936 byte chunk.
; copy_x_pages:
; as above, but accepts number of pages to copy in X register.
copy_31_pages:
ldx #$1f
copy_x_pages:
lda #$0
tay
sta srcptr
lda #$80
sta srcptr+1
@copypage:
lda (srcptr),y
sta (destptr),y
dey
bne @copypage
inc srcptr+1
inc destptr+1
dex
bne @copypage
init:
rts
mem_msg:
scrcode "Sorry, this game requires at least 32K"
mem_msg_len = * - mem_msg - 1
memory_error:
lda #$20 ; red BG
sta COLOR2
ldy #mem_msg_len
@mloop:
lda mem_msg,y
sta (SAVMSC),y
dey
bpl @mloop
@hang:
bmi @hang
cartstart:
lda RAMTOP
cmp #$80
bne memory_error
; turn off ANTIC DMA to speed up copying to RAM
lda #0
sta SDMCTL
sta DMACTL
; copy code to RAM
lda #<codedest
sta destptr
lda #>codedest
sta destptr+1
lda #0 ; bank 0...
sta CCNTL ; ...select it
jsr copy_31_pages
lda #1 ; bank 1...
sta CCNTL ; ...select it
jsr copy_31_pages
lda #2 ; bank 2...
sta CCNTL ; ...select it
jsr copy_31_pages
lda #3 ; bank 3...
sta CCNTL ; ...select it
ldx #(>BANK3SIZE)+1 ; BANK3SIZE defined on the command line
jsr copy_x_pages
.out .sprintf("BANK3SIZE %x (%x pages)", BANK3SIZE, (>BANK3SIZE)+1)
; leave bank 3 enabled, as it has our custom font in it
lda #1
sta COLDST ; System Reset = reboot
jsr start ; 'start' is from newtitle.s
jsr codedest ; run the game (romable_taimain)
jmp cartstart ; redisplay title screen if "play again? N"
.if * > cart_trailer
.fatal "bank7 code too large"
.else
.out .sprintf("=> %d bytes free in bank 7", cart_trailer - *)
.endif
; fill with 1 bits until the cart trailer
.res cart_trailer - *, $ff
; trailer (some docs called it a 'header' but, eh, it doesn't come at
; the head of the cart...)
; see Mapping the Atari's entry for 'Cartridge B' or the Tech Ref Manual
; for a description of this.
.word cartstart ; entry point
.byte 0 ; 0 = cartridge present
.byte 4 ; init and run the cart, don't boot the disk, non-diagnostic
.word init ; init address (just an RTS)
|