-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNagra_Kwon_Lim_Disassembler.X68
executable file
·5008 lines (3990 loc) · 145 KB
/
Nagra_Kwon_Lim_Disassembler.X68
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
*------------------------------------------------------------------
* Title : Team A Disassembler- CSS 422
* Written by : Orpal Nagra, Kris (Giwhan) Kwon, Yuunbum Lim
* Date : 12/8/2018
* Description: Please see attached docs for detailed description
*------------------------------------------------------------------
STACK EQU $7000 ;
range_start EQU $7000 ;
range_end EQU $9FFF ;
list_hex_size EQU 16 ;
clear EQU $00000000 ;
display_size EQU 20 ;
init EQU 0 ;
increment EQU 1 ;
long EQU 8 ;
word EQU 4 ;
byte EQU 2 ;
* Special characters ;
CR EQU $0D ;
LF EQU $0A ;
NULL EQU $00 ;
TAB EQU $09 ;
DOLLAR EQU $24 ; #36 in dec
COMMA EQU $2C ;
PERIOD EQU $2E ;
PLUS EQU $2B ;
MINUS EQU $2D ;
Open_paren EQU $28 ;
Close_paren EQU $29 ;
SPACE EQU $20 ;
SHARP EQU $23 ;
SLASH EQU $2F ;
DASH EQU $2D ;
COLON EQU $3A ;
* Alphabet
A_ EQU $41 ;
B_ EQU $42 ;
C_ EQU $43 ;
D_ EQU $44 ;
E_ EQU $45 ;
F_ EQU $46 ;
G_ EQU $47 ;
H_ EQU $48 ;
I_ EQU $49 ;
J_ EQU $4A ;
K_ EQU $4B ;
L_ EQU $4C ;
M_ EQU $4D ;
N_ EQU $4E ;
O_ EQU $4F ;
P_ EQU $50 ;
Q_ EQU $51 ;
R_ EQU $52 ;
S_ EQU $53 ;
T_ EQU $54 ;
U_ EQU $55 ;
V_ EQU $56 ;
W_ EQU $57 ;
X_ EQU $58 ;
Y_ EQU $59 ;
Z_ EQU $5A ;
* Numbers
ZERO_ EQU $30 ;
ONE_ EQU $31 ;
TWO_ EQU $32 ;
THREE_ EQU $33 ;
FOUR_ EQU $34 ;
FIVE_ EQU $35 ;
SIX_ EQU $36 ;
SEVEN_ EQU $37 ;
EIGHT_ EQU $38 ;
NINE_ EQU $39 ;
ORG $1000
START: ; first instruction of program
* Put program code here
* get starting address
StartPrompt
* prompt user to ask starting address
BSR PROMPT_START ;
* take starting address from the user
BSR TAKE_INPUT ;
* convert input string to hex value
BSR STR_TO_HEX ; result hex in D1
* check if starting address is in the range
BSR CHECK_STARTING_BOUND ;
BGE startingIsGreater ;
BRA StartPrompt ;
startingIsGreater
MOVE.L D1, START_HEX ;
* get ending address
EndPrompt
* prompt to ask ending address
BSR PROMPT_END
* take ending address from the user
BSR TAKE_INPUT
* convert input string to hex value
BSR STR_TO_HEX
* check if starting address is in the range
BSR CHECK_ENDING_BOUND
BGT endingIsGreaterThanStart ;
BRA EndPrompt
endingIsGreaterThanStart ;
CMP.L #range_end, D1 ;
BGT EndPrompt ;
MOVE.L D1, END_HEX ;
BRA MAIN
PROMPT_START ; Asking starting address
LEA PROMPT_1, A1 ;
MOVE.B #13, D0 ;
TRAP #15 ;
LEA PROMPT_3, A1 ;
MOVE.B #14, D0 ;
TRAP #15 ;
RTS
TAKE_INPUT
LEA INPUT, A1 ;
* take input
MOVE.B #2, D0 ;
TRAP #15 ;
* move input to INPUT_LENGTH
MOVE.W D1, INPUT_LENGTH
RTS
* convert input string to hex
STR_TO_HEX
MOVE.B #0, D2 ; starting index of the string
MOVE.W D1, D3 ; size of input string in D3
MOVE.L #clear, D1 ; clear D1
str_loop
CMP.L D2, D3 ; compare currentIndex of the string and the size
BEQ str_loop_end ;
MOVE.B (A1)+, D6 ; read one character from the input string store in D6
MOVE.B #0, D4 ; store starting index of list hex in D4
MOVE.B list_hex_size, D5 ; store list hex size in D5
hex_loop
CMP.B D4, D5 ;
BEQ str_loop
LEA LIST_HEX, A2 ; address hex list in A2
ADDA.L D4, A2 ; current index in the list
CMP.B (A2), D6 ; compare with current character and the list character
BEQ hex_found ;
ADD.B #1, D4 ; increment D4 by 1
BRA hex_loop ; go back to hex loop
hex_found
ASL #4, D1 ; shift D1 by 4bits
ADD.B D4, D1 ; add current index into D1
ADD.B #1, D2 ; increment currentIndex pointing at input hex string
BRA str_loop ; go back to str_loop
str_loop_end
RTS
* check if the input is valid
CHECK_STARTING_BOUND
CMP.L #range_start, D1 ; input is greater than the starting range
RTS ;
PROMPT_END ; Asking ending address
LEA PROMPT_2, A1 ;
MOVE.B #13, D0 ;
TRAP #15 ;
LEA PROMPT_3, A1 ;
MOVE.B #14, D0 ;
TRAP #15 ;
RTS ;
CHECK_ENDING_BOUND
CMP.L (START_HEX), D1 ; ending address bigger than starting address
RTS
* Global variables (START_HEX & END_HEX) is set, use any registers.
MAIN
* Output display 20 lines per enter
MOVEA.L #STACK, A7 ;
* Print the humanReadable codes until reaches the end_hex
MOVEA.L (END_HEX), A3 ; move endHex address to A3
MOVEA.L (START_HEX), A2 ; move start address to A2
LEA RESULT_MSG, A4 ; move result message starting address
decode_loop
CMPA.L A2, A3 ;
BEQ finishProgram ; reached the end, finish Program
* otherwise initialize counter and ask user for 'ENTER' to continue
MOVE.B #display_size, D4 ; move display size to D4
MOVE.B #init, D3 ; move 0 to D3 ;
MOVEA.L A4, A5 ; initialize current message index by copying starting addr
BSR printContinueMessage ;
BSR takeContinueInput ;
continue_decoding
* if not reached the end Index,
* read 20 instructions or currentHex to endHex (if fewer than 20 left)
CMP.B D3, D4 ; reached 20 lines,
BEQ finish_page ; go back to decode_loop
decode
MOVEA.L A2, A6 ;
MOVE.W (A2)+, D5 ; move current opcode into D5
* move D3 (= i), D4( = 20), A3(endHex), A4(result_message) into stack
MOVEM.L D3/D4/A3/A4, -(A7) ;
* D5 contains current opcode and A2 contains startHex
decode_start
* decode starts here****************************************************************************
MOVEM.L D5, -(A7) ; store opcode in the stack
* print address of current instruction
MOVE.B #word, D1 ; size is word
BSR hex_to_string ; put current opcode address into A6 and size into D1,
MOVE.B #TAB, (A5)+ ; then current opcode address will be added in the result msg
MOVEM.L (A7)+, D5 ; get opcode back from stack
LEA $6000, A6 ; A6 as $6000 where temporary result is going to be saved
* if RTS
CMPI.W #$4E75, D5 ;
BEQ RTS_function ;
CMPI.W #$4E71, D5 ; check if nop function
BEQ NOP_function ;
BSR get_firstFourBits ; return first four bits in D0
BSR get_secondFourBits ; return second four bits in D1
* if first four bits are 0
CMPI.B #0, D0 ;
BEQ zero_start ;
CMPI.B #1, D0 ;
BEQ one_start ;
CMPI.B #2, D0 ;
BEQ two_start ;
CMPI.B #3, D0 ;
BEQ three_start ;
CMPI.B #4, D0 ;
BEQ four_start ;
CMPI.B #5, D0 ;
BEQ five_start ;
CMPI.B #6, D0 ;
BEQ six_start ;
CMPI.B #8, D0 ;
BEQ eight_start ;
CMPI.B #9, D0 ;
BEQ nine_start ;
CMPI.B #$B, D0 ;
BEQ B_start ;
CMPI.B #$C, D0 ;
BEQ C_start ;
CMPI.B #$D, D0 ;
BEQ D_start ;
CMPI.B #$E, D0 ;
BEQ E_start ;
* no matcing operation
BRA invalid_code ;
* check second four bits and send to decode functions
invalid_code
LEA INVALID_MSG, A6 ; move message in A6
MOVE.B #12, D6 ; size is 10 for DATA $WXYZ
BSR copy_string ;
BRA decode_end ;
zero_start
* if second four bits are 0, ORI function
CMPI.B #0, D1 ;
BEQ ORI_function ;
* if second foubits are 8, BCLR #, EA function
CMPI.B #8, D1 ;
BEQ BCLR_immediate_EA_function ;
* if second four bits are C, CMPI function
CMPI.B #$C, D1 ;
BEQ CMPI_function ;
* otherwise, go to BCLR Dn, EA function
BRA BCLR_Dn_EA ;
one_start
* branch to move.B function
BRA MOVE_B ;
two_start
* branch to move.L or movea.L function
BRA MOVE_MOVEA_L ;
three_start
* branch to move.w or movea.w funciton
BRA MOVE_MOVEA_W ;
four_start
* if second four bits are 4, branch to NEG function
CMPI.B #4, D1 ;
BEQ NEG_function ;
* if second four bits are 8, branch to MOVEM.W, or MOVEM.L (Register to memory) function
CMPI.B #8, D1 ;
BEQ MOVEM_W_L_RtoM ;
* if second fourbits are C, branch to MULS.L, DIVS.L, MOVEM.W, MOVEM.L (Memory to Register) function
CMPI.B #$C, D1 ;
BEQ MULS_DIVS_L_MOVEM_W_L_MtoR ;
* if second four bits are E, branch to JSR_function
CMPI.B #$E, D1 ;
BEQ JSR_function ;
* otherwise, branch to LEA function
BRA LEA_function ;
five_start
* branch to SUBQ function
BRA SUBQ_function ;
six_start
* if second four bits are 0, branch to BRA function
CMPI.B #0, D1 ;
BEQ BRA_function ;
* if second four bits are 4, branch to BCC function
CMPI.B #4, D1 ;
BEQ BCC_function ;
* if second four bits are 5, branch to BCS function
CMPI.B #5, D1 ;
BEQ BCS_function ;
* if second four bits are 8, branch to BVC function
CMPI.B #8, D1 ;
BEQ BVC_function ;
* if second four bits are C, branch to BGE function
CMPI.B #$C, D1 ;
BEQ BGE_function ;
* if second four bts are D, branch to BLT function
CMPI.B #$D, D1 ;
BEQ BLT_function ;
* otherwise, branch to invalid code function
BRA invalid_code ;
eight_start
* branch to OR or DIVS.W function
BRA OR_DIVS_W ;
nine_start
* branch to SUB function
BRA SUB_function ;
B_start
* barnch to EOR or CMP function
BRA EOR_CMP ;
C_start
* branch to ASLR, LSLR, ROLR, MULS.W function
BRA MULS_W ;
D_start
* branch to Add or ADDA function
BRA ADD_ADDA ;
E_start
* banch to ASLR_LSLR_ROLR
BRA ASLR_LSLR_ROLR ;
* decode ends here*******************************************************************************
decode_end
* add decoded instruction to the result
* this should have done in decode functions
* add CR, LF at the end of line
MOVE.B #CR, (A5)+ ;
MOVE.B #LF, (A5)+ ;
MOVEM.L (A7)+, D3-D4/A3 ; move parameters back from stack
ADDI.B #increment, D3 ; increment D3 by 1
CMPA.L A2, A3 ; if input hex reached the end before reaching 20 lines,
BEQ finish_page ; go back to decode_loop to finish the program
BRA continue_decoding ; otherwise, continue decoding
* hex in A6, size in D1 convert to string and put it in the A5,
* Long 4byte, Word = 2byte, Byte = 1byte, therefore D1 = 4, 2, or 1;
hex_to_string ; since address is in word size
LEA LIST_HEX, A0 ; load list hex into A0
MOVE.L A6, D2 ; move A6(address value) into D2
MOVE.B #init, D0 ; initilize count 0 in D0
CMPI.B #long, D1 ; if size is long
BEQ initLong ;
CMPI.B #word, D1 ; if size is word
BEQ initWord ;
CMPI.B #byte, D1 ; if size is byte
BEQ initByte ;
initLong
MOVE.L #$F0000000, D3 ;
BRA htsLoop ;
initWord
MOVE.L #$0000F000, D3 ;
BRA htsLoop ;
initByte
MOVE.L #$000000F0, D3 ;
BRA htsLoop ;
htsLoop
CMP.B D0, D1 ;
BEQ htsDone ;
* A0 has list_hex, D2 has address val, D3 has mask (D0, D1 reserved)
MOVE.L D2, D4 ; copy addr value into D4
AND.L D3, D4 ; masking and store in D4
* shift amount(D5) = (size(D1) * 2) - 1 - current(D0)
MOVE.L D1, D5 ;
SUBI.L #1, D5 ; ((size) - 1 -> D5);
SUB.L D0, D5 ; ((size) - 1 - current ->D5)
MOVE.L #4, D6 ;
MULU.W D6, D5 ; ((size) - 1 - current ->D5) * 4
LSR.L D5, D4 ; shift masked value right by shift amount
LSR.L D6, D3 ; shift mask to the right
* now D4 contains 4bits, find character in the hex list and add into result message
MOVEA.L A0, A3 ; copy hex list starting address to A3
ADD.L D4, A3 ; index of character
MOVE.B (A3), (A5)+ ; move the character into result message
ADDI.B #increment, D0 ;
BRA htsLoop ;
htsDone
RTS
* logical shift because sign is not necessary
get_firstFourBits ; from word input in D5, return in D0
MOVE.W D5, D0 ;
MOVE.B #12, D1 ;
LSR.W D1, D0 ;
RTS
* logical shift because sign is not necessary
get_secondFourBits ; from word input in D5, return in D1
MOVE.W D5, D1 ;
MOVE.B #4, D2 ;
LSL.W D2, D1 ;
MOVE.B #12, D2 ;
LSR.W D2, D1 ;
RTS
* clear console page
* print a page and go back to decode_loop to continue
finish_page
BSR clearScreen
BSR print_page
BRA decode_loop
* print a page that contains "human readable" code
print_page
MOVE.B #NULL, (A5)+
MOVEA.L A4, A1 ;
MOVE.B #13, D0 ;
TRAP #15 ;
RTS
finishProgram
BSR printFinalMessage ;
BSR finishingInput ;
SIMHALT ; halt simulator
printContinueMessage
LEA CONTINUE_MSG, A1 ;
MOVE.B #14, D0 ;
TRAP #15 ;
RTS
takeContinueInput
LEA INPUT, A1 ; dummy input holder
* take input
MOVE.B #2, D0 ;
TRAP #15 ;
RTS
* print final message before exit
printFinalMessage ;
LEA FINAL_MSG, A1 ;
MOVE.B #14, D0 ;
TRAP #15 ;
RTS
* take final input to exit program
finishingInput ;
LEA INPUT, A1 ;
* take input
MOVE.B #2, D0 ;
TRAP #15 ;
RTS
clearScreen
MOVE.B #11, D0 ;
MOVE.W #$FF00, D1 ;
TRAP #15 ;
RTS
*OP_ADD_MSG
* LEA ADD_MSG, A6 ;
* MOVE.B #3, D6 ; we know that 'add' size is 3
* BSR copyLoop ;
* D6 contains the size of the string and A6 has string
copy_string
MOVE.B #0, D5 ;
copyLoop
CMP.B D5, D6 ;
BEQ copyLoopDone ;
MOVE.B (A6)+, (A5)+ ; A6 = string, A5 = result message
ADDI.B #1, D5 ;
BRA copyLoop ;
copyLoopDone
RTS ;
* D5 contains opcode, A2 contains next opcode to read from memory
* A5 contains result output pointer (string)
* Decode functions************************************************************************************
RTS_function
LEA RTS_, A6 ; move memory address for RTS characters
MOVE.B #3, D6 ; RTS is 3 characters, size of string into D6
BSR copy_string ;
BRA decode_end
NOP_function
LEA NOP_, A6 ; move memory address for NOP characters
MOVE.B #3, D6 ; NOP is 3 characters, size of string into D6
BSR copy_string ;
BRA decode_end
* zero_start********************
ORI_function
MOVEM.L A5, -(A7) ; save A5 in the stack (pointer to result message)
MOVEA.L A6, A0 ; starting address of temp
MOVEA.L A6, A5 ; move starting address of curent temp Message into A0
* add function name in temporary memory
MOVE.B #O_, (A5)+ ;
MOVE.B #R_, (A5)+ ;
MOVE.B #I_, (A5)+ ;
MOVE.B #PERIOD, (A5)+
* check size 00 - byte, 01 - word, 10 - long
MOVE.W D5, D0 ; copy opcode into D0 only byte size because starts with $00
MOVE.W #$00C0, D6 ; bit mask in D6
MOVE.B #6, D7 ; shift value after masking
BSR get_bit ; return size in D0
CMPI.B #$00, D0 ; if size == 0
BEQ add_B ;
CMPI.B #$01, D0 ; if size == 1
BEQ add_W
CMPI.B #$02, D0 ; if size == 2
BEQ add_L ;
MOVEM.L (A7)+, A5 ;
BRA invalid_code ;
add_B
MOVE.B #B_, (A5)+ ;
MOVE.B #TAB, (A5)+ ;
MOVE.B #SHARP, (A5)+ ;
MOVE.B #DOLLAR, (A5)+ ;
MOVE.W (A2)+, A6 ; A6 now contains word size next opcode
valid
MOVE.B #byte, D1 ;
MOVEM.L D5/A0, -(A7) ;
BSR hex_to_string ;
MOVEM.L (A7)+, D5/A0 ;
BRA check_mode ;
add_W
MOVE.B #W_, (A5)+ ;
MOVE.B #TAB, (A5)+ ;
MOVE.B #SHARP, (A5)+ ;
MOVE.B #DOLLAR, (A5)+ ;
MOVE.W (A2)+, A6 ; read next opcode word size
MOVE.B #word, D1 ;
MOVEM.L D5/A0, -(A7) ;
BSR hex_to_string ;
MOVEM.L (A7)+, D5/A0 ;
BRA check_mode ;
add_L
MOVE.B #L_, (A5)+ ;
MOVE.B #TAB, (A5)+ ;
MOVE.B #SHARP, (A5)+ ;
MOVE.B #DOLLAR, (A5)+ ;
MOVE.L (A2)+, A6 ;
MOVE.B #long, D1 ;
MOVEM.L D5/A0, -(A7)
BSR hex_to_string ;
MOVEM.L (A7)+, D5/A0 ;
BRA check_mode ;
check_mode
MOVE.B #COMMA, (A5)+ ;
MOVe.B #SPACE, (A5)+ ;
* check mode 000(Dn), 010 ((An)), 011((An)+), 100, (-(An)), 111(xxx.W or xxx.L)
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$0038, D6 ; bit mask in D6
MOVE.B #3, D7 ; shift value after masking
BSR get_bit ; get mode bit
MOVE.W D0, D1 ; move mode bits to D1
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$0007, D6 ; bit mask in D6
MOVE.B #0, D7 ; shift value after masking
BSR get_bit ; get mode bit
* now D1 has mode bits, D0 has register bits
CMPI.W #$00, D1 ; if mode == 000
BEQ ori_Data_reg ;
CMPI.W #$02, D1 ; if mode == 010
BEQ ori_Addr_paren ;
CMPI.W #$03, D1 ; if mode == 011
BEQ ori_Addr_paren_plus ;
CMPI.W #$04, D1 ; if mode == 100
BEQ ori_Addr_paren_minus ;
CMPI.w #$07, D1 ; if mode == 111
BEQ ori_ea ;
MOVEM.L (A7)+, A5 ; Restore A5 from the stack
BRA invalid_code ; otherwise, invalid code
ori_Data_reg
MOVE.B #D_, (A5)+ ; put Dn with number
BSR put_number ;
BRA ori_done ;
ori_Addr_paren
MOVE.B #Open_paren, (A5)+ ; put (An) with number
MOVE.B #A_, (A5)+ ;
BSR put_number ;
MOVE.B #Close_paren, (A5)+ ;
BRA ori_done ;
ori_Addr_paren_plus
MOVE.B #Open_paren, (A5)+ ; put (An)+ with number
MOVE.B #A_, (A5)+ ;
BSR put_number ;
MOVE.B #Close_paren, (A5)+ ;
MOVE.B #PLUS, (A5)+ ;
BRA ori_done ;
ori_Addr_paren_minus
MOVE.B #MINUS, (A5)+ ; put -(An) with number
MOVE.B #Open_paren, (A5)+ ;
MOVE.B #A_, (A5)+ ;
BSR put_number ;
MOVE.B #Close_paren, (A5)+ ;
BRA ori_done ;
ori_ea
MOVE.B #DOLLAR, (A5)+ ;
CMPI.W #$00, D0 ; if register == 00
BEQ word_ea ;
CMPI.W #$01, D0 ; if register == 01
BEQ long_ea ;
MOVEM.L (A7)+, A5 ;
BRA invalid_code ;
word_ea ;
MOVEA.W (A2)+, A6 ; read word size more opcode
MOVE.W #word, D1 ;
MOVEM.L D5/A0, -(A7) ;
BSR hex_to_string ;
MOVEM.L (A7)+, D5/A0 ;
BRA ori_done ;
long_ea ;
MOVEA.L (A2)+, A6 ;
MOVE.W #long, D1 ; read long size more opcode
MOVEM.L D5/A0, -(A7) ;
BSR hex_to_string ;
MOVEM.L (A7)+, D5/A0 ;
BRA ori_done ;
ori_done
* copy into the result message ;
* get size of the message
MOVEA.L A0, A6 ; move starting address back to A6
* count till A0 == A5 ;
CLR D6 ; D6 == 0
ori_loop
CMPA.L A0, A5 ;
BEQ ori_message_out
ADDI.L #1, D6 ; increment count
MOVE.L A0, D5 ;
ADDI.L #1, D5 ;
MOVEA.L D5, A0 ; increment address
BRA ori_loop ;
ori_message_out
* D6 contains size and A6 pointing to the tempMessage
MOVEM.L (A7)+, A5 ; Restore A5 from the stack
BSR copy_string ;
BRA decode_end
***********************************************************************
BCLR_immediate_EA_function
MOVEM.L A5, -(A7) ; save A5 in the stack (pointer to result message)
MOVEA.L A6, A0 ; starting address of temp
MOVEA.L A6, A5 ; move starting address of curent temp Message into A0
* add function name in temporary memory
MOVE.B #B_, (A5)+ ;
MOVE.B #C_, (A5)+ ;
MOVE.B #L_, (A5)+ ;
MOVE.B #R_, (A5)+ ;
MOVE.B #TAB, (A5)+ ;
* check size 00 - byte, 01 - word, 10 - long
MOVE.W D5, D0 ; copy opcode into D0 only byte size because starts with $00
MOVE.W #$00C0, D6 ; bit mask in D6
MOVE.B #6, D7 ; shift value after masking
BSR get_bit ; return size in D0
CMPI.B #$02, D0 ; if size == 1
BEQ bclr_immediate_ea_valid ;
MOVEM.L (A7)+, A5 ;
BRA invalid_code ;
bclr_immediate_ea_valid ;
* put immediate value in the temp message
MOVE.B #SHARP, (A5)+ ;
MOVE.B #DOLLAR, (A5)+ ;
MOVE.W (A2)+, A6 ; A6 now contains word size next opcode
* check if first 8 bits are 0s
MOVE.L A6, D1 ;
LSR.W #8, D1 ; shift right 8
CMPI.B #$00, D1 ; if $00 is starting bits
BEQ bclr_im_val ; true, then go to valid
MOVEM.L (A7)+, A5 ; Restore A5 from the stack
BRA invalid_code ; otherwise, go to invalid code
bclr_im_val
MOVE.B #byte, D1 ;
MOVEM.L D5/A0, -(A7)
BSR hex_to_string ;
MOVEM.L (A7)+, D5/A0 ;
MOVE.B #COMMA, (A5)+ ;
MOVE.B #SPACE, (A5)+ ;
* now get mode and register number
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$0038, D6 ; bit mask in D6
MOVE.B #3, D7 ; shift value after masking
BSR get_bit ; get mode bit
MOVE.W D0, D1 ; move mode bits to D1
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$0007, D6 ; bit mask in D6
MOVE.B #0, D7 ; shift value after masking
BSR get_bit ; get mode bit
* D1 has mode, D0 has register number
CMPI.W #$00, D1 ; 000
BEQ ori_Data_reg ;
CMPI.W #$02, D1 ; 010
BEQ ori_Addr_paren ;
CMPI.W #$03, D1 ; 011
BEQ ori_Addr_paren_plus ;
CMPI.W #$04, D1 ; 100
BEQ ori_Addr_paren_minus ;
CMPI.w #$07, D1 ; 111
BEQ ori_ea ;
MOVEM.L (A7)+, A5 ; Restore A5 from the stack
BRA invalid_code ; otherwise, invalid code
***********************************************************************
CMPI_function
MOVEM.L A5, -(A7) ; save A5 in the stack (pointer to result message)
MOVEA.L A6, A0 ; starting address of temp
MOVEA.L A6, A5 ; move starting address of curent temp Message into A0
* add function name in temporary memory
MOVE.B #C_, (A5)+ ;
MOVE.B #M_, (A5)+ ;
MOVE.B #P_, (A5)+ ;
MOVE.B #I_, (A5)+ ;
MOVE.B #PERIOD, (A5)+
* check size 00 - byte, 01 - word, 10 - long
MOVE.W D5, D0 ; copy opcode into D0 only byte size because starts with $00
MOVE.W #$00C0, D6 ; bit mask in D6
MOVE.B #6, D7 ; shift value after masking
BSR get_bit ; return size in D0
CMPI.B #$00, D0 ; if size == 0
BEQ add_B ;
CMPI.B #$01, D0 ; if size == 1
BEQ add_W
CMPI.B #$02, D0 ; if size == 2
BEQ add_L ;
MOVEM.L (A7)+, A5 ;
BRA invalid_code ;
***********************************************************************
BCLR_Dn_EA
MOVEM.L A5, -(A7) ; save A5 in the stack (pointer to result message)
MOVEA.L A6, A0 ; starting address of temp
MOVEA.L A6, A5 ; move starting address of curent temp Message into A0
* add function name in temporary memory
MOVE.B #B_, (A5)+ ;
MOVE.B #C_, (A5)+ ;
MOVE.B #L_, (A5)+ ;
MOVE.B #R_, (A5)+ ;
MOVE.B #TAB, (A5)+
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$01C0, D6 ; bit mask in D6
MOVE.B #6, D7 ; shift value after masking
BSR get_bit ;
CMPI.W #6, D0 ;
BEQ bclr_dn_valid ;
MOVEM.L (A7)+, A5 ;
BRA invalid_code ;
bclr_dn_valid ;
* get first D register value ;
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$0F00, D6 ; bit mask in D6
MOVE.B #9, D7 ; shift value after masking in D7
BSR get_bit ;
MOVE.B #D_, (A5)+ ;
BSR put_number ;
BRA check_mode ;
***********************************************************************
* one_start **********************************************************************************
MOVE_B
MOVEM.L A5, -(A7) ; save A5 in the stack (pointer to result message)
MOVEA.L A6, A0 ; starting address of temp
MOVEA.L A6, A5 ; move starting address of curent temp Message into A0
MOVE.B #M_, (A5)+ ;
MOVE.B #O_, (A5)+ ;
MOVE.B #V_, (A5)+ ;
MOVE.B #E_, (A5)+ ;
MOVE.B #PERIOD, (A5)+ ;
MOVE.B #B_, (A5)+ ;
MOVE.B #TAB, (A5)+ ;
move_b_src
* get source mode and register in D1 and D0
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$0038, D6 ; bit mask in D6
MOVE.B #3, D7 ; shift value after masking
BSR get_bit ;
MOVE.W D0, D1 ; D1 contains mode of source
MOVE.W D5, D0 ; copy opcode into D0
MOVE.W #$0007, D6 ; bit mask in D6
MOVE.B #0, D7 ; shift value after masking
BSR get_bit ;
* now D1 has source mode, D0 has source register number
CMPI.W #$0000, D1 ; if mode == 0
BEQ move_b_Data_reg ;
CMPI.W #$0001, D1 ; if mode == 1
BEQ move_b_Addr_reg ;
CMPI.W #$0002, D1 ; if mode == 2
BEQ move_b_Addr_reg_paren ;
CMPI.W #$0003, D1 ; if mode == 3
BEQ move_b_Addr_reg_plus ;
CMPI.W #$0004, D1 ; if mode == 4
BEQ move_b_Addr_reg_minus ;
CMPI.W #$0007, D1 ; if mode == 7
BEQ move_b_ea_im ;
MOVEM.L (A7)+, A5 ;