forked from dhansel/Altair8800
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprog_examples_asm.h
490 lines (482 loc) · 15.7 KB
/
prog_examples_asm.h
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
481
482
483
484
485
486
487
488
489
490
// this gets included from prog_examples.cpp
const char asm_dump[] =
"\tORG\t20000Q\t;SET LOCATION COUNTER\r"
"DUMP:\tLHLD\tFIRST\t;GET ADDRESS OF FIRST BYTE TO BE DUMPED\r"
"\tXCHG\t\t;PUT ADDRESS IN D&E\r"
"NEWLN:\tLXI\tH,BUF\t;GET ADDDRESS OF OUTPUT BUFFER\r"
"\tPUSH\tH\t;SAVE ADDRESS\r"
"\tLHLD\tLAST\t;LOAD ADDRESS OF LAST BYTE TO BE DUMPED\r"
"\tMOV\tA,L\t;SUBTRACT LOW ORDER BYTES\r"
"\tSUB\tE\r"
"\tMOV\tA,H\t;SUBTRACT HIGH ORDER BYTE\r"
"\tSBB\tD\r"
"\tPOP\tH\t;RESTORE H&L\r"
"\tJC\tMON\t;JUMPS OUT IF NO MORE BYTES TO BE DUMPED\r"
"\tMOV\tA,D\t;START CONVERSION OF ADDRESS TO ASCII\r"
"\tRAL\t\t;ROTATE HIGH BIT INTO C\r"
"\tMVI\tA,0\t;ZERO OUT REST OF A BUT DONT CHANGE FLAGS\r"
"\tRAL\t\t;ROTATE HIGH BIT INTO LOW ORDER POSITION\r"
"\tORI\t60Q\t;OR IN ASCII 0\r"
"\tMOV\tM,A\t;STORE IN OUTPUT BUFFER\r"
"\tINX\tH\t;INCREMENT BUFFER POINTER\r"
"\tMOV\tA,D\t;PICK UP HIGH ORDER BITE AGAIN\r"
"\tRAR\t;ROTATE BITS 4,5,6 INTO LOW ORDER POSITIONS\r"
"\tRAR\r"
"\tRAR\r"
"\tRAR\r"
"\tANI\t7\t;MASK OFF ALL BITS EXCEPT LOW THREE\r"
"\tORI\t60Q\t;OR IN ASCII 0\r"
"\tMOV\tM,A\t;STORE IN OUTPUT BUFFER\r"
"\tINX\tH\t;INCREMENT POINTER INTO OUTPUT BUFFER\r"
"\tMOV\tA,D\t;PICK UP HIGH BYTE OF ADDRESS\r"
"\tRAR\t\t;ROTATE BITS 1,2,3 INTO LOW ORDER POSITION\r"
"\tANI\t7\t;MASK OFF ALL BITS EXCEPT LOW THREE\r"
"\tORI\t60Q\t;OR IN ASCII 0\r"
"\tMOV\tM,A\t;STORE IN OUTPUT BUFFER\r"
"\tINX\tH\t;INCREMENT POINTER INTO OUTPUT BUFFER\r"
"\tMOV\tA,D\t;PICK UP HIGH BYTE OF ADDRESS\r"
"\tRAR\t\t;SAVE LOW BIT IN THE CARRY FLAG\r"
"\tMOV\tA,E\t;PICK UP LOW BYTE OF ADDRESS\r"
"\tCALL\tLAST3\t;CALL SUBROUTINE THAT CONVERTS 3 DIGITS\r"
"\tMVI\tB,8\t;LOAD B WITH NO OF BYTES TO DUMP PER LINE\r"
"NXTNUM:\tPUSH\tH\t;SAVE H&L\r"
"\tLHLD\tLAST ;LOAD ADDRESS OF LAST BYTE TO DUMP\r"
"\tMOV\tA,L\t;DO THE DOUBLE WORD COMPARE AGAIN\r"
"\tSUB\tE\r"
"\tMOV\tA,H\r"
"\tSBB\tD\r"
"\tPOP\tH\t;RESTORE THE H&L REGISTERS\r"
"\tJC\tLNDN\t;JUMP TO ROUTINE TO FINISH UP IF DONE\r"
"\tMVI\tC,5\t;IF ANOTHER TO COME SEPERATE THEM BY 5 BLANKS\r"
"\tCALL\tBLANK\r"
"\tXRA\tA\t;SET THE CARRY FLAG TO 0\r"
"\tLDAX\tD\t;GET BYTE TO DUMP\r"
"\tCALL\tLAST3\t;CALL ROUTINE TO CONVERT 3 DIGITS\r"
"\tINX\tD\t;INCREMENT POINTER TO DUMP NEXT BYTE\r"
"CHKLN:\tDCR\tB\t;DECREMENT LINE BYTE COUNTER\r"
"\tJNZ\tNXTNUM\t;CONVERT NEXT NUMBER IF IT WILL FIT ON LINE\r"
"\tLXI\tB,OUT\t;GET ADDRESS OF MONITOR CONTROL BLOCK\r"
"\tCALL\tIO\t;WRITE OUT LINE\r"
"\tJMP\tNEWLN\t;JUMP TO WRITE OUT NEXT LINE\r"
"LNDN:\tMVI\tC,8\t;PAD LINE WITH 8 BLANKS FOR EACH NUMBER THAT\r"
"\tCALL\tBLANK\t;WOULD FIT\r"
"\tDCR\tB\t;DECREMENT NUMBERS THAT COULD FIT IN LINE\r"
"\tJNZ\tLNDN\t;LOOP UNTIL LINE FILLED WITH BLANKS\r"
"\tLXI\tB,OUT\t;GET ADDRESS OF MONITOR CONTROL BLOCK\r"
"\tCALL\tIO\t;WRITE OUT LINE\r"
"\tJMP\tMON\t;BACK TO MONITOR\r"
"BLANK:\tMVI\tA,40Q\t;PUT A ASCII BLANK IN A\r"
"BL:\tMOV\tM,A\t;STORE IT IN THE OUTPUT BUFFER\r"
"\tINX\tH\t;INCREMENT THE OUTPUT BUFFER POINTER\r"
"\tDCR\tC\t;DECREMENT THE NUMBER OF BLANKS TO STORE\r"
"\tJNZ\tBL\t;LOOP UNTIL ALL STORED\r"
"\tRET\t\t;RETURN TO CALLER\r"
"LAST3:\tPUSH\tPSW\t;SAVE BYTE TO CONVERT\r"
"\tRAL\t\t;ROTATE CARRY AND HIGH 2 BITS TO LOW ORDER\r"
"\tRAL\t\t;POSITION\r"
"\tRAL\r"
"\tANI\t7\t;MASK OFF ALL BUT LOW ORDER THREE BITS\r"
"\tORI\t60Q\t;OR IN A ASCII 0\r"
"\tMOV\tM,A\t;STORE DIGIT IN OUTPUT BUFFER\r"
"\tINX\tH\t;INCREMENT THE OUTPUT BUFFER POINTER\r"
"\tPOP\tPSW\t;POP BYTE TO CONVERT\r"
"\tPUSH\tPSW\t;SAVE FOR LATER ALSO\r"
"\tRAR\t\t;ROTATE BITS 3,4,5 INTO LOW ORDER POSITION\r"
"\tRAR\r"
"\tRAR\r"
"\tANI\t7\t;MASK OFF ALL BUT LOW THREE BITS\r"
"\tORI\t60Q\t;OR IN AN ASCII 0\r"
"\tMOV\tM,A\t;STORE DIGIT IN OUTPUT BUFFER\r"
"\tINX\tH\t;INCREMENT OUTPUT BUFFER POINTER\r"
"\tPOP\tPSW\t;POP BYTE TO CONVERT\r"
"\tANI\t7\t;MASK OFF ALL BUT LOW THREE BYTES\r"
"\tORI\t60Q\t;OR IN ASCII 0\r"
"\tMOV\tM,A\t;STORE DIGIT IN OUTPUT BUFFER\r"
"\tINX\tH\t;INCREMENT OUTPUT BUFFER POINTER\r"
"\tRET\t\t;RETURN TO CALLER\r"
"OUT:\tDB\t22Q\t;MONITOR WRITE OPERATION CODE\r"
"\tDB\t\"LST\"\t;SYMBOLIC DEVICE TO WRITE ON\r"
"\tDW\tBUF\t;ADDRESS OF OUTPUT BUFFER\r"
"\tDW\t72\t;WRITE OUT 72 CHARATERS\r"
"\tDW\tSTAT\t;ADDRESS OF STATUS WORD\r"
"STAT:\tDW\t0\r"
"FIRST:\tDW\t15100Q\r"
"LAST:\tDW\t15272Q\r"
"BUF:\tDS\t70\t;RESERVE 70 MEMORY LOCATIONS\r"
"\tDB\t15Q\t;ASCII CARRIAGE RETURN\r"
"\tDB\t12Q\t;ASCII LINE FEED\r"
"\tBEG\tDUMP\t;SETS ADDRESS OF PLACE TO START PROGRAM\r"
"\tEND\tDMP\r";
/* this can't work with PS2: It HAS to be located in first
page (0x0000-0x00FF). Otherwise the result lights A8-A15 will
light up incorrectly because instructions are read from that
region. However, PS2 does not allow any program to be loaded
in the same memory space as the monitor (0x0000-0x0A40). */
const char asm_calc[] =
"\tORG\t0H\r"
"\tORR\t2000H\r"
"START:\tLXI\tB,0H\t;CLEAR B (SUM) AND C\r"
"DISP:\tIN\t0FFH\t;READ SENSE SWITCHES\r"
"\tANI\t80H\t;ISOLATE HIGHEST BIT\r"
"\tMOV\tD,A\t;REMEMBER IN D\r"
"LOOP:\tLDAX\tB\t;SHOW CONTENT OF B ON A8-A15 LEDS\r"
"\tLDAX\tB\t;(C SHOWS ON A0-A7 BUT IS ALWAYS 0)\r"
"\tLDAX\tB\r"
"\tLDAX\tB\r"
"\tLDAX\tB\r"
"\tLDAX\tB\r"
"\tIN\t0FFH\t;READ SENSE SWITCHES\r"
"\tXRA\tD\t;HAS HIGHEST BIT CHANGED?\r"
"\tJP\tLOOP\t;LOOP IF NO CHANGE\r"
"\tMOV\tE,A\t;SAVE FULL INPUT IN E\r"
"\tANI\t2FH\t;ISOLATE LOWER 5 BITS\r"
"\tMOV\tD,A\t;SAVE INPUT VALUE IN D\r"
"\tMOV\tA,E\t;GET FULL INPUT BACK\r"
"\tANI\t60H\t;ISOLATE BITS 5+6\r"
"\tCPI\t00H\t;BITS 5/6 = 00?\r"
"\tJZ\tADD\t;=> ADDITION\r"
"\tCPI\t20H\t;BITS 5/6 = 01?\r"
"\tJZ\tSUB\t;=> SUBTRACTION\r"
"\tCPI\t40H\t;BITS 5/6 = 10?\r"
"\tJZ\tMLT\t;=> MULTIPLICATION\r"
"\tINR\tD\r"
"\tDCR\tD\r"
"\tJNZ\tDIV\t;DIVISOR = 0?\r"
"\tJMP\tMON\t;DIVISION BY ZERO => RETURN TO MONITOR\r"
"\tJMP\tDISP\t;START OVER\r"
"DIV:\tMOV\tA,B ;MOVE DIVIDENT TO A\r"
"\tMVI\tE,00H\t;RESULT <- 0\r"
"DIVL:\tINR\tE\t;INCREMENT RESULT\r"
"\tSUB\tD\t;SUBTRACT DIVISOR\r"
"\tJZ\tDIVD\t;IF =0 THEN WE'RE DONE\r"
"\tJNC\tDIVL\t;IF >0 (NO UNDERFLOW) THEN SUBTRACT AGAIN\r"
"\tADD\tD\t;ADD BACK DIVISOR TO GET REMAINDER\r"
"\tDCR\tE\t;DECREMENT RESULT (SINCE WE OVERSHOT)\r"
"\tCMC\t\t;CLEAR CARRY (IS SET AT THIS POINT)\r"
"\tRLC\t\t;MULTIPLY REMAINDER BY 2\r"
"\tCMP\tD\t;COMPARE REMAINDER TO DIVISOR\r"
"\tJM\tDIVD\t;IF 2*REMAINDER < DIVISOR THEN WE'RE DONE (ROUNDED DOWN)\r"
"\tINR\tE\t;OTHERWISE WE ROUND UP\r"
"DIVD:\tMOV\tB,E\t;MOVE RESULT TO B\r"
"\tJMP\tDISP\t;START OVER\r"
"SUB:\tMOV\tA,B\t;MOVE MINUEND TO A\r"
"\tSUB\tD\t;SUBTRACT (SUBTRAHEND IS IN D)\r"
"\tJMP\tDONE\t;FINISH UP\r"
"ADD:\tMOV\tA,B\t;MOVE ADDEND 1 TO A\r"
"\tADD\tD\t;ADD (ADDEND 2 IS IN D)\r"
"\tJMP\tDONE\t;FINISH UP\r"
"MLT:\tMVI\tA,00H\t;RESULT IS 0\r"
"\tCMP\tD\t;IF MULTIPLICATOR IS 0\r"
"\tJZ\tDONE\t;THEN WE'RE DONE\r"
"MLTL:\tADD\tB\t;ADD MULTIPLICANT\r"
"\tDCR\tD\t;DECREMENT MULTIPLICATOR\r"
"\tJNZ\tMLTL\t;REPEAT IF MULTIPLICATOR>0\r"
"DONE:\tMOV\tB,A\t;MOVE RESULT TO B\r"
"\tJMP\tDISP\t;START OVER\r"
"\tBEG\tSTART\r"
"\tEND\tCALC\r";
const char asm_pong[] =
"\tORG\t2000H\r"
"\t;INITIALIZE SCREEN\r"
"START:\tLXI\tSP,STCK\t;SET STACK POINTER\r"
"\tLXI\tH,INITS\t;CLEAR SCREEN AND HIDE CURSOR\r"
"\tCALL\tSTROUT\r"
"\t;INITIALIZE SCORE\r"
"\tMVI\tA,0\t;SET INITIAL SCORES TO 0\r"
"\tSTA\tSCR1\r"
"\tSTA\tSCR2\r"
"\tCALL\tPSCR\t;PRINT INITIAL SCORES\r"
"\t;INITIALIZE PLAYERS\r"
"\tMVI\tA,9\t;PLAYER 1 STARTS AT ROW 9\r"
"\tSTA\tP1R\r"
"\tMOV\tD,A\r"
"\tMVI\tA,9\t;PLAYER 2 STARTS AT ROW 9\r"
"\tSTA\tP2R\r"
"\tMOV\tE,A\r"
"\tMOV\tB,D\t;MOVE CURSOR TO ROW/COL OF PLAYER 1\r"
"\tMVI\tC,1\r"
"\tCALL\tMOVC\r"
"\tLXI\tH,PLYRS\t;DISPLAY PLAYER\r"
"\tCALL\tSTROUT\r"
"\tMOV\tB,E\t;MOVE CURSOR TO ROW/COL OF PLAYER 2\r"
"\tMVI\tC,70\r"
"\tCALL\tMOVC\r"
"\tLXI\tH,PLYRS\t;DISPLAY PLAYER\r"
"\tCALL\tSTROUT\r"
"\t;INITIALIZE BALL\r"
"\tMVI\tB,089H\t;START AT ROW 9,GOING DOWN\r"
"\tMVI\tC,0A3H\t;START AT COLUMN 35,GOING RIGHT\r"
"\t;MANAGE VERTICAL BALL DIRECTION\r"
"LOOP:\tMOV\tA,B\t;CHECK ROW\r"
"\tANI\t7FH\t;MASK OUT BIT 7\r"
"\tCPI\t20\t;AT ROW 20?\r"
"\tJNZ\tL1\r"
"\tMOV\tB,A\t;YES => CLEAR BIT 7 (REVERSE DIRECTION)\r"
"L1:\tCPI\t2\t;AT ROW 2?\r"
"\tJNZ\tL2\r"
"\tORI\t80H\t;YES => SET BIT 7 (REVERSE DIRECTION)\r"
"\tMOV\tB,A\r"
"\t;MANAGE HORIZONTAL BALL DIRECTION\r"
"L2:\tMOV\tA,B\t;BALL ROW TO H\r"
"\tANI\t7FH\r"
"\tMOV\tH,A\r"
"\tMOV\tA,C\t;BALL COLUMN TO L\r"
"\tANI\t7FH\r"
"\tMOV\tL,A\r"
"\tCPI\t69\t;CHECK IF COLUMN = 69\r"
"\tJNZ\tL41\r"
"\tMOV\tA,H\r"
"\tCMP\tE\r"
"\tJM\tSCP1\t;BALL ROW < PLAYER 2 => PLAYER 1 SCORES\r"
"\tSUI\t3\r"
"\tCMP\tE\r"
"\tJP\tSCP1\t;BALL ROW - 3 >= PLAYER 2 => PLAYER 1 SCORES\r"
"\tMOV\tC,L\t;MAKE BALL MOVE LEFT\r"
"\tJMP\tL42\r"
"L41:\tMOV\tA,L\r"
"\tCPI\t2\t;CHECK IF COLUMN = 2\r"
"\tJNZ\tL42\r"
"\tMOV\tA,H\r"
"\tCMP\tD\r"
"\tJM\tSCP2\t;BALL ROW < PLAYER 1 => PLAYER 2 SCORES\r"
"\tSUI\t3\r"
"\tCMP\tD\r"
"\tJP\tSCP2\t;BALL ROW - 3 >= PLAYER 1 => PLAYER 2 SCORES\r"
"\tMOV\tA,L\t;MAKE BALL MOVE RIGHT\r"
"\tORI\t80H\r"
"\tMOV\tC,A\r"
"L42:\tPUSH\tB\t;SAVE BALL POSITION\r"
"\t; CHECK INPUTS\r"
"CHKIN:\tIN\t10H\r"
"\tRRC\r"
"\tJNC\tMPLYR\r"
"\tIN\t11H\r"
"\tANI\t0DFH\t;ACCEPT LOWERCASE\r"
"\tLXI\tH,P1R\r"
"\tCPI\t65\t; \"A\" => PLAYER 1 UP\r"
"\tJNZ\tL3A\r"
"\tLDA\tP1R\r"
"\tCPI\t2\r"
"\tJM\tCHKIN\r"
"\tDCR\tM\r"
"\tJMP\tCHKIN\r"
"L3A:\tCPI\t90\t; \"Z\" => PLAYER 1 DOWN\r"
"\tJNZ\tL3B\r"
"\tLDA\tP1R\r"
"\tCPI\t18\r"
"\tJP\tCHKIN\r"
"\tINR\tM\r"
"\tJMP\tCHKIN\r"
"L3B:\tLXI\tH,P2R\r"
"\tCPI\t75\t; \"K\" => PLAYER 2 UP\r"
"\tJNZ\tL3C\r"
"\tLDA\tP2R\r"
"\tCPI\t2\r"
"\tJM\tCHKIN\r"
"\tDCR\tM\r"
"\tJMP\tCHKIN\r"
"L3C:\tCPI\t77\t; \"M\" => PLAYER 2 DOWN\r"
"\tJNZ\tCHKIN\r"
"\tLDA\tP2R\r"
"\tCPI\t18\r"
"\tJP\tCHKIN\r"
"\tINR\tM\r"
"\tJMP\tCHKIN\r"
"\t;MANAGE PLAYER 1\r"
"MPLYR:\tLDA\tP1R\r"
"\tMOV\tB,D\r"
"\tMVI\tC,1\r"
"\tCALL\tPLYR\r"
"\tMOV\tD,B\r"
"\t;MANAGE PLAYER 2\r"
"\tLDA\tP2R\r"
"\tMOV\tB,E\r"
"\tMVI\tC,70\r"
"\tCALL\tPLYR\r"
"\tMOV\tE,B\r"
"\t;MOVE BALL\r"
"BALL:\tPOP\tB\t;RESTORE BALL POSIION\r"
"\tCALL \tMOVC\t;MOVE CURSOR TO CURRENT BALL POSITION\r"
"\tMVI\tA,\" \"\t;ERASE BALL AT CURRENT POSITION\r"
"\tCALL\tCHROUT\r"
"\tMOV\tA,C\t;ONLY MOVE VECRTIAL AT EVERY OTHER\r"
"\tANI\t1\t;HORIZONTAL STEP\r"
"\tJZ\tL11\r"
"\tMOV\tA,B\t;CHECK VERTICAL BALL DIRECTION\r"
"\tORA\tA\r"
"\tJP\tL10\t;JUMP IF BIT 7 IS 0 (MOVING DOWN)\r"
"\tINR\tB\t;BIT 7 IS 1 (MOVING UP)\r"
"\tJMP\tL11 \r"
"L10:\tDCR\tB\t;BIT 7 IS 0 (MOVING DOWN)\r"
"L11:\tMOV\tA,C\t;CHECK HORIZONTAL BALL DIRECTION\r"
"\tORA\tA \r"
"\tJP\tL20\t;JUMP IF BIT 7 IS 0 (MOVING LEFT)\r"
"\tINR\tC\t;BIT 7 IS 1 (MOVING RIGHT)\r"
"\tJMP\tL21\r"
"L20:\tDCR\tC\t;BIT 7 IS 0 (MOVING LEFT)\r"
"L21:\tCALL\tMOVC\t;MOVE CURSOR TO NEW BALL POSITION\r"
"\tMVI\tA,\"*\"\t;DRAW BALL AT NEW POSITION\r"
"\tCALL\tCHROUT\r"
"\t;START NEXT CYCLE\r"
"\tJMP\tLOOP\r"
"PLYR:\tCMP\tB\r"
"\tJZ\tPNOP\r"
"\tJM\tPUP\r"
"PDN:\tCALL\tMOVC\t;MOVING DOWN\r"
"\tMVI\tA,\" \"\r"
"\tCALL\tCHROUT\r"
"\tINR\tB\r"
"\tINR\tB\r"
"\tINR\tB\r"
"\tCALL\tMOVC\r"
"\tMVI\tA,\"I\"\r"
"\tCALL\tCHROUT\r"
"\tDCR\tB\r"
"\tDCR\tB\r"
"\tRET\r"
"PUP:\tDCR\tB\t;MOVING UP\r"
"\tCALL\tMOVC\r"
"\tMVI\tA,\"I\"\r"
"\tCALL\tCHROUT\r"
"\tINR\tB\r"
"\tINR\tB\r"
"\tINR\tB\r"
"\tCALL\tMOVC\r"
"\tMVI\tA,\" \"\r"
"\tCALL\tCHROUT\r"
"\tDCR\tB\r"
"\tDCR\tB\r"
"\tDCR\tB\r"
"\tRET\r"
"PNOP:\tCALL\tMOVC\t;NOT MOVING\r"
"\tMVI\tA,\"I\"\r"
"\tCALL\tCHROUT\r"
"\tCALL\tMOVC\r"
"\tMVI\tA,\"I\"\r"
"\tJMP\tCHROUT\r"
"\t;PLAYER 1 SCORES\r"
"SCP1:\tLDA\tSCR1\t;INCREASE SCORE OF PLAYER 1\r"
"\tINR\tA\r"
"\tSTA\tSCR1\r"
"\tCPI\t10\r"
"\tJZ\tEND\t;IF SCORE=10 then end game\r"
"\tCALL\tPSCR\t;PRINT SCORES\r"
"\tCALL\tMOVC\t;MOVE TO CURRENT POSITION OF BALL\r"
"\tMVI\tA,\" \"\t;ERASE BALL\r"
"\tCALL\tCHROUT\r"
"\tMVI\tB,89H\t;START IN ROW 9,MOVING DOWN\r"
"\tMVI\tC,23H\t;START IN COLUMN 35,MOVING LEFT\r"
"\tJMP\tLOOP\t;START NEXT CYCLE\r"
"\t;PLAYER 2 SCORES\r"
"SCP2:\tLDA SCR2\t;INCREASE SCORE OF PLAYER 2\r"
"\tINR\tA\r"
"\tSTA\tSCR2\r"
"\tCPI\t10\r"
"\tJZ\tEND\t;IF SCORE=10 then end game\r"
"\tCALL\tPSCR\t;PRINT SCORES\r"
"\tCALL\tMOVC\t;MOVE TO CURRENT POSITION OF BALL\r"
"\tMVI\tA,\" \"\t;ERASE BALL\r"
"\tCALL\tCHROUT\r"
"\tMVI\tB,089H\t;START IN ROW 9,MOVING DOWN\r"
"\tMVI\tC,0A3H\t;START IN COLUMN 35,MOVING RIGHT\r"
"\tJMP\tLOOP\t;START NEXT CYCLE\r"
"\t;PRINT BOTH PLAYER'S SCORES\r"
"END:\tLXI\tH,ENDS\t;CLEAR SCREEN AND SHOW CURSOR\r"
"\tCALL\tSTROUT\r"
"EMPTY:\tIN\t10H\t;EMPTY INPUT BUFFER\r"
"\tRRC\r"
"\tJNC\tMON\t;BACK TO MONITOR\r"
"\tIN\t11H\r"
"\tJMP\tEMPTY\r"
"PSCR:\tPUSH\tB\t;SAVE BALL POSITION\r"
"\tMVI\tB,1\t;MOVE CURSOR TO ROW 1,COLUMN 10\r"
"\tMVI\tC,10 \r"
"\tCALL\tMOVC\r"
"\tLDA\tSCR1\t;LOAD PLAYER 1 SCORE\r"
"\tCALL\tDSPN\t;PRINT NUMBER IN A\r"
"\tMVI\tB,1\t;MOVE CURSOR TO ROW 1,COLUMN 60\r"
"\tMVI\tC,60\r"
"\tCALL\tMOVC\r"
"\tLDA\tSCR2\t;LOAD PLAYER 2 SCORE\r"
"\tCALL\tDSPN\t;PRINT NUMBER IN A\r"
"\tPOP\tB\t;RESTORE BALL POSITION\r"
"\tRET\r"
"\t;MOVE CURSOR TO POSITION IN B (ROW) AND C (COLUMN)\r"
"MOVC:\tMVI\tA,1BH\t;PRINT ESC\r"
"\tCALL\tCHROUT\r"
"\tMVI\tA,\"[\"\t;PRINT '['\r"
"\tCALL\tCHROUT\r"
"\tMOV\tA,B\t;ROW TO A\r"
"\tANI\t7FH\t;CLEAR BIT 7\r"
"\tCALL\tDSPN\t;PRINT NUMBER IN A\r"
"\tMVI\tA,\";\"\t;PRINT ';'\r"
"\tCALL\tCHROUT\r"
"\tMOV\tA,C\t;COLUMN TO A\r"
"\tANI\t7FH\t;CLEAR BIT 7\r"
"\tCALL\tDSPN\t;PRINT NUMBER IN A\r"
"\tMVI\tA,\"H\"\t;PRINT 'H;\r"
"\tCALL\tCHROUT\r"
"\tRET\r"
"\t;PRINT 2-DIGIT DECIMAL NUMBER IN A\r"
"DSPN:\tMVI H,0\t;10S DIGIT IS 0\r"
"DSPL1:\tINR H\t;INCREASE 10S DIGIT\r"
"\tSBI\t10\t;SUBTRACT 10 FROM SCORE\r"
"\tJNC\tDSPL1\t;REPEAT UNTIL OVERFLOW\r"
"\tDCR\tH\t;OVERSHOT BY ONE\r"
"\tADI\t10\t;INCREASE BY 10 AGAIN TO GET 1S DIGIT\r"
"\tMOV\tL,A\t;SAVE 1S DIGIT\r"
"\tMOV\tA,H\t;GET 10S DIGIT\r"
"\tADI\t30H\t;ADD 48 TO GET ASCII VALUE\r"
"\tCALL\tCHROUT\t;PRINT DIGIT\r"
"\tMOV\tA,L\t;GET 1S DIGIT\r"
"\tADI\t30H\t;ADD 48 TO GET ASCII VALUE\r"
"\tCALL\tCHROUT\t;PRINT DIGIT\r"
"\tRET\r"
"\t;PRINT STRING POINTED TO BY H/L\r"
"STROUT:\tMOV\tA,M\t;LOAD NEXT CHARACTER\r"
"\tORA\tA\t;UPDATE Z FLAG\r"
"\tRZ\t\t;RETURN IF 0\r"
"\tCALL\tCHROUT\t;OUTPUT CHARACTER\r"
"\tINX\tH\t;INCREASE POINTER\r"
"\tJMP\tSTROUT\t;START OVER\r"
"CHROUT:\tPUSH\tA\r"
"WAIT:\tIN\t10H\r"
"\tRRC\r"
"\tRRC\r"
"\tJNC\tWAIT\r"
"\tPOP\tA\r"
"\tOUT\t11H\r"
"\tRET\r"
"SCR1:\tDB\t0\t\t;PLAYER 1 SCORE\r"
"SCR2:\tDB\t0\t\t;PLAYER 2 SCORE\r"
"INITS:\tDB\t27,\"[2J\"\t;CLEAR SCREEN\r"
"\tDB\t27,\"[?25\",108\t;HIDE CURSOR\r"
"\tDB\t0\r"
"ENDS:\tDB\t27,\"[2J\"\t;CLEAR SCREEN\r"
"\tDB\t27,\"[H\"\t\t;CURSOR HOME\r"
"\tDB\t27,\"[?25\",104\t;SHOW CURSOR\r"
"\tDB\t0\r"
"\t;PLAYER ICON\r"
"PLYRS:\tDB\t\"I\"\t\t;'I'\r"
"\tDB\t27,\"[1D\"\t;CURSOR LEFT\r"
"\tDB\t27,\"[1B\"\t;CURSOR DOWN\r"
"\tDB\t\"I\"\t\t;'I'\r"
"\tDB\t27,\"[1D\"\t;CURSOR LEFT\r"
"\tDB\t27,\"[1B\"\t;CURSOR DOWN\r"
"\tDB\t\"I\"\t\t;'I'\r"
"\tDB\t0\r"
"P1R:\tDB\t0\t;PLAYER1 REQUESTED POS\r"
"P2R:\tDB\t0\t;PLAYER2 REQUESTED POS\r"
"STCKB:\tDS\t16\t;RESERVE 16 BYTES FOR STACK\r"
"STCK:\tBEG\tSTART\r"
"\tEND\tPONG\r";
const char asm_dir[] =
"10000000) [this directory]\r"
//"10000001) calculator\r" // see comment for asm_calc
"10000001) pong\r"
"10000010) memory dump\r";
const char * const asm_programs[] = {
asm_dir,
//asm_calc, // see comment for asm_calc
asm_pong,
asm_dump};