-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
6283 lines (5639 loc) · 257 KB
/
Copy pathmain.c
File metadata and controls
6283 lines (5639 loc) · 257 KB
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
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#define _CRT_SECURE_NO_WARNINGS
#define SDL_MAIN_HANDLED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#ifdef _WIN32
#include "Windows.h"
#else
#include <unistd.h>
#endif
#include <time.h>
#include <SDL.h>
#include <stdbool.h>
#ifdef _WIN32
#define strcasecmp _stricmp
#else
#include <strings.h>
#endif
// Classic VGA 8x16 Font (256 characters, 16 bytes each)
// Each byte represents a row, MSB is the leftmost pixel.
static const unsigned char vga_font_8x16[256][16] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 0 Null
{0x7E, 0xFF, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 1 White Smiley Face
{0x7E, 0xFF, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0xFF, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 2 Black Smiley Face
{0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x10, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x6C, 0x00}, // 3 Black Heart Suit
{0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x10, 0x10, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x6C, 0xFF}, // 4 Black Diamond Suit
{0x38, 0x7C, 0x7C, 0x38, 0xFC, 0xFE, 0x7E, 0x10, 0x10, 0x7E, 0xFE, 0xFC, 0x38, 0x7C, 0x7C, 0x38}, // 5 Black Club Suit
{0x10, 0x38, 0x7C, 0xFE, 0x10, 0x10, 0x10, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00}, // 6 Black Spade Suit
{0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 7 Bullet
{0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF}, // 8 Inverse Bullet
{0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 9 White Circle
{0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 10 Black Circle
{0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 11 Male Sign
{0x38, 0x7C, 0x38, 0x10, 0x7C, 0xFE, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 12 Female Sign
{0x3C, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x00, 0x7E, 0x7E, 0x00, 0x18, 0x18, 0x18, 0x18}, // 13 Eighth Note
{0x3C, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x00, 0x7E, 0x7E, 0x7E, 0x60, 0x60, 0x60, 0x60}, // 14 Beamed Eighth Notes
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 15 White Sun with Rays (*) Actually solid block fill
{0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 16 Black Right Pointing Pointer
{0x00, 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 17 Black Left Pointing Pointer
{0x18, 0x3C, 0x7E, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 18 Up Down Arrow
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00}, // 19 Double Exclamation Mark !!
{0x00, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0xD8, 0xD8, 0xC0, 0xC0, 0xD8, 0x7E, 0x18, 0x00, 0x00}, // 20 Paragraph Sign
{0x00, 0x00, 0xFC, 0xFE, 0x06, 0x06, 0x06, 0xFE, 0xFC, 0x06, 0x06, 0x06, 0xFE, 0xFC, 0x00, 0x00}, // 21 Section Sign
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0x00}, // 22 Lower Half Block Rectangle
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x3C, 0x7E, 0xFF}, // 23 Up Down Arrow With Base
{0x18, 0x3C, 0x7E, 0xFF, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 24 Upwards Arrow
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00}, // 25 Downwards Arrow
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00}, // 26 Rightwards Arrow
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 27 Leftwards Arrow
{0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}, // 28 Right Angle (*) Actually Lower Half Inverse Block
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 29 Left Right Arrow
{0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00}, // 30 Black Up Pointing Triangle
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x18, 0x3C, 0x7E, 0xFF, 0x00}, // 31 Black Down Pointing Triangle
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 32 Space
{0x30, 0x78, 0x78, 0x30, 0x30, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 33 !
{0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 34 "
{0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 35 #
{0x18, 0x3C, 0x60, 0x38, 0x0C, 0x78, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 36 $
{0x00, 0xC6, 0xC6, 0x0C, 0x18, 0x30, 0x60, 0x60, 0xC6, 0x8C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // 37 %
{0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 38 &
{0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 39 '
{0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 40 (
{0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 41 )
{0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 42 *
{0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 43 +
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00}, // 44 ,
{0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 45 -
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 46 .
{0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 47 /
{0x3C, 0x66, 0xC6, 0xCE, 0xDE, 0xEE, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 48 0
{0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 49 1
{0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 50 2
{0x3C, 0x66, 0x06, 0x1C, 0x06, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 51 3
{0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 52 4
{0xFE, 0x60, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 53 5
{0x3C, 0x66, 0xC0, 0xFC, 0xC6, 0xC6, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 54 6
{0xFE, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 55 7
{0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 56 8
{0x3C, 0x66, 0xC6, 0xC6, 0x7E, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 57 9
{0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 58 :
{0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 59 ;
{0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 60 <
{0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 61 =
{0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 62 >
{0x3C, 0x66, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 63 ?
{0x3C, 0x66, 0xC6, 0xC0, 0xDE, 0xCE, 0xC6, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 64 @
{0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 65 A
{0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 66 B
{0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 67 C
{0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 68 D
{0x7E, 0xC0, 0xC0, 0xFC, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 69 E
{0xFE, 0xC0, 0xC0, 0xFC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 70 F
{0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0xC6, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 71 G
{0x66, 0x66, 0x66, 0xFE, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 72 H
{0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 73 I
{0x0E, 0x06, 0x06, 0x06, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 74 J
{0xC6, 0xC6, 0xCC, 0xD8, 0xF0, 0xD8, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 75 K
{0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 76 L
{0xC6, 0xEE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 77 M
{0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 78 N
{0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 79 O
{0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 80 P
{0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 81 Q
{0xFC, 0x66, 0x66, 0x6C, 0x7C, 0x6C, 0x66, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 82 R
{0x3C, 0x66, 0x60, 0x38, 0x0C, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 83 S
{0xFE, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 84 T
{0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 85 U
{0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 86 V
{0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 87 W
{0xC6, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 88 X
{0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 89 Y
{0xFE, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 90 Z
{0x7E, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 91 [
{0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 92 \ Backslash
{0x7E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 93 ]
{0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 94 ^ Caret
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00}, // 95 _ Underscore
{0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 96 ` Grave Accent
{0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 97 a
{0xC0, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 98 b
{0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 99 c
{0x06, 0x06, 0x06, 0x7E, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 100 d
{0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 101 e
{0x1E, 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 102 f
{0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 103 g
{0xC0, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 104 h
{0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 105 i
{0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 106 j
{0xC0, 0xC0, 0xC0, 0xCC, 0xD8, 0xF0, 0xD8, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 107 k
{0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 108 l
{0x00, 0x00, 0xEC, 0xFE, 0xD6, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 109 m
{0x00, 0x00, 0xDC, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 110 n
{0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 111 o
{0x00, 0x00, 0xDC, 0xC6, 0xC6, 0xDC, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 112 p
{0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 113 q
{0x00, 0x00, 0xDC, 0x6C, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 114 r
{0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 115 s
{0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x16, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 116 t
{0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 117 u
{0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 118 v
{0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 119 w
{0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 120 x
{0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 121 y
{0x00, 0x00, 0xFE, 0x18, 0x30, 0x60, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 122 z
{0x0E, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 123 {
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 124 | Vertical Bar
{0x70, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 125 }
{0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 126 ~ Tilde
{0x3C, 0x66, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 127 House / Delete
{0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x0E, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00}, // 128 Ç C cedilla
{0x6C, 0x6C, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 129 ü u umlaut
{0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 130 é e acute
{0x6C, 0x6C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 131 â a circumflex
{0x6C, 0x6C, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 132 ä a umlaut
{0x18, 0x30, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 133 à a grave
{0x18, 0x3C, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 134 å a ring
{0x18, 0x3C, 0x18, 0x7C, 0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x0E, 0x0C, 0x18, 0x00, 0x00, 0x00}, // 135 ç c cedilla
{0x10, 0x38, 0x6C, 0xC6, 0xC0, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00}, // 136 ê e circumflex
{0x6C, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 137 ë e umlaut
{0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 138 è e grave
{0x6C, 0x6C, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 139 ï i umlaut
{0x10, 0x38, 0x6C, 0xC6, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00}, // 140 î i circumflex
{0x18, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 141 ì i grave
{0x6C, 0x6C, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 142 Ä A umlaut
{0x18, 0x3C, 0x00, 0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, // 143 Å A ring
{0x18, 0x30, 0x00, 0x7E, 0xC0, 0xC0, 0xFC, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00}, // 144 É E acute
{0x00, 0x00, 0x78, 0xCC, 0xC0, 0xC0, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 145 æ ae ligature
{0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x7C, 0x60, 0x60, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 146 Æ AE ligature
{0x10, 0x38, 0x6C, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 147 ô o circumflex
{0x6C, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 148 ö o umlaut
{0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 149 ò o grave
{0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 150 û u circumflex
{0x18, 0x30, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 151 ù u grave
{0x6C, 0x6C, 0x00, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 152 ÿ y umlaut
{0x6C, 0x6C, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00}, // 153 Ö O umlaut
{0x6C, 0x6C, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 154 Ü U umlaut
{0x18, 0x3C, 0x60, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 155 ø o slash (*) Cent sign
{0x78, 0xCC, 0xC0, 0xFC, 0x0C, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 156 £ Pound sign
{0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 157 Ø O slash (*) Yen sign
{0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0x7C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 158 Pt Peseta sign
{0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 159 ƒ Florin sign
{0x18, 0x30, 0x00, 0x18, 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00}, // 160 á a acute
{0x18, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 161 í i acute
{0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 162 ó o acute
{0x18, 0x30, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 163 ú u acute
{0x00, 0x00, 0xDC, 0xC6, 0xC6, 0xD6, 0xF6, 0xE6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 164 ñ n tilde
{0x00, 0x00, 0xDC, 0xC6, 0xC6, 0xD6, 0xF6, 0xE6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 165 Ñ N tilde
{0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 166 ª Feminine Ordinal Indicator
{0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 167 º Masculine Ordinal Indicator
{0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00}, // 168 ¿ Inverted question mark
{0x00, 0x00, 0xFE, 0x0C, 0x0C, 0x0C, 0x0C, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 169 ® Registered Trade Mark Sign (*) Reversed Not Sign
{0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 170 ¬ Not sign
{0x00, 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 171 ½ One half
{0x00, 0xFE, 0xC6, 0x8E, 0x1E, 0x3E, 0x7E, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 172 ¼ One quarter
{0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x30, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00}, // 173 ¡ Inverted Exclamation Mark
{0x0C, 0x18, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0xC0, 0xC0, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00}, // 174 « Left Guillemet
{0x30, 0x18, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x06, 0x03, 0x03, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00}, // 175 » Right Guillemet
{0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}, // 176 Light Shade (25%)
{0xDB, 0x6D, 0xDB, 0x6D, 0xDB, 0x6D, 0xDB, 0x6D, 0xDB, 0x6D, 0xDB, 0x6D, 0xDB, 0x6D, 0xDB, 0x6D}, // 177 Medium Shade (50%)
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 178 Dark Shade (75%) (*) Actually Full Block
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 179 │ Box Drawings Light Vertical
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 180 ┤ Box Drawings Light Vertical and Left
{0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18}, // 181 Á A acute
{0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x6C, 0x38, 0x10, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00}, // 182 Â A circumflex
{0x18, 0x30, 0x60, 0xC0, 0xC0, 0xFE, 0x6C, 0x38, 0x10, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00}, // 183 À A grave
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 184 © Copyright Sign (*) Top Half Integral
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 185 ╣ Box Drawings Double Vertical and Left
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 186 ║ Box Drawings Double Vertical
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}, // 187 ╗ Box Drawings Double Down and Left
{0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 188 ╝ Box Drawings Double Up and Left
{0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 189 ¢ Cent Sign
{0x7E, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x7E, 0x00, 0x00, 0x00}, // 190 ¥ Yen Sign
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60}, // 191 ┐ Box Drawings Light Down and Left
{0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 192 └ Box Drawings Light Up and Right
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 193 ┴ Box Drawings Light Up and Horizontal
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 194 ┬ Box Drawings Light Down and Horizontal
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60}, // 195 ├ Box Drawings Light Vertical and Right
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 196 ─ Box Drawings Light Horizontal
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 197 ┼ Box Drawings Light Vertical and Horizontal
{0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 198 ã a tilde
{0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 199 Ã A tilde
{0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xFF, 0xFF, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}, // 200 ╚ Box Drawings Double Up and Right
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}, // 201 ╔ Box Drawings Double Down and Right
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 202 ╩ Box Drawings Double Up and Horizontal
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 203 ╦ Box Drawings Double Down and Horizontal
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 204 ╠ Box Drawings Double Vertical and Right
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 205 ═ Box Drawings Double Horizontal
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // 206 ╬ Box Drawings Double Vertical and Horizontal
{0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 207 õ o tilde
{0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 208 Õ O tilde
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xC6, 0xC6, 0x60, 0x30, 0x60, 0xC6, 0x7E, 0x00}, // 209 Ð Icelandic eth (lowercase)
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x7E, 0x00}, // 210 Ð Icelandic eth (uppercase)
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xC6, 0xC6, 0xDC, 0xC0, 0xC0, 0xC0, 0xFE, 0x00}, // 211 Þ Icelandic thorn (lowercase)
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xC0, 0x00}, // 212 Þ Icelandic thorn (uppercase)
{0x6C, 0x6C, 0x00, 0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00}, // 213 Ý Y acute
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 214 Ö O Umlaut (*) Full Block
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 215 µ Micro Sign (*) Upper Half Block
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x7C, 0x7C, 0x38, 0xFC, 0xFE, 0x7E, 0x10, 0x10}, // 216 ¶ Pilcrow Sign
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 217 ┘ Box Drawings Light Up and Left
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 218 ┌ Box Drawings Light Down and Right
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 219 █ Full Block
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 220 ▄ Lower Half Block
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF}, // 221 ▌ Left Half Block
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}, // 222 ▐ Right Half Block
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF}, // 223 ▀ Upper Half Block
{0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 224 α Greek Alpha
{0x00, 0x00, 0xFC, 0xC6, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 225 ß German Sharp s
{0x00, 0x00, 0x00, 0xFF, 0x38, 0x6C, 0x6C, 0x6C, 0x38, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 226 Γ Greek Gamma
{0x00, 0x00, 0x18, 0x18, 0xFE, 0x18, 0x18, 0x18, 0xFE, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // 227 π Greek Pi
{0x00, 0x00, 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 228 Σ Greek Sigma
{0x00, 0x00, 0x7E, 0xC6, 0xC0, 0xC0, 0xC0, 0xFE, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00}, // 229 σ Greek sigma
{0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00}, // 230 µ Micro Sign
{0x00, 0x00, 0xFE, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // 231 τ Greek tau
{0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00}, // 232 Φ Greek Phi
{0x00, 0x00, 0x7E, 0x18, 0x18, 0x7E, 0xC6, 0xC6, 0xC6, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 233 Θ Greek Theta
{0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00}, // 234 Ω Greek Omega
{0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x7C, 0x18, 0x30, 0x60, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 235 δ Greek delta
{0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00}, // 236 ∞ Infinity
{0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00}, // 237 φ Greek phi
{0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 238 ε Greek epsilon
{0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 239 ∩ Intersection
{0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 240 ≡ Identical To
{0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 241 ± Plus-Minus Sign
{0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 242 ≥ Greater-Than or Equal To
{0x00, 0x00, 0x06, 0x06, 0x06, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 243 ≤ Less-Than or Equal To
{0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 244 ⌠ Top Half Integral
{0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 245 ⌡ Bottom Half Integral
{0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00}, // 246 ÷ Division Sign
{0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 247 ≈ Almost Equal To
{0x00, 0x18, 0x3C, 0x00, 0x3C, 0x18, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 248 ° Degree Sign
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 249 ∙ Bullet Operator
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 250 · Middle Dot
{0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // 251 √ Square Root
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00}, // 252 ⁿ Superscript n
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00}, // 253 ² Superscript Two
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // 254 ■ Black Square
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 255 Non-breaking space (same as space)
};
#define CPU_VERSION 5
#define MEMORY_SIZE (65536 * 1024)
#define NUM_REGISTERS 32
#define NUM_F_REGISTERS 16
#define MAX_PROGRAM_SIZE 65536
#define MAX_LINE_LENGTH 512
#define DEFAULT_SCREEN_WIDTH 256
#define DEFAULT_SCREEN_HEIGHT 192
#define MAX_SCREEN_DIM 1024
#define PALETTE_SIZE 16
#define MAX_DEFINES 4096
typedef enum {
MOV, ADD, SUB, MUL, DIV, INTR, NOP, HLT, NOT, AND, OR, XOR, SHL, SHR, JMP,
CMP, JMPNE, JMPH, JMPL, NEG, INC, DEC, XCHG, CLR, PUSH, POP, CALL, RET, ROL,
ROR, STRMOV, RND, JMPE, MOD, POW, ABS, LOOP, LOAD, STORE, TEST,
LEA, PUSHF, POPF, SETF, CLRF, BT, BSET, BCLR, BTOG,
STRCMP, STRLEN, STRCPY, MEMCPY, MEMSET, CPUID, BSWAP, SAR, RVD,
INC_MEM, DEC_MEM, JMPO, JMPNO, JMPHE, JMPLE,
FMOV, FADD, FSUB, FMUL, FDIV, FCMP, FABS, FNEG, FSQRT, CVTIF, CVTFI,
FLOAD, FSTORE, FINC, FDEC, FPUSH, FPOP, FCLR, FXCHG, FPOW,
CALLH, CALLL, CALLE, CALLNE, CALLO, CALLNO, CALLHE, CALLLE,
IF, ELSE, END, WHILE, BREAK, CONTINUE,
INVALID_INST
} InstructionType;
typedef struct {
char name[64];
char value[64];
} DefineEntry;
#define MAX_PREPROC_DEPTH 64
typedef struct {
bool condition_met;
bool parent_active;
bool seen_else;
} PreprocessorState;
typedef struct {
char label_name[64];
int line_number;
} LabelEntry;
#define FPU_EPSILON 1e-9
#define FLAG_ZERO 0x01
#define FLAG_GREATER 0x02
#define FLAG_LESS 0x04
#define FLAG_OVERFLOW 0x08
//Null
#define INT_NOP 0x00 // No operation
// Console Input/Output
#define INT_PRINT_REG0 0x01 // Print integer in R0
#define INT_PRINT_STRING 0x02 // Print string from memory address in R0 until null terminator
#define INT_PRINT_NEWLINE 0x03 // Print a newline character
#define INT_GET_CHAR 0x04 // Keyboard input, reads a character into R0
#define INT_GET_STRING 0x05 // Read string input into memory at R0, max length R1
#define INT_PRINT_HEX_REG0 0x06 // Print R0 as hexadecimal
#define INT_CLEAR_SCREEN_OS 0x07 // Clear console screen
#define INT_SET_CONSOLE_COLOR 0x08 // Set console text color (R0=FG, R1=BG [Win32 codes])
#define INT_RESET_CONSOLE_COLOR 0x09 // Reset console color to default
#define INT_GOTOXY 0x0A // Move console cursor (R0=Col, R1=Row [0-based])
#define INT_GETXY 0x0B // Get console cursor pos (R0=Col, R1=Row) [Win32 only reliable]
#define INT_GET_CONSOLE_SIZE 0x0C // Get console dimensions (R0=Width, R1=Height)
#define INT_SET_CONSOLE_TITLE 0x0D // Set console window title (R0=title_addr)
#define INT_PRINT_FREG0 0x0E // Print floating point in F0
// Graphics Output / Control
#define INT_DRAW_PIXEL 0x10 // Draw pixel at (R0, R1) with palette color index R2
#define INT_CLEAR_GFX_SCREEN 0x11 // Clear graphics screen with palette color index R0
#define INT_SCREEN_ON 0x12 // Enable automatic graphics screen updates
#define INT_SCREEN_OFF 0x13 // Disable automatic graphics screen updates
#define INT_SET_RESOLUTION 0x14 // Change screen resolution to R0 x R1
#define INT_GET_PIXEL 0x15 // Get pixel color index at (R0, R1) into R0 (-1 if invalid)
#define INT_DRAW_STRING_GFX 0x16 // Draw string (R0=X, R1=Y, R2=StrAddr, R3=ColorIdx)
#define INT_BLIT 0x17 // Blit from Mem (R0=DX, R1=DY, R2=SrcAddr, R3=SW, R4=SH)
#define INT_GET_SCREEN_SIZE 0x18 // Get current GFX screen dimensions (R0=Width, R1=Height)
#define INT_UPDATE_GFX_SCREEN 0x19 // Manually update the screen with current pixel buffer contents
// Audio Control
#define INT_SPEAKER_ON 0x20 // Turn the virtual speaker on
#define INT_SPEAKER_OFF 0x21 // Turn the virtual speaker off
#define INT_SET_FREQ 0x22 // Set speaker frequency from R0 (Hz)
#define INT_SET_VOLUME 0x23 // Set speaker volume from R0 (0-100)
#define INT_SPEAKER_SLEEP 0x24 // Make speaker silent for R0 milliseconds
// Time / Date / Sleep
#define INT_SLEEP_MS 0x30 // Sleep for milliseconds specified in R0
#define INT_GET_TIME 0x31 // Get current time into R0 (H), R1 (M), R2 (S)
#define INT_GET_TICKS 0x32 // Get SDL Ticks (ms since init) into R0
#define INT_GET_DATETIME 0x33 // Get Date/Time (R0=Y, R1=M, R2=D, R3=h, R4=m, R5=s)
// CPU / System / Memory Control
#define INT_RESET_CPU 0x40 // Full CPU reset (state, memory, registers, flags, ip)
#define INT_SYSTEM_SHUTDOWN 0x41 // Requests the emulator session to end
#define INT_GET_MEMORY_SIZE 0x42 // Get configured MEMORY_SIZE into R
#define INT_BREAKPOINT 0x43 // Trigger host debugger breakpoint (if attached and set)
#define INT_DUMP_REGISTERS 0x44 // Print all register values, IP, SP, Flags
#define INT_DUMP_MEMORY 0x45 // Dump memory from R0 for length R1
// Input Device State
#define INT_GET_KEY_STATE 0x50 // Get state of key (SDL_Scancode in R0). R0=1 if pressed, 0 if not.
#define INT_WAIT_FOR_KEY 0x51 // Waits for a key press, returns SDL_Scancode in R0.
#define INT_GET_MOUSE_STATE 0x52 // Get mouse state: R0=X, R1=Y, R2=ButtonMask (1=L, 2=M, 4=R)
// Disk I/O
#define INT_DISK_READ 0x60 // Read sectors (R0=Sector#, R1=MemAddr, R2=NumSectors) -> R0=Status
#define INT_DISK_WRITE 0x61 // Write sectors (R0=Sector#, R1=MemAddr, R2=NumSectors) -> R0=Status
#define INT_DISK_INFO 0x62 // Get disk info -> R0=TotalSectors, R1=SectorSize
#define INT_DISK_FORMAT 0x63 // Format (zero-fill) the entire disk -> R0=Status
// Extended Graphics Output / Control
#define INT_DRAW_LINE 0x70 // Draw line (R0=x1, R1=y1, R2=x2, R3=y2, R4=color_idx)
#define INT_DRAW_RECT_FILLED 0x71 // Draw filled rectangle (R0=x, R1=y, R2=w, R3=h, R4=color_idx)
#define INT_DRAW_RECT_HOLLOW 0x72 // Draw hollow rectangle (R0=x, R1=y, R2=w, R3=h, R4=color_idx)
#define INT_DRAW_CIRCLE_FILLED 0x73 // Draw filled circle (R0=center_x, R1=center_y, R2=radius, R3=color_idx)
#define INT_DRAW_CIRCLE_HOLLOW 0x74 // Draw hollow circle (R0=center_x, R1=center_y, R2=radius, R3=color_idx)
#define INT_DRAW_TRIANGLE_FILLED 0x76 // Draw filled triangle (R0=x1, R1=y1, R2=x2, R3=y2, R4=x3, R5=y3, R6=color_idx)
#define INT_DRAW_TRIANGLE_HOLLOW 0x77 // Draw hollow triangle (R0=x1, R1=y1, R2=x2, R3=y2, R4=x3, R5=y3, R6=color_idx)
#define DISK_IMAGE_FILENAME "disk.img"
#define DISK_IMAGE_SIZE_BYTES (16 * 1024 * 1024) // 16 MB
#define DISK_SECTOR_SIZE 512
typedef struct {
int registers[NUM_REGISTERS];
double f_registers[NUM_F_REGISTERS];
int memory[MEMORY_SIZE];
int ip;
int flags;
int sp;
SDL_AudioSpec audioSpec;
SDL_AudioDeviceID audioDevice;
double frequency;
double volume;
int speaker_on;
int sleep_duration;
Uint32 sleep_start_time;
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Texture* texture;
int screen_width;
int screen_height;
Uint32* pixels;
SDL_Color palette[PALETTE_SIZE];
int screen_on;
bool shutdown_requested;
FILE* disk_image_fp;
long long disk_image_size;
int disk_sector_size;
} VirtualCPU;
bool init_cpu(VirtualCPU* cpu);
void cleanup_cpu(VirtualCPU* cpu);
bool init_sdl(VirtualCPU* cpu);
void cleanup_sdl(VirtualCPU* cpu);
InstructionType parseInstruction(const char* instruction);
int loadProgram(const char* filename, char* program[], int max_size);
void execute(VirtualCPU* cpu, char* program[], int program_size, bool debug_mode);
void interrupt(VirtualCPU* cpu, int interrupt_id);
void updateScreen(VirtualCPU* cpu);
void mov(VirtualCPU* cpu, int reg1, int value);
void add(VirtualCPU* cpu, int reg1, int reg2);
void sub(VirtualCPU* cpu, int reg1, int reg2);
void mul(VirtualCPU* cpu, int reg1, int reg2);
void divi(VirtualCPU* cpu, int reg1, int reg2);
void nop(VirtualCPU* cpu);
void hlt(VirtualCPU* cpu, bool* running_flag);
void not_op(VirtualCPU* cpu, int reg1);
void and_op(VirtualCPU* cpu, int reg1, int reg2);
void or_op(VirtualCPU* cpu, int reg1, int reg2);
void xor_op(VirtualCPU* cpu, int reg1, int reg2);
void shl(VirtualCPU* cpu, int reg1, int count);
void shr(VirtualCPU* cpu, int reg1, int count);
void jmp(VirtualCPU* cpu, int line_number);
void cmp(VirtualCPU* cpu, int reg1, int reg2);
void neg(VirtualCPU* cpu, int reg1);
void inc(VirtualCPU* cpu, int reg1);
void dec(VirtualCPU* cpu, int reg1);
void xchg(VirtualCPU* cpu, int reg1, int reg2);
void clr(VirtualCPU* cpu, int reg1);
void push(VirtualCPU* cpu, int reg1);
void pop(VirtualCPU* cpu, int reg1);
void call(VirtualCPU* cpu, int line_number);
void ret(VirtualCPU* cpu);
void rol(VirtualCPU* cpu, int reg1, int count);
void ror(VirtualCPU* cpu, int reg1, int count);
void rnd(VirtualCPU* cpu, int reg1);
void mod_op(VirtualCPU* cpu, int reg1, int reg2);
void pow_op(VirtualCPU* cpu, int reg1, int reg2);
void abs_op(VirtualCPU* cpu, int reg1);
void loop_op(VirtualCPU* cpu, int counter_reg, int target_line);
void load_op(VirtualCPU* cpu, int dest_reg, int addr_src_reg);
void store_op(VirtualCPU* cpu, int val_src_reg, int addr_dest_reg);
void test_op(VirtualCPU* cpu, int reg1, int reg2);
void lea_op(VirtualCPU* cpu, int dest_reg, int base_reg, int offset);
void pushf_op(VirtualCPU* cpu);
void popf_op(VirtualCPU* cpu);
void loope_op(VirtualCPU* cpu, int counter_reg, int target_line);
void loopne_op(VirtualCPU* cpu, int counter_reg, int target_line);
void setf_op(VirtualCPU* cpu, int flag_mask);
void clrf_op(VirtualCPU* cpu, int flag_mask);
void bt_op(VirtualCPU* cpu, int reg1, int bit_index);
void bset_op(VirtualCPU* cpu, int reg1, int bit_index);
void bclr_op(VirtualCPU* cpu, int reg1, int bit_index);
void btog_op(VirtualCPU* cpu, int reg1, int bit_index);
void strcmp_op(VirtualCPU* cpu, int reg_addr1, int reg_addr2);
void strlen_op(VirtualCPU* cpu, int reg_dest, int reg_addr);
void strcpy_op(VirtualCPU* cpu, int reg_dest_addr, int reg_src_addr);
void memcpy_op(VirtualCPU* cpu, int dest_addr_reg, int src_addr_reg, int len_reg);
void memset_op(VirtualCPU* cpu, int dest_addr_reg, int val_reg, int len_reg);
void cpuid_op(VirtualCPU* cpu, int dest_reg);
void bswap_op(VirtualCPU* cpu, int reg);
void sar_op(VirtualCPU* cpu, int reg, int count);
void rvd_op(VirtualCPU* cpu, int reg);
void inc_mem_op(VirtualCPU* cpu, int addr_reg);
void dec_mem_op(VirtualCPU* cpu, int addr_reg);
void loopo_op(VirtualCPU* cpu, int counter_reg, int target_line);
void loopno_op(VirtualCPU* cpu, int counter_reg, int target_line);
void eli_op(VirtualCPU* cpu);
void dli_op(VirtualCPU* cpu);
void fmov_reg(VirtualCPU* cpu, int dest_freg, int src_freg);
void fmov_imm(VirtualCPU* cpu, int dest_freg, double value);
void fadd(VirtualCPU* cpu, int dest_freg, int src_freg);
void fsub(VirtualCPU* cpu, int dest_freg, int src_freg);
void fmul(VirtualCPU* cpu, int dest_freg, int src_freg);
void fdiv(VirtualCPU* cpu, int dest_freg, int src_freg);
void fcmp(VirtualCPU* cpu, int freg1, int freg2);
void fabs_op(VirtualCPU* cpu, int freg);
void fneg_op(VirtualCPU* cpu, int freg);
void fsqrt(VirtualCPU* cpu, int freg);
void cvtif(VirtualCPU* cpu, int dest_freg, int src_reg);
void cvtfi(VirtualCPU* cpu, int dest_reg, int src_freg);
void fload(VirtualCPU* cpu, int dest_freg, int addr_src_reg);
void fstore(VirtualCPU* cpu, int addr_dest_reg, int src_freg);
void finc(VirtualCPU* cpu, int freg);
void fdec(VirtualCPU* cpu, int freg);
void fpush(VirtualCPU* cpu, int freg);
void fpop(VirtualCPU* cpu, int freg);
void fclr(VirtualCPU* cpu, int freg);
void fxchg(VirtualCPU* cpu, int freg1, int freg2);
void fpow_op(VirtualCPU* cpu, int dest_freg, int src_freg);
void audioCallback(void* userdata, Uint8* stream, int len);
void draw_pixel_gfx(VirtualCPU* cpu, int x, int y, int color_index);
void draw_line_gfx(VirtualCPU* cpu);
void draw_rect_filled_gfx(VirtualCPU* cpu);
void draw_rect_hollow_gfx(VirtualCPU* cpu);
void draw_circle_filled_gfx(VirtualCPU* cpu);
void draw_circle_hollow_gfx(VirtualCPU* cpu);
bool isValidReg(int reg) {
return reg >= 0 && reg < NUM_REGISTERS;
}
bool isValidFReg(int reg) {
return reg >= 0 && reg < NUM_F_REGISTERS;
}
bool isValidMem(int addr) {
return addr >= 0 && addr < MEMORY_SIZE;
}
char* strdup_portable(const char* s) {
if (s == NULL) {
return NULL;
}
#ifdef _MSC_VER
return _strdup(s);
#else
size_t len = strlen(s) + 1;
char* new_s = malloc(len);
if (new_s == NULL) {
return NULL;
}
memcpy(new_s, s, len);
return new_s;
#endif
}
void draw_pixel_gfx(VirtualCPU* cpu, int x, int y, int color_index) {
if (!cpu->pixels) return;
if (x >= 0 && x < cpu->screen_width && y >= 0 && y < cpu->screen_height &&
color_index >= 0 && color_index < PALETTE_SIZE)
{
SDL_Color palette_color = cpu->palette[color_index];
Uint32 color = ((Uint32)palette_color.a << 24) |
((Uint32)palette_color.r << 16) |
((Uint32)palette_color.g << 8) |
((Uint32)palette_color.b);
cpu->pixels[y * cpu->screen_width + x] = color;
}
else {
}
}
void draw_line_gfx(VirtualCPU* cpu) {
int x1 = cpu->registers[0];
int y1 = cpu->registers[1];
int x2 = cpu->registers[2];
int y2 = cpu->registers[3];
int color_index = cpu->registers[4];
if (color_index < 0 || color_index >= PALETTE_SIZE) color_index = 0;
if (x1 > x2) {
int tmpx = x1; x1 = x2; x2 = tmpx;
int tmpy = y1; y1 = y2; y2 = tmpy;
}
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
int sx = (x1 < x2) ? 1 : -1;
int sy = (y1 < y2) ? 1 : -1;
int err = dx - dy;
int current_x = x1;
int current_y = y1;
while (true) {
draw_pixel_gfx(cpu, current_x, current_y, color_index);
if (current_x == x2 && current_y == y2) break;
int e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
current_x += sx;
}
if (e2 < dx) {
err += dx;
current_y += sy;
}
if (abs(current_x - x1) > MAX_SCREEN_DIM + MAX_SCREEN_DIM ||
abs(current_y - y1) > MAX_SCREEN_DIM + MAX_SCREEN_DIM) {
fprintf(stderr, "Warning DRAW_LINE: Potential infinite loop detected for line from (%d,%d) to (%d,%d) at line %d. Aborting drawing.\n",
cpu->registers[0], cpu->registers[1], cpu->registers[2], cpu->registers[3], cpu->ip + 1);
break;
}
}
if (cpu->screen_on == 1) {
updateScreen(cpu);
}
}
void draw_line_gfx_impl(VirtualCPU* cpu, int x1, int y1, int x2, int y2, int color_index) {
if (x1 == x2 && y1 == y2) {
draw_pixel_gfx(cpu, x1, y1, color_index);
return;
}
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
int sx = (x1 < x2) ? 1 : -1;
int sy = (y1 < y2) ? 1 : -1;
int err = dx - dy;
int current_x = x1;
int current_y = y1;
int step_count = 0;
const int max_steps = cpu->screen_width + cpu->screen_height + 100;
while (true) {
draw_pixel_gfx(cpu, current_x, current_y, color_index);
if (current_x == x2 && current_y == y2) break;
step_count++;
if (step_count > max_steps) {
fprintf(stderr, "Warning draw_line_gfx_impl: Exceeded max steps (%d) for line from (%d,%d) to (%d,%d) at line %d. Aborting drawing.\n",
max_steps, x1, y1, x2, y2, cpu->ip + 1);
break;
}
int e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
current_x += sx;
}
if (e2 < dx) {
err += dx;
current_y += sy;
}
}
}
// Draws a filled rectangle
void draw_rect_filled_gfx(VirtualCPU* cpu) {
int x = cpu->registers[0];
int y = cpu->registers[1];
int w = cpu->registers[2];
int h = cpu->registers[3];
int color_index = cpu->registers[4];
if (w <= 0 || h <= 0) return;
if (color_index < 0 || color_index >= PALETTE_SIZE) color_index = 0;
int start_x = (x < 0) ? 0 : x;
int start_y = (y < 0) ? 0 : y;
int end_x = (x + w > cpu->screen_width) ? cpu->screen_width : x + w;
int end_y = (y + h > cpu->screen_height) ? cpu->screen_height : y + h;
if (start_x >= end_x || start_y >= end_y) return;
for (int current_y = start_y; current_y < end_y; ++current_y) {
for (int current_x = start_x; current_x < end_x; ++current_x) {
draw_pixel_gfx(cpu, current_x, current_y, color_index);
}
}
if (cpu->screen_on == 1) {
updateScreen(cpu);
}
}
void draw_rect_hollow_gfx(VirtualCPU* cpu) {
int x = cpu->registers[0];
int y = cpu->registers[1];
int w = cpu->registers[2];
int h = cpu->registers[3];
int color_index = cpu->registers[4];
if (w <= 0 || h <= 0) return;
if (color_index < 0 || color_index >= PALETTE_SIZE) color_index = 0;
int r0_orig = cpu->registers[0];
int r1_orig = cpu->registers[1];
int r2_orig = cpu->registers[2];
int r3_orig = cpu->registers[3];
int r4_orig = cpu->registers[4];
cpu->registers[0] = x;
cpu->registers[1] = y;
cpu->registers[2] = x + w - 1;
cpu->registers[3] = y;
cpu->registers[4] = color_index;
draw_line_gfx(cpu);
cpu->registers[0] = x;
cpu->registers[1] = y + h - 1;
cpu->registers[2] = x + w - 1;
cpu->registers[3] = y + h - 1;
cpu->registers[4] = color_index;
draw_line_gfx(cpu);
cpu->registers[0] = x;
cpu->registers[1] = y;
cpu->registers[2] = x;
cpu->registers[3] = y + h - 1;
cpu->registers[4] = color_index;
draw_line_gfx(cpu);
cpu->registers[0] = x + w - 1;
cpu->registers[1] = y;
cpu->registers[2] = x + w - 1;
cpu->registers[3] = y + h - 1;
cpu->registers[4] = color_index;
draw_line_gfx(cpu);
cpu->registers[0] = r0_orig;
cpu->registers[1] = r1_orig;
cpu->registers[2] = r2_orig;
cpu->registers[3] = r3_orig;
cpu->registers[4] = r4_orig;
}
void draw_circle_points(VirtualCPU* cpu, int cx, int cy, int x, int y, int color_index) {
draw_pixel_gfx(cpu, cx + x, cy + y, color_index);
draw_pixel_gfx(cpu, cx - x, cy + y, color_index);
draw_pixel_gfx(cpu, cx + x, cy - y, color_index);
draw_pixel_gfx(cpu, cx - x, cy - y, color_index);
draw_pixel_gfx(cpu, cx + y, cy + x, color_index);
draw_pixel_gfx(cpu, cx - y, cy + x, color_index);
draw_pixel_gfx(cpu, cx + y, cy - x, color_index);
draw_pixel_gfx(cpu, cx - y, cy - x, color_index);
}
// Draws a hollow circle using the Midpoint Circle Algorithm
void draw_circle_hollow_gfx(VirtualCPU* cpu) {
int cx = cpu->registers[0];
int cy = cpu->registers[1];
int radius = cpu->registers[2];
int color_index = cpu->registers[3];
if (radius <= 0) {
if (radius == 0) draw_pixel_gfx(cpu, cx, cy, color_index);
return;
}
if (color_index < 0 || color_index >= PALETTE_SIZE) color_index = 0;
int x = 0;
int y = radius;
int p = 1 - radius;
draw_circle_points(cpu, cx, cy, x, y, color_index);
while (x < y) {
x++;
if (p < 0) {
p += 2 * x + 1;
}
else {
y--;
p += 2 * (x - y) + 1;
}
draw_circle_points(cpu, cx, cy, x, y, color_index);
}
}
void draw_circle_filled_gfx(VirtualCPU* cpu) {
int cx = cpu->registers[0];
int cy = cpu->registers[1];
int radius = cpu->registers[2];
int color_index = cpu->registers[3];
if (radius <= 0) {
if (radius == 0) draw_pixel_gfx(cpu, cx, cy, color_index);
return;
}
if (color_index < 0 || color_index >= PALETTE_SIZE) color_index = 0;
for (int y = -radius; y <= radius; ++y) {
int dy_sq = y * y;
int radius_sq = radius * radius;
int dx_sq = radius_sq - dy_sq;
if (dx_sq >= 0) {
int dx = round(sqrt(dx_sq));
int start_x = cx - dx;
int end_x = cx + dx;
int current_y = cy + y;
for (int current_x = start_x; current_x <= end_x; ++current_x) {
draw_pixel_gfx(cpu, current_x, current_y, color_index);
}
}
}
}
long long triangle_signed_area_test(long long p1x, long long p1y, long long p2x, long long p2y, long long ptx, long long pty) {
return (p2x - p1x) * (pty - p1y) - (ptx - p1x) * (p2y - p1y);
}
void draw_triangle_filled_gfx(VirtualCPU* cpu) {
int x1 = cpu->registers[0]; int y1 = cpu->registers[1];
int x2 = cpu->registers[2]; int y2 = cpu->registers[3];
int x3 = cpu->registers[4]; int y3 = cpu->registers[5];
int color_index = cpu->registers[6];
int min_x = SDL_min(x1, SDL_min(x2, x3));
int max_x = SDL_max(x1, SDL_max(x2, x3));
int min_y = SDL_min(y1, SDL_min(y2, y3));
int max_y = SDL_max(y1, SDL_max(y2, y3));
min_x = SDL_max(min_x, 0);
min_y = SDL_max(min_y, 0);
max_x = SDL_min(max_x, cpu->screen_width - 1);
max_y = SDL_min(max_y, cpu->screen_height - 1);
for (int py = min_y; py <= max_y; ++py) {
for (int px = min_x; px <= max_x; ++px) {
long long d1 = triangle_signed_area_test(x1, y1, x2, y2, px, py);
long long d2 = triangle_signed_area_test(x2, y2, x3, y3, px, py);
long long d3 = triangle_signed_area_test(x3, y3, x1, y1, px, py);
bool has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
bool has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
bool is_inside = !(has_neg && has_pos);
if (is_inside) {
draw_pixel_gfx(cpu, px, py, color_index);
}
}
}
}
void draw_triangle_hollow_gfx(VirtualCPU* cpu) {
int x1 = cpu->registers[0]; int y1 = cpu->registers[1];
int x2 = cpu->registers[2]; int y2 = cpu->registers[3];
int x3 = cpu->registers[4]; int y3 = cpu->registers[5];
int color_index = cpu->registers[6];
draw_line_gfx_impl(cpu, x1, y1, x2, y2, color_index);
draw_line_gfx_impl(cpu, x2, y2, x3, y3, color_index);
draw_line_gfx_impl(cpu, x3, y3, x1, y1, color_index);
}
int parse_condition_operands(const char* line_ptr, char* reg1_str, char* op_str, char* val_str, int max_val_len, int line_num) {
reg1_str[0] = '\0'; op_str[0] = '\0'; val_str[0] = '\0';
while (*line_ptr && (isspace((unsigned char)*line_ptr) || *line_ptr == ',')) line_ptr++;
if (!*line_ptr) { fprintf(stderr, "Error parsing condition: Missing first operand at line %d\n", line_num); return -1; }
char* reg1_start = line_ptr;
char* reg1_end = line_ptr;
while (*reg1_end && !isspace((unsigned char)*reg1_end) && *reg1_end != ',') reg1_end++;
if (reg1_end == reg1_start) { fprintf(stderr, "Error parsing condition: Cannot parse first operand at line %d\n", line_num); return -1; }
size_t reg1_len = reg1_end - reg1_start;
if (reg1_len >= 64) { fprintf(stderr, "Error parsing condition: First operand too long at line %d\n", line_num); return -1; }
strncpy(reg1_str, reg1_start, reg1_len);
reg1_str[reg1_len] = '\0';
line_ptr = reg1_end;
while (*line_ptr && (isspace((unsigned char)*line_ptr) || *line_ptr == ',')) line_ptr++;
if (!*line_ptr) { fprintf(stderr, "Error parsing condition: Missing operator at line %d\n", line_num); return -1; }
char* op_start = line_ptr;
char* op_end = line_ptr;
if (strncmp(op_end, "==", 2) == 0) op_end += 2;
else if (strncmp(op_end, "!=", 2) == 0) op_end += 2;
else if (strncmp(op_end, ">=", 2) == 0) op_end += 2;
else if (strncmp(op_end, "<=", 2) == 0) op_end += 2;
else if (strncmp(op_end, ">", 1) == 0) op_end += 1;
else if (strncmp(op_end, "<", 1) == 0) op_end += 1;
else { fprintf(stderr, "Error parsing condition: Invalid operator at line %d\n", line_num); return -1; }
size_t op_len = op_end - op_start;
if (op_len >= 10) { fprintf(stderr, "Error parsing condition: Operator too long at line %d\n", line_num); return -1; }
strncpy(op_str, op_start, op_len);
op_str[op_len] = '\0';
line_ptr = op_end;
while (*line_ptr && (isspace((unsigned char)*line_ptr) || *line_ptr == ',')) line_ptr++;
if (!*line_ptr) { fprintf(stderr, "Error parsing condition: Missing second operand at line %d\n", line_num); return -1; }
char* val_start = line_ptr;
strncpy(val_str, val_start, max_val_len - 1);
val_str[max_val_len - 1] = '\0';
char* val_end = val_str + strlen(val_str) - 1;
while (val_end >= val_str && isspace((unsigned char)*val_end)) val_end--;
*(val_end + 1) = '\0';
return 0;
}
int evaluate_condition(VirtualCPU* cpu, const char* reg_str, const char* op_str, const char* val_str, int line_num) {
int reg_idx = -1;
if (sscanf(reg_str, "R%d", ®_idx) != 1 || !isValidReg(reg_idx)) {
fprintf(stderr, "Error evaluating condition: Invalid register '%s' at line %d\n", reg_str, line_num);
return -1;
}
int value1 = cpu->registers[reg_idx];
int value2;
int reg2_idx = -1;
if (sscanf(val_str, "R%d", ®2_idx) == 1 && isValidReg(reg2_idx)) {
value2 = cpu->registers[reg2_idx];
}
else {
char* endptr;
long parsed_val = strtol(val_str, &endptr, 0);
if (val_str == endptr || *endptr != '\0') {
double float_val;
if (sscanf(val_str, "%lf", &float_val) == 1 && *endptr == '\0') {
fprintf(stderr, "Error evaluating condition: Floating point immediate '%s' is not supported for integer comparisons at line %d\n", val_str, line_num);
return -1;
}
fprintf(stderr, "Error evaluating condition: Invalid second operand '%s' (must be register or integer immediate) at line %d\n", val_str, line_num);
return -1;
}
value2 = (int)parsed_val;
if (parsed_val > INT_MAX || parsed_val < INT_MIN) {
}
}
if (strcmp(op_str, "==") == 0) return (value1 == value2);
if (strcmp(op_str, "!=") == 0) return (value1 != value2);
if (strcmp(op_str, ">") == 0) return (value1 > value2);
if (strcmp(op_str, "<") == 0) return (value1 < value2);
if (strcmp(op_str, ">=") == 0) return (value1 >= value2);
if (strcmp(op_str, "<=") == 0) return (value1 <= value2);
fprintf(stderr, "Error evaluating condition: Unknown operator '%s' at line %d\n", op_str, line_num);
return -1;
}
int find_matching_end(char* program[], int program_size, int start_ip) {
InstructionType start_type = INVALID_INST;
if (start_ip >= 0 && start_ip < program_size && program[start_ip]) {
char op_str[MAX_LINE_LENGTH];
char* scan_ptr = program[start_ip];
while (*scan_ptr && isspace((unsigned char)*scan_ptr)) scan_ptr++;
int scan_op_idx = 0;
while (*scan_ptr && !isspace((unsigned char)*scan_ptr) && *scan_ptr != ',' && scan_op_idx < sizeof(op_str) - 1) {
op_str[scan_op_idx++] = toupper((unsigned char)*scan_ptr++);
}
op_str[scan_op_idx] = '\0';
start_type = parseInstruction(op_str);
if (start_type != IF && start_type != WHILE) {
fprintf(stderr, "Error (Internal): find_matching_end called on IP %d with non-block start instruction.\n", start_ip + 1);
return -1;
}
}
else {
fprintf(stderr, "Error (Internal): find_matching_end called with invalid start_ip %d.\n", start_ip);
return -1;
}
int nested_level = 0;