-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathexample_adder.hell
More file actions
1176 lines (942 loc) · 26.1 KB
/
example_adder.hell
File metadata and controls
1176 lines (942 loc) · 26.1 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
/*
* This file is part of LMAO (Low-level Malbolge Assembler, Ooh!), an
* assembler for Malbolge.
* Copyright (C) 2013-2017 Matthias Lutter
*
* LMAO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMAO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* E-Mail: matthias@lutter.cc
*
*
* Example in HeLL: Adding two 3-digit numbers.
*
* This HeLL program reads two numbers of up to 3 digits from stdin
* and prints out their sum.
* Transforming decimal numbers into ternary and back would require to
* implement multiplication and modulo operations, which would
* slow down the program and probably require more initialization code
* than the allowed 59049 bytes.
* Thus, this program sums the numbers in their decimal representation.
* Therefore, xlat2-cycles (Malbolge instruction cycles) of size 2 and 5
* are used to represent each of the three digits.
* Summing is done by calling the R_ prefixed instruction of the first
* number until the cycle of the second number turns from Nop to MovD.
* The resulting cycles represent the sum of the two digits.
* They are used as conditions to leave a loop in which the ASCII
* character '9' is decremented. In this way, the ASCII representation
* to be printed out is generated finally.
*
* Unfortunately, this code has not been revised before publication.
* Thus, it may be chaotic and hard to understand.
* Development of this program has been started with the digital root
* program. Some comments may not be adapted properly.
*/
.CODE
// standard malbolge commands
// used with U_-prefix to skip some code
NOP:
Jmp
MOVED:
MovD/Nop
Jmp
CRAZY:
Opr/Nop
Jmp
ROT:
Rot/Nop
Jmp
HALT:
Hlt
OUT:
Out/Nop
Jmp
IN:
In/Nop
Jmp
// used in increment and decrement subroutines for carry-detection
@C21 CARRY:
RNop
RNop
Jmp
// flags follow
// classic return-flags that are used to return to the position where
// a subroutine (or variable access) has been called
SUBROUTINE_FLAG2:
Nop/MovD
Jmp
SUBROUTINE_FLAG3:
Nop/MovD
Jmp
SUBROUTINE_FLAG1:
FLAG1:
Nop/MovD
Jmp
SUBROUTINE_FLAG6:
FLAG2:
Nop/MovD
Jmp
SUBROUTINE_FLAG7:
FLAG3:
Nop/MovD
Jmp
SUBROUTINE_FLAG4:
FLAG4:
Nop/MovD
Jmp
SUBROUTINE_FLAG5:
FLAG5:
Nop/MovD
Jmp
SUBROUTINE_FLAG8:
FLAG8:
Nop/MovD
Jmp
SUBROUTINE_FLAG9:
FLAG9:
Nop/MovD
Jmp
// flags that act as loop counter
LOOP2:
Nop/MovD
Jmp
LOOP2_2:
Nop/MovD
Jmp
LOOP2_3:
Nop/MovD
Jmp
LOOP2_4:
Nop/MovD
Jmp
LOOP5:
Nop/Nop/Nop/Nop/MovD
Jmp
// read input: count down until '0'
LOOP4_1:
Nop/Nop/Nop/MovD
Jmp
LOOP4_2:
Nop/Nop/Nop/MovD
Jmp
LOOP2_special:
Nop/MovD
Jmp
// more sophisticated flags follow below
// flag used inside increment and decrement subroutines.
// if this is set when the routine returns,
// it indicates an overflow (add: C2->C0; sub: C0->C2).
NO_MORE_CARRY_FLAG:
Nop/MovD
Jmp
// this flag is set to indicate that the user has typed at least
// one valid digit.
READ_DIGIT_FLAG:
Nop/MovD
Jmp
// used during input precessing to indicate that a character is in the
// ASCII range of digits ('0' until '9').
// if set, the character should be written into the xlat2-cycles.
// otherwise, the character should be ignored or treated as separator.
NUMBER_READ_FLAG:
Nop/MovD
Jmp
// indicates whether the first or the second number is being read
// from stdin at the moment
WAITING_FOR_FIRST_NUMBER_FLAG:
MovD/Nop
Jmp
// loop through digits of output (3 digits; possible leading 1 from
// overflow is handled separately)
PRINT_ALL_DIGITS_LOOP:
Nop/Nop/MovD/Nop // print 3 times
Jmp
// indicated whether the program is in "print out mode"
IS_PRINTING_FLAG:
Nop/MovD
Jmp
// leading zeroes are ignored. if any digit has been printed, this flag
// is set to indicate that zeroes are now printed as well.
ANY_DIGIT_HAS_BEEN_PRINTED_FLAG:
MovD/Nop
Jmp
// if no digit has been printed at all, the last digit is a the leading
// digit as well. however, in this case it should be printed out, even
// if it is zero.
// this flag is used to indicate that case.
PRINT_ZERO_FLAG:
MovD/Nop/Nop/Nop/Nop/Nop/Nop/Nop/Nop
Jmp
/*** decimal digits/numbers represented by xlat2-cycles follow ***/
// store three digits (DIGIT0..DIGIT2) of NUMBER1 (N1) by
// two xlat2-cycles each
N1_DIGIT0_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
N1_DIGIT0_LOW:
Nop/MovD
Jmp
N1_DIGIT1_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
N1_DIGIT1_LOW:
Nop/MovD
Jmp
N1_DIGIT2_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
N1_DIGIT2_LOW:
Nop/MovD
Jmp
// store three digits (DIGIT0..DIGIT2) of NUMBER2 (N2) by
// two xlat2-cycles each
N2_DIGIT0_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
N2_DIGIT0_LOW:
Nop/MovD
Jmp
N2_DIGIT1_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
N2_DIGIT1_LOW:
Nop/MovD
Jmp
N2_DIGIT2_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
N2_DIGIT2_LOW:
Nop/MovD
Jmp
// store temporary "tmp" digit in these two xlat2 cycles
TMP_DIGIT_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
TMP_DIGIT_LOW:
Nop/MovD
Jmp
// store temporary "tmp2" digit in these two xlat2 cycles
// it is used for cloning/shifting while TMP is occupied
TMP2_DIGIT_HIGH:
Nop/Nop/Nop/Nop/MovD
Jmp
TMP2_DIGIT_LOW:
Nop/MovD
Jmp
// stores an overflow occured during adding of the two numbers.
// if this flag is set, the result is between 1000 and 1998, thus
// a leading '1' is forced to be printed out.
// afterwards, the last 3 digits of the number are printed out normally
// (with ANY_DIGIT_HAS_BEEN_PRINTED_FLAG set).
OVERFLOW:
MovD/Nop
Jmp
.DATA
/// data section, containing the program logic, but not the numbers,
/// which are stored in the CODE section.
/// thus, the semantic purpose of the CODE and DATA section are confused
/// totally.
/// however, the sections indicate the kind of Malbolge cells, not their
/// semantic properties.
// var carry
// carry: this variable stores whether there is an overflow or not
// (used by subroutines increment and decrement).
// CARRY from .CODE-section will be used to branch dependent on variable value,
// which is either CARRY or CARRY+1
crazy_carry:
U_CRAZY carry
exec_carry:
R_MOVED
carry:
CARRY
U_NOP execution_not_jumped_to_carry
U_NOP carry_was_not_set U_NOP carry_was_set
carry_was_set:
MOVED return_carry_was_set
carry_was_not_set:
MOVED return_carry_was_not_set
execution_not_jumped_to_carry:
FLAG2 return_from_carry_2 R_FLAG2
return_carry_was_set:
FLAG2 return_from_carry_was_set_2 R_FLAG2
return_carry_was_not_set:
FLAG2 return_from_carry_was_not_set_2
restore_initial_state:
R_MOVED //destroy moved (for reset_value_loop)
restore_initial_state_and_moved:
READ_DIGIT_FLAG restore_initial_state_and_moved
R_READ_DIGIT_FLAG
// write C1 into value and value_C1.
ROT C1 R_ROT
reset_value_loop:
R_MOVED
crazy_value:
U_CRAZY value
rot_value:
U_ROT value
value:
C1
FLAG2 return_from_value_2 R_FLAG2
FLAG3 return_from_value_3 R_FLAG3
FLAG4 return_from_value_4 R_FLAG4
FLAG5 return_from_value_5 R_FLAG5
FLAG8 return_from_value_8 R_FLAG8
FLAG9 return_from_value_9 R_FLAG9
return_from_value_1:
R_CRAZY
LOOP2 value_reset
MOVED reset_value_loop
value_reset:
R_MOVED
reset_value_C1_loop:
R_MOVED
crazy_value_C1:
U_CRAZY value_C1
rot_value_C1:
U_ROT value_C1
value_C1:
C1
FLAG2 return_from_value_C1_2 R_FLAG2
return_from_value_C1_1:
R_CRAZY
LOOP2 value_C1_reset
MOVED reset_value_C1_loop
restore_tmp_digit_high:
R_MOVED
value_C1_reset:
TMP_DIGIT_HIGH restore_tmp_digit_high_done
MOVED restore_tmp_digit_high
restore_tmp_digit_low:
R_MOVED
restore_tmp_digit_high_done:
TMP_DIGIT_LOW restore_tmp_digit_low_done
MOVED restore_tmp_digit_low
restore_tmp_digit_low_done:
ENTRY:
// read character from stdin and store it in value_C1 and then in value
IN ?- R_IN
R_FLAG2
MOVED crazy_value_C1
return_from_value_C1_2:
R_CRAZY R_MOVED
R_FLAG2
MOVED crazy_value
return_from_value_2:
R_CRAZY R_MOVED
// decrement to determine actual value
R_SUBROUTINE_FLAG1
MOVED decrement_value
{
decrement_compare_loop:
R_MOVED
// decrement value until an overflow is reached
// by using LOOPs from the .CODE-section,
// we can branch dependent on the number of decrements done so far
R_SUBROUTINE_FLAG1
MOVED decrement_value
return_from_decrement_value_1:
NO_MORE_CARRY_FLAG no_decrement_overflow
MOVED decrement_overflow_detected
}
no_decrement_overflow:
; NO_EXIT_FLAG no_decrement_overflow
; R_NO_EXIT_FLAG
// if we have reached the number of decrements for ASCII character '1' before,
// every further decrement cycle tells us that the number we read is one greater than we thought
READ_DIGIT_FLAG increment_digit R_READ_DIGIT_FLAG
// if '1' has not yet been reached, we jump into LOOP5_2 every 5th decrement step.
LOOP4_1 outer4loop
MOVED decrement_compare_loop
outer4loop:
// jump into inner5loop every 5th steo again.
// so it will be executed every 25th decrement step
LOOP4_2 middle4loop
MOVED decrement_compare_loop
middle4loop:
// jump into inner5loop every 5th steo again.
// so it will be executed every 25th decrement step
LOOP2_special inner2loop
MOVED decrement_compare_loop
inner2loop:
; NO_EXIT_FLAG inner2loop // at least a space has been read (?)
R_LOOP2_special // only one more time!
// we read an ASCII character of value at least 24.
// therefore we did not read EOF or newline, so we shall not output
// the digital root right now. we store this by forcing the NO_EXIT_FLAG to be set.
// every second step (50 decrements executed) we go into the innerst loop
LOOP2_4 innerst2loop
MOVED decrement_compare_loop
innerst2loop:
// when we get here the first time, we read an ASCII value at least 49,
// which is '1'. So we set the READ_DIGIT_FLAG to indicate we read such a digit.
R_READ_DIGIT_FLAG
MOVED decrement_compare_loop
increment_digit:
; NO_EXIT_FLAG increment_digit
// restore R_READ_DIGIT_FLAG
R_READ_DIGIT_FLAG
// increment digit (stored in TMP_DIGIT) by calling TMP_DIGIT:
// the next element of the MovD-cycle is set
// if TMP_DIGIT was set to MovD before, this is the 9th increment - we did
// not read a digit from '1' to '9', but an ASCII character that is greater than '9'.
// then we abort parsing the current input character and read another one.
TMP_DIGIT_LOW tmp_digit_overflow_low
MOVED decrement_compare_loop
tmp_digit_overflow_low:
TMP_DIGIT_HIGH exitloop
MOVED decrement_compare_loop
exitloop:
; NO_EXIT_FLAG exitloop
; R_NO_EXIT_FLAG
// reset READ_DIGIT_FLAG and leave input-parsing decrement-loop
R_READ_DIGIT_FLAG
MOVED decrement_overflow_detected
// this is the exit label for the input character recognition above.
decrement_overflow_detected:
// at first, we restore the LOOPs, so we could use them again.
restore_2_loop2:
R_MOVED
restore_5_loop2_done:
LOOP2_4 restore_2_loop2_done
MOVED restore_2_loop2
restore_loop4:
R_MOVED
restore_2_loop2_done:
LOOP4_1 restore_loop4_done
MOVED restore_loop4
restore_2_loop4:
R_MOVED
restore_loop4_done:
LOOP4_2 restore_2_loop4_done
MOVED restore_2_loop4
restore_special_loop2:
R_MOVED
restore_2_loop4_done:
LOOP2_special restore_special_loop2_done
MOVED restore_special_loop2
restore_special_loop2_done:
// now we test whether we shall output the current digital root
// or adapt it and read the next character
; NO_EXIT_FLAG process_input // adapt current digital root
READ_DIGIT_FLAG process_input_digit
MOVED process_input_nondigit // print out digital root and exit
process_input_nondigit:
R_MOVED
NUMBER_READ_FLAG process_input_number
NUMBER_READ_FLAG restore_initial_state
process_input_number:
WAITING_FOR_FIRST_NUMBER_FLAG read_first_number
WAITING_FOR_FIRST_NUMBER_FLAG read_second_number
read_first_number:
R_NUMBER_READ_FLAG
NUMBER_READ_FLAG restore_initial_state
read_second_number:
// ADD NUMBERS AND PRINT RESULT
R_SUBROUTINE_FLAG3
MOVED clear_tmp2
process_input_digit:
NUMBER_READ_FLAG process_input_digit // a number has been read
// shift tmp_digit into number (n1 or n2)
WAITING_FOR_FIRST_NUMBER_FLAG append_tmp_digit_to_first_number // and restore WAITING_FOR_FIRST_NUMBER_FLAG
WAITING_FOR_FIRST_NUMBER_FLAG append_tmp_digit_to_second_number
// shift digit...
append_tmp_digit_to_first_number:
R_WAITING_FOR_FIRST_NUMBER_FLAG
MOVED clear_n1_msd
append_tmp_digit_to_second_number:
MOVED clear_n2_msd
return_clear_tmp2_3:
;R_N2_DIGIT0_LOW
N2_DIGIT0_LOW add_n2_digit0_to_n1_digit0_5
MOVED add_n2_digit0_to_n1_digit0_2
add_n2_digit0_to_n1_digit0_5:
N1_DIGIT0_LOW add_n2_digit0_to_n1_digit0_overflow_low
MOVED add_n2_digit0_to_n1_digit0_2
add_n2_digit0_to_n1_digit0_overflow_low:
R_OVERFLOW
MOVED add_n2_digit0_to_n1_digit0_2
add_n2_digit0_to_n1_digit0_2:
R_MOVED
// now the digits have to be added...
N2_DIGIT0_HIGH add_n2_digit0_to_n1_digit0_1
R_TMP2_DIGIT_HIGH
MOVED add_n2_digit0_to_n1_digit0_2
add_n2_digit0_to_n1_digit0_1:
OVERFLOW add_n2_digit0_to_n1_digit0_6
N1_DIGIT0_HIGH add_n2_digit0_to_n1_digit0_6
R_OVERFLOW
add_n2_digit0_to_n1_digit0_6:
R_OVERFLOW
R_MOVED
add_n2_digit0_to_n1_digit0_4:
R_MOVED
TMP2_DIGIT_HIGH add_n2_digit1_to_n1_digit1 // NEXT DIGIT
N1_DIGIT0_HIGH add_n2_digit0_to_n1_digit0_6
MOVED add_n2_digit0_to_n1_digit0_4
add_n2_digit1_to_n1_digit1:
R_SUBROUTINE_FLAG6
MOVED clear_tmp2
return_clear_tmp2_6:
add_n2_digit1_to_n1_digit1_3:
OVERFLOW add_n2_digit1_to_n1_digit1_overflow_low2
N1_DIGIT1_LOW add_n2_digit1_to_n1_digit1_overflow_low2
R_OVERFLOW
add_n2_digit1_to_n1_digit1_overflow_low2:
R_OVERFLOW
N2_DIGIT1_LOW add_n2_digit1_to_n1_digit1_5
MOVED add_n2_digit1_to_n1_digit1_2
add_n2_digit1_to_n1_digit1_5:
N1_DIGIT1_LOW add_n2_digit1_to_n1_digit1_overflow_low
MOVED add_n2_digit1_to_n1_digit1_2
add_n2_digit1_to_n1_digit1_overflow_low:
R_OVERFLOW
MOVED add_n2_digit1_to_n1_digit1_2
add_n2_digit1_to_n1_digit1_2:
R_MOVED
// now the digits have to be added...
N2_DIGIT1_HIGH add_n2_digit1_to_n1_digit1_1
R_TMP2_DIGIT_HIGH
MOVED add_n2_digit1_to_n1_digit1_2
add_n2_digit1_to_n1_digit1_1:
OVERFLOW add_n2_digit1_to_n1_digit1_6
N1_DIGIT1_HIGH add_n2_digit1_to_n1_digit1_6
R_OVERFLOW
add_n2_digit1_to_n1_digit1_6:
R_OVERFLOW
R_MOVED
add_n2_digit1_to_n1_digit1_4:
R_MOVED
TMP2_DIGIT_HIGH add_n2_digit2_to_n1_digit2 ;NEXT DIGIT
N1_DIGIT1_HIGH add_n2_digit1_to_n1_digit1_6
MOVED add_n2_digit1_to_n1_digit1_4
add_n2_digit2_to_n1_digit2:
R_SUBROUTINE_FLAG9
MOVED clear_tmp2
return_clear_tmp2_9:
add_n2_digit2_to_n1_digit2_3:
OVERFLOW add_n2_digit2_to_n1_digit2_overflow_low2
N1_DIGIT2_LOW add_n2_digit2_to_n1_digit2_overflow_low2
R_OVERFLOW
add_n2_digit2_to_n1_digit2_overflow_low2:
R_OVERFLOW
N2_DIGIT2_LOW add_n2_digit2_to_n1_digit2_5
MOVED add_n2_digit2_to_n1_digit2_2
add_n2_digit2_to_n1_digit2_5:
N1_DIGIT2_LOW add_n2_digit2_to_n1_digit2_overflow_low
MOVED add_n2_digit2_to_n1_digit2_2
add_n2_digit2_to_n1_digit2_overflow_low:
R_OVERFLOW
MOVED add_n2_digit2_to_n1_digit2_2
add_n2_digit2_to_n1_digit2_2:
R_MOVED
// now the digits have to be added...
N2_DIGIT2_HIGH add_n2_digit2_to_n1_digit2_1
R_TMP2_DIGIT_HIGH
MOVED add_n2_digit2_to_n1_digit2_2
add_n2_digit2_to_n1_digit2_1:
OVERFLOW add_n2_digit2_to_n1_digit2_6
N1_DIGIT2_HIGH add_n2_digit2_to_n1_digit2_6
R_OVERFLOW
add_n2_digit2_to_n1_digit2_6:
R_OVERFLOW
R_MOVED
add_n2_digit2_to_n1_digit2_4:
R_MOVED
TMP2_DIGIT_HIGH add_n2_digit2_to_n1_digit2_fin
N1_DIGIT2_HIGH add_n2_digit2_to_n1_digit2_6
MOVED add_n2_digit2_to_n1_digit2_4
add_n2_digit2_to_n1_digit2_fin:
R_OVERFLOW
OVERFLOW print_leading_one
MOVED print_result
print_leading_one:
// do not process
ROT '1'<<1 R_ROT OUT ?- R_OUT
R_ANY_DIGIT_HAS_BEEN_PRINTED_FLAG
MOVED print_result
// MSD of N1 is DIGIT2.
clear_n1_msd: // clear most significant digit of n1
n1_msd_high_clearloop:
R_MOVED
N1_DIGIT2_HIGH n1_msd_high_cleared
MOVED n1_msd_high_clearloop
n1_msd_high_cleared:
N1_DIGIT2_LOW n1_msd_high_cleared
R_N1_DIGIT2_LOW
// now the digit is cleared
// clear TMP2
R_SUBROUTINE_FLAG1
MOVED clear_tmp2
clone_n1_digit1_digit_to_n1_digit2_2:
R_MOVED
return_clear_tmp2:
// now the digits have to be shifted...
clone_n1_digit1_digit_to_n1_digit2:
N1_DIGIT1_HIGH clone_n1_digit1_digit_to_n1_digit2_1
R_TMP2_DIGIT_HIGH
MOVED clone_n1_digit1_digit_to_n1_digit2_2
clone_n1_digit1_digit_to_n1_digit2_4:
R_MOVED
clone_n1_digit1_digit_to_n1_digit2_1:
TMP2_DIGIT_HIGH clone_n1_digit1_digit_to_n1_digit2_3
R_N1_DIGIT2_HIGH
MOVED clone_n1_digit1_digit_to_n1_digit2_4
clone_n1_digit1_digit_to_n1_digit2_3:
// high has bee cloned. now clone low.
R_N1_DIGIT2_LOW
N1_DIGIT1_LOW clone_n1_digit1_digit_to_n1_digit2_5
R_N1_DIGIT2_LOW
R_N1_DIGIT1_LOW
clone_n1_digit1_digit_to_n1_digit2_5:
// done.
R_SUBROUTINE_FLAG7
MOVED clear_tmp2
clone_n1_digit0_digit_to_n1_digit1_2:
R_MOVED
return_clear_tmp2_7:
// now the digits have to be shifted...
clone_n1_digit0_digit_to_n1_digit1:
N1_DIGIT0_HIGH clone_n1_digit0_digit_to_n1_digit1_1
R_TMP2_DIGIT_HIGH
MOVED clone_n1_digit0_digit_to_n1_digit1_2
clone_n1_digit0_digit_to_n1_digit1_4:
R_MOVED
clone_n1_digit0_digit_to_n1_digit1_1:
TMP2_DIGIT_HIGH clone_n1_digit0_digit_to_n1_digit1_3
R_N1_DIGIT1_HIGH
MOVED clone_n1_digit0_digit_to_n1_digit1_4
clone_n1_digit0_digit_to_n1_digit1_3:
// high has bee cloned. now clone low.
R_N1_DIGIT1_LOW
N1_DIGIT0_LOW clone_n1_digit0_digit_to_n1_digit1_5
R_N1_DIGIT1_LOW
R_N1_DIGIT0_LOW
clone_n1_digit0_digit_to_n1_digit1_5:
// done.
R_SUBROUTINE_FLAG4
MOVED clear_tmp2
clone_tmp_digit_to_n1_digit0_2:
R_MOVED
// now, TMP_DIGIT has to be shifted into LSD (least sognificant digit) of N1.
return_clear_tmp2_4:
clone_tmp_digit_to_n1_digit0:
TMP_DIGIT_HIGH clone_tmp_digit_to_n1_digit0_1
R_TMP2_DIGIT_HIGH
MOVED clone_tmp_digit_to_n1_digit0_2
clone_tmp_digit_to_n1_digit0_4:
R_MOVED
clone_tmp_digit_to_n1_digit0_1:
TMP2_DIGIT_HIGH clone_tmp_digit_to_n1_digit0_3
R_N1_DIGIT0_HIGH
MOVED clone_tmp_digit_to_n1_digit0_4
clone_tmp_digit_to_n1_digit0_3:
// high has bee cloned. now clone low.
R_N1_DIGIT0_LOW
TMP_DIGIT_LOW clone_tmp_digit_to_n1_digit0_5
R_N1_DIGIT0_LOW
clone_tmp_digit_to_n1_digit0_5:
// done.
IS_PRINTING_FLAG print_next R_IS_PRINTING_FLAG
MOVED restore_initial_state_and_moved
// MSD of N2 is DIGIT2.
clear_n2_msd: // clear most significant digit of n1
n2_msd_high_clearloop:
R_MOVED
N2_DIGIT2_HIGH n2_msd_high_cleared
MOVED n2_msd_high_clearloop
n2_msd_high_cleared:
N2_DIGIT2_LOW n2_msd_high_cleared
R_N2_DIGIT2_LOW
// now the digit is cleared
// clear TMP2
R_SUBROUTINE_FLAG2
MOVED clear_tmp2
clone_n2_digit1_digit_to_n2_digit2_2:
R_MOVED
return_clear_tmp2_2:
// now the digits has to be shifted...
clone_n2_digit1_digit_to_n2_digit2:
N2_DIGIT1_HIGH clone_n2_digit1_digit_to_n2_digit2_1
R_TMP2_DIGIT_HIGH
MOVED clone_n2_digit1_digit_to_n2_digit2_2
clone_n2_digit1_digit_to_n2_digit2_4:
R_MOVED
clone_n2_digit1_digit_to_n2_digit2_1:
TMP2_DIGIT_HIGH clone_n2_digit1_digit_to_n2_digit2_3
R_N2_DIGIT2_HIGH
MOVED clone_n2_digit1_digit_to_n2_digit2_4
clone_n2_digit1_digit_to_n2_digit2_3:
// high has bee cloned. now clone low.
R_N2_DIGIT2_LOW
N2_DIGIT1_LOW clone_n2_digit1_digit_to_n2_digit2_5
R_N2_DIGIT2_LOW
R_N2_DIGIT1_LOW
clone_n2_digit1_digit_to_n2_digit2_5:
// done.
R_SUBROUTINE_FLAG8
MOVED clear_tmp2
clone_n2_digit0_digit_to_n2_digit1_2:
R_MOVED
return_clear_tmp2_8:
// now the digits has to be shifted...
clone_n2_digit0_digit_to_n2_digit1:
N2_DIGIT0_HIGH clone_n2_digit0_digit_to_n2_digit1_1
R_TMP2_DIGIT_HIGH
MOVED clone_n2_digit0_digit_to_n2_digit1_2
clone_n2_digit0_digit_to_n2_digit1_4:
R_MOVED
clone_n2_digit0_digit_to_n2_digit1_1:
TMP2_DIGIT_HIGH clone_n2_digit0_digit_to_n2_digit1_3
R_N2_DIGIT1_HIGH
MOVED clone_n2_digit0_digit_to_n2_digit1_4
clone_n2_digit0_digit_to_n2_digit1_3:
// high has bee cloned. now clone low.
R_N2_DIGIT1_LOW
N2_DIGIT0_LOW clone_n2_digit0_digit_to_n2_digit1_5
R_N2_DIGIT1_LOW
R_N2_DIGIT0_LOW
clone_n2_digit0_digit_to_n2_digit1_5:
// done.
R_SUBROUTINE_FLAG5
MOVED clear_tmp2
clone_tmp_digit_to_n2_digit0_2:
R_MOVED
return_clear_tmp2_5:
// now , TMP_DIGIT has to be shifted into LSD (least sognificant digit) of N1.
clone_tmp_digit_to_n2_digit0:
TMP_DIGIT_HIGH clone_tmp_digit_to_n2_digit0_1
R_TMP2_DIGIT_HIGH
MOVED clone_tmp_digit_to_n2_digit0_2
clone_tmp_digit_to_n2_digit0_4:
R_MOVED
clone_tmp_digit_to_n2_digit0_1:
TMP2_DIGIT_HIGH clone_tmp_digit_to_n2_digit0_3
R_N2_DIGIT0_HIGH
MOVED clone_tmp_digit_to_n2_digit0_4
clone_tmp_digit_to_n2_digit0_3:
// high has bee cloned. now clone low.
R_N2_DIGIT0_LOW
TMP_DIGIT_LOW clone_tmp_digit_to_n2_digit0_5
R_N2_DIGIT0_LOW
clone_tmp_digit_to_n2_digit0_5:
// done.
MOVED restore_initial_state_and_moved
clear_tmp2:
R_MOVED
TMP2_DIGIT_HIGH tmp2_high_cleared
MOVED clear_tmp2
tmp2_high_cleared:
TMP2_DIGIT_LOW tmp2_high_cleared
R_TMP2_DIGIT_LOW
// return
SUBROUTINE_FLAG1 return_clear_tmp2 R_SUBROUTINE_FLAG1
SUBROUTINE_FLAG2 return_clear_tmp2_2 R_SUBROUTINE_FLAG2
SUBROUTINE_FLAG3 return_clear_tmp2_3 R_SUBROUTINE_FLAG3
SUBROUTINE_FLAG4 return_clear_tmp2_4 R_SUBROUTINE_FLAG4
SUBROUTINE_FLAG5 return_clear_tmp2_5 R_SUBROUTINE_FLAG5
SUBROUTINE_FLAG6 return_clear_tmp2_6 R_SUBROUTINE_FLAG6
SUBROUTINE_FLAG7 return_clear_tmp2_7 R_SUBROUTINE_FLAG7
SUBROUTINE_FLAG8 return_clear_tmp2_8 R_SUBROUTINE_FLAG8
SUBROUTINE_FLAG9 return_clear_tmp2_9
;N1_DIGIT0_HIGH (Nop/Nop/Nop/Nop/MovD)
;N1_DIGIT0_LOW (Nop/MovD)
;
;N2_DIGIT0_HIGH (Nop/Nop/Nop/Nop/MovD)
;N2_DIGIT0_LOW (Nop/MovD)
;
;TMP2_DIGIT_HIGH
;TMP2_DIGIT_LOW
// start printing the MSD.
// then shift number and print it again - and so on.
// test whether it is zero, then don't print (except the whole number is 0).
print_next:
R_MOVED
print_result:
LOOP2 print_result
R_LOOP2
restore_zf_loop:
PRINT_ZERO_FLAG restore_zf_done
R_MOVED
MOVED restore_zf_loop
restore_zf_done:
// set value to '9'.
// therefore, reset it to C1 first.
ROT C1 R_ROT
just_another_reset_value_loop:
R_MOVED
R_FLAG3
MOVED crazy_value
return_from_value_3:
R_CRAZY R_MOVED
LOOP2 continue_printing
MOVED just_another_reset_value_loop
continue_printing:
TMP_DIGIT_LOW continue_printing
R_LOOP2
// now set value to '0' by crazy operator
load_9_char:
ROT C2 R_ROT
CRAZY '9'!C1 R_CRAZY
LOOP2 load_9_char
R_FLAG4