-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsimple_i8086.spin2
3007 lines (2497 loc) · 104 KB
/
simple_i8086.spin2
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
{
INTEL 8086 CPU Emulator
Copyright (c) 2022 by Marco Maccaferri <[email protected]>
Monitor code based on SCP 8086 Monitor by Seattle Computer Products, Inc.
Memory Map:
00000-3FFFF ram (256k)
F0000-FFFFF rom (64k)
I/O Map:
00F6 ACIA data port
00F7 ACIA status register
}
CON
_CLKFREQ = 160_000_000
ACIA_RX = 63 '8 { I }
ACIA_TX = 62 '9 { O }
ACIA_BAUD = 115_200
DAT ' 8086
org $000
i8086
asmclk
add ptrb, ##@i8086_lut - @i8086
setq2 #(@i8086_lut_end - @i8086_lut) / 4 -1
rdlong 0, ptrb
call #\@system_init
mov i_optable, ##@i8086_optable
getct i_lastwait
.nextop
getct i_total
sub i_total, i_lastwait
'add i_total, i_cycles
bitl i_flags, #I_SEG_BIT
call #\@system_run
bitl i_flags, #I_NO_INT_BIT wcz
testb i_flags, #I_TF_BIT wz
if_01 mov i_temp0, #1
if_01 call #\@i_trap
getct i_lastwait
mov i_cycles, #0
getword i_ip_start, i_ip, #0
.loop
call #\i_readcodeb
mov i_opcode, i_tmpb
cmp i_opcode, #$26 wz
if_ne cmp i_opcode, #$2E wz
if_ne cmp i_opcode, #$36 wz
if_ne cmp i_opcode, #$3E wz
if_e jmp #.seg
cmp i_opcode, #$F2 wz
if_ne cmp i_opcode, #$F3 wz
if_e jmp #.rep
shl i_tmpb, #2
add i_tmpb, i_optable
rdlong i_opimpl, i_tmpb
bitl i_flags, #I_REP_BIT wcz
if_11 call #.rep_valid
if_11 jmp #.repeat
push #.nextop
jmp i_opimpl
.seg
cmp i_opcode, #$26 wz
if_e mov i_override, i_es
cmp i_opcode, #$2E wz
if_e mov i_override, i_cs
cmp i_opcode, #$36 wz
if_e mov i_override, i_ss
cmp i_opcode, #$3E wz
if_e mov i_override, i_ds
bith i_flags, #I_SEG_BIT
add i_cycles, #2
jmp #.loop
.rep
bith i_flags, #I_REP_BIT
testb i_opcode, #0 wz
bitz i_flags, #I_REP_ZF_BIT
add i_cycles, #2
jmp #.loop
.rep_valid
cmp i_opcode, #$A4 wz
if_ne cmp i_opcode, #$A5 wz
if_ne cmp i_opcode, #$AA wz
if_ne cmp i_opcode, #$AB wz
if_ne cmp i_opcode, #$AC wz
if_ne cmp i_opcode, #$AD wz
if_ne cmp i_opcode, #$A6 wz
if_ne cmp i_opcode, #$A7 wz
if_ne cmp i_opcode, #$AE wz
if_ne cmp i_opcode, #$AF wz
ret
.repeat
cmp i_cx, #0 wz
if_z jmp #.nextop
call i_opimpl
sub i_cx, #1
cmp i_opcode, #$A4 wz
if_ne cmp i_opcode, #$A5 wz
if_ne cmp i_opcode, #$AA wz
if_ne cmp i_opcode, #$AB wz
if_ne cmp i_opcode, #$AC wz
if_ne cmp i_opcode, #$AD wz
if_e jmp #.repeat
testb i_flags, #I_REP_ZF_BIT wc
testb i_flags, #I_ZF_BIT wz
if_c_eq_z jmp #.repeat
jmp #.nextop
i_esc_op
' fall-through
i_readcodeb
getword i_ea, i_cs, #0
shl i_ea, #4
add i_ea, i_ip
incmod i_ip, i_ffffh
jmp #\i_readmemb
i_readimmb
call #\i_readcodeb
_ret_ getbyte i_data, i_tmpb, #0
i_readimmw
call #\i_readcodeb
getbyte i_data, i_tmpb, #0
call #\i_readcodeb
_ret_ setbyte i_data, i_tmpb, #1
' +-----+---------------+------------------+-------------------+---------+---------+
' | mod | 00 | 01 | 10 | 11 | |
' +-----+---------------+------------------+-------------------+---------+---------+
' | r/m | | | | | reg |
' +-----+---------------+------------------+-------------------+---------+----+----+
' | 000 | [DS:BX+SI] | [DS:BX+SI+disp8] | [DS:BX+SI+disp16] | [DS:AX] | AL | AX |
' | 001 | [DS:BX+DI] | [DS:BX+DI+disp8] | [DS:BX+DI+disp16] | [DS:CX] | CL | CX |
' | 010 | [SS:BP+SI] | [SS:BP+SI+disp8] | [SS:BP+SI+disp16] | [DS:DX] | DL | DX |
' | 011 | [SS:BP+DI] | [SS:BP+DI+disp8] | [SS:BP+DI+disp16] | [DS:BX] | BL | BX |
' | 100 | [DS:SI] | [DS:SI+disp8] | [DS:SI+disp16] | [DS:SP] | AH | SP |
' | 101 | [DS:DI] | [DS:DI+disp8] | [DS:DI+disp16] | [DS:BP] | CH | BP |
' | 110 | [DS:disp16] | [SS:BP+disp8] | [SS:BP+disp16] | [DS:SI] | DH | SI |
' | 111 | [DS:BX] | [DS:BX+disp8] | [DS:BX+disp16] | [DS:DI] | BH | DI |
' +-----+---------------+------------------+-------------------+---------+----+----+
' setup i_ea based on i_modrm bits
i_setupmodrm
call #\i_readcodeb
mov i_modrm, i_tmpb
i_setupmodrm2
getword i_segment, i_ds, #0
mov i_offset, #0
testb i_modrm, #7 wc
testb i_modrm, #6 wz
mov i_modrm0, i_modrm
and i_modrm0, #%00_000_111
if_00 call #\_mod00
if_01 call #\_mod01
if_10 call #\_mod10
if_11 call #\_mod11
_ret_ getword i_offset, i_offset, #0
i_setupea
add i_cycles, #2
testb i_flags, #I_SEG_BIT wz
if_x1 getword i_ea, i_override, #0
if_x0 getword i_ea, i_segment, #0
shl i_ea, #4
_ret_ add i_ea, i_offset
_mod00
altgw i_modrm0, #i_modrm_00
getword i_modrm0
jmp i_modrm0
_mod01
add i_cycles, #4
call #\i_readcodeb
signx i_tmpb, #7
add i_offset, i_tmpb
jmp #_modxx
_mod10
add i_cycles, #4
call #\i_readcodeb
getbyte i_temp0, i_tmpb, #0
call #\i_readcodeb
setbyte i_temp0, i_tmpb, #1
add i_offset, i_temp0
_modxx
altgw i_modrm0, #i_modrm_xx
getword i_modrm0
jmp i_modrm0
_mod11
jmprel i_modrm0
_ret_ getword i_offset, i_ax, #0
_ret_ getword i_offset, i_cx, #0
_ret_ getword i_offset, i_dx, #0
_ret_ getword i_offset, i_bx, #0
_ret_ getword i_offset, i_sp, #0
_ret_ getword i_offset, i_bp, #0
_ret_ getword i_offset, i_si, #0
_ret_ getword i_offset, i_di, #0
i_modrm_00 word i_modrm_00_xxx_000, i_modrm_00_xxx_001, i_modrm_00_xxx_010, i_modrm_00_xxx_011
word i_modrm_00_xxx_100, i_modrm_00_xxx_101, i_modrm_00_xxx_110, i_modrm_00_xxx_111
i_modrm_xx word i_modrm_00_xxx_000, i_modrm_00_xxx_001, i_modrm_00_xxx_010, i_modrm_00_xxx_011
word i_modrm_00_xxx_100, i_modrm_00_xxx_101, i_modrm_xx_xxx_110, i_modrm_00_xxx_111
i_modrm_00_xxx_000
add i_cycles, #7
add i_offset, i_bx
_ret_ add i_offset, i_si
i_modrm_00_xxx_001
add i_cycles, #8
add i_offset, i_bx
_ret_ add i_offset, i_di
i_modrm_00_xxx_010
add i_cycles, #8
getword i_segment, i_ss, #0
add i_offset, i_bp
_ret_ add i_offset, i_si
i_modrm_00_xxx_011
add i_cycles, #7
getword i_segment, i_ss, #0
add i_offset, i_bp
_ret_ add i_offset, i_di
i_modrm_00_xxx_100
add i_cycles, #5
_ret_ add i_offset, i_si
i_modrm_00_xxx_101
add i_cycles, #5
_ret_ add i_offset, i_di
i_modrm_00_xxx_110
add i_cycles, #6 + 4
call #\i_readcodeb
getbyte i_temp0, i_tmpb, #0
call #\i_readcodeb
setbyte i_temp0, i_tmpb, #1
_ret_ add i_offset, i_temp0
i_modrm_00_xxx_111
add i_cycles, #5
_ret_ add i_offset, i_bx
i_modrm_xx_xxx_110
add i_cycles, #5
getword i_segment, i_ss, #0
_ret_ add i_offset, i_bp
' get 8-bit register based on i_modrm bits 5..3
i_getmodr8
mov pa, i_modrm
shr pa, #3
i_getr8
and pa, #7
jmprel pa
_ret_ getbyte i_data, i_ax, #0
_ret_ getbyte i_data, i_cx, #0
_ret_ getbyte i_data, i_dx, #0
_ret_ getbyte i_data, i_bx, #0
_ret_ getbyte i_data, i_ax, #1
_ret_ getbyte i_data, i_cx, #1
_ret_ getbyte i_data, i_dx, #1
_ret_ getbyte i_data, i_bx, #1
' get 16-bit register based on i_modrm bits 5..3
i_getmodr16
mov pa, i_modrm
shr pa, #3
i_getr16
and pa, #7
jmprel pa
_ret_ getword i_data, i_ax, #0
_ret_ getword i_data, i_cx, #0
_ret_ getword i_data, i_dx, #0
_ret_ getword i_data, i_bx, #0
_ret_ getword i_data, i_sp, #0
_ret_ getword i_data, i_bp, #0
_ret_ getword i_data, i_si, #0
_ret_ getword i_data, i_di, #0
' set 8-bit register based on i_modrm bits 5..3
i_setmodr8
mov pa, i_modrm
shr pa, #3
i_setr8
and pa, #7
jmprel pa
_ret_ setbyte i_ax, i_data, #0
_ret_ setbyte i_cx, i_data, #0
_ret_ setbyte i_dx, i_data, #0
_ret_ setbyte i_bx, i_data, #0
_ret_ setbyte i_ax, i_data, #1
_ret_ setbyte i_cx, i_data, #1
_ret_ setbyte i_dx, i_data, #1
_ret_ setbyte i_bx, i_data, #1
' set 16-bit register based on i_modrm bits 5..3
i_setmodr16
mov pa, i_modrm
shr pa, #3
i_setr16
and pa, #7
jmprel pa
_ret_ getword i_ax, i_data, #0
_ret_ getword i_cx, i_data, #0
_ret_ getword i_dx, i_data, #0
_ret_ getword i_bx, i_data, #0
_ret_ getword i_sp, i_data, #0
_ret_ getword i_bp, i_data, #0
_ret_ getword i_si, i_data, #0
_ret_ getword i_di, i_data, #0
' get segment register based on i_modrm bits 5..3
i_getmodsreg
mov pa, i_modrm
i_getsreg
shr pa, #3
and pa, #3
jmprel pa
_ret_ getword i_data, i_es, #0
_ret_ getword i_data, i_cs, #0
_ret_ getword i_data, i_ss, #0
_ret_ getword i_data, i_ds, #0
' set segment register based on i_modrm bits 5..3
i_setmodsreg
mov pa, i_modrm
i_setsreg
shr pa, #3
and pa, #3
jmprel pa
_ret_ getword i_es, i_data, #0
_ret_ getword i_cs, i_data, #0
_ret_ getword i_ss, i_data, #0
_ret_ getword i_ds, i_data, #0
' --------------------------------------------------------------------
i_readopb
testb i_modrm, #7 wc
testb i_modrm, #6 wz
if_11 mov pa, i_modrm
if_11 jmp #\i_getr8
call #\i_setupea
jmp #\i_readb
i_writeopb
testb i_modrm, #7 wc
testb i_modrm, #6 wz
if_11 mov pa, i_modrm
if_11 jmp #\i_setr8
call #\i_setupea
jmp #\i_writeb
' --------------------------------------------------------------------
i_readopw
testb i_modrm, #7 wc
testb i_modrm, #6 wz
if_11 mov pa, i_modrm
if_11 jmp #\i_getr16
call #\i_setupea
jmp #\i_readw
i_writeopw
testb i_modrm, #7 wc
testb i_modrm, #6 wz
if_11 mov pa, i_modrm
if_11 jmp #\i_setr16
call #\i_setupea
jmp #\i_writew
' --------------------------------------------------------------------
i_readb
add i_cycles, #4
call #\i_readmemb
_ret_ getbyte i_data, i_tmpb, #0
i_writeb
add i_cycles, #4
getbyte i_tmpb, i_data, #0
jmp #\i_writememb
i_readw
add i_cycles, #4
testb i_ea, #0 wc
if_c add i_cycles, #4
call #\i_readmemb
getbyte i_data, i_tmpb, #0
add i_ea, #1
call #\i_readmemb
setbyte i_data, i_tmpb, #1
_ret_ add i_ea, #1
i_writew
add i_cycles, #4
testb i_ea, #0 wc
if_c add i_cycles, #4
getbyte i_tmpb, i_data, #0
call #\i_writememb
add i_ea, #1
getbyte i_tmpb, i_data, #1
jmp #\i_writememb
' --------------------------------------------------------------------
i_add_flags16
testb i_data0, #15 wc ' (resultDst ^ resultSrc)
testb i_data1, #15 xorc ' |
testb i_data1, #15 wz ' (resultSrc ^ resultArith)
testb i_data, #15 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
testb i_data0, #15 xorz ' (resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith)))
bitz i_flags, #I_CF_BIT
i_add_flags16_nc
testb i_data0, #15 wc ' (resultDst ^ resultArith)
testb i_data, #15 xorc ' |
testb i_data1, #15 wz ' (resultSrc ^ resultArith)
testb i_data, #15 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
bitz i_flags, #I_OF_BIT
testb i_data0, #4 wz
testb i_data1, #4 xorz
testb i_data, #4 xorz
bitz i_flags, #I_AF_BIT
test i_data, #$FF wcz
bitnc i_flags, #I_PF_BIT
testb i_data, #15 wz
bitz i_flags, #I_SF_BIT
and i_data, i_ffffh wcz
_ret_ bitz i_flags, #I_ZF_BIT
i_sub_flags16
testb i_data, #15 wc ' (resultDst ^ resultSrc)
testb i_data1, #15 xorc ' |
testb i_data1, #15 wz ' (resultSrc ^ resultArith)
testb i_data0, #15 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
testb i_data, #15 xorz ' (resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith)))
bitz i_flags, #I_CF_BIT
i_sub_flags16_nc
testb i_data, #15 wc ' (resultDst ^ resultArith)
testb i_data0, #15 xorc ' |
testb i_data1, #15 wz ' (resultSrc ^ resultArith)
testb i_data0, #15 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
bitz i_flags, #I_OF_BIT
testb i_data0, #4 wz
testb i_data1, #4 xorz
testb i_data, #4 xorz
bitz i_flags, #I_AF_BIT
test i_data, #$FF wcz
bitnc i_flags, #I_PF_BIT
testb i_data, #15 wz
bitz i_flags, #I_SF_BIT
and i_data, i_ffffh wcz
_ret_ bitz i_flags, #I_ZF_BIT
i_add_flags8
testb i_data0, #7 wc ' (resultDst ^ resultSrc)
testb i_data1, #7 xorc ' |
testb i_data1, #7 wz ' (resultSrc ^ resultArith)
testb i_data, #7 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
testb i_data0, #7 xorz ' (resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith)))
bitz i_flags, #I_CF_BIT
i_add_flags8_nc
testb i_data0, #7 wc ' (resultDst ^ resultArith)
testb i_data, #7 xorc ' |
testb i_data1, #7 wz ' (resultSrc ^ resultArith)
testb i_data, #7 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
bitz i_flags, #I_OF_BIT
testb i_data0, #4 wz
testb i_data1, #4 xorz
testb i_data, #4 xorz
bitz i_flags, #I_AF_BIT
testb i_data, #7 wz
bitz i_flags, #I_SF_BIT
and i_data, #$FF wcz
bitz i_flags, #I_ZF_BIT
_ret_ bitnc i_flags, #I_PF_BIT
i_sub_flags8
testb i_data, #7 wc ' (resultDst ^ resultSrc)
testb i_data1, #7 xorc ' |
testb i_data1, #7 wz ' (resultSrc ^ resultArith)
testb i_data0, #7 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
testb i_data, #7 xorz ' (resultDst ^ ((resultDst ^ resultSrc) & (resultSrc ^ resultArith)))
bitz i_flags, #I_CF_BIT
i_sub_flags8_nc
testb i_data, #7 wc ' (resultDst ^ resultArith)
testb i_data0, #7 xorc ' |
testb i_data1, #7 wz ' (resultSrc ^ resultArith)
testb i_data0, #7 xorz ' |
modz _c_and_z wz ' ((resultDst ^ resultSrc) & (resultSrc ^ resultArith))
bitz i_flags, #I_OF_BIT
testb i_data0, #4 wz
testb i_data1, #4 xorz
testb i_data, #4 xorz
bitz i_flags, #I_AF_BIT
testb i_data, #7 wz
bitz i_flags, #I_SF_BIT
and i_data, #$FF wcz
bitz i_flags, #I_ZF_BIT
_ret_ bitnc i_flags, #I_PF_BIT
i_logic_flags8
bitl i_flags, #I_CF_BIT
bitl i_flags, #I_OF_BIT
testb i_data, #7 wz
bitz i_flags, #I_SF_BIT
and i_data, #$FF wcz
bitz i_flags, #I_ZF_BIT
_ret_ bitnc i_flags, #I_PF_BIT
i_logic_flags16
bitl i_flags, #I_CF_BIT
bitl i_flags, #I_OF_BIT
test i_data, #$FF wcz
bitnc i_flags, #I_PF_BIT
testb i_data, #15 wz
bitz i_flags, #I_SF_BIT
and i_data, i_ffffh wcz
_ret_ bitz i_flags, #I_ZF_BIT
' --------------------------------------------------------------------
i_ax long $0000
i_bx long $0000
i_cx long $0000
i_dx long $0000
i_sp long $0000
i_bp long $0000
i_si long $0000
i_di long $0000
i_cs long $F000
i_ds long $0000
i_es long $0000
i_ss long $0000
i_flags long $0000
i_flags_pre long $0002
i_ip long $FFF0
i_cycles long 0
i_total long 0
i_ffffh long $FFFF
i_eamask long $FFFFF
i_optable long 0
i_rambase long @ram_00000
i_rombase long @rom_F0000
acia_ctl_reg long 0
i_opcode res 1
i_modrm res 1
i_modrm0 res 1
i_override res 1
i_segment res 1
i_offset res 1
i_ea res 1
i_tmpb res 1
i_data res 1
i_data0 res 1
i_data1 res 1
i_temp0 res 1
i_temp1 res 1
i_temp2 res 1
i_opimpl res 1
i_rep_cnt res 1
i_ip_start res 1
i_lastwait res 1
DAT ' 8086 LUT
org $200
i8086_lut
i_readmemb
' i_ea = address
' i_tmpb = data
and i_ea, i_eamask
mov i_tmpb, #$FF
mov pa, i_ea
shr pa, #12 ' get 4k-bank number
' 00000
cmp pa, #$40 wcz ' 3FFFF ram (256k)
if_b jmp #.ram
cmp pa, #$F0 wcz ' F0000
if_ae jmp #.rom ' FFFFF rom (64k)
ret wcz
.ram
mov pa, i_ea
add pa, i_rambase
rdbyte i_tmpb, pa
ret wcz
.rom
mov pa, i_ea
sub pa, ##$F0000
add pa, i_rombase
rdbyte i_tmpb, pa
ret wcz
i_writememb
' i_ea = address
' i_tmpb = data
and i_ea, i_eamask
mov pa, i_ea
shr pa, #12 ' get 4k-bank number
' 00000
cmp pa, #$40 wcz ' 0FFFF ram (64k)
if_b jmp #.ram
ret wcz
.ram
mov pa, i_ea
add pa, i_rambase
wrbyte i_tmpb, pa
ret wcz
i_readiob
' i_ea = address
' i_tmpb = data
mov i_tmpb, #$FF
cmp i_ea, #$F6 wcz
if_e jmp #\@acia_data_rd
cmp i_ea, #$F7 wcz
if_e jmp #\@acia_ctl_rd
ret wcz
i_writeiob
' i_ea = address
' i_tmpb = data
cmp i_ea, #$F6 wcz
if_e jmp #\@acia_data_wr
cmp i_ea, #$F7 wcz
if_e jmp #\@acia_ctl_wr
ret wcz
i8086_lut_end
DAT ' 8086 HUB
orgh
i8086_optable
long @i_math_modrm_r8 ' 00 rm add [rm], r8
long @i_math_modrm_r16 ' 01 rm add [rm], r16
long @i_math_r8_modrm ' 02 rm add r16, [rm]
long @i_math_r16_modrm ' 03 rm add r8, [rm]
long @i_math_al_imm8 ' 04 nn add al, nn
long @i_math_ax_imm16 ' 05 ll hh add ax, hhll
long @i_push_sreg ' 06 push es
long @i_pop_sreg ' 07 pop es
long @i_math_modrm_r8 ' 08 rm or [rm], r8
long @i_math_modrm_r16 ' 09 rm or [rm], r16
long @i_math_r8_modrm ' 0A rm or r16, [rm]
long @i_math_r16_modrm ' 0B rm or r8, [rm]
long @i_math_al_imm8 ' 0C nn or al, nn
long @i_math_ax_imm16 ' 0D ll hh or ax, hhll
long @i_push_sreg ' 0E push cs
long @i_pop_sreg ' 0F pop cs
long @i_math_modrm_r8 ' 10 rm adc [rm], r8
long @i_math_modrm_r16 ' 11 rm adc [rm], r16
long @i_math_r8_modrm ' 12 rm adc r16, [rm]
long @i_math_r16_modrm ' 13 rm adc r8, [rm]
long @i_math_al_imm8 ' 14 nn adc al, nn
long @i_math_ax_imm16 ' 15 ll hh adc ax, hhll
long @i_push_sreg ' 16 push ss
long @i_pop_sreg ' 17 pop ss
long @i_math_modrm_r8 ' 18 rm sbb [rm], r8
long @i_math_modrm_r16 ' 19 rm sbb [rm], r16
long @i_math_r8_modrm ' 1A rm sbb r16, [rm]
long @i_math_r16_modrm ' 1B rm sbb r8, [rm]
long @i_math_al_imm8 ' 1C nn sbb al, nn
long @i_math_ax_imm16 ' 1D ll hh sbb ax, hhll
long @i_push_sreg ' 1E push ds
long @i_pop_sreg ' 1F pop ds
long @i_math_modrm_r8 ' 20 rm and [rm], r8
long @i_math_modrm_r16 ' 21 rm and [rm], r16
long @i_math_r8_modrm ' 22 rm and r16, [rm]
long @i_math_r16_modrm ' 23 rm and r8, [rm]
long @i_math_al_imm8 ' 24 nn and al, nn
long @i_math_ax_imm16 ' 25 ll hh and ax, hhll
long @i_hlt ' 26 es:
long @i_daas ' 27 daa
long @i_math_modrm_r8 ' 28 rm sub [rm], r8
long @i_math_modrm_r16 ' 29 rm sub [rm], r16
long @i_math_r8_modrm ' 2A rm sub r16, [rm]
long @i_math_r16_modrm ' 2B rm sub r8, [rm]
long @i_math_al_imm8 ' 2C nn sub al, nn
long @i_math_ax_imm16 ' 2D ll hh sub ax, hhll
long @i_hlt ' 2E cs:
long @i_daas ' 2F das
long @i_math_modrm_r8 ' 30 rm xor [rm], r8
long @i_math_modrm_r16 ' 31 rm xor [rm], r16
long @i_math_r8_modrm ' 32 rm xor r16, [rm]
long @i_math_r16_modrm ' 33 rm xor r8, [rm]
long @i_math_al_imm8 ' 34 nn xor al, nn
long @i_math_ax_imm16 ' 35 ll hh xor ax, hhll
long @i_hlt ' 26 ss:
long @i_aaas ' 37 aaa
long @i_math_modrm_r8 ' 38 rm cmp [rm], r8
long @i_math_modrm_r16 ' 39 rm cmp [rm], r16
long @i_math_r8_modrm ' 3A rm cmp r16, [rm]
long @i_math_r16_modrm ' 3B rm cmp r8, [rm]
long @i_math_al_imm8 ' 3C nn cmp al, nn
long @i_math_ax_imm16 ' 3D ll hh cmp ax, hhll
long @i_hlt ' 3E ds:
long @i_aaas ' 3F aas
long @i_inc16 ' 40 inc ax
long @i_inc16 ' 41 inc cx
long @i_inc16 ' 42 inc dx
long @i_inc16 ' 43 inc bx
long @i_inc16 ' 44 inc sp
long @i_inc16 ' 45 inc bp
long @i_inc16 ' 46 inc si
long @i_inc16 ' 47 inc di
long @i_dec16 ' 48 dec ax
long @i_dec16 ' 49 dec cx
long @i_dec16 ' 4A dec dx
long @i_dec16 ' 4B dec bx
long @i_dec16 ' 4C dec sp
long @i_dec16 ' 4D dec bp
long @i_dec16 ' 4E dec si
long @i_dec16 ' 4F dec di
long @i_push_r16 ' 50 push ax
long @i_push_r16 ' 51 push cx
long @i_push_r16 ' 52 push dx
long @i_push_r16 ' 53 push bx
long @i_push_r16 ' 54 push sp
long @i_push_r16 ' 55 push bp
long @i_push_r16 ' 56 push si
long @i_push_r16 ' 57 push di
long @i_pop_r16 ' 58 pop ax
long @i_pop_r16 ' 59 pop cx
long @i_pop_r16 ' 5A pop dx
long @i_pop_r16 ' 5B pop bx
long @i_pop_r16 ' 5C pop sp
long @i_pop_r16 ' 5D pop bp
long @i_pop_r16 ' 5E pop si
long @i_pop_r16 ' 5F pop di
long @i_jo ' 60 dd jo dd 60 - 6F are aliases to 70 - 7F
long @i_jo ' 61 dd jno dd
long @i_jc ' 62 dd jc dd
long @i_jc ' 63 dd jnc dd
long @i_jz ' 64 dd jz dd
long @i_jz ' 65 dd jnz dd
long @i_jce ' 66 dd jce dd
long @i_jce ' 67 dd jnce dd
long @i_js ' 68 dd js dd
long @i_js ' 69 dd jns dd
long @i_jp ' 6A dd jp dd
long @i_jp ' 6B dd jnp dd
long @i_jl ' 6C dd jl dd
long @i_jnl ' 6D dd jnl dd
long @i_jle ' 6E dd jle dd
long @i_jnle ' 6F dd jnle dd
long @i_jo ' 70 dd jo dd 60 - 6F are aliases to 70 - 7F
long @i_jo ' 71 dd jno dd
long @i_jc ' 72 dd jc dd
long @i_jc ' 73 dd jnc dd
long @i_jz ' 74 dd jz dd
long @i_jz ' 75 dd jnz dd
long @i_jce ' 76 dd jce dd
long @i_jce ' 77 dd jnce dd
long @i_js ' 78 dd js dd
long @i_js ' 79 dd jns dd
long @i_jp ' 7A dd jp dd
long @i_jp ' 7B dd jnp dd
long @i_jl ' 7C dd jl dd
long @i_jnl ' 7D dd jnl dd
long @i_jle ' 7E dd jle dd
long @i_jnle ' 7F dd jnle dd
long @i_math_imm8 ' 80 rm nn add/or/adc/sbb/and/sub/xor/cmp [rm8], nn
long @i_math_imm16 ' 81 rm ll hh add/or/adc/sbb/and/sub/xor/cmp [rm16], hhll
long @i_math_imm8s ' 82 rm sn add/or/adc/sbb/and/sub/xor/cmp [rm8], sn
long @i_math_imm16s ' 83 rm sn add/or/adc/sbb/and/sub/xor/cmp [rm16], sn
long @i_test_r8_modrm ' 84 rm test r8, [mm]
long @i_test_r16_modrm ' 85 rm test r16, [mm]
long @i_xchg_modrm8 ' 86 rm xchg r8, [mm]
long @i_xchg_modrm16 ' 87 rm xchg r16, [mm]
long @i_mov_modrm_r8 ' 88 rm mov [rm], r8
long @i_mov_modrm_r16 ' 89 rm mov [rm], r16
long @i_mov_r8_modrm ' 8A rm mov r8, [rm]
long @i_mov_r16_modrm ' 8B rm mov r16, [rm]
long @i_mov_modrm_sreg ' 8C rm mov [rm], sreg
long @i_lea ' 8D oo lea r16, oo
long @i_mov_sreg_modrm ' 8E rm mov sregs, [rm]
long @i_pop_modrm ' 8F mm pop [rm]
long @i_xchg ' 90 xchg ax, cx
long @i_xchg ' 91 xchg ax, cx
long @i_xchg ' 92 xchg ax, dx
long @i_xchg ' 93 xchg ax, bx
long @i_xchg ' 94 xchg ax, sp
long @i_xchg ' 95 xchg ax, bp
long @i_xchg ' 96 xchg ax, si
long @i_xchg ' 97 xchg ax, di
long @i_cbw ' 98 cbw
long @i_cwd ' 99 cwd
long @i_call_far ' 9A ol oh sl sh call shsl:ohol
long @i_wait ' 9B wait
long @i_pushf ' 9C pushf
long @i_popf ' 9C popf
long @i_sahf ' 9E sahf
long @i_lahf ' 9F lahf
long @i_mov_al_offs ' A0 ol oh mov al, [DS:ohol]
long @i_mov_ax_offs ' A1 ol oh mov ax, [DS:ohol]
long @i_mov_offs_al ' A2 ol oh mov [DS:ohol], al
long @i_mov_offs_ax ' A3 ol oh mov [DS:ohol], ax
long @i_movsb ' A4 movsb
long @i_movsw ' A5 movsw
long @i_cmpsb ' A6 cmpsb
long @i_cmpsw ' A7 cmpsw
long @i_test_al_imm ' A8 nn test al, nn
long @i_test_ax_imm ' A9 ll hh test ax, hhll
long @i_stosb ' AA stosb
long @i_stosw ' AB stosw
long @i_lodsb ' AC lodsb
long @i_lodsw ' AD lodsw
long @i_scasb ' AE scasb
long @i_scasw ' AF scasw
long @i_mov_immb ' B0 nn mov al, nn
long @i_mov_immb ' B1 nn mov cl, nn
long @i_mov_immb ' B2 nn mov dl, nn
long @i_mov_immb ' B3 nn mov bl, nn
long @i_mov_immb ' B4 nn mov ah, nn
long @i_mov_immb ' B5 nn mov ch, nn
long @i_mov_immb ' B6 nn mov dh, nn
long @i_mov_immb ' B7 nn mov bh, nn
long @i_mov_immw ' B8 ll hh mov ax, hhll
long @i_mov_immw ' B9 ll hh mov cx, hhll
long @i_mov_immw ' BA ll hh mov dx, hhll
long @i_mov_immw ' BB ll hh mov bx, hhll
long @i_mov_immw ' BC ll hh mov sp, hhll
long @i_mov_immw ' BD ll hh mov bp, hhll
long @i_mov_immw ' BE ll hh mov si, hhll
long @i_mov_immw ' BF ll hh mov di, hhll
long @i_ret_near_sp ' C0 dl dh ret (SP+dhdl)
long @i_ret_near ' C1 ret
long @i_ret_near_sp ' C2 dl dh ret (SP+dhdl)
long @i_ret_near ' C3 ret
long @i_les ' C4 rm les [rm]
long @i_lds ' C5 rm lds [rm]
long @i_mov_modrm_imm8 ' C6 rm nn mov byte [rm], nn
long @i_mov_modrm_imm16 ' C7 rm ll hh mov word [rm], hhll
long @i_ret_far_sp ' C8 dl dh retf (SP+dhdl)
long @i_ret_far ' C9 retf
long @i_ret_far_sp ' CA dl dh retf (SP+dhdl)
long @i_ret_far ' CB retf
long @i_int3 ' CC int3
long @i_int ' CD int
long @i_into ' CE into
long @i_iret ' CF iret
long @i_d0_prefix ' D0 rm rol/ror/rolc/rorc/shl/shr/shra byte[rm]
long @i_d1_prefix ' D1 rm rol/ror/rolc/rorc/shl/shr/shraw word[rm]
long @i_d2_prefix ' D2 rm rol/ror/rolc/rorc/shl/shr/shrab byte[rm], cl
long @i_d3_prefix ' D3 rm rol/ror/rolc/rorc/shl/shr/shraw word[rm], cl
long @i_aam ' D4 aam
long @i_aad ' D5 aad
long @i_salc ' D6 salc
long @i_xlatb ' D7 xlatb
long i_esc_op ' D8 rm esc rm
long i_esc_op ' D9 rm esc rm
long i_esc_op ' DA rm esc rm
long i_esc_op ' DB rm esc rm
long i_esc_op ' DC rm esc rm
long i_esc_op ' DD rm esc rm
long i_esc_op ' DE rm esc rm
long i_esc_op ' DF rm esc rm
long @i_loopne ' E0 dd loopne dd
long @i_loope ' E1 dd loope dd
long @i_loop ' E2 dd loop dd
long @i_jcxz ' E3 dd jcxz dd
long @i_in_al_imm ' E4 pp in al, [pp]
long @i_in_ax_imm ' E5 pp in ax, [pp]
long @i_out_imm_al ' E6 pp out [pp], al
long @i_out_imm_ax ' E7 pp out [pp], ax
long @i_call_displ ' E8 dl dh call +dhdl
long @i_jmp_displ ' E9 dl dh jmp +dhdl
long @i_jmp_far ' EA ol oh sl sh jmp shsl:ohol
long @i_jmp_displ8 ' EB dd jmp +dd
long @i_in_al_dx ' EC pp in al, [dx]
long @i_in_ax_dx ' ED pp in ax, [dx]
long @i_out_dx_al ' EE pp out [dx], al
long @i_out_dx_ax ' EF pp out [dx], ax
long @i_lock ' F0 lock
long @i_lock ' F1 lock
long @i_hlt ' F2 repne
long @i_hlt ' F3 repe
long @i_hlt ' F4 hlt
long @i_cmc ' F5 cmc
long @i_f6_prefix ' F6 rm test/not/net/mul/imul/div/idiv [rm8]
long @i_f7_prefix ' F7 rm test/not/net/mul/imul/div/idiv [rm16]
long @i_clc ' F8 clc
long @i_stc ' F9 stc
long @i_cli ' FA cli
long @i_sti ' FB sti
long @i_cld ' FC cld
long @i_std ' FD std
long @i_fe_prefix ' FF rm inc/dec [rm]
long @i_ff_prefix ' FF rm inc/dec/call/call far/jmp/jmp far/push/cmp [rm]
i_hlt
bith i_flags, #I_HALT_BIT
_ret_ decmod i_ip, i_ffffh
' add [modrm], r8
' or [modrm], r8
' adc [modrm], r8
' sbb [modrm], r8
' and [modrm], r8
' sub [modrm], r8
' xor [modrm], r8
' cmp [modrm], r8
i_math_modrm_r8
call #\i_setupmodrm
call #\i_getmodr8
mov i_data1, i_data
call #\i_readopb
mov i_data0, i_data
mov i_temp0, i_opcode
_do_modrm_op8
and i_temp0, #%00_111_000 wz
if_z jmp #.add
cmp i_temp0, #%00_001_000 wz
if_z jmp #.or
cmp i_temp0, #%00_010_000 wz