-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathASSEMBLER-ATARI2600
154 lines (145 loc) · 4.16 KB
/
ASSEMBLER-ATARI2600
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
PROCESSOR 6502
INCLUDE "vcs.h"
ORG $F000 ; Start of "cart area" (see Atari memory map)
StartFrame:
lda #%00000010 ; Vertical sync is signaled by VSYNC's bit 1...
sta VSYNC
REPEAT 3 ; ...and lasts 3 scanlines
sta WSYNC ; (WSYNC write => wait for end of scanline)
REPEND
lda #0
sta VSYNC ; Signal vertical sync by clearing the bit
PreparePlayfield: ; We'll use the first VBLANK scanline for setup
lda #$00 ; (could have done it before, just once)
sta ENABL ; Turn off ball, missiles and players
sta ENAM0
sta ENAM1
sta GRP0
sta GRP1
sta COLUBK ; Background color (black)
sta PF0 ; PF0 and PF2 will be "off" (we'll focus on PF1)...
sta PF2
lda #$FF ; Playfield collor (yellow-ish)
sta COLUPF
lda #$00 ; Ensure we will duplicate (and not reflect) PF
sta CTRLPF
ldx #0 ; X will count visible scanlines, let's reset it
REPEAT 37 ; Wait until this (and the other 36) vertical blank
sta WSYNC ; scanlines are finished
REPEND
lda #0 ; Vertical blank is done, we can "turn on" the beam
sta VBLANK
Scanline:
cpx #174 ; "HELLO WORLD" = (11 chars x 8 lines - 1) x 2 scanlines =
bcs ScanlineEnd ; 174 (0 to 173). After that, skip drawing code
txa ; We want each byte of the hello world phrase on 2 scanlines,
lsr ; which means Y (bitmap counter) = X (scanline counter) / 2.
tay ; For division by two we use (A-only) right-shift
lda Phrase,y ; "Phrase,Y" = mem(Phrase+Y) (Y-th address after Phrase)
sta PF1 ; Put the value on PF bits 4-11 (0-3 is PF0, 12-15 is PF2)
ScanlineEnd:
sta WSYNC ; Wait for scanline end
inx ; Increase counter; repeat untill we got all kernel scanlines
cpx #191
bne Scanline
Overscan:
lda #%01000010 ; "turn off" the beam again...
sta VBLANK ;
REPEAT 30 ; ...for 30 overscan scanlines...
sta WSYNC
REPEND
jmp StartFrame ; ...and start it over!
Phrase:
.BYTE %00000000 ; H
.BYTE %01000010
.BYTE %01111110
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %00000000
.BYTE %00000000 ; E
.BYTE %01111110
.BYTE %01000000
.BYTE %01111100
.BYTE %01000000
.BYTE %01000000
.BYTE %01111110
.BYTE %00000000
.BYTE %00000000 ; L
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01111110
.BYTE %00000000
.BYTE %00000000 ; L
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01111110
.BYTE %00000000 ; O
.BYTE %00000000
.BYTE %00111100
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %00111100
.BYTE %00000000
.BYTE %00000000 ; white space
.BYTE %00000000
.BYTE %00000000
.BYTE %00000000
.BYTE %00000000
.BYTE %00000000
.BYTE %00000000
.BYTE %00000000
.BYTE %00000000 ; W
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %01011010
.BYTE %00100100
.BYTE %00000000
.BYTE %00000000 ; O
.BYTE %00111100
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %01000010
.BYTE %00111100
.BYTE %00000000
.BYTE %00000000 ; R
.BYTE %01111100
.BYTE %01000010
.BYTE %01000010
.BYTE %01111100
.BYTE %01000100
.BYTE %01000010
.BYTE %00000000
.BYTE %00000000 ; L
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01000000
.BYTE %01111110
.BYTE %00000000
.BYTE %00000000 ; D
.BYTE %01111000
.BYTE %01000100
.BYTE %01000010
.BYTE %01000010
.BYTE %01000100
.BYTE %01111000
.BYTE %00000000 ; Last byte written to PF1 (important, ensures lower tip
; of letter "D" won't "bleeed")
ORG $FFFA ; Cart config (so 6502 can start it up)
.WORD StartFrame ; NMI
.WORD StartFrame ; RESET
.WORD StartFrame ; IRQ
END