-
Notifications
You must be signed in to change notification settings - Fork 0
/
tetris.lst
779 lines (774 loc) · 43.1 KB
/
tetris.lst
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
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
; Pass 1...
; tetris.asm:510: error: Undefined symbol 'prep_piece_hor_ptr'
; 1 errors detected in pass 1
; Pass 2...
; 1 ; Tetris implementation
; 2 ; Ryan Crosby 2022
; 3 ;
; 4 ; Run from 0x01.
; 5 ;
; 6 ; Controls:
; 7 ;
; 8 ; Relay computer numpad is used to control the game.
; 9 ;
; 10 ; 0: Re-render the gameboard
; 11 ; 2: Move piece down
; 12 ; 4: Move piece left
; 13 ; 6: Move piece right
; 14 ; 7: Rotate piece left
; 15 ; 8: Hard drop piece
; 16 ; 9: Rotate piece right
; 17 ; A: Enable automatic gameboard rendering (default)
; 18 ; B: Disable automatic gameboard rendering
; 19 ; C: New Game
; 20 ; D: Exit game
; 21 ;
; 22 ; Game is rendered to console output.
; 23 ;
; 24 ; Note: If any more instructions are required for future features, render_board and line_clr are yet to be inlined (for readability),
; 25 ; but doing so could save 4 instructions.
; 26
; 27 ; =========
; 28 ; Constants
; 29 ; =========
; 30
; 31 ; Gameboard parameters
; 32 ; These constants are used for convenience. Changing the value won't change the actual sizes of the gameboards, code will need to be modified as well.
; 33 0000_0000 GAMEBOARD_STRIDE equ 2 ; How many bytes high is the gameboard. 2 bytes = 16 rows.
; 34 0000_0000 GAMEBOARD_COLS equ 10 ; How many columns wide is the gameboard. This is generic enough that it can be adjusted without altering any code.
; 35 0000_0000 GAMEBOARD_SIZE equ (GAMEBOARD_STRIDE*GAMEBOARD_COLS) ; Gameboard total size = stride * columns
; 36
; 37 0000_0000 PIECE_STAGE_SIZE equ (GAMEBOARD_STRIDE*4) ; The piece stage is the same height as the gameboard, but only 4 wide.
; 38
; 39 0000_0000 PIECE_X_OFFSET equ 4 ; The piece always spawns at x = 0. This offsets the piece so that x = 0 aligns with the center of the board.
; 40
; 41 0000_0000 BLOCK_CHAR equ 0x23 ; #
; 42 0000_0000 EMPTY_CHAR equ 0x7E ; ~
; 43
; 44 0000_0000 CR_CHAR equ 0x0D ; Carriage Return CR \r
; 45 0000_0000 LF_CHAR equ 0x0A ; Linefeed LF \n
; 46
; 47 ; Additional custom instructions
; 48 ; To use these, call them like: insn INCTO_INSN aa, bb
; 49 0000_0000 OTOC_INSN equ 0x02000000 ; [aa].0 --> C. Stores oddness of [aa] in Carry.
; 50 0000_0000 IMADD_INSN equ 0xC0800000 ; aa + [bb] --> [aa]. Immediate version of ADD. If aa is 0, allows single instruction LOAD of [bb] to [0].
; 51 0000_0000 AND_INSN equ 0x81800000 ; The WRA version of andto. ANDs [aa] and [bb], and stores in [aa].
; 52 0000_0000 CLRA_INSN equ 0x81000000 ; Stores 0 --> [aa]. Implemented as [aa] & 0 --> [aa].
; 53 0000_0000 INCA_INSN equ 0x80200000 ; Stores [aa] + 1 --> [aa] in one instruction.
; 54 0000_0000 INCTO_INSN equ 0x08200000 ; Stores [aa] + 1 --> [bb] in one instruction.
; 55 0000_0000 ALTB_TOC_INSN equ 0x00C00000 ; Stores [aa] < [bb] --> Carry.
; 56 0000_0000 ALEB_TOC_INSN equ 0x00E00000 ; Stores [aa] <= [bb] --> Carry.
; 57 0000_0000 STC_INSN equ 0x08100000 ; Stores [aa] + C --> [bb]
; 58 0000_0000 STNC_INSN equ 0x08300000 ; Stores [aa] + ~C --> [bb]
; 59 0000_0000 ST_JMP_INSN equ 0x08080000 ; Stores [aa] --> [bb] and jumps to bb.
; 60 0000_0000 OUTC_JMP_INSN equ 0x98080000 ; Writes [aa] to the console and jumps to bb. WRA and WRB are set to make OUT write to console.
; 61 0000_0000 LSR_JE_INSN equ 0x820A0000 ; Shifts [aa] right, writes the result back to [aa], and jumps if Z (ALU carry out) set.
; 62 0000_0000 INC_JMP_INSN equ 0x80280000 ; Stores [aa] + 1 --> [aa] and unconditionally jumps to bb
; 63 0000_0000 CLR_JMP_INSN equ 0x81080000 ; Stores 0 --> [aa] and unconditionally jumps to bb
; 64 0000_0000 LSRO_JMP_INSN equ 0x82280000 ; Rotates [aa] right. 1 --> [aa].7. Z (ALU carry out) --> C. Unconditionally jumps to bb
; 65
; 66 ; Pieces templates
; 67 ;
; 68 ; Piece patterns are stored as a single byte.
; 69 ; The 4 lsb bits represent the left of the piece, the 4 msb bits representing the right of the piece.
; 70 ; The alignment and bit direction matches the piece stage.
; 71 ;
; 72 ; A "flipped" version of each piece is also stored, which is similar to the piece being left-to-right bitswapped.
; 73 ; However using a dedicated version of the flipped piece removes the need for a bitswap subroutine,
; 74 ; which actually saves instructions overall, and also allows the pieces to be tweaked so that they rotate correctly.
; 75 ;
; 76 ; The Gameboy left-handed rotation system was used as a reference, but the code doesn't attempt to exactly adhere to any particular system,
; 77 ; it just attempts to look somewhat acceptable and use minimal instructions.
; 78
; 79 ; Convention: Piece "major axis", aka the axis that it rotates around, should be on the right in unflipped form, and left in flipped form.
; 80 ; Piece kind indicies that are even require "adjustment" where they are shifted during piece rendering. Odd piece kinds do not.
; 81 ; The adjustment depends on whether the piece is rendering vertically or horizontally, and whether or not it is flipped.
; 82 ; Adjustment required: {I, T, J, L}
; 83 ; No adjustment required: {O, S, Z}
; 84
; 85 ; I piece
; 86 ;
; 87 ;3 7
; 88 ; 0 1
; 89 ; 0 1
; 90 ; 0 1
; 91 ; 0 1
; 92 ;0 4
; 93 0000_0000 I_PIECE equ 0xF0
; 94
; 95 ; I piece flipped
; 96 ;
; 97 ;3 7
; 98 ; 1 0
; 99 ; 1 0
; 100 ; 1 0
; 101 ; 1 0
; 102 ;0 4
; 103 0000_0000 I_PIECE_FLIP equ 0x0F
; 104
; 105 ; O (square) piece
; 106 ;
; 107 ;3 7
; 108 ; 1 1
; 109 ; 1 1
; 110 ; 0 0
; 111 ; 0 0
; 112 ;0 4
; 113 0000_0000 O_PIECE equ 0xCC
; 114 0000_0000 O_PIECE_FLIP equ O_PIECE ; Square is same in any rotation
; 115
; 116 ; T piece
; 117 ;
; 118 ;3 7
; 119 ; 0 1
; 120 ; 1 1
; 121 ; 0 1
; 122 ; 0 0
; 123 ;0 4
; 124 0000_0000 T_PIECE equ 0xE4
; 125
; 126 ; T piece flipped
; 127 ;
; 128 ;3 7
; 129 ; 1 0
; 130 ; 1 1
; 131 ; 1 0
; 132 ; 0 0
; 133 ;0 4
; 134 0000_0000 T_PIECE_FLIP equ 0x4E
; 135
; 136 ; S piece
; 137 ;
; 138 ;3 7
; 139 ; 1 0
; 140 ; 1 1
; 141 ; 0 1
; 142 ; 0 0
; 143 ;0 4
; 144 0000_0000 S_PIECE equ 0x6C
; 145 0000_0000 S_PIECE_FLIP equ S_PIECE ; S piece is the same rotated
; 146
; 147 ; J piece
; 148 ;
; 149 ;3 7
; 150 ; 0 1
; 151 ; 0 1
; 152 ; 1 1
; 153 ; 0 0
; 154 ;0 4
; 155 0000_0000 J_PIECE equ 0xE2
; 156
; 157 ; J piece flipped
; 158 ;
; 159 ;3 7
; 160 ; 1 1
; 161 ; 1 0
; 162 ; 1 0
; 163 ; 0 0
; 164 ;0 4
; 165 0000_0000 J_PIECE_FLIP equ 0x8E
; 166
; 167 ; Z piece
; 168 ;
; 169 ;3 7
; 170 ; 0 1
; 171 ; 1 1
; 172 ; 1 0
; 173 ; 0 0
; 174 ;0 4
; 175 0000_0000 Z_PIECE equ 0xC6
; 176 0000_0000 Z_PIECE_FLIP equ Z_PIECE ; Z piece is the same rotated
; 177
; 178 ; L piece
; 179 ;
; 180 ;3 7
; 181 ; 1 1
; 182 ; 0 1
; 183 ; 0 1
; 184 ; 0 0
; 185 ;0 4
; 186 0000_0000 L_PIECE equ 0xE8
; 187
; 188 ; L piece flipped
; 189 ;
; 190 ;3 7
; 191 ; 1 0
; 192 ; 1 0
; 193 ; 1 1
; 194 ; 0 0
; 195 ;0 4
; 196 0000_0000 L_PIECE_FLIP equ 0x2E
; 197
; 198 ; ================
; 199 ; Application code
; 200 ; ================
; 201
; 202 ; Temporary variable tmp at address 0x00.
; 203 ;
; 204 ; Used as a halt catch for any jumps to null (0x00). This usually indicates a subroutine hasn't had its return address set.
; 205 ; Also used as a temporary storage register, and sometimes as the return value for subroutines that only need to return a status.
; 206
; 207 00 org 0x00
; 209 00 c810_ff00 tmp halt
; 210
; 211 ; -----------
; 212 ; ENTRY POINT
; 213 ; -----------
; 214 01 org 0x01
; 216 ; --------------------------
; 217 ; new_game: Start a new game
; 218 ; --------------------------
; 221 01 8100_0100 lines_cleared insn CLRA_INSN lines_cleared, 0
; 222 02 8100_0200 rendering_off_flag insn CLRA_INSN rendering_off_flag, 0
; 223 03 8100_0300 piece_kind insn CLRA_INSN piece_kind, 0
; 224 04 8100_0400 piece_rotation insn CLRA_INSN piece_rotation, 0
; 225 05 8100_0500 piece_x insn CLRA_INSN piece_x, 0
; 226 06 8100_0600 piece_y insn CLRA_INSN piece_y, 0
; 227 07 8100_0700 undo_retry_count insn CLRA_INSN undo_retry_count, 0
; 228
; 261
; 262 08 0000_00ff insn 0x00000000 , 0xFF ; A wall for the gameboard to provide collisions at column -1
; 263 09 0000_00ff insn 0x00000000 , 0xFF
; 265 0a 8100_0a00 insn CLRA_INSN gameboard+0, 0
; 266 0b 8100_0b00 insn CLRA_INSN gameboard+1, 0
; 267 0c 8100_0c00 insn CLRA_INSN gameboard+2, 0
; 268 0d 8100_0d00 insn CLRA_INSN gameboard+3, 0
; 269 0e 8100_0e00 insn CLRA_INSN gameboard+4, 0
; 270 0f 8100_0f00 insn CLRA_INSN gameboard+5, 0
; 271 10 8100_1000 insn CLRA_INSN gameboard+6, 0
; 272 11 8100_1100 insn CLRA_INSN gameboard+7, 0
; 273 12 8100_1200 insn CLRA_INSN gameboard+8, 0
; 274 13 8100_1300 insn CLRA_INSN gameboard+9, 0
; 275 14 8100_1400 insn CLRA_INSN gameboard+10, 0
; 276 15 8100_1500 insn CLRA_INSN gameboard+11, 0
; 277 16 8100_1600 insn CLRA_INSN gameboard+12, 0
; 278 17 8100_1700 insn CLRA_INSN gameboard+13, 0
; 279 18 8100_1800 insn CLRA_INSN gameboard+14, 0
; 280 19 8100_1900 insn CLRA_INSN gameboard+15, 0
; 281 1a 8100_1a00 insn CLRA_INSN gameboard+16, 0
; 282 1b 8100_1b00 insn CLRA_INSN gameboard+17, 0
; 283 1c 8100_1c00 insn CLRA_INSN gameboard+18, 0
; 284 1d 8100_1d00 insn CLRA_INSN gameboard+19, 0
; 285 1e 0000_00ff insn 0x00000000 , 0xFF ; A wall for the gameboard to provide collisions at column 11
; 286 1f 0000_00ff insn 0x00000000 , 0xFF
; 289 20 8100_2000 stamp_flag insn CLRA_INSN stamp_flag, 0
; 291 21 8100_2100 hard_drop_flag insn CLRA_INSN hard_drop_flag, 0
; 292
; 296
; 300 22 40e0_0603 insn ALEB_TOC_INSN #6, piece_kind ; Set carry if piece_kind >= 6.
; 301 23 4890_0103 adcto #1, piece_kind ; If carry set, increment by 2, otherwise increment by 1.
; 302 24 4980_0703 andto #0x07, piece_kind ; Clear all bits above first three so that value wraps.
; 305 25 8100_2500 prev_piece_rotation insn CLRA_INSN prev_piece_rotation, 0
; 306 26 8100_2600 prev_piece_x insn CLRA_INSN prev_piece_x, 0
; 307 27 8100_2700 prev_piece_y insn CLRA_INSN prev_piece_y, 0
; 313 28 8022_07fe incjeq undo_retry_count, game_over ; Check if out of undo retries.
; 318 29 0800_2504 st prev_piece_rotation, piece_rotation
; 319 2a 0800_2605 st prev_piece_x, piece_x
; 320 2b 0800_2706 st prev_piece_y, piece_y
; 346 2c 8100_2c00 insn CLRA_INSN piece_stage+0, 0
; 347 2d 8100_2d00 insn CLRA_INSN piece_stage+1, 0
; 348 2e 8100_2e00 insn CLRA_INSN piece_stage+2, 0
; 349 2f 8100_2f00 insn CLRA_INSN piece_stage+3, 0
; 350 30 8100_3000 insn CLRA_INSN piece_stage+4, 0
; 351 31 8100_3100 insn CLRA_INSN piece_stage+5, 0
; 352 32 8100_3200 insn CLRA_INSN piece_stage+6, 0
; 353 33 8100_3300 insn CLRA_INSN piece_stage+7, 0
; 356 34 8408_986c jsr prep_piece_ret, prep_piece
; 359 35 0800_0600 st piece_y, tmp
; 360 36 8408_a799 jsr shift_piece_ret, shift_piece
; 368 37 006a_2040 jne stamp_flag, main_full_render ; If stamping, skip collision detection.
; 371 38 4800_b2b1 st #stamp_piece_coll_op, stamp_piece_op
; 372 39 8408_bda8 jsr stamp_piece_ret, stamp_piece
; 373 3a 006a_0028 jne tmp, main_undo_then_render ; We have a collision. Undo changes and re-render.
; 383 3b 0800_0425 st piece_rotation, prev_piece_rotation
; 384 3c 0800_0526 st piece_x, prev_piece_x
; 385 3d 0800_0627 st piece_y, prev_piece_y
; 388 3e 006a_215f jne hard_drop_flag, main_move_drop ; No hard drop
; 389 3f 4800_0020 clr stamp_flag ; Clear stamp flag
; 391 40 4800_fe07 st #-2, undo_retry_count ; Reset retry count every time an undo isn't required.
; 396 41 006a_0248 jne rendering_off_flag, main_stamp_piece_only ; Skip rendering if rendering flag bit 0 is set
; 397 42 4800_b5b1 main_force_render st #stamp_piece_merge_op, stamp_piece_op
; 398 43 8408_bda8 jsr stamp_piece_ret, stamp_piece ; Stamp piece to game board
; 399 44 8408_d1be jsr render_board_ret, render_board ; Print game board to console
; 400 45 006a_204b jne stamp_flag, main_clear_lines ; If stamp flag is set, jump to clearing lines and new piece.
; 401 46 4800_b7b1 st #stamp_piece_clear_op, stamp_piece_op ; Clear piece from game board
; 402 47 8408_bda8 jsr stamp_piece_ret, stamp_piece
; 404 48 0062_204d jeq stamp_flag, main_stamp_piece_end ; If stamp flag isn't set, skip all stamp actions.
; 408 49 4800_b5b1 st #stamp_piece_merge_op, stamp_piece_op
; 409 4a 8408_bda8 jsr stamp_piece_ret, stamp_piece ; Stamp piece to game board
; 412 4b 8408_fdd2 jsr line_clr_ret, line_clr
; 414 4c 4018_ff20 jmp main_next_piece ; TODO: Print character here to indicate new piece? 'P'?
; 416
; 421 4d e800_0000 inwait tmp
; 422 4e 4980_0f00 andto #0x0F, tmp ; Clear upper bits to allow compatibility with ASCII inputs
; 423 4f 0860_0000 neg tmp ; Invert tmp so we can incjeq
; 428 50 0062_0042 jeq tmp, main_force_render
; 432 51 4880_0100 inc tmp
; 433 52 8022_005f incjeq tmp, main_move_drop
; 437 53 4880_0100 inc tmp
; 438 54 8022_0065 incjeq tmp, main_move_left
; 442 55 4880_0100 inc tmp
; 443 56 8022_0066 incjeq tmp, main_move_right
; 447 57 8022_0067 incjeq tmp, main_rot_left
; 451 58 8022_0069 incjeq tmp, main_hard_drop
; 455 59 8022_0068 incjeq tmp, main_rot_right
; 459 5a 8022_006a incjeq tmp, main_enable_rendering
; 463 5b 8022_006b incjeq tmp, main_disable_rendering
; 467 5c 8022_0001 incjeq tmp, new_game
; 471 5d 8022_00fe incjeq tmp, game_over
; 472
; 474 5e d808_3f4d insn OUTC_JMP_INSN #0x3F, main_read_input ; Print '?'
; 477 5f 48e0_0106 dec piece_y
; 478 60 4800_ff00 st #-1, tmp
; 479 61 8408_a799 jsr shift_piece_ret, shift_piece
; 480 62 0062_0064 jeq tmp, main_move_drop_2 ; Check collision with floor
; 483 63 8028_2040 insn INC_JMP_INSN stamp_flag, main_full_render ; Re-render board and restart game loop.
; 484 64 8028_2038 main_move_drop_2 insn INC_JMP_INSN stamp_flag, main_check_collision ; Set stamp flag and check collision
; 485
; 487 65 48e0_0205 rsbto #2, piece_x
; 489 66 8028_0538 insn INC_JMP_INSN piece_x, main_check_collision
; 491 67 48e0_0204 rsbto #2, piece_rotation
; 493 68 8028_042c insn INC_JMP_INSN piece_rotation, main_render_fresh_piece
; 495 69 8228_215f insn LSRO_JMP_INSN hard_drop_flag, main_move_drop
; 497 6a 8108_024d insn CLR_JMP_INSN rendering_off_flag, main_read_input
; 499 6b 8228_024d insn LSRO_JMP_INSN rendering_off_flag, main_read_input
; 501
; 502 ; ------------------------------------------------
; 503 ; prep_piece: Render a piece into the piece stage.
; 504 ; ------------------------------------------------
; 505 ;
; 506 ; piece_kind = which piece to render. {0,1,2,3,4,5,6}.
; 507 ; piece_rotation = which orientation to render. {0,1,2,3}. Only considers bottom two bits, so piece_rotation can be incremented forever.
; 508 ;
; 510 0000_006c prep_piece_is_flipped equ prep_piece_hor_ptr ; Reuse prep_piece_hor_ptr as a temp variable since we don't need it until later.
; 511
; 512 6c 0800_0371 st piece_kind, prep_piece_target
; 513 6d 0a00_0491 lsrto piece_rotation, prep_piece_is_flipped ; prep_piece_is_flipped.0 = piece_rotation.1
; 514 6e 0200_9100 insn OTOC_INSN prep_piece_is_flipped ; If piece is flipped, set carry.
; 515 6f 0890_0371 adcto piece_kind, prep_piece_target ; Add piece_kind + carry into prep_piece_target.
; 516 70 4880_7271 addto #prep_piece_jmp, prep_piece_target ; Offset target into jump table.
; 518 71 4018_ff00 prep_piece_target jmp 0 ; prep_piece_target = #prep_piece_jmp + (2 * piece_kind) + piece_rotation.1
; 520 72 4808_f080 insn ST_JMP_INSN #I_PIECE, prep_piece_value
; 521 73 4808_0f80 insn ST_JMP_INSN #I_PIECE_FLIP, prep_piece_value
; 522 74 4808_cc80 insn ST_JMP_INSN #O_PIECE, prep_piece_value
; 523 75 4808_cc80 insn ST_JMP_INSN #O_PIECE_FLIP, prep_piece_value
; 524 76 4808_e480 insn ST_JMP_INSN #T_PIECE, prep_piece_value
; 525 77 4808_4e80 insn ST_JMP_INSN #T_PIECE_FLIP, prep_piece_value
; 526 78 4808_6c80 insn ST_JMP_INSN #S_PIECE, prep_piece_value
; 527 79 4808_6c80 insn ST_JMP_INSN #S_PIECE_FLIP, prep_piece_value
; 528 7a 4808_e280 insn ST_JMP_INSN #J_PIECE, prep_piece_value
; 529 7b 4808_8e80 insn ST_JMP_INSN #J_PIECE_FLIP, prep_piece_value
; 530 7c 4808_c680 insn ST_JMP_INSN #Z_PIECE, prep_piece_value
; 531 7d 4808_c680 insn ST_JMP_INSN #Z_PIECE_FLIP, prep_piece_value
; 532 7e 4808_e880 insn ST_JMP_INSN #L_PIECE, prep_piece_value
; 533 7f 4808_2e80 insn ST_JMP_INSN #L_PIECE_FLIP, prep_piece_value
; 534 80 4010_ff00 prep_piece_value nop ; prep_piece_value stores the jump table result.
; 535
; 537 81 020a_048d je piece_rotation, prep_piece_hor ; Piece renders horizontally initially, then rotates vertically.
; 539 82 0800_802f st prep_piece_value, piece_stage+3
; 540 83 4980_f02f andto #0xF0, piece_stage+3 ; Clear lower 4 bits
; 541 84 4800_fc00 st #-4, tmp
; 542 85 0880_8080 prep_piece_vert_loop lsl prep_piece_value
; 543 86 802a_0085 incjne tmp, prep_piece_vert_loop
; 544 87 0800_802d st prep_piece_value, piece_stage+1
; 547 88 0202_0398 jo piece_kind, prep_piece_ret ; If odd piece kind, no adjustment required.
; 548 89 020a_9198 je prep_piece_is_flipped, prep_piece_ret ; If not flipped, no adjustment required.
; 549 8a 0800_2f31 st piece_stage+3, piece_stage+5
; 550 8b 0800_2d2f st piece_stage+1, piece_stage+3
; 551 8c 8108_2d98 insn CLR_JMP_INSN piece_stage+1, prep_piece_ret
; 553 0000_008d prep_piece_hor_i equ prep_piece_target ; Reuse prep_piece_target as the outer loop variable.
; 554
; 559 8d 0202_038f jo piece_kind, prep_piece_hor_inel ; Note: Carry is set when jumping
; 560 8e 0200_9100 insn OTOC_INSN prep_piece_is_flipped
; 561 8f 4810_fd71 prep_piece_hor_inel insn STC_INSN #-3, prep_piece_hor_i ; ; Store + carry. stc?
; 563 90 4800_3391 st #(piece_stage+7), prep_piece_hor_ptr
; 565 91 c080_0000 prep_piece_hor_ptr insn IMADD_INSN tmp, 0 ; LOAD
; 566 92 0800_9194 st prep_piece_hor_ptr, prep_piece_hor_wb_ptr
; 567 93 0a00_8080 lsr prep_piece_value
; 568 94 0a10_0000 prep_piece_hor_wb_ptr rorto tmp, 0 ; STORE
; 569 95 48e0_0291 rsbto #2, prep_piece_hor_ptr
; 573 96 40e2_2c91 insn 0x00E20000 #piece_stage, prep_piece_hor_ptr ; If #aa <= [bb], jump to bb.
; 574 97 802a_7190 incjne prep_piece_hor_i, prep_piece_hor_loop_a
; 575 98 4018_ff00 prep_piece_ret jmp 0
; 576
; 577 ; -------------------------------------------------------------------
; 578 ; shift_piece: Shifts the gameboard downwards by the specified amount
; 579 ; -------------------------------------------------------------------
; 580 ;
; 581 ; Shifts the piece stage downwards by the set amount stored negated in tmp.
; 582 ; If the piece is shifted to the bottom of the board, stops and returns non-zero in tmp.
; 584 99 0062_00a7 jeq tmp, shift_piece_ret
; 586 9a 0202_32a7 jo piece_stage+6, shift_piece_ret
; 587 9b 0202_30a7 jo piece_stage+4, shift_piece_ret
; 588 9c 0202_2ea7 jo piece_stage+2, shift_piece_ret
; 589 9d 0202_2ca7 jo piece_stage+0, shift_piece_ret
; 591 9e 0a00_3333 lsr piece_stage+7
; 592 9f 0a10_3232 ror piece_stage+6
; 593 a0 0a00_3131 lsr piece_stage+5
; 594 a1 0a10_3030 ror piece_stage+4
; 595 a2 0a00_2f2f lsr piece_stage+3
; 596 a3 0a10_2e2e ror piece_stage+2
; 597 a4 0a00_2d2d lsr piece_stage+1
; 598 a5 0a10_2c2c ror piece_stage+0
; 599 a6 802a_009a incjne tmp, shift_piece_loop
; 600 a7 4018_ff00 shift_piece_ret jmp 0 ; Return from subroutine
; 601
; 602 ; -----------------------------------------------------------------------------
; 603 ; stamp_piece: Performs an operation between the piece stage and the gameboard.
; 604 ; -----------------------------------------------------------------------------
; 605 ;
; 606 ; This subroutine handles several operations:
; 607 ;
; 608 ; * ADDing the piece_stage to the gameboard (Stamping the piece down)
; 609 ; * BICing the piece_stage to the gameboard (Clearing the piece off)
; 610 ; * Checking for any common bits (AND result > 0) between piece_stage and gameboard (Checking for collision).
; 611 ;
; 612 ; stamp_piece_op must be set to #stamp_piece_coll_op, #stamp_piece_merge_op, or #stamp_piece_clear_op before executing.
; 613 ;
; 614 ; When executing stamp_piece_coll_op, tmp will be non-zero if a collision occured.
; 615 ;
; 618 a8 4800_2cae st #piece_stage, stamp_piece_ps_ptr
; 619 a9 4800_12b0 st #(gameboard+(PIECE_X_OFFSET*2)), stamp_piece_gb_ptr
; 620 aa 0880_05b0 addto piece_x, stamp_piece_gb_ptr
; 621 ab 0880_05b0 addto piece_x, stamp_piece_gb_ptr ; stamp_piece_gb_ptr = #gameboard + 2 * piece_x
; 624 ac 4800_f800 st #-PIECE_STAGE_SIZE, tmp
; 626
; 627 ad 8100_ad00 stamp_piece_ps_val insn CLRA_INSN stamp_piece_ps_val, 0 ; Self clearing variable stamp_piece_ps_val
; 628 ae 8080_ad00 stamp_piece_ps_ptr add stamp_piece_ps_val, 0 ; Piece stage LOAD
; 630 af 8100_af00 stamp_piece_gb_val insn CLRA_INSN stamp_piece_gb_val, 0 ; Self clearing variable stamp_piece_gb_val
; 631 b0 8080_af00 stamp_piece_gb_ptr add stamp_piece_gb_val, 0 ; Game board LOAD
; 632
; 634 b1 4018_ff00 stamp_piece_op jmp 0 ; This is set before calling the subroutine
; 637 b2 0980_adaf andto stamp_piece_ps_val, stamp_piece_gb_val
; 638 b3 0062_afba jeq stamp_piece_gb_val, stamp_piece_loop_end ; If collision didn't occur, keep looping.
; 641 b4 4018_ffbd jmp stamp_piece_ret ; Break out of loop and exit
; 645 b5 0880_adaf addto stamp_piece_ps_val, stamp_piece_gb_val
; 646 b6 4018_ffb8 jmp stamp_piece_writeback
; 648 b7 09c0_adaf bicto stamp_piece_ps_val, stamp_piece_gb_val
; 650 b8 0800_b0b9 st stamp_piece_gb_ptr, stamp_piece_gb_wb_ptr
; 651 b9 0800_af00 stamp_piece_gb_wb_ptr st stamp_piece_gb_val, 0 ; Game board STORE
; 654 ba 8020_ae00 rem_bits_mask insn INCA_INSN stamp_piece_ps_ptr, 0 ; Variable storage for rem_bits_mask, in rem_bits
; 655 bb 8020_b000 insn INCA_INSN stamp_piece_gb_ptr, 0
; 656 bc 802a_00ad incjne tmp, stamp_piece_loop
; 657 bd 4018_ff00 stamp_piece_ret jmp 0 ; Return from subroutine
; 658
; 659 ; --------------------------------------------------------------------------
; 660 ; render_board: Renders the gameboard to the console using ASCII characters.
; 661 ; --------------------------------------------------------------------------
; 662 ;
; 663 ; How:
; 664 ; Render the gameboard from left to right, top to bottom, to give the most simple console output (avoids ANSI console cursor movement).
; 665 ;
; 666 ; LOOP A: Starts at top of the board and then switches to bottom half of the board. The gameboard ptr offset changes from 1 to 0. (or 2 -> 1 -> 0 if using a bigger game board)
; 667 ; LOOP B: Work down the rows using a single byte bitmask, shifting it right each iteration.
; 668 ; LOOP C: Work along the columns from 0 to 10, incrementing the gameboard ptr by 2 each iteration.
; 669 ; Decide whether to render a block or empty character by ANDing the gameboard ptr value with the current bitmask
; 670 ;
; 672 be d800_0d00 get_full_lines_mask outc #CR_CHAR ; get_full_lines_mask: variable for get_full_lines
; 673 bf d800_0a00 outc #LF_CHAR
; 674
; 675 c0 4800_01c5 st #(GAMEBOARD_STRIDE-1), render_board_ptr ; Start the render_board_ptr with an offset of 1 to render the top half of the board.
; 676 ; LOOP A
; 678 c1 4880_0ac5 addto #gameboard, render_board_ptr ; Adjust the render_board_ptr to point into the gameboard. TODO: Move out of loop after implementing ALEB_TOC_INSN below since this won't be changed.
; 679 c2 4800_80cc st #%1000_0000, render_board_mask ; Initialize the bitmask for testing the column byte for which row is set
; 680 ; LOOP B
; 682 c3 4800_f6cd st #(-GAMEBOARD_COLS), render_board_col ; Prepare column loop counter
; 683 ; LOOP C
; 685 c4 0800_cc00 st render_board_mask, tmp
; 686 c5 8180_0000 render_board_ptr insn AND_INSN tmp, 0 ; Indirect AND, store result in tmp
; 689 c6 006a_00c8 jne tmp, render_board_print_a
; 690 c7 d808_7ec9 insn OUTC_JMP_INSN #EMPTY_CHAR, render_board_print_b ; Print empty char and jump over the block char print
; 692 c8 d800_2300 line_clr_i outc #BLOCK_CHAR ; Used as variable storage for line_clr_i in line_clr
; 694 c9 4880_02c5 addto #GAMEBOARD_STRIDE, render_board_ptr ; Move onto next column byte
; 695 ca 802a_cdc4 incjne render_board_col, render_board_loop_c ; If we still have columns to render, continue LOOP C
; 696 ; END LOOP C
; 697 cb 48e0_14c5 rsbto #GAMEBOARD_SIZE, render_board_ptr ; Reset render_board_ptr to pre-loop state
; 701 cc d800_0d00 render_board_mask outc #CR_CHAR ; render_board_mask: The row bitmask for selecting the row to render
; 702 cd d800_0a00 render_board_col outc #LF_CHAR ; render_board_col: The current column iteration loop counter.
; 703
; 706 ce 820a_ccc3 insn LSR_JE_INSN render_board_mask, render_board_loop_b
; 707 ; END LOOP B
; 710 cf 48e0_0bc5 rsbto #(gameboard+1), render_board_ptr ; TODO: Can replace with ALEB_TOC_INSN + jcs
; 712 d0 0069_c5c1 jge render_board_ptr, render_board_loop_a ; Otherwise continue LOOP A.
; 713 ; END LOOP A
; 714 d1 4018_ff00 render_board_ret jmp 0 ; Return from subroutine.
; 715
; 716 ; --------------------------------------------------
; 717 ; line_clr: Clears all full rows from the gameboard.
; 718 ; --------------------------------------------------
; 719 ;
; 720 ; How:
; 721 ; 1. Call get_full_lines to generate a bitmask of all the complete rows
; 722 ; 2. Call rem_bits on each column in the gameboard with a copy of the complete rows bitmask.
; 723 ; 3. Copy the result back over the gameboard.
; 724 ;
; 728 ; --------------
; 729 ; get_full_lines
; 730 ; --------------
; 731 ; Subroutine inlined to save instructions.
; 732 ;
; 733 ; Generates a 2 byte, 16 bit bitmask indicating which rows in the gameboard are filled.
; 734 ; This is the bitwise AND of all columns in the gameboard.
; 735 ;
; 736 ;get_full_lines_mask skip 2 ; Stored in render_board
; 738 d2 4800_f600 st #(-GAMEBOARD_COLS), tmp
; 739 d3 4800_ffbe st #0xFF, get_full_lines_mask+0
; 740 d4 4800_ffbf st #0xFF, get_full_lines_mask+1
; 741 d5 4800_0ad7 st #gameboard, get_full_lines_ptr_0
; 743 d6 0820_d7d8 insn INCTO_INSN get_full_lines_ptr_0, get_full_lines_ptr_1
; 744 d7 8180_be00 get_full_lines_ptr_0 insn AND_INSN get_full_lines_mask+0, 0
; 745 d8 8180_bf00 get_full_lines_ptr_1 insn AND_INSN get_full_lines_mask+1, 0
; 746 d9 4880_02d7 addto #2, get_full_lines_ptr_0
; 747 da 802a_00d6 incjne tmp, get_full_lines_loop
; 748 ;get_full_lines_ret jmp 0 ; Return from subroutine
; 749 ;-------------------
; 750 ; get_full_lines end
; 751 ; ------------------
; 753 db 006a_bede jne get_full_lines_mask+0, line_clr_do_remove
; 754 dc 006a_bfde jne get_full_lines_mask+1, line_clr_do_remove
; 755 dd 4018_fffd jmp line_clr_ret ; Fastpath to returning from the subroutine
; 758 de 8100_de00 rem_bits_value insn CLRA_INSN rem_bits_value+0, 0 ; rem_bits_value: 2 bytes. Variable storage for rem_bits.
; 759 df 8100_df00 insn CLRA_INSN rem_bits_value+1, 0 ; Self clearing.
; 760
; 762 e0 4800_f6c8 st #(-GAMEBOARD_COLS), line_clr_i ; Prep the loop counter
; 763
; 765 e1 4800_0ae5 st #gameboard, line_clr_read_ptr_0
; 767
; 768 ; Line clear loop. It will call rem_bits with the line clear mask and each column of the gameboard.
; 772 e2 0800_beba st get_full_lines_mask+0, rem_bits_mask+0 ; Prep mask +0
; 773 e3 0800_bfbb st get_full_lines_mask+1, rem_bits_mask+1 ; Prep mask +1
; 774
; 776 e4 0820_e5e6 insn INCTO_INSN line_clr_read_ptr_0, line_clr_read_ptr_1 ; Prep ptr +1
; 778 e5 8080_de00 line_clr_read_ptr_0 add rem_bits_value+0, 0 ; Load +0
; 779 e6 8080_df00 line_clr_read_ptr_1 add rem_bits_value+1, 0 ; Load +1
; 780
; 783 ; --------
; 784 ; rem_bits
; 785 ; --------
; 786 ; Subroutine inlined to save instructions.
; 787 ;
; 788 ; Remove the bits from rem_bits_value in the positions they are set in rem_bits_mask.
; 789 ; For each bit removed, the more significant bits are shifted right to fill its place.
; 790 ; The leftmost most significant bits are filled with zeroes.
; 791 ;
; 792 ; The output is placed in rem_bits_result.
; 793 ; rem_bits_mask and rem_bits_value are zeroed as a result of this process.
; 794 ;
; 795 ;rem_bits_mask skip 2 ; Stored in stamp_piece
; 796 ;rem_bits_value skip 2 ; Stored in line_clr
; 799 e7 8100_e700 rem_bits_result insn CLRA_INSN rem_bits_result+0, 0 ; Self clearing variables
; 800 e8 8100_e800 insn CLRA_INSN rem_bits_result+1, 0
; 802 e9 4800_f000 st #-16, tmp ; Loop 16 times
; 804 ea 0880_baba lsl rem_bits_mask+0 ; Logical shift left mask (0 -> bit 0)
; 805 eb 0890_bbbb rol rem_bits_mask+1 ; (bit 15 -> carry)
; 806 ec 0064_00f2 jcc rem_bits_A ; GOTO A if carry clear
; 808 ed 0880_dede lsl rem_bits_value+0 ; Logical shift left value (0 -> bit 0)
; 809 ee 0890_dfdf rol rem_bits_value+1 ; The carry result is discarded.
; 812 ef 40e0_ffc8 insn ALEB_TOC_INSN #-1, line_clr_i ; If this is the last iteration of rem_bits (last column), store 1 in carry
; 813 f0 4890_0001 adcto #0, lines_cleared ; Add carry to lines cleared
; 815 f1 4018_fff6 jmp rem_bits_loop_end
; 817 f2 0880_dede lsl rem_bits_value+0 ; Logical shift left value (0 -> bit 0)
; 818 f3 0890_dfdf rol rem_bits_value+1 ; (bit 15 -> carry)
; 819 f4 0890_e7e7 rol rem_bits_result+0 ; Rotate left to save the carry into result (carry -> bit 0)
; 820 f5 0890_e8e8 rol rem_bits_result+1 ; Carry from rotating result is discarded.
; 821 f6 802a_00ea rem_bits_loop_end incjne tmp, rem_bits_loop ; Loop
; 822 ;rem_bits_ret jmp 0 ; Return from subroutine
; 823 ; ------------
; 824 ; rem_bits end
; 825 ; ------------
; 827 f7 0800_e5f9 st line_clr_read_ptr_0, line_clr_write_ptr_0 ; Prep ptr +0
; 828 f8 0800_e6fa st line_clr_read_ptr_1, line_clr_write_ptr_1 ; Prep ptr +1
; 830 f9 0800_e700 line_clr_write_ptr_0 st rem_bits_result+0, 0 ; Store +0
; 831 fa 0800_e800 line_clr_write_ptr_1 st rem_bits_result+1, 0 ; Store +1
; 832
; 834 fb 4880_02e5 addto #2, line_clr_read_ptr_0 ; Iterate ptr +0
; 835 fc 802a_c8e2 incjne line_clr_i, line_clr_loop ; Loop
; 836 fd 4018_ff00 line_clr_ret jmp 0 ; Return from subroutine
; 837
; 838 ; ---------------------------------
; 839 ; game_over: End the game and halt.
; 840 ; ---------------------------------
; 842 fe d808_5800 insn OUTC_JMP_INSN #0x58, stop ; Print 'X' and halt.
; 843
; 845 0000_00ff PROGRAM_FREE_SPACE equ (256-PROGRAM_SIZE)
; 846
; 847
; 0 errors detected in pass 2
; Symbol table:
; ALEB_TOC_INSN = 0xe00000
; ALTB_TOC_INSN = 0xc00000
; AND_INSN = 0x81800000
; BLOCK_CHAR = 0x23
; CLRA_INSN = 0x81000000
; CLR_JMP_INSN = 0x81080000
; CR_CHAR = 0xd
; EMPTY_CHAR = 0x7e
; GAMEBOARD_COLS = 0xa
; GAMEBOARD_SIZE = 0x14
; GAMEBOARD_STRIDE = 0x2
; IMADD_INSN = 0xc0800000
; INCA_INSN = 0x80200000
; INCTO_INSN = 0x8200000
; INC_JMP_INSN = 0x80280000
; I_PIECE = 0xf0
; I_PIECE_FLIP = 0xf
; J_PIECE = 0xe2
; J_PIECE_FLIP = 0x8e
; LF_CHAR = 0xa
; LSRO_JMP_INSN = 0x82280000
; LSR_JE_INSN = 0x820a0000
; L_PIECE = 0xe8
; L_PIECE_FLIP = 0x2e
; OTOC_INSN = 0x2000000
; OUTC_JMP_INSN = 0x98080000
; O_PIECE = 0xcc
; O_PIECE_FLIP = 0xcc
; PIECE_STAGE_SIZE = 0x8
; PIECE_X_OFFSET = 0x4
; PROGRAM_FREE_SPACE = 0x1
; PROGRAM_SIZE = 0xff
; STC_INSN = 0x8100000
; STNC_INSN = 0x8300000
; ST_JMP_INSN = 0x8080000
; S_PIECE = 0x6c
; S_PIECE_FLIP = 0x6c
; T_PIECE = 0xe4
; T_PIECE_FLIP = 0x4e
; Z_PIECE = 0xc6
; Z_PIECE_FLIP = 0xc6
; game_over = 0xfe
; gameboard = 0xa
; get_full_lines = 0xd2
; get_full_lines_loop = 0xd6
; get_full_lines_mask = 0xbe
; get_full_lines_ptr_0 = 0xd7
; get_full_lines_ptr_1 = 0xd8
; hard_drop_flag = 0x21
; line_clr = 0xd2
; line_clr_do_remove = 0xde
; line_clr_i = 0xc8
; line_clr_loop = 0xe2
; line_clr_read_ptr_0 = 0xe5
; line_clr_read_ptr_1 = 0xe6
; line_clr_ret = 0xfd
; line_clr_write_ptr_0 = 0xf9
; line_clr_write_ptr_1 = 0xfa
; lines_cleared = 0x1
; main = 0x1
; main_check_collision = 0x38
; main_clear_lines = 0x4b
; main_disable_rendering = 0x6b
; main_enable_rendering = 0x6a
; main_end = 0x6c
; main_force_render = 0x42
; main_full_render = 0x40
; main_hard_drop = 0x69
; main_move_drop = 0x5f
; main_move_drop_2 = 0x64
; main_move_left = 0x65
; main_move_right = 0x66
; main_next_piece = 0x20
; main_read_input = 0x4d
; main_render_fresh_piece = 0x2c
; main_rot_left = 0x67
; main_rot_right = 0x68
; main_save_piece_state = 0x3b
; main_stamp_piece_end = 0x4d
; main_stamp_piece_only = 0x48
; main_undo_then_render = 0x28
; new_game = 0x1
; piece_kind = 0x3
; piece_rotation = 0x4
; piece_stage = 0x2c
; piece_x = 0x5
; piece_y = 0x6
; prep_piece = 0x6c
; prep_piece_hor = 0x8d
; prep_piece_hor_i = 0x71
; prep_piece_hor_inel = 0x8f
; prep_piece_hor_loop_a = 0x90
; prep_piece_hor_loop_b = 0x91
; prep_piece_hor_ptr = 0x91
; prep_piece_hor_wb_ptr = 0x94
; prep_piece_is_flipped = 0x91
; prep_piece_jmp = 0x72
; prep_piece_ret = 0x98
; prep_piece_target = 0x71
; prep_piece_value = 0x80
; prep_piece_vert = 0x82
; prep_piece_vert_loop = 0x85
; prev_piece_rotation = 0x25
; prev_piece_x = 0x26
; prev_piece_y = 0x27
; rem_bits = 0xe7
; rem_bits_A = 0xf2
; rem_bits_loop = 0xea
; rem_bits_loop_end = 0xf6
; rem_bits_mask = 0xba
; rem_bits_result = 0xe7
; rem_bits_value = 0xde
; render_board = 0xbe
; render_board_col = 0xcd
; render_board_loop_a = 0xc1
; render_board_loop_b = 0xc3
; render_board_loop_c = 0xc4
; render_board_mask = 0xcc
; render_board_print_a = 0xc8
; render_board_print_b = 0xc9
; render_board_ptr = 0xc5
; render_board_ret = 0xd1
; rendering_off_flag = 0x2
; shift_piece = 0x99
; shift_piece_loop = 0x9a
; shift_piece_ret = 0xa7
; stamp_flag = 0x20
; stamp_piece = 0xa8
; stamp_piece_clear_op = 0xb7
; stamp_piece_coll_op = 0xb2
; stamp_piece_gb_ptr = 0xb0
; stamp_piece_gb_val = 0xaf
; stamp_piece_gb_wb_ptr = 0xb9
; stamp_piece_loop = 0xad
; stamp_piece_loop_end = 0xba
; stamp_piece_merge_op = 0xb5
; stamp_piece_op = 0xb1
; stamp_piece_ps_ptr = 0xae
; stamp_piece_ps_val = 0xad
; stamp_piece_ret = 0xbd
; stamp_piece_writeback = 0xb8
; stop = 0x0
; tmp = 0x0
; undo_retry_count = 0x7
; Memory image:
00: c810ff00 81000100 81000200 81000300 81000400 81000500 81000600 81000700
08: 000000ff 000000ff 81000a00 81000b00 81000c00 81000d00 81000e00 81000f00
10: 81001000 81001100 81001200 81001300 81001400 81001500 81001600 81001700
18: 81001800 81001900 81001a00 81001b00 81001c00 81001d00 000000ff 000000ff
20: 81002000 81002100 40e00603 48900103 49800703 81002500 81002600 81002700
28: 802207fe 08002504 08002605 08002706 81002c00 81002d00 81002e00 81002f00
30: 81003000 81003100 81003200 81003300 8408986c 08000600 8408a799 006a2040
38: 4800b2b1 8408bda8 006a0028 08000425 08000526 08000627 006a215f 48000020
40: 4800fe07 006a0248 4800b5b1 8408bda8 8408d1be 006a204b 4800b7b1 8408bda8
48: 0062204d 4800b5b1 8408bda8 8408fdd2 4018ff20 e8000000 49800f00 08600000
50: 00620042 48800100 8022005f 48800100 80220065 48800100 80220066 80220067
58: 80220069 80220068 8022006a 8022006b 80220001 802200fe d8083f4d 48e00106
60: 4800ff00 8408a799 00620064 80282040 80282038 48e00205 80280538 48e00204
68: 8028042c 8228215f 8108024d 8228024d 08000371 0a000491 02009100 08900371
70: 48807271 4018ff00 4808f080 48080f80 4808cc80 4808cc80 4808e480 48084e80
78: 48086c80 48086c80 4808e280 48088e80 4808c680 4808c680 4808e880 48082e80
80: 4010ff00 020a048d 0800802f 4980f02f 4800fc00 08808080 802a0085 0800802d
88: 02020398 020a9198 08002f31 08002d2f 81082d98 0202038f 02009100 4810fd71
90: 48003391 c0800000 08009194 0a008080 0a100000 48e00291 40e22c91 802a7190
98: 4018ff00 006200a7 020232a7 020230a7 02022ea7 02022ca7 0a003333 0a103232
a0: 0a003131 0a103030 0a002f2f 0a102e2e 0a002d2d 0a102c2c 802a009a 4018ff00
a8: 48002cae 480012b0 088005b0 088005b0 4800f800 8100ad00 8080ad00 8100af00
b0: 8080af00 4018ff00 0980adaf 0062afba 4018ffbd 0880adaf 4018ffb8 09c0adaf
b8: 0800b0b9 0800af00 8020ae00 8020b000 802a00ad 4018ff00 d8000d00 d8000a00
c0: 480001c5 48800ac5 480080cc 4800f6cd 0800cc00 81800000 006a00c8 d8087ec9
c8: d8002300 488002c5 802acdc4 48e014c5 d8000d00 d8000a00 820accc3 48e00bc5
d0: 0069c5c1 4018ff00 4800f600 4800ffbe 4800ffbf 48000ad7 0820d7d8 8180be00
d8: 8180bf00 488002d7 802a00d6 006abede 006abfde 4018fffd 8100de00 8100df00
e0: 4800f6c8 48000ae5 0800beba 0800bfbb 0820e5e6 8080de00 8080df00 8100e700
e8: 8100e800 4800f000 0880baba 0890bbbb 006400f2 0880dede 0890dfdf 40e0ffc8
f0: 48900001 4018fff6 0880dede 0890dfdf 0890e7e7 0890e8e8 802a00ea 0800e5f9
f8: 0800e6fa 0800e700 0800e800 488002e5 802ac8e2 4018ff00 d8085800