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
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
.Dd 26 February, 2024
.Dt U8ASM 5
.Os Ahoy 1.0.0
.Sh NAME
.Nm c8asm
.Nd the c8 assembly dialect
.Sh DESCRIPTION
The
.Nm
assembly dialect is the language understood by the
.Xr c8asm 1
assembler.
It is a small language consisting of only the few instructions and syntax
elements described in this manual.
A basic program to display the number 69 followed by an exclamation-mark
on the screen may look as follows:
.Bd -literal -offset indent
; Draw the sprite for ‘6’
ld v2 6
hex v2
drw v0 v1 5
; Draw the sprite for ‘9’
ld v2 9
hex v2
add v0 5 ; Offset the X position by 5
drw v0 v1 5
; Draw the sprite for ‘!’
ld i exclamation_sprite
add v0 5
drw v0 v1 5
; Infinite loop
loop:
jp loop
exclamation_sprite:
db 0b1000'0000
db 0b1000'0000
db 0b1000'0000
db 0b0000'0000
db 0b1000'0000
.Ed
.Sh LANGUAGE SYNTAX
.Ss Encoding
All
.Nm
documents must be UTF-8 encoded.
No other encodings are valid.
.Ss Whitespace
Syntax elements are often separated by whitespace.
When mentioned in this document,
.Sq whitespace
refers to all Unicode codepoints with the property Pattern_White_Space.
.Ss Case
Unlike most assembly dialects,
.Nm
is case-sensitive.
This means that the labels
.Ql .foo
and
.Ql .FOO
are not interchangeable and neither are the instructions
.Ql add
and
.Ql ADD .
.Ss Labels
Labels are a way to assign names to a particular memory address.
They’re useful for referencing locations of sprites,
or instructions to jump to.
.Pp
A label is composed of a Unicode codepoint with the property XID_Start,
followed by zero-or-more Unicode codepoints with the property
XID_Continue.
In simple terms this means labels follow the same syntax rules as most
modern programming languages.
As an extension to the Unicode specification labels may also begin with
an underscore
.Pq Sq _ .
.Pp
All labels must be terminated by any amount of whitespace and a colon
.Pq Sq \&: .
.Pp
By default labels are globally scoped.
This means that if you define the label
.Ql foo ,
you’ll be able to reference that label from any file in your project.
To define a label local to the current file you can prefix it with a
period.
.Ss Instructions
The following is a list of available instructions in
.Nm ,
and a description of their behavior.
.Pp
The following terms are used in this section:
.Pp
.Bl -tag -compact -width "nibble, byte, and addr"
.It vx and vy
arbitrary v-registers
.Pq see: Sx Registers
.It nibble, byte, and addr
4-, 8-, and 12-bit integer literals
.It dt, st, i, and v0
the dt, st, i, and v0 registers
.El
.Pp
The instructions are as follows:
.Pp
.Bl -tag -width Ds
.It Ic add Ar i Ar vx , Ic add Ar vx Ar byte
Add the values of the first- and second oprands and store the result in
the first oprand.
.It Ic add Ar vx Ar vy
Add the values of
.Ar vx
and
.Ar vy
and store the result in
.Ar vx.
If the result is greater than 255 then
.Ar vf
is set to 1,
otherwise 0.
.It Ic and Ar vx Ar vy
Perform a bitwise-AND of
.Ar vx
and
.Ar vy
and store the result in
.Ar vx .
.It Ic bcd Ar vx
Store the hundreds-, tens-, and ones-digit of the BCD representation of
the value in
.Ar vx
to the memory addresses stored in
.Va i ,
.Va i+1 ,
and
.Va i+2 .
.It Ic call Ar addr
Push the current address to the top of the callstack and set the
instruction pointer to
.Ar addr .
.It Ic cls
Clear the display.
.It Ic db Ar byte ...
Insert the byte arguments literally into the assembled binary.
.It Ic drw Ar vx Ar vy Ar nibble
Draw the sprite pointed to by the
.Va i
register at the position
.Pq Va vx , Va vy
with a height of
.Ar nibble .
.It Ic hex Ar vx
Set the
.Va i
register to the address of the hexadecimal sprite corresponding to the
value of
.Ar vx .
.It Ic jp Ar addr
Set the instruction pointer to
.Ar addr .
.It Ic jp Ar v0 Ar addr
Set the instruction pointer to
.Ar v0
+
.Ar addr .
.It Ic ld Ar dt Ar vx , Ic ld Ar i Ar addr , Ic ld Ar st Ar vx , Ic ld Ar vx Ar byte , Ic ld Ar vx Ar dt , Ic ld Ar vx Ar vy
Store the value of the second oprand into the first oprand.
.It Ic ld Ar vx Ar k
Block until the user presses a key,
and store the value of the key pressed into
.Ar vx .
.It Ic or Ar vx Ar vy
Perform a bitwise-OR of
.Ar vx
and
.Ar vy
and store the result in
.Ar vx .
.It Ic ret
Pop an address off the top of the callstack and set the instruction
pointer to that location.
.It Ic rnd Ar vx Ar byte
Set
.Ar vx
to the bitwise-AND of a randomly-generated byte and the given
.Ar byte .
.It Ic rstr Ar vx
Reads data starting at the memory address stored in the
.Va i
register into the registers
.Va v0
though to
.Ar vx
inclusive.
.Pp
The
.Va i
register is incremented by
.Ar x .
.It Ic se Ar vx Ar byte , Ic se Ar vx Ar vy
Skip the next instruction if the two oprands are equal.
.It Ic shl Ar vx
Left-shift
.Ar vx
by 1 and store the result in
.Ar vx .
If the most-significant-byte of
.Ar vx
was 1
.Va vf
is set to 1
otherwise 0.
.It Ic shr Ar vx
Right-shift
.Ar vx
by 1 and store the result in
.Ar vx .
If the least-significant-byte of
.Ar vx
was 1
.Va vf
is set to 1
otherwise 0.
.It Ic sknp Ar vx
Skip the next instruction if the key with the value of
.Ar vx
is not pressed.
.It Ic skp Ar vx
Skip the next instruction if the key with the value of
.Ar vx
is pressed.
.It Ic sne Ar vx Ar byte , Ic sne Ar vx Ar vy
Skip the next instruction if the two oprands are not equal.
.It Ic stor Ar vx
Stores the values of the registers
.Va v0
through
.Ar vx
inclusive starting at the memory address stored in the
.Va i
register.
.Pp
The
.Va i
register is incremented by
.Ar x .
.It Ic subn Ar vx Ar vy
Subtract
.Ar vx
from
.Ar vy
and store the result in
.Ar vx .
If
.Ar vy
was greater than
.Ar vx
then
.Va vf
is set to 1 otherwise 0.
.It Ic sub Ar vx Ar vy
Subtract
.Ar vy
from
.Ar vx
and store the result in
.Ar vx .
If
.Ar vx
was greater than
.Ar vy
then
.Va vf
is set to 1 otherwise 0.
.It Ic sys Ar addr
Jump to a machine-code routine at the address
.Ar addr .
.Pp
Most interpreters completely ignore this instruction.
.It Ic xor Ar vx Ar vy
Perform a bitwise-XOR of
.Ar vx
and
.Ar vy
and store the result in
.Ar vx .
.El
.Ss Registers
The following registers are available for use in
.Nm
programs:
.TS
box;
c | c
l | r.
Name Size (Bits)
_
v0–vf 8
i 16
dt 8
st 8
.TE
.Pp
The
.Va v0 Ns – Ns Va ve
registers are general-purpose registers intended for use by the
programmer.
The
.Va vf
register is also a general-purpose register but is overriden by various
instructions which utilize it as a flags register.
.Pp
The
.Va i
register is intended to be used to store 12-bit memory addresses.
.Pp
The
.Va dt
and
.Va st
registers are special registers.
When non-zero they are decremented by 1 at a rate of 60 Hz.
Additionally, when the
.Va st
register is non-zero,
a monotone beep is played.
.Ss Integer Literals
The
.Nm
language supports non-negative binary-, octal-, decimal-, and hexadecimal
integer literals.
Integer literals are prefixed by a literal
.Sq 0
and a lowercase base-specifier,
but this prefix is optional for base-10 integers.
The base-specifiers are as follows:
.Pp
.Bl -tag -compact -width Ds
.It b
binary
.It o
octal
.It d
decimal
.It x
hexadecimal
.El
.Pp
The following table shows how different numbers can be represented in
different bases:
.Pp
.TS
box;
c | c | c | c
r | r | r | r.
Binary Octal Decimal Hexadecimal
_
0b01100000 0o140 96 0x60
0b00010011 0o023 19 0x13
0b01111111 0o177 127 0x7F
0b00111010 0o072 58 0x3A
.TE
.Pp
An apostrophe
.Pq Sq \(aq
can also be included anywhere in an integer literal
.Em after
the base-specifier as a digit-separator,
such as in
.Ql 0b1011\(aq1001 .
.Ss Strings
Strings are composed of an opening- and closing double quote
.Pq Sq \(dq
with zero-or-more bytes between them.
Strings can only be used as an argument to the
.Ql db
instruction and they expand to a sequence of bytes representing their
contents.
.Pp
The following two lines are equivalent:
.Bd -literal -offset indent
db "foo"
db 0x66 0x6F 0x6F
.Ed
.Sh SEE ALSO
.Xr ahoy 1 ,
.Xr c8asm 1 ,
.Xr c8dump 1
.Rs
.%A Thomas P. Greene
.%D 30th August, 1997
.%R Cowgod’s Chip-8 Technical Reference
.%U http://devernay.free.fr/hacks/chip8/C8TECH10.HTM
.Re
.Sh AUTHORS
.An Thomas Voss Aq Mt mail@thomasvoss.com
|