-
Notifications
You must be signed in to change notification settings - Fork 1
/
GFMASM.SRC
480 lines (401 loc) · 9.9 KB
/
GFMASM.SRC
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
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
[number match level address z80 print disk full map]
BEGIN
SET ASCII_A = ^h41
SET ASCII_B = ^h42
SET ASCII_C = ^h43
SET ASCII_D = ^h44
SET ASCII_E = ^h45
SET ASCII_F = ^h46
SET ASCII_G = ^h47
SET ASCII_H = ^h48
SET ASCII_I = ^h49
SET ASCII_J = ^h4A
SET ASCII_K = ^h4B
SET ASCII_L = ^h4C
SET ASCII_M = ^h4D
SET ASCII_N = ^h4E
SET ASCII_O = ^h4F
SET ASCII_P = ^h50
SET ASCII_Q = ^h51
SET ASCII_R = ^h52
SET ASCII_S = ^h53
SET ASCII_T = ^h54
SET ASCII_U = ^h55
SET ASCII_V = ^h56
SET ASCII_W = ^h57
SET ASCII_X = ^h58
SET ASCII_Y = ^h59
SET ASCII_Z = ^h5A
SET ASCII_0 = ^h30
SET ASCII_1 = ^h31
SET ASCII_2 = ^h32
SET ASCII_3 = ^h33
SET ASCII_4 = ^h34
SET ASCII_5 = ^h35
SET ASCII_6 = ^h36
SET ASCII_7 = ^h37
SET ASCII_8 = ^h38
SET ASCII_9 = ^h39
STRING DEBUG_STR 5;
POINTER TO BYTE DEBUG_POINTER VALUE #DEBUG_STR;
STRING LENGTHSTR 20 VALUE "LENGTH:"
BYTE INCHAR;
STRING INBUFFER 512;
FILE INFILE DISK FILE1 TEXT RECORD INCHAR BUFFER INBUFFER;
BYTE OUTCHAR;
STRING OUTBUFFER 512;
FILE OUTFILE DISK TEXT RECORD OUTCHAR BUFFER OUTBUFFER VALUE "SONG.BIN";
WORD OUTLENGTH VALUE 0;
BYTE LASTCHAR;
WORD LINENUM VALUE 1;
OPEN INFILE INPUT;
OPEN OUTFILE OUTPUT;
DISPLAY "ASSEMBLING SONG.BIN...";
READ INFILE;
WHILE INCHAR <> ^h1A DO
{--DISPLAY "PARSING CHARACTER"
SWITCH ON INCHAR:
ASCII_D: CALL SUB_PARSE_DETUNE;
ASCII_E: CALL SUB_PARSE_END;
ASCII_I: CALL SUB_PARSE_INSTRUMENT;
ASCII_K, ASCII_O: CALL SUB_PARSE_KEY;
ASCII_L: CALL SUB_PARSE_LOOP;
ASCII_R: CALL SUB_PARSE_REPEAT;
ASCII_T: CALL SUB_PARSE_TEMPO;
ASCII_V: CALL SUB_PARSE_VOL;
ASCII_W: CALL SUB_PARSE_WAIT;
^h2A: CALL SUB_SKIP_LINE;
ENDSWITCH;
IF INCHAR = ^h0A THEN
ADD 1 TO LINENUM;
FI;
READ INFILE;
OD;
DISPLAY "WARNING: NO END COMMAND SPECIFIED";
GOTO FINISH;
GOTO END;
SUB_PARSE_END:
MOVE ^h0F TO OUTCHAR;
CALL WRITEBYTE;
MOVE ^hFF TO OUTCHAR;
CALL WRITEBYTE;
FINISH:
CLOSE INFILE;
CLOSE OUTFILE;
DISPLAY "ASSEMBLY SUCCESS";
CONVERT OUTLENGTH TO HEX DEBUG_STR;
DISPLAY DEBUG_STR, " BYTES";
GOTO END;
EXIT;
SUB_PARSE_DETUNE:
{--DISPLAY "PARSING DETUNE";
MOVE ^h40 TO OUTCHAR;
CALL SUB_SKIP_WORD;
CALL SUB_PARSE_NIBBLE;
ADD LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_PARSE_BYTE;
MOVE LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
EXIT;
SUB_PARSE_INSTRUMENT:
{--DISPLAY "PARSING INSTRUMENT";
MOVE ^h20 TO OUTCHAR;
CALL SUB_SKIP_WORD;
CALL SUB_PARSE_NIBBLE;
ADD LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_PARSE_BYTE;
MOVE LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
EXIT;
SUB_PARSE_KEY:
{--DISPLAY "PARSING KEY";
WHILE INCHAR <> ^h0A DO
IF INCHAR = ASCII_N THEN
{--DISPLAY "PARSING KEY ON";
MOVE ^h10 TO OUTCHAR;
CALL SUB_SKIP_WORD;
CALL SUB_PARSE_NIBBLE;
IF LASTCHAR = ^h06 THEN
MOVE ^h16 TO OUTCHAR;
CALL WRITEBYTE;
MOVE ^b00100000 TO OUTCHAR;
WHILE INCHAR <> ^h0A DO
SWITCH ON INCHAR
ASCII_B: ADD ^b00010000 TO OUTCHAR;
ASCII_S: ADD ^b00001000 TO OUTCHAR;
ASCII_M: ADD ^b00000100 TO OUTCHAR;
ASCII_C: ADD ^b00000010 TO OUTCHAR;
ASCII_H: ADD ^b00000001 TO OUTCHAR;
ENDSWITCH;
READ INFILE;
OD;
CALL WRITEBYTE;
ELSE
ADD LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
WHILE INCHAR <> ^h0A DO
MOVE INCHAR TO @DEBUG_POINTER;
{--DISPLAY DEBUG_STR;
SWITCH ON INCHAR
ASCII_A - ASCII_G: GOTO LABEL_NOTE_FOUND;
ELSE NULL
ENDSWITCH;
READ INFILE;
OD;
DISPLAY "ERROR: EXPECTED NOTE, GOT NEWLINE";
GOTO QUIT;
LABEL_NOTE_FOUND:
SWITCH ON INCHAR
ASCII_C: MOVE ^h00 TO OUTCHAR;
ASCII_D: MOVE ^h02 TO OUTCHAR;
ASCII_E: MOVE ^h04 TO OUTCHAR;
ASCII_F: MOVE ^h05 TO OUTCHAR;
ASCII_G: MOVE ^h07 TO OUTCHAR;
ASCII_A: MOVE ^h09 TO OUTCHAR;
ASCII_B: MOVE ^h0B TO OUTCHAR;
ENDSWITCH;
READ INFILE;
IF INCHAR = ^h2B THEN
ADD 1 TO OUTCHAR;
READ INFILE;
FI;
IF INCHAR = ^h2D THEN
SUBTRACT 1 FROM OUTCHAR;
READ INFILE;
FI;
SWITCH ON INCHAR:
ASCII_0: MOVE ^h00 TO LASTCHAR;
ASCII_1: MOVE ^h01 TO LASTCHAR;
ASCII_2: MOVE ^h02 TO LASTCHAR;
ASCII_3: MOVE ^h03 TO LASTCHAR;
ASCII_4: MOVE ^h04 TO LASTCHAR;
ASCII_5: MOVE ^h05 TO LASTCHAR;
ASCII_6: MOVE ^h06 TO LASTCHAR;
ASCII_7: MOVE ^h07 TO LASTCHAR;
ASCII_8: MOVE ^h08 TO LASTCHAR;
ASCII_9: MOVE ^h09 TO LASTCHAR;
ASCII_A: MOVE ^h0A TO LASTCHAR;
ASCII_B: MOVE ^h0B TO LASTCHAR;
ASCII_C: MOVE ^h0C TO LASTCHAR;
ASCII_D: MOVE ^h0D TO LASTCHAR;
ASCII_E: MOVE ^h0E TO LASTCHAR;
ASCII_F: MOVE ^hFF TO LASTCHAR;
ELSE NULL;
ENDSWITCH;
IF INCHAR = ^hFF THEN
DISPLAY "ERROR: EXPECTED NUMBER, GOT SOMETHING ELSE";
GOTO QUIT;
FI;
MULTIPLY LASTCHAR BY 12;
ADD LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
FI;
{-- TODO CALCULATE AND EMIT NOTE VALUE FOR KEY ON
EXIT;
FI;
IF INCHAR = ASCII_F THEN
{--DISPLAY "PARSING KEY OFF";
MOVE ^h02 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_WORD;
CALL SUB_PARSE_NIBBLE;
MOVE LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
EXIT;
FI;
READ INFILE;
OD;
DISPLAY "ERROR: EXPECTED 'ON' OR 'OFF', GOT NEWLINE";
GOTO QUIT;
EXIT;
SUB_PARSE_LOOP:
{--DISPLAY "PARSING LOOP";
MOVE ^h04 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_WORD;
WHILE INCHAR <> ^h0A DO
IF INCHAR = ASCII_S THEN
MOVE ^h00 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
FI;
IF INCHAR = ASCII_N THEN
MOVE ^h01 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
FI;
READ INFILE;
OD;
DISPLAY "ERROR: EXPECTED 'START' OR 'END', GOT NEWLINE";
GOTO QUIT;
EXIT;
SUB_PARSE_REPEAT:
{--DISPLAY "PARSING REPEAT";
MOVE ^h04 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_WORD;
WHILE INCHAR <> ^h0A DO
IF INCHAR = ASCII_S THEN
MOVE ^h02 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
FI;
IF INCHAR = ASCII_N THEN
MOVE ^h03 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
FI;
READ INFILE;
OD;
DISPLAY "ERROR: EXPECTED 'START' OR 'END', GOT NEWLINE";
GOTO QUIT;
EXIT;
SUB_PARSE_TEMPO:
{--DISPLAY "PARSING TEMPO";
MOVE ^h01 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_WORD;
CALL SUB_PARSE_BYTE;
MOVE LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
SUB_PARSE_VOL:
{--DISPLAY "PARSING VOL";
MOVE ^h30 TO OUTCHAR;
CALL SUB_SKIP_WORD;
MOVE ^h10 TO LASTCHAR;
READ INFILE;
WHILE INCHAR <> ^h0A DO
SWITCH ON INCHAR:
ASCII_0: MOVE ^h00 TO LASTCHAR;
ASCII_1: MOVE ^h01 TO LASTCHAR;
ASCII_2: MOVE ^h02 TO LASTCHAR;
ASCII_3: MOVE ^h03 TO LASTCHAR;
ASCII_4: MOVE ^h04 TO LASTCHAR;
ASCII_5: MOVE ^h05 TO LASTCHAR;
ASCII_B: MOVE ^h06 TO LASTCHAR;
ASCII_H: MOVE ^h07 TO LASTCHAR;
ASCII_S: MOVE ^h08 TO LASTCHAR;
ASCII_M: MOVE ^h09 TO LASTCHAR;
ASCII_C: MOVE ^h0A TO LASTCHAR;
ELSE NULL;
ENDSWITCH;
IF LASTCHAR < ^h10 THEN
GOTO VOL_CHANNEL_FOUND;
FI;
READ INFILE;
OD;
DISPLAY "ERROR: EXPECTED CHANNEL, GOT NEWLINE";
DISPLAY "VALID CHANNELS ARE 0-5, B, S, H, M, and C";
GOTO QUIT;
VOL_CHANNEL_FOUND:
ADD LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_PARSE_NIBBLE;
MOVE LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
SUB_PARSE_WAIT:
{--DISPLAY "PARSING WAIT";
MOVE ^h03 TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_WORD;
CALL SUB_PARSE_BYTE;
MOVE LASTCHAR TO OUTCHAR;
CALL WRITEBYTE;
CALL SUB_SKIP_LINE;
EXIT;
SUB_SKIP_LINE:
{--DISPLAY "SKIPPING TO END OF LINE";
WHILE INCHAR <> ^h0A DO
READ INFILE;
OD;
EXIT;
SUB_SKIP_WORD:
{--DISPLAY "SKIPPING TO NEXT WORD";
WHILE INCHAR <> ^h20 DO
READ INFILE;
OD;
EXIT;
SUB_PARSE_BYTE:
{--DISPLAY "PARSING BYTE";
CALL SUB_PARSE_NIBBLE;
READ INFILE;
MOVE INCHAR TO @DEBUG_POINTER;
{--DISPLAY DEBUG_STR;
SWITCH ON INCHAR:
ASCII_0: MOVE ^h00 TO INCHAR;
ASCII_1: MOVE ^h01 TO INCHAR;
ASCII_2: MOVE ^h02 TO INCHAR;
ASCII_3: MOVE ^h03 TO INCHAR;
ASCII_4: MOVE ^h04 TO INCHAR;
ASCII_5: MOVE ^h05 TO INCHAR;
ASCII_6: MOVE ^h06 TO INCHAR;
ASCII_7: MOVE ^h07 TO INCHAR;
ASCII_8: MOVE ^h08 TO INCHAR;
ASCII_9: MOVE ^h09 TO INCHAR;
ASCII_A: MOVE ^h0A TO INCHAR;
ASCII_B: MOVE ^h0B TO INCHAR;
ASCII_C: MOVE ^h0C TO INCHAR;
ASCII_D: MOVE ^h0D TO INCHAR;
ASCII_E: MOVE ^h0E TO INCHAR;
ASCII_F: MOVE ^h0F TO INCHAR;
ELSE EXIT;
ENDSWITCH;
MULTIPLY LASTCHAR BY ^h10;
ADD INCHAR TO LASTCHAR;
EXIT;
SUB_PARSE_NIBBLE:
{--DISPLAY "PARSING NIBBLE";
MOVE ^h10 TO LASTCHAR;
READ INFILE;
WHILE INCHAR <> ^h0A DO
MOVE INCHAR TO @DEBUG_POINTER;
{--DISPLAY DEBUG_STR;
SWITCH ON INCHAR:
ASCII_0: MOVE ^h00 TO LASTCHAR;
ASCII_1: MOVE ^h01 TO LASTCHAR;
ASCII_2: MOVE ^h02 TO LASTCHAR;
ASCII_3: MOVE ^h03 TO LASTCHAR;
ASCII_4: MOVE ^h04 TO LASTCHAR;
ASCII_5: MOVE ^h05 TO LASTCHAR;
ASCII_6: MOVE ^h06 TO LASTCHAR;
ASCII_7: MOVE ^h07 TO LASTCHAR;
ASCII_8: MOVE ^h08 TO LASTCHAR;
ASCII_9: MOVE ^h09 TO LASTCHAR;
ASCII_A: MOVE ^h0A TO LASTCHAR;
ASCII_B: MOVE ^h0B TO LASTCHAR;
ASCII_C: MOVE ^h0C TO LASTCHAR;
ASCII_D: MOVE ^h0D TO LASTCHAR;
ASCII_E: MOVE ^h0E TO LASTCHAR;
ASCII_F: MOVE ^h0F TO LASTCHAR;
ELSE NULL;
ENDSWITCH;
IF LASTCHAR < ^h10 THEN
EXIT;
FI;
READ INFILE;
OD;
DISPLAY "ERROR: NUMBER EXPECTED, GOT NEWLINE";
GOTO QUIT;
EXIT;
WRITEBYTE:
WRITE OUTFILE;
ADD 1 TO OUTLENGTH;
EXIT;
QUIT:
CLOSE INFILE;
CLOSE OUTFILE REMOVE;
CONVERT LINENUM TO DEBUG_STR;
DISPLAY "ASSEMBLY FAILED ON LINE ", DEBUG_STR;
END;