git @ Cat's Eye Technologies SixtyPical / 6e8dc97
Fork the Atari 2600 Ophis example for easier comparing to 60p. Chris Pressey 3 years ago
5 changed file(s) with 532 addition(s) and 233 deletion(s). Raw diff Collapse all Expand all
+0
-168
eg/atari2600/atari-2600-example.60p less more
0 // atari-2600-example.60p - SixtyPical translation of atari-2600-example.oph
1
2 byte VSYNC @ $00
3 byte VBLANK @ $01
4 byte WSYNC @ $02
5 byte NUSIZ0 @ $04
6 byte NUSIZ1 @ $05
7 byte COLUPF @ $08
8 byte COLUBK @ $09
9 byte PF0 @ $0D
10 byte PF1 @ $0E
11 byte PF2 @ $0F
12 byte SWCHA @ $280
13 byte INTIM @ $284
14 byte TIM64T @ $296
15 byte CTRLPF @ $0A
16 byte COLUP0 @ $06
17 byte COLUP1 @ $07
18 byte GP0 @ $1B
19 byte GP1 @ $1C
20 byte HMOVE @ $2a
21 byte RESP0 @ $10
22 byte RESP1 @ $11
23
24 byte colour @ $80
25 byte luminosity @ $81
26 byte joystick_delay @ $82
27
28 byte table[8] image_data : 126, 129, 153, 165, 129, 165, 129, 126
29 // %01111110
30 // %10000001
31 // %10011001
32 // %10100101
33 // %10000001
34 // %10100101
35 // %10000001
36 // %01111110
37
38
39 define vertical_blank routine
40 outputs VSYNC, WSYNC, TIM64T
41 trashes a, x, z, n
42 {
43 ld x, $00
44 ld a, $02
45 st a, WSYNC
46 st a, WSYNC
47 st a, WSYNC
48 st a, VSYNC
49 st a, WSYNC
50 st a, WSYNC
51 ld a, $2C
52 st a, TIM64T
53 ld a, $00
54 st a, WSYNC
55 st a, VSYNC
56 }
57
58 define display_frame routine
59 inputs INTIM, image_data
60 outputs WSYNC, HMOVE, VBLANK, RESP0, GP0, PF0, PF1, PF2, COLUPF, COLUBK
61 trashes a, x, y, z, n
62 {
63 repeat {
64 ld a, INTIM
65 } until z
66
67 //; (After that loop finishes, we know the accumulator must contain 0.)
68
69 st a, WSYNC
70 st a, HMOVE
71 st a, VBLANK
72
73 //;
74 //; Wait for $3f (plus one?) scan lines to pass, by waiting for
75 //; WSYNC that many times.
76 //;
77
78 ld x, $3F
79 repeat {
80 st a, WSYNC
81 dec x
82 } until z // FIXME orig loop used "bpl _wsync_loop"
83 st a, WSYNC
84
85 //;
86 //; Delay while the raster scans across the screen. The more
87 //; we delay here, the more to the right the player will be when
88 //; we draw it.
89 //;
90
91 nop
92 nop
93 nop
94 nop
95 nop
96 nop
97 nop
98 nop
99 nop
100 nop
101 nop
102 nop
103 nop
104 nop
105 nop
106
107 //;
108 //; OK, *now* display the player.
109 //;
110
111 st a, RESP0
112
113 //;
114 //; Loop over the rows of the sprite data, drawing each to the screen
115 //; over four scan lines.
116 //;
117 //; TODO understand this better and describe it!
118 //;
119
120 ld y, $07
121 for y down to 0 {
122 ld a, image_data + y
123 st a, GP0
124
125 st a, WSYNC
126 st a, WSYNC
127 st a, WSYNC
128 st a, WSYNC
129 } // FIXME original was "dec y; bpl _image_loop"
130
131 ld a, $00
132 st a, GP0
133
134 //;
135 //; Turn off screen display and clear display registers.
136 //;
137
138 ld a, $02
139 st a, WSYNC
140 st a, VBLANK
141 ld a, $00
142 st a, PF0
143 st a, PF1
144 st a, PF2
145 st a, COLUPF
146 st a, COLUBK
147 }
148
149 define main routine
150 inputs image_data, INTIM
151 outputs CTRLPF, colour, luminosity, NUSIZ0, VSYNC, WSYNC, TIM64T, HMOVE, VBLANK, RESP0, GP0, PF0, PF1, PF2, COLUPF, COLUBK
152 trashes a, x, y, z, n
153 {
154 ld a, $00
155 st a, CTRLPF
156 ld a, $0c
157 st a, colour
158 ld a, $0a
159 st a, luminosity
160 ld a, $00
161 st a, NUSIZ0
162 repeat {
163 call vertical_blank
164 call display_frame
165 // call read_joystick
166 } forever
167 }
113113 main:
114114 jsr vertical_blank
115115 jsr display_frame
116 ;;; jsr read_joystick
116 jsr read_joystick
117117 jmp main
118 rts ;;;
119118
120119 ;
121120 ; Vertical blank routine.
255254 ; of the player.
256255 ;
257256
258 ;;; .scope
259 ;;; read_joystick:
260 ;;; lda joystick_delay
261 ;;; beq _continue
262 ;;;
263 ;;; dec joystick_delay
264 ;;; rts
265 ;;;
266 ;;; _continue:
267 ;;; lda SWCHA
268 ;;; and #$f0
269 ;;; cmp #$e0
270 ;;; beq _up
271 ;;; cmp #$d0
272 ;;; beq _down
273 ;;; cmp #$b0
274 ;;; beq _left
275 ;;; cmp #$70
276 ;;; beq _right
277 ;;; jmp _tail
278 ;;;
279 ;;; _up:
280 ;;; inc luminosity
281 ;;; jmp _tail
282 ;;; _down:
283 ;;; dec luminosity
284 ;;; jmp _tail
285 ;;; _left:
286 ;;; dec colour
287 ;;; jmp _tail
288 ;;; _right:
289 ;;; inc colour
290 ;;; ;jmp _tail
291 ;;;
292 ;;; _tail:
293 ;;; lda colour
294 ;;; and #$0f
295 ;;; sta colour
296 ;;;
297 ;;; lda luminosity
298 ;;; and #$0f
299 ;;; sta luminosity
300 ;;;
301 ;;; lda colour
302 ;;; clc
303 ;;; rol
304 ;;; rol
305 ;;; rol
306 ;;; rol
307 ;;; ora luminosity
308 ;;; sta COLUP0
309 ;;;
310 ;;; lda #$06
311 ;;; sta joystick_delay
312 ;;;
313 ;;; rts
314 ;;; .scend
257 .scope
258 read_joystick:
259 lda joystick_delay
260 beq _continue
261
262 dec joystick_delay
263 rts
264
265 _continue:
266 lda SWCHA
267 and #$f0
268 cmp #$e0
269 beq _up
270 cmp #$d0
271 beq _down
272 cmp #$b0
273 beq _left
274 cmp #$70
275 beq _right
276 jmp _tail
277
278 _up:
279 inc luminosity
280 jmp _tail
281 _down:
282 dec luminosity
283 jmp _tail
284 _left:
285 dec colour
286 jmp _tail
287 _right:
288 inc colour
289 ;jmp _tail
290
291 _tail:
292 lda colour
293 and #$0f
294 sta colour
295
296 lda luminosity
297 and #$0f
298 sta luminosity
299
300 lda colour
301 clc
302 rol
303 rol
304 rol
305 rol
306 ora luminosity
307 sta COLUP0
308
309 lda #$06
310 sta joystick_delay
311
312 rts
313 .scend
315314
316315 ;
317316 ; Player (sprite) data.
00 #!/bin/sh
11
2 sixtypical --prelude=atari2600 atari-2600-example.60p > atari-2600-example-60p.bin
2 sixtypical --prelude=atari2600 smiley.60p > smiley-60p.bin
33 if [ "x$COMPARE" != "x" ]; then
4 ophis atari-2600-example.oph -o atari-2600-example.bin
5 dcc6502 -o 0xf000 -m 200 atari-2600-example.bin > atari-2600-example.bin.disasm.txt
6 dcc6502 -o 0xf000 -m 200 atari-2600-example-60p.bin > atari-2600-example-60p.bin.disasm.txt
7 paste atari-2600-example.bin.disasm.txt atari-2600-example-60p.bin.disasm.txt | pr -t -e24
8 #diff -ru atari-2600-example.bin.disasm.txt atari-2600-example-60p.bin.disasm.txt
4 ophis smiley.oph -o smiley.bin
5 dcc6502 -o 0xf000 -m 200 smiley.bin > smiley.bin.disasm.txt
6 dcc6502 -o 0xf000 -m 200 smiley-60p.bin > smiley-60p.bin.disasm.txt
7 paste smiley.bin.disasm.txt smiley-60p.bin.disasm.txt | pr -t -e24
98 fi
0 // smiley.60p - SixtyPical translation of smiley.oph (2018),
1 // which is itself a stripped-down version of atari-2600-example.oph
2
3 byte VSYNC @ $00
4 byte VBLANK @ $01
5 byte WSYNC @ $02
6 byte NUSIZ0 @ $04
7 byte NUSIZ1 @ $05
8 byte COLUPF @ $08
9 byte COLUBK @ $09
10 byte PF0 @ $0D
11 byte PF1 @ $0E
12 byte PF2 @ $0F
13 byte SWCHA @ $280
14 byte INTIM @ $284
15 byte TIM64T @ $296
16 byte CTRLPF @ $0A
17 byte COLUP0 @ $06
18 byte COLUP1 @ $07
19 byte GP0 @ $1B
20 byte GP1 @ $1C
21 byte HMOVE @ $2a
22 byte RESP0 @ $10
23 byte RESP1 @ $11
24
25 byte colour @ $80
26 byte luminosity @ $81
27 byte joystick_delay @ $82
28
29 byte table[8] image_data : 126, 129, 153, 165, 129, 165, 129, 126
30 // %01111110
31 // %10000001
32 // %10011001
33 // %10100101
34 // %10000001
35 // %10100101
36 // %10000001
37 // %01111110
38
39
40 define vertical_blank routine
41 outputs VSYNC, WSYNC, TIM64T
42 trashes a, x, z, n
43 {
44 ld x, $00
45 ld a, $02
46 st a, WSYNC
47 st a, WSYNC
48 st a, WSYNC
49 st a, VSYNC
50 st a, WSYNC
51 st a, WSYNC
52 ld a, $2C
53 st a, TIM64T
54 ld a, $00
55 st a, WSYNC
56 st a, VSYNC
57 }
58
59 define display_frame routine
60 inputs INTIM, image_data
61 outputs WSYNC, HMOVE, VBLANK, RESP0, GP0, PF0, PF1, PF2, COLUPF, COLUBK
62 trashes a, x, y, z, n
63 {
64 repeat {
65 ld a, INTIM
66 } until z
67
68 //; (After that loop finishes, we know the accumulator must contain 0.)
69
70 st a, WSYNC
71 st a, HMOVE
72 st a, VBLANK
73
74 //;
75 //; Wait for $3f (plus one?) scan lines to pass, by waiting for
76 //; WSYNC that many times.
77 //;
78
79 ld x, $3F
80 repeat {
81 st a, WSYNC
82 dec x
83 } until z // FIXME orig loop used "bpl _wsync_loop"
84 st a, WSYNC
85
86 //;
87 //; Delay while the raster scans across the screen. The more
88 //; we delay here, the more to the right the player will be when
89 //; we draw it.
90 //;
91
92 nop
93 nop
94 nop
95 nop
96 nop
97 nop
98 nop
99 nop
100 nop
101 nop
102 nop
103 nop
104 nop
105 nop
106 nop
107
108 //;
109 //; OK, *now* display the player.
110 //;
111
112 st a, RESP0
113
114 //;
115 //; Loop over the rows of the sprite data, drawing each to the screen
116 //; over four scan lines.
117 //;
118 //; TODO understand this better and describe it!
119 //;
120
121 ld y, $07
122 for y down to 0 {
123 ld a, image_data + y
124 st a, GP0
125
126 st a, WSYNC
127 st a, WSYNC
128 st a, WSYNC
129 st a, WSYNC
130 } // FIXME original was "dec y; bpl _image_loop"
131
132 ld a, $00
133 st a, GP0
134
135 //;
136 //; Turn off screen display and clear display registers.
137 //;
138
139 ld a, $02
140 st a, WSYNC
141 st a, VBLANK
142 ld a, $00
143 st a, PF0
144 st a, PF1
145 st a, PF2
146 st a, COLUPF
147 st a, COLUBK
148 }
149
150 define colourize_player routine
151 inputs colour, luminosity
152 outputs COLUP0
153 trashes a, z, c, n
154 {
155 ld a, colour
156 st off, c
157 shl a
158 shl a
159 shl a
160 shl a
161 or a, luminosity
162 st a, COLUP0
163 }
164
165 define main routine
166 inputs image_data, INTIM
167 outputs CTRLPF, colour, luminosity, NUSIZ0, VSYNC, WSYNC, TIM64T, HMOVE, VBLANK, RESP0, GP0, PF0, PF1, PF2, COLUPF, COLUBK, COLUP0
168 trashes a, x, y, z, c, n
169 {
170 ld a, $00
171 st a, CTRLPF
172 ld a, $0c
173 st a, colour
174 ld a, $0a
175 st a, luminosity
176 ld a, $00
177 st a, NUSIZ0
178 repeat {
179 call vertical_blank
180 call display_frame
181 call colourize_player
182 } forever
183 }
0 ;
1 ; smiley.oph (2018)
2 ; stripped-down version of atari-2600-example.oph (2012)
3 ;
4 ; This work is in the public domain. See the file UNLICENSE for more info.
5 ;
6 ; to build and run in Stella:
7 ; ophis smiley.oph -o smiley.bin
8 ; stella smiley.bin
9
10 ;
11 ; Useful system addresses (TODO: briefly describe each of these.)
12 ;
13
14 .alias VSYNC $00
15 .alias VBLANK $01
16 .alias WSYNC $02
17 .alias NUSIZ0 $04
18 .alias NUSIZ1 $05
19 .alias COLUPF $08
20 .alias COLUBK $09
21 .alias PF0 $0D
22 .alias PF1 $0E
23 .alias PF2 $0F
24 .alias SWCHA $280
25 .alias INTIM $284
26 .alias TIM64T $296
27 .alias CTRLPF $0A
28 .alias COLUP0 $06
29 .alias COLUP1 $07
30 .alias GP0 $1B
31 .alias GP1 $1C
32 .alias HMOVE $2a
33 .alias RESP0 $10
34 .alias RESP1 $11
35
36 ;
37 ; Cartridge ROM occupies the top 4K of memory ($F000-$FFFF).
38 ; Thus, typically, the program will occupy all that space too.
39 ;
40 ; Zero-page RAM we can use with impunity starts at $80 and goes
41 ; upward (at least until $99, but probably further.)
42 ;
43
44 .alias colour $80
45 .alias luminosity $81
46 .alias joystick_delay $82
47
48 .org $F000
49
50 ;
51 ; Standard prelude for Atari 2600 cartridge code.
52 ;
53 ; Get various parts of the machine into a known state:
54 ;
55 ; - Disable interrupts
56 ; - Clear the Decimal flag
57 ; - Initialize the Stack Pointer
58 ; - Zero all bytes in Zero Page memory
59 ;
60
61 start:
62 sei
63 cld
64 ldx #$FF
65 txs
66 lda #$00
67
68 zero_loop:
69 sta $00, x
70 dex
71 bne zero_loop
72
73 ; and fall through to...
74
75 ;
76 ; Initialization.
77 ;
78 ; - Clear the Playfield Control register.
79 ; - Set the player (sprite) colour to light green (write to COLUP0.)
80 ; - Set the player (sprite) size/repetion to normal (write to NUSIZ0.)
81 ;
82
83 lda #$00
84 sta CTRLPF
85 lda #$0c
86 sta colour
87 lda #$0a
88 sta luminosity
89 lda #$00
90 sta NUSIZ0
91
92 ; and fall through to...
93
94 ;
95 ; Main loop.
96 ;
97 ; A typical main loop consists of:
98 ; - Waiting for the frame to start (vertical blank period)
99 ; - Displaying stuff on the screen (the _display kernel_)
100 ; - Doing any processing you like (reading joysticks, updating program state,
101 ; etc.), as long as you get it all done before the next frame starts!
102 ;
103
104 main:
105 jsr vertical_blank
106 jsr display_frame
107 jsr colourize_player
108 jmp main
109 rts ; NOTE just to pad out to match the SixtyPical version
110
111 ;
112 ; Vertical blank routine.
113 ;
114 ; In brief: wait until it is time for the next frame of video.
115 ; TODO: describe this in more detail.
116 ;
117
118 vertical_blank:
119 ldx #$00
120 lda #$02
121 sta WSYNC
122 sta WSYNC
123 sta WSYNC
124 sta VSYNC
125 sta WSYNC
126 sta WSYNC
127 lda #$2C
128 sta TIM64T
129 lda #$00
130 sta WSYNC
131 sta VSYNC
132 rts
133
134 ;
135 ; Display kernal.
136 ;
137 ; First, wait until it's time to display the frame.
138 ;
139
140 .scope
141 display_frame:
142 lda INTIM
143 bne display_frame
144
145 ;
146 ; (After that loop finishes, we know the accumulator must contain 0.)
147 ; Wait for the next scanline, zero HMOVE (for some reason; TODO discover
148 ; this), then turn on the screen.
149 ;
150
151 sta WSYNC
152 sta HMOVE
153 sta VBLANK
154
155 ;
156 ; Actual work in the display kernal is done here.
157 ;
158 ; This is a pathological approach to writing a display kernal.
159 ; This wouldn't be how you'd do things in a game. So be it.
160 ; One day I may improve it. For now, be happy that it displays
161 ; anything at all!
162 ;
163
164 ;
165 ; Wait for $3f (plus one?) scan lines to pass, by waiting for
166 ; WSYNC that many times.
167 ;
168
169 ldx #$3F
170 _wsync_loop:
171 sta WSYNC
172 dex
173 bpl _wsync_loop
174 sta WSYNC
175
176 ;
177 ; Delay while the raster scans across the screen. The more
178 ; we delay here, the more to the right the player will be when
179 ; we draw it.
180 ;
181
182 nop
183 nop
184 nop
185 nop
186 nop
187 nop
188 nop
189 nop
190 nop
191 nop
192 nop
193 nop
194 nop
195 nop
196 nop
197
198 ;
199 ; OK, *now* display the player.
200 ;
201
202 sta RESP0
203
204 ;
205 ; Loop over the rows of the sprite data, drawing each to the screen
206 ; over four scan lines.
207 ;
208 ; TODO understand this better and describe it!
209 ;
210
211 ldy #$07
212 _image_loop:
213 lda image_data, y
214 sta GP0
215
216 sta WSYNC
217 sta WSYNC
218 sta WSYNC
219 sta WSYNC
220 dey
221 bpl _image_loop
222
223 lda #$00
224 sta GP0
225
226 ;
227 ; Turn off screen display and clear display registers.
228 ;
229
230 lda #$02
231 sta WSYNC
232 sta VBLANK
233 lda #$00
234 sta PF0
235 sta PF1
236 sta PF2
237 sta COLUPF
238 sta COLUBK
239
240 rts
241 .scend
242
243 ;
244 ; Modify the colour and luminosity of the player.
245 ;
246
247 .scope
248 colourize_player:
249 lda colour
250 clc
251 rol
252 rol
253 rol
254 rol
255 ora luminosity
256 sta COLUP0
257 rts
258 .scend
259
260 ;
261 ; Player (sprite) data.
262 ;
263 ; Because we loop over these bytes with the Y register counting *down*,
264 ; this image is stored "upside-down".
265 ;
266
267 image_data:
268 .byte %01111110
269 .byte %10000001
270 .byte %10011001
271 .byte %10100101
272 .byte %10000001
273 .byte %10100101
274 .byte %10000001
275 .byte %01111110
276
277 ;
278 ; Standard postlude for Atari 2600 cartridge code.
279 ; Give BRK and boot vectors that point to the start of the code.
280 ;
281
282 .advance $FFFC
283 .word start
284 .word start