summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/m68000gen.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m68000/m68000gen.py')
-rwxr-xr-xsrc/devices/cpu/m68000/m68000gen.py2569
1 files changed, 2569 insertions, 0 deletions
diff --git a/src/devices/cpu/m68000/m68000gen.py b/src/devices/cpu/m68000/m68000gen.py
new file mode 100755
index 00000000000..35412cb2db1
--- /dev/null
+++ b/src/devices/cpu/m68000/m68000gen.py
@@ -0,0 +1,2569 @@
+#!/bin/python3
+
+# m68000 emulation code generator
+
+# Decode table generation: m68000gen.py decode m68000.lst m68000-decode.cpp
+# Header generation: m68000gen.py header m68000.lst m68000-head.h
+# Handlers generation: m68000gen.py sdf m68000.lst m68000-sdf.cpp
+# m68000gen.py sdp m68000.lst m68000-sdp.cpp
+# m68000gen.py sif m68000.lst m68000-sif.cpp
+# m68000gen.py sip m68000.lst m68000-sip.cpp
+
+
+import sys
+from enum import IntEnum, auto
+
+microcode_base_table = [
+ [ 0x000, 0x3f0, [ 0x12160, 0x10800, 0x052d0, 0x07cc0, 0x0800c, 0x0800c, 0x08480, 0x118e0, 0x08880, 0x10080, 0x10080, 0x08880, 0x01480, 0x10100, 0x10100, 0x0d300 ] ],
+ [ 0x020, 0x3f0, [ 0x00004, 0x01580, 0x07060, 0x04a4a, 0x0000c, 0x161a1, 0x0000c, 0x01d00, 0x06940, 0x046a0, 0x00480, 0x10c02, 0x07d80, 0x008e0, 0x05ea0, 0x12702 ] ],
+ [ 0x040, 0x3f0, [ 0x13a00, 0x00996, 0x05280, 0x161a1, 0x00004, 0x07c20, 0x12ea0, 0x08c20, 0x0af00, 0x1149a, 0x08ca1, 0x00cba, 0x098a0, 0x11497, 0x08021, 0x069c0 ] ],
+ [ 0x060, 0x3f0, [ 0x00460, 0x09421, 0x169c0, 0x036a0, 0x10004, 0x169c0, 0x00004, 0x01040, 0x008e6, 0x11ca1, 0x000f2, 0x090c0, 0x010a6, 0x11437, 0x001f2, 0x091c0 ] ],
+ [ 0x080, 0x3f0, [ 0x15201, 0x11041, 0x08004, 0x0987a, 0x00c40, 0x02c60, 0x03400, 0x161a1, 0x0f060, 0x03000, 0x00921, 0x00004, 0x00160, 0x00004, 0x022a0, 0x12e21 ] ],
+ [ 0x0a0, 0x3f0, [ 0x00460, 0x00004, 0x0f0e0, 0x036a0, 0x05a00, 0x08cba, 0x05a00, 0x11560, 0x0ac60, 0x03180, 0x0ac60, 0x11ce1, 0x00960, 0x08cba, 0x00960, 0x115e0 ] ],
+ [ 0x0c0, 0x3f0, [ 0x15201, 0x01156, 0x03ea0, 0x0db80, 0x00004, 0x17c20, 0x008e0, 0x11941, 0x00c40, 0x01c12, 0x04a16, 0x05a20, 0x000e0, 0x011e0, 0x04a1a, 0x069c0 ] ],
+ [ 0x0e0, 0x3f0, [ 0x00422, 0x01580, 0x00004, 0x05a80, 0x0a280, 0x08dc0, 0x00004, 0x000b2, 0x06940, 0x046a0, 0x10008, 0x0d680, 0x07d80, 0x008e0, 0x12a00, 0x0fca0 ] ],
+ [ 0x100, 0x3f0, [ 0x11941, 0x10502, 0x08540, 0x03f20, 0x14f01, 0x12582, 0x0e9c0, 0x02e80, 0x15701, 0x12502, 0x0e120, 0x00120, 0x14b21, 0x10582, 0x09540, 0x02e00 ] ],
+ [ 0x120, 0x3f0, [ 0x01500, 0x15721, 0x0a621, 0x12a80, 0x00180, 0x17421, 0x0b280, 0x12a00, 0x05b60, 0x14721, 0x0bd00, 0x0e8e0, 0x057c0, 0x161a1, 0x0aaa1, 0x00000 ] ],
+ [ 0x110, 0x3f0, [ 0x02216, 0x0e53a, 0x16880, 0x069c0, 0x08486, 0x0e5bb, 0x0f800, 0x05a20, 0x05251, 0x0b7e0, 0x0dec0, 0x04700, 0x07c30, 0x00000, 0x15ec0, 0x00000 ] ],
+ [ 0x130, 0x3f0, [ 0x07100, 0x0b600, 0x01120, 0x11941, 0x04300, 0x0b680, 0x011a0, 0x133a1, 0x00cba, 0x0b700, 0x001a0, 0x13a81, 0x00000, 0x00000, 0x00000, 0x00000 ] ],
+ [ 0x150, 0x3f0, [ 0x161a1, 0x03a20, 0x03a20, 0x0222e, 0x0b580, 0x0b2a0, 0x13aa0, 0x00004, 0x161a1, 0x06c00, 0x160e1, 0x160e1, 0x13a01, 0x0e9c0, 0x05b20, 0x13100 ] ],
+ [ 0x170, 0x3f0, [ 0x10004, 0x00004, 0x009c0, 0x009c0, 0x009c0, 0x018aa, 0x01016, 0x05280, 0x13100, 0x03720, 0x08880, 0x0800c, 0x13081, 0x137a0, 0x13fa1, 0x03080 ] ],
+ [ 0x1c0, 0x3f0, [ 0x07c40, 0x15721, 0x11500, 0x15721, 0x04680, 0x16061, 0x10180, 0x16161, 0x00000, 0x16161, 0x16da0, 0x143a1, 0x07880, 0x13b01, 0x17d20, 0x126a1 ] ],
+ [ 0x1e0, 0x3f0, [ 0x01500, 0x17c20, 0x10900, 0x07460, 0x00180, 0x13200, 0x10980, 0x074e0, 0x05b60, 0x11dc0, 0x15f40, 0x02900, 0x057c0, 0x16860, 0x15fc0, 0x02880 ] ],
+ [ 0x1d0, 0x3f0, [ 0x078a0, 0x15701, 0x15340, 0x15701, 0x00000, 0x13e21, 0x153c0, 0x13621, 0x00000, 0x126a1, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000 ] ],
+ [ 0x1f0, 0x3f0, [ 0x07100, 0x16960, 0x152a0, 0x05640, 0x04300, 0x11c80, 0x15e40, 0x056c0, 0x00cba, 0x17180, 0x13ba0, 0x07560, 0x00000, 0x156e0, 0x0c7a1, 0x075e0 ] ],
+ [ 0x210, 0x3f0, [ 0x04a00, 0x00816, 0x00004, 0x01c0e, 0x04200, 0x161a1, 0x04aca, 0x07060, 0x04b01, 0x13080, 0x0db00, 0x0000c, 0x0cb80, 0x0000c, 0x0187a, 0x0987a ] ],
+ [ 0x230, 0x3f0, [ 0x15e01, 0x009c0, 0x15e01, 0x00004, 0x04e80, 0x01d60, 0x1a300, 0x0653a, 0x00004, 0x009c0, 0x00004, 0x161a1, 0x0cf81, 0x10004, 0x0f920, 0x0c321 ] ],
+ [ 0x250, 0x3f0, [ 0x00060, 0x114a1, 0x06d06, 0x00004, 0x04200, 0x17c20, 0x14e20, 0x07080, 0x10004, 0x05320, 0x05b20, 0x00004, 0x04ba0, 0x00004, 0x04ba0, 0x04ba0 ] ],
+ [ 0x270, 0x3f0, [ 0x14e20, 0x0d620, 0x0fc21, 0x14e20, 0x14e40, 0x17c20, 0x05e80, 0x0653a, 0x00004, 0x14721, 0x00004, 0x004e1, 0x14fa0, 0x00004, 0x05fa0, 0x05f60 ] ],
+ [ 0x290, 0x3f0, [ 0x04a40, 0x05216, 0x06420, 0x04620, 0x04ac0, 0x052e0, 0x057b0, 0x05e40, 0x02800, 0x169c1, 0x0e520, 0x161a1, 0x02980, 0x169a1, 0x0f1a0, 0x17da1 ] ],
+ [ 0x2b0, 0x3f0, [ 0x046a0, 0x04e20, 0x00d02, 0x17c20, 0x008e0, 0x06180, 0x00d82, 0x12380, 0x169c1, 0x10008, 0x0e120, 0x16940, 0x12ba1, 0x17c20, 0x0dbe0, 0x15740 ] ],
+ [ 0x2d0, 0x3f0, [ 0x05216, 0x114e1, 0x04206, 0x05a06, 0x052e0, 0x114e1, 0x06dc6, 0x05a86, 0x11941, 0x16940, 0x15b60, 0x0fc21, 0x14b21, 0x15740, 0x157c0, 0x0c321 ] ],
+ [ 0x2f0, 0x3f0, [ 0x0653a, 0x114a1, 0x16900, 0x169c1, 0x0e5ba, 0x114a1, 0x156a0, 0x169a1, 0x17921, 0x0df80, 0x08c81, 0x15fe0, 0x15781, 0x0c780, 0x0e921, 0x16000 ] ],
+ [ 0x300, 0x3f0, [ 0x13380, 0x06c00, 0x05e40, 0x17c20, 0x069c0, 0x11920, 0x00004, 0x06400, 0x008a6, 0x07c20, 0x07c20, 0x14ec0, 0x0e981, 0x0e920, 0x12a00, 0x16d00 ] ],
+ [ 0x320, 0x3f0, [ 0x06c00, 0x02c60, 0x00cba, 0x00cba, 0x069c0, 0x17480, 0x01d80, 0x00004, 0x161a1, 0x0f500, 0x0ac61, 0x17580, 0x161a0, 0x0428a, 0x0ac61, 0x0e120 ] ],
+ [ 0x340, 0x3f0, [ 0x009c0, 0x17021, 0x00004, 0x060a0, 0x0fc20, 0x170a1, 0x00004, 0x07060, 0x0fc20, 0x10004, 0x0f920, 0x08004, 0x00004, 0x0e9c0, 0x0f9a0, 0x0e520 ] ],
+ [ 0x360, 0x3f0, [ 0x09de0, 0x00004, 0x00004, 0x161a1, 0x00000, 0x00000, 0x00000, 0x0b300, 0x0f521, 0x0004a, 0x10004, 0x0e5a0, 0x0eda0, 0x0f5a1, 0x0fc20, 0x00004 ] ],
+ [ 0x380, 0x3f0, [ 0x119a7, 0x17841, 0x17841, 0x05a06, 0x11967, 0x178c1, 0x178c1, 0x05a86, 0x16940, 0x0fc20, 0x16940, 0x17921, 0x17d80, 0x08004, 0x17d80, 0x17121 ] ],
+ [ 0x3a0, 0x3f0, [ 0x17c00, 0x16481, 0x07c81, 0x07060, 0x15380, 0x16021, 0x05f20, 0x07170, 0x0653a, 0x0f540, 0x08c81, 0x08c80, 0x0e5ba, 0x0f5c0, 0x0e921, 0x0e921 ] ],
+ [ 0x3c0, 0x3f0, [ 0x053a0, 0x11920, 0x0e420, 0x161a1, 0x0041e, 0x0f000, 0x08140, 0x16081, 0x05ba0, 0x17400, 0x09440, 0x16c21, 0x00000, 0x00000, 0x00000, 0x00000 ] ],
+ [ 0x3e0, 0x3f0, [ 0x14f40, 0x00000, 0x12402, 0x14e01, 0x14fc0, 0x00000, 0x12482, 0x11ce1, 0x04660, 0x0424a, 0x12602, 0x115a1, 0x0c6e0, 0x042ca, 0x12682, 0x11521 ] ],
+]
+
+nanocode_base_table = [
+ [ 0x000, 0x3fc, [ [ 0x0, 0x00010000, 0x00000000 ], [ 0x0, 0x00010000, 0x00000000 ], [ 0x0, 0x00010000, 0x00000000 ], [ 0x8, 0x25000398, 0x10000000 ] ] ],
+ [ 0x020, 0x3fc, [ [ 0x8, 0x532200e5, 0x08418425 ], [ 0x0, 0x008c400a, 0x01000002 ], [ 0x0, 0x20062f89, 0x4c018084 ], [ 0xc, 0x08280211, 0x00018044 ] ] ],
+ [ 0x004, 0x3fc, [ [ 0x9, 0x26020058, 0x12218084 ], [ 0x9, 0x24024018, 0x10140180 ], [ 0x0, 0xa1010028, 0x02218004 ], [ 0x8, 0xa0020088, 0x10000083 ] ] ],
+ [ 0x024, 0x3fc, [ [ 0x0, 0x08010000, 0x62000680 ], [ 0x8, 0xa0020008, 0x10000000 ], [ 0x9, 0x240a4018, 0x10140180 ], [ 0x0, 0x00010000, 0x00210014 ] ] ],
+ [ 0x008, 0x3f8, [ [ 0x0, 0x80028000, 0x00218084 ], [ 0x1, 0x8b00c022, 0x60100682 ], [ 0x1, 0x8980c022, 0x60100682 ], [ 0x0, 0xa0020008, 0x00218084 ] ] ],
+ [ 0x028, 0x3f8, [ [ 0x0, 0x008c400a, 0x01218046 ], [ 0x0, 0x004c8001, 0x49000000 ], [ 0x9, 0x240a4018, 0x12218004 ], [ 0x1, 0xa04c0009, 0x00400000 ] ] ],
+ [ 0x040, 0x3fc, [ [ 0x8, 0xa0010008, 0x10120048 ], [ 0x0, 0x01110060, 0x00038044 ], [ 0x0, 0x00010062, 0x00020048 ], [ 0x8, 0xb6022059, 0x98000000 ] ] ],
+ [ 0x060, 0x3fc, [ [ 0x0, 0x00010000, 0x0082002c ], [ 0x1, 0x80800002, 0x00104800 ], [ 0x5, 0x0b000060, 0x441200ae ], [ 0xc, 0x08280211, 0x00858044 ] ] ],
+ [ 0x044, 0x3fc, [ [ 0x0, 0x08212081, 0x00000345 ], [ 0x8, 0x20020088, 0x10000001 ], [ 0x9, 0x24024018, 0x58098004 ], [ 0x0, 0xc102a024, 0x085000c8 ] ] ],
+ [ 0x064, 0x3fc, [ [ 0x8, 0xa0020088, 0x10000083 ], [ 0x5, 0x0b000060, 0x441200ca ], [ 0x8, 0x360200d9, 0x90000083 ], [ 0x8, 0x40028004, 0x10400392 ] ] ],
+ [ 0x048, 0x3f8, [ [ 0x0, 0x80068000, 0x00280080 ], [ 0x8, 0xa0020019, 0x10418044 ], [ 0x0, 0xc101a024, 0x0a140080 ], [ 0x0, 0x0300c560, 0x00000082 ] ] ],
+ [ 0x068, 0x3f8, [ [ 0x4, 0x088c0002, 0x44100000 ], [ 0x1, 0x80010380, 0x00280308 ], [ 0x8, 0x20020009, 0x5808038a ], [ 0x0, 0xa008c008, 0x02000000 ] ] ],
+ [ 0x080, 0x3fc, [ [ 0x8, 0xb0220058, 0x10498010 ], [ 0x8, 0xc0028004, 0x1028038a ], [ 0x0, 0x830100e0, 0x02024b45 ], [ 0x0, 0x81068521, 0x40000800 ] ] ],
+ [ 0x0a0, 0x3fc, [ [ 0x0, 0x00010000, 0x00820028 ], [ 0x0, 0x10212081, 0x00420345 ], [ 0x4, 0x88228481, 0x0001c804 ], [ 0xc, 0x08280211, 0x00018044 ] ] ],
+ [ 0x084, 0x3f4, [ [ 0x0, 0x08212001, 0x00080308 ], [ 0x8, 0x20020088, 0x10000001 ], [ 0x0, 0x41028024, 0x02000080 ], [ 0x8, 0xc0028005, 0x50100048 ] ] ],
+ [ 0x0a4, 0x3f4, [ [ 0x0, 0x0421c009, 0x08298144 ], [ 0x0, 0x80028501, 0x40000800 ], [ 0x0, 0x0421c009, 0x48098144 ], [ 0x0, 0x9022a001, 0x00200080 ] ] ],
+ [ 0x088, 0x3fc, [ [ 0x4, 0x960685d1, 0x8401c805 ], [ 0x4, 0x2c042019, 0x4c018004 ], [ 0x0, 0x00010000, 0x00030048 ], [ 0x8, 0x20020089, 0xb8400083 ] ] ],
+ [ 0x0a8, 0x3fc, [ [ 0x5, 0x888c0200, 0x44004800 ], [ 0x0, 0x24046019, 0x08018004 ], [ 0x5, 0x888c0002, 0x44104800 ], [ 0x1, 0xcb01c000, 0x60000600 ] ] ],
+ [ 0x0c0, 0x3fc, [ [ 0x8, 0xa0020008, 0x10498018 ], [ 0x0, 0x01110060, 0x00038044 ], [ 0x0, 0x08210001, 0x0081010c ], [ 0x0, 0x81068021, 0x40000800 ] ] ],
+ [ 0x0e0, 0x3fc, [ [ 0xc, 0x000e8050, 0x84418030 ], [ 0x0, 0x200c400a, 0x01000002 ], [ 0x8, 0x40028084, 0x10000083 ], [ 0x8, 0x20060388, 0x10000000 ] ] ],
+ [ 0x0c4, 0x3fc, [ [ 0x0, 0x00010081, 0x88420345 ], [ 0x0, 0x80028000, 0x00000082 ], [ 0x8, 0x20020088, 0x10000001 ], [ 0x8, 0xc0028004, 0x10000000 ] ] ],
+ [ 0x0e4, 0x3fc, [ [ 0x0, 0x00068000, 0x00000000 ], [ 0x0, 0x88228001, 0x00000800 ], [ 0x0, 0x00010080, 0x000000d7 ], [ 0x8, 0x20020009, 0x58098086 ] ] ],
+ [ 0x0c8, 0x3f8, [ [ 0x0, 0x00010000, 0x00400310 ], [ 0x0, 0x00010000, 0x00030048 ], [ 0x0, 0x06210023, 0x00850008 ], [ 0x0, 0x03000060, 0x0041808a ] ] ],
+ [ 0x0e8, 0x3f8, [ [ 0x0, 0x200c400a, 0x01218046 ], [ 0x0, 0x080ca001, 0x49000000 ], [ 0x8, 0xc4228005, 0x98200082 ], [ 0x0, 0x84448410, 0x0003c804 ] ] ],
+ [ 0x100, 0x3f0, [ [ 0x1, 0x8001c00b, 0x40000048 ], [ 0x1, 0xa04ce009, 0x08400000 ], [ 0x0, 0xc622a007, 0x08000800 ], [ 0x0, 0x280ec008, 0x60140600 ] ] ],
+ [ 0x120, 0x3f0, [ [ 0x0, 0x008c450a, 0x01000082 ], [ 0x8, 0xcc02a015, 0x58018044 ], [ 0x0, 0xa0082008, 0x0a218084 ], [ 0x0, 0x80028601, 0x00200082 ] ] ],
+ [ 0x110, 0x3f0, [ [ 0x0, 0x00010000, 0x00000000 ], [ 0x0, 0xa102c52a, 0x00000080 ], [ 0x0, 0x84228001, 0x00200080 ], [ 0x0, 0x03000060, 0x004080ae ] ] ],
+ [ 0x130, 0x3f0, [ [ 0x0, 0x008c450a, 0x01000082 ], [ 0x1, 0x10016000, 0x8a218004 ], [ 0x0, 0x200e2008, 0x0a000080 ], [ 0x8, 0xc0028005, 0x58010048 ] ] ],
+ [ 0x150, 0x3fc, [ [ 0x8, 0xc0028004, 0x10000000 ], [ 0x0, 0x00068000, 0x40180048 ], [ 0x0, 0x00068008, 0x40080048 ], [ 0x8, 0x40028004, 0x10038044 ] ] ],
+ [ 0x170, 0x3fc, [ [ 0x8, 0xb0024088, 0x905000cb ], [ 0x0, 0x08210081, 0x000004af ], [ 0x0, 0x20112002, 0x000200ae ], [ 0x0, 0x28312003, 0x000000ae ] ] ],
+ [ 0x154, 0x3fc, [ [ 0x1, 0x46018054, 0x00280080 ], [ 0x0, 0x80028000, 0x00100180 ], [ 0x8, 0xb0024008, 0x90500048 ], [ 0x0, 0x00010080, 0x000204af ] ] ],
+ [ 0x174, 0x3fc, [ [ 0x0, 0x26312003, 0x000000ae ], [ 0x0, 0x0302c060, 0x0003800e ], [ 0x0, 0x00010001, 0x40010008 ], [ 0x0, 0x00010022, 0x00820048 ] ] ],
+ [ 0x158, 0x3fc, [ [ 0x8, 0xd0428005, 0x90200000 ], [ 0x0, 0x00068601, 0x00200000 ], [ 0x1, 0x04004210, 0x40190144 ], [ 0x1, 0x04004218, 0x40090144 ] ] ],
+ [ 0x178, 0x3fc, [ [ 0x1, 0xa444e019, 0x08200002 ], [ 0x0, 0x20040008, 0x00218004 ], [ 0x0, 0xc0028004, 0x00000080 ], [ 0x9, 0x34006018, 0x9a038084 ] ] ],
+ [ 0x15c, 0x3fc, [ [ 0x1, 0x8001c000, 0x00210048 ], [ 0x0, 0x83060060, 0x0003482c ], [ 0x0, 0x08212007, 0x008100ae ], [ 0x1, 0xa004e019, 0x08200002 ] ] ],
+ [ 0x17c, 0x3fc, [ [ 0x1, 0xac04e019, 0x48018086 ], [ 0x0, 0x8c02a010, 0x48218086 ], [ 0x1, 0x868cc052, 0x00800000 ], [ 0x0, 0x24046019, 0x08018086 ] ] ],
+ [ 0x1c0, 0x3e0, [ [ 0x8, 0x20060388, 0x10000000 ], [ 0x1, 0x8441c01b, 0x48000048 ], [ 0x1, 0x888c2002, 0x48100082 ], [ 0x1, 0x8441c01b, 0x08200048 ] ] ],
+ [ 0x1e0, 0x3e0, [ [ 0x0, 0x200c450a, 0x01000082 ], [ 0x8, 0xc0028605, 0x10200082 ], [ 0x0, 0x84228001, 0x00200080 ], [ 0x0, 0x00010000, 0x00210014 ] ] ],
+ [ 0x210, 0x3fc, [ [ 0x0, 0x06210001, 0x00018044 ], [ 0x0, 0x08210001, 0x00058444 ], [ 0x0, 0x00010086, 0x080204cb ], [ 0x0, 0x20112002, 0x00020048 ] ] ],
+ [ 0x230, 0x3fc, [ [ 0x1, 0xac00c01b, 0x40000600 ], [ 0x0, 0x53014067, 0x80000082 ], [ 0x1, 0x8441c011, 0x4801804c ], [ 0x8, 0x360220d9, 0x98000083 ] ] ],
+ [ 0x214, 0x3fc, [ [ 0xc, 0x000e8000, 0x00418010 ], [ 0x8, 0xc0028004, 0x10200344 ], [ 0x0, 0x00010051, 0x00018044 ], [ 0x4, 0x30066f89, 0x8c018004 ] ] ],
+ [ 0x234, 0x3fc, [ [ 0x4, 0x10014303, 0x84058004 ], [ 0x0, 0x20062a88, 0x08000000 ], [ 0x1, 0x06010050, 0x00000002 ], [ 0x0, 0x8302c560, 0x00000080 ] ] ],
+ [ 0x218, 0x3fc, [ [ 0x8, 0x240a4019, 0x10018004 ], [ 0x1, 0xa004e008, 0x08000082 ], [ 0x0, 0x81028020, 0x00140100 ], [ 0x8, 0x30026008, 0x98000080 ] ] ],
+ [ 0x238, 0x3fc, [ [ 0x8, 0x20020089, 0xb0400001 ], [ 0x0, 0x28310003, 0x000000ae ], [ 0x8, 0x20020088, 0x10000083 ], [ 0x8, 0xd0428405, 0x90018044 ] ] ],
+ [ 0x21c, 0x3fc, [ [ 0x0, 0xa9080028, 0x62140600 ], [ 0x8, 0x30026008, 0x9a038084 ], [ 0x0, 0x2106c528, 0x00000002 ], [ 0x0, 0x89268521, 0x00000800 ] ] ],
+ [ 0x23c, 0x3fc, [ [ 0x0, 0x80028001, 0x48018844 ], [ 0x8, 0xb0024088, 0x900380a7 ], [ 0x0, 0x8826a001, 0x0001c824 ], [ 0x9, 0xa0000009, 0x58018844 ] ] ],
+ [ 0x250, 0x3fc, [ [ 0x0, 0x10210001, 0x00410004 ], [ 0x8, 0xa4220009, 0x10438044 ], [ 0x0, 0x00010022, 0x00820048 ], [ 0x8, 0x20020088, 0xb8400001 ] ] ],
+ [ 0x270, 0x3fc, [ [ 0x1, 0x2604e058, 0x08000002 ], [ 0x4, 0xc822a007, 0x08000800 ], [ 0x1, 0x83020061, 0x44000800 ], [ 0x1, 0x2c042018, 0x48000002 ] ] ],
+ [ 0x254, 0x3fc, [ [ 0x0, 0x00010011, 0x00418018 ], [ 0x0, 0xa0020008, 0x00000002 ], [ 0x1, 0x2604e019, 0x08200002 ], [ 0x0, 0x40110002, 0x88440400 ] ] ],
+ [ 0x274, 0x3fc, [ [ 0x9, 0x24024018, 0x10000000 ], [ 0x0, 0x90428001, 0x80200002 ], [ 0x8, 0x240a4018, 0x10000002 ], [ 0x0, 0x0302c560, 0x00000080 ] ] ],
+ [ 0x258, 0x3fc, [ [ 0x8, 0xc0028084, 0x100380a7 ], [ 0x0, 0x00010001, 0x88400082 ], [ 0x0, 0x28310003, 0x0000002c ], [ 0x8, 0x30222089, 0x10400001 ] ] ],
+ [ 0x278, 0x3fc, [ [ 0x0, 0x4b2120e7, 0x080180a7 ], [ 0x8, 0xc4428015, 0x58000000 ], [ 0x8, 0x20020089, 0xb0400083 ], [ 0x0, 0x00860002, 0x00800000 ] ] ],
+ [ 0x25c, 0x3fc, [ [ 0x0, 0x20112003, 0x804200ae ], [ 0x8, 0x30220089, 0x10400001 ], [ 0x0, 0x28312003, 0x0000002c ], [ 0x0, 0x26312003, 0x0000002c ] ] ],
+ [ 0x27c, 0x3fc, [ [ 0x8, 0xb0024009, 0x90000000 ], [ 0x0, 0x16012081, 0x88200083 ], [ 0x0, 0x00010680, 0x00000000 ], [ 0x0, 0x00800300, 0x00000000 ] ] ],
+ [ 0x290, 0x3f8, [ [ 0x0, 0x00010051, 0x00018044 ], [ 0xc, 0x000e8000, 0x00418010 ], [ 0x0, 0x00010080, 0x00000001 ], [ 0x0, 0x04410011, 0x00200000 ] ] ],
+ [ 0x2b0, 0x3f8, [ [ 0x0, 0x088c2002, 0x48100000 ], [ 0x0, 0x2004e008, 0x08000002 ], [ 0x0, 0x088c2002, 0x48800000 ], [ 0x0, 0x83020002, 0x00100002 ] ] ],
+ [ 0x298, 0x3f8, [ [ 0x0, 0x00010000, 0x00410014 ], [ 0x1, 0x8300c061, 0x401000ca ], [ 0x0, 0x80028000, 0x02001080 ], [ 0x8, 0xc0028005, 0xb0218044 ] ] ],
+ [ 0x2b8, 0x3f8, [ [ 0x1, 0x8300c060, 0x002100ca ], [ 0x8, 0xc0028005, 0x90200082 ], [ 0x0, 0x8822a001, 0x00098824 ], [ 0x1, 0x8300c013, 0x48118046 ] ] ],
+ [ 0x2d0, 0x3f8, [ [ 0xc, 0x000e8000, 0x00418018 ], [ 0x8, 0xa0020008, 0x10000000 ], [ 0x0, 0x00010022, 0x00820048 ], [ 0xc, 0x000e8000, 0x00418050 ] ] ],
+ [ 0x2f0, 0x3f8, [ [ 0x0, 0x81028521, 0x80200080 ], [ 0x1, 0xa101c629, 0x00200000 ], [ 0x1, 0x888c2002, 0x48100000 ], [ 0x1, 0x9340c461, 0x801000ca ] ] ],
+ [ 0x2d8, 0x3f8, [ [ 0x1, 0x9041c40b, 0x80000048 ], [ 0x1, 0x8080c013, 0x48118046 ], [ 0x1, 0x888cc002, 0x40100002 ], [ 0x9, 0xa0020009, 0x5a018844 ] ] ],
+ [ 0x2f8, 0x3f8, [ [ 0x1, 0xa00ee009, 0x480180c6 ], [ 0x0, 0xa822e009, 0x08080800 ], [ 0x0, 0xa008e009, 0x4a018844 ], [ 0x0, 0x90228801, 0x00200080 ] ] ],
+ [ 0x300, 0x3fc, [ [ 0x0, 0x80028f01, 0x80200080 ], [ 0x0, 0x0806a601, 0x48000000 ], [ 0x0, 0x4421a107, 0x082000e0 ], [ 0x0, 0x93024003, 0x80100002 ] ] ],
+ [ 0x320, 0x3fc, [ [ 0x0, 0x00028601, 0x00400000 ], [ 0x0, 0x00010100, 0x00000060 ], [ 0x0, 0x204cc509, 0x00200002 ], [ 0x0, 0x2000c508, 0x00000002 ] ] ],
+ [ 0x304, 0x3fc, [ [ 0x0, 0x03000060, 0x004180d2 ], [ 0x0, 0x80028011, 0x00200000 ], [ 0x8, 0x20020088, 0x10038025 ], [ 0x0, 0x00010409, 0x08000008 ] ] ],
+ [ 0x324, 0x3fc, [ [ 0x0, 0x03000461, 0x00018086 ], [ 0x0, 0x800a8601, 0x00200082 ], [ 0x8, 0x40068015, 0x10210014 ], [ 0x8, 0x40068104, 0x10000061 ] ] ],
+ [ 0x308, 0x3fc, [ [ 0x8, 0x204c0408, 0x10000000 ], [ 0x8, 0x300a4009, 0x90000002 ], [ 0x8, 0x300a4009, 0x90000000 ], [ 0x0, 0x8c02a011, 0x48018004 ] ] ],
+ [ 0x328, 0x3fc, [ [ 0x8, 0xa0020008, 0x10000000 ], [ 0x0, 0x83020053, 0x0011c844 ], [ 0x9, 0xa0020008, 0x1003c824 ], [ 0x1, 0x8111c002, 0x00a180c4 ] ] ],
+ [ 0x30c, 0x3fc, [ [ 0x0, 0xc6228005, 0x00000800 ], [ 0x1, 0x888c2002, 0x48104800 ], [ 0x0, 0x9042a001, 0x88200002 ], [ 0x1, 0x8111c013, 0x00a38084 ] ] ],
+ [ 0x32c, 0x3fc, [ [ 0x8, 0xb6022059, 0x98000000 ], [ 0x0, 0x00010000, 0x00000000 ], [ 0x9, 0x26020009, 0x12204800 ], [ 0x0, 0x80028011, 0x0043c424 ] ] ],
+ [ 0x340, 0x3fc, [ [ 0x0, 0x00010401, 0x88000082 ], [ 0x1, 0x8931e00b, 0x00058044 ], [ 0x0, 0x1602a084, 0x008380a7 ], [ 0x0, 0x0300c461, 0x00100008 ] ] ],
+ [ 0x360, 0x3fc, [ [ 0x4, 0xc822ae85, 0x0801c804 ], [ 0x0, 0x00010080, 0x000380a7 ], [ 0x0, 0x08212081, 0x000180a7 ], [ 0x8, 0xc0028004, 0x10000000 ] ] ],
+ [ 0x344, 0x3fc, [ [ 0x9, 0xa0000008, 0x1221c844 ], [ 0x1, 0x8001c409, 0x00040008 ], [ 0x0, 0x00028081, 0xa84380c7 ], [ 0x0, 0x20062f89, 0x4c018004 ] ] ],
+ [ 0x364, 0x3fc, [ [ 0x0, 0x00010000, 0x00000000 ], [ 0x0, 0x00010000, 0x00000000 ], [ 0x0, 0x00010000, 0x00000000 ], [ 0x8, 0xc3020064, 0x10000080 ] ] ],
+ [ 0x348, 0x3fc, [ [ 0x9, 0xa00200d9, 0x10000801 ], [ 0x8, 0xb0024088, 0x90000083 ], [ 0x0, 0x80068000, 0x0003c824 ], [ 0x9, 0x30024088, 0x92004801 ] ] ],
+ [ 0x368, 0x3fc, [ [ 0x9, 0xa00a0008, 0x12002080 ], [ 0x0, 0x10210001, 0x00410004 ], [ 0x8, 0xc0028084, 0x90200083 ], [ 0x0, 0x88228001, 0x02001800 ] ] ],
+ [ 0x34c, 0x3fc, [ [ 0x0, 0x00010080, 0x00000083 ], [ 0x0, 0x88268001, 0x00004c2c ], [ 0x0, 0x80028000, 0x02002080 ], [ 0x0, 0x90228001, 0x02201080 ] ] ],
+ [ 0x36c, 0x3fc, [ [ 0x0, 0x88228001, 0x02002800 ], [ 0x0, 0x80028008, 0x0a005000 ], [ 0x9, 0xa00a0008, 0x52002800 ], [ 0x0, 0x40112082, 0x000384a7 ] ] ],
+ [ 0x380, 0x3f8, [ [ 0x8, 0xc0018004, 0x10010004 ], [ 0x1, 0x88a0e201, 0x00018004 ], [ 0x1, 0x88a0e00b, 0x08018004 ], [ 0xc, 0x000e8000, 0x488181c6 ] ] ],
+ [ 0x3a0, 0x3f8, [ [ 0x0, 0x80028601, 0x00200000 ], [ 0x1, 0x8001c380, 0x00000000 ], [ 0x8, 0x40028605, 0x10210005 ], [ 0x4, 0x30066f09, 0x8c018004 ] ] ],
+ [ 0x388, 0x3f8, [ [ 0x1, 0x8080c002, 0x00a18046 ], [ 0x9, 0xa0020088, 0x12004801 ], [ 0x1, 0x888cc002, 0x40a18046 ], [ 0x1, 0xa00ee008, 0x082180c6 ] ] ],
+ [ 0x3a8, 0x3f8, [ [ 0x0, 0x91428521, 0x80200080 ], [ 0x0, 0xa002e008, 0x0821c444 ], [ 0x0, 0x80028000, 0x0003c824 ], [ 0x0, 0xa008e008, 0x0a218844 ] ] ],
+ [ 0x3c0, 0x3f0, [ [ 0x0, 0x00010006, 0x08800082 ], [ 0x0, 0x84428011, 0x00200000 ], [ 0x0, 0x80048401, 0x0001c804 ], [ 0x8, 0xc0028004, 0x10218044 ] ] ],
+ [ 0x3e0, 0x3f0, [ [ 0x0, 0x90228001, 0x00200080 ], [ 0x0, 0x00010000, 0x00000000 ], [ 0x1, 0xa04c0009, 0x00400000 ], [ 0x1, 0xac00c01b, 0x40000600 ] ] ],
+]
+
+# Expand microcode arrays
+microcode_table = []
+for address in range(0, 0x400):
+ mc = 0x00000
+ for j in range(0, len(microcode_base_table)):
+ if (address & microcode_base_table[j][1]) == microcode_base_table[j][0]:
+ mc = microcode_base_table[j][2][address & 15];
+ break
+ microcode_table.append(mc)
+
+nanocode_table = []
+for address in range(0, 0x400):
+ nc = [ 0x0, 0x00010000, 0x00000000]
+ for j in range(0, len(nanocode_base_table)):
+ if (address & nanocode_base_table[j][1]) == nanocode_base_table[j][0]:
+ nc = nanocode_base_table[j][2][address & 3];
+ break
+ nanocode_table.append(nc)
+
+# a1 pal
+
+a1_pal = [
+ [ 0x2b9, 0x0880, 0xff80, 0 ],
+ [ 0x0a9, 0x6100, 0xffff, 0 ],
+ [ 0x089, 0x6100, 0xff00, 0, [-1 ] ],
+ [ 0x068, 0x6000, 0xf0ff, 0, [-2 ] ],
+ [ 0x308, 0x6000, 0xf000, 0, [-3, -2, -1 ] ],
+ [ 0x3e0, 0x0080, 0xf1c0, 0, [-5 ] ],
+ [ 0x3a6, 0x4e70, 0xffff, 0 ],
+ [ 0x341, 0x4840, 0xfff8, 0 ],
+ [ 0x230, 0x4e68, 0xfff8, 0 ],
+ [ 0x3a5, 0x40c0, 0xfff8, 0 ],
+ [ 0x3a2, 0x4e72, 0xffff, 0 ],
+ [ 0x325, 0x48b0, 0xffb8, 0 ],
+ [ 0x3a0, 0x4890, 0xffb8, 0 ],
+ [ 0x1f1, 0x48a8, 0xffb8, 0 ],
+ [ 0x382, 0xe020, 0xf0a0, 0 ],
+ [ 0x386, 0xe0a0, 0xf0e0, 0 ],
+ [ 0x381, 0xe000, 0xf0a0, 0 ],
+ [ 0x385, 0xe080, 0xf0e0, 0 ],
+ [ 0x1ed, 0x48b8, 0xffbf, 0 ],
+ [ 0x1e5, 0x48b9, 0xffbf, 0 ],
+ [ 0x384, 0x50c0, 0xf0f8, 0 ],
+ [ 0x126, 0x4e75, 0xffff, 0 ],
+ [ 0x12a, 0x4e73, 0xfffb, 0 ],
+ [ 0x301, 0x44c0, 0xfdf8, 0 ],
+ [ 0x121, 0x1000, 0xd1f0, 0 ],
+ [ 0x279, 0x3040, 0xf1f0, 0 ],
+ [ 0x129, 0x2000, 0xf1b0, 0 ],
+ [ 0x1c1, 0x9100, 0xb1b8, 0 ],
+ [ 0x1c1, 0x8000, 0xa1b0, 0 ],
+ [ 0x1c9, 0x90c0, 0xb1f0, 0 ],
+ [ 0x1c5, 0x91c0, 0xb1f0, 0 ],
+ [ 0x1c5, 0x9180, 0xb1b8, 0 ],
+ [ 0x1c5, 0x8080, 0xa1f0, 0 ],
+ [ 0x100, 0xb100, 0xf1b8, 0 ],
+ [ 0x10c, 0xb180, 0xf1f8, 0 ],
+ [ 0x1eb, 0x1180, 0xd1f0, 0 ],
+ [ 0x1ef, 0x2180, 0xf1f0, 0 ],
+ [ 0x2fa, 0x1080, 0xd1f0, 0 ],
+ [ 0x2f9, 0x2080, 0xf1f0, 0 ],
+ [ 0x2f8, 0x1100, 0xd1f0, 0 ],
+ [ 0x2fc, 0x2100, 0xf1f0, 0 ],
+ [ 0x2fe, 0x10c0, 0xd1f0, 0 ],
+ [ 0x2fd, 0x20c0, 0xf1f0, 0 ],
+ [ 0x2da, 0x1140, 0xd1f0, 0 ],
+ [ 0x2de, 0x2140, 0xf1f0, 0 ],
+ [ 0x23b, 0x7000, 0xf100, 0 ],
+ [ 0x1cd, 0x8100, 0xb1f8, 0 ],
+ [ 0x2d9, 0x11c0, 0xdff0, 0 ],
+ [ 0x2dd, 0x21c0, 0xfff0, 0 ],
+ [ 0x2d8, 0x5000, 0xf0b8, 0 ],
+ [ 0x2dc, 0x5048, 0xf0f8, 0 ],
+ [ 0x2dc, 0x5080, 0xf0f0, 0 ],
+ [ 0x1ea, 0x13c0, 0xdff0, 0 ],
+ [ 0x1ee, 0x23c0, 0xfff0, 0 ],
+ [ 0x3a4, 0x48a0, 0xffb8, 0 ],
+ [ 0x123, 0x4c98, 0xffb8, 0 ],
+ [ 0x21c, 0x0018, 0x0038, 2 ],
+ [ 0x00f, 0x0018, 0x0038, 1 ],
+ [ 0x1ff, 0x487b, 0xffff, 0 ],
+ [ 0x1ff, 0x4870, 0xfff8, 0 ],
+ [ 0x17d, 0x487a, 0xffff, 0 ],
+ [ 0x17d, 0x4868, 0xfff8, 0 ],
+ [ 0x17c, 0x4850, 0xfff8, 0 ],
+ [ 0x103, 0x0020, 0x0038, 2 ],
+ [ 0x179, 0x0020, 0x0038, 1 ],
+ [ 0x178, 0x4878, 0xffff, 0 ],
+ [ 0x1fa, 0x4879, 0xffff, 0 ],
+ [ 0x119, 0x4e58, 0xfff8, 0 ],
+ [ 0x2b9, 0x0000, 0xf180, 0 ],
+ [ 0x12d, 0x4a00, 0xffb8, 0 ],
+ [ 0x133, 0x4880, 0xfff8, 0 ],
+ [ 0x133, 0x4000, 0xf9b8, 0 ],
+ [ 0x137, 0x4080, 0xf9f8, 0 ],
+ [ 0x13b, 0x4800, 0xfff8, 0 ],
+ [ 0x15b, 0xc0c0, 0xf0f8, 0 ],
+ [ 0x1ca, 0x0188, 0xf1f8, 0 ],
+ [ 0x1ce, 0x01c8, 0xf1f8, 0 ],
+ [ 0x1d2, 0x0108, 0xf1f8, 0 ],
+ [ 0x1d6, 0x0148, 0xf1f8, 0 ],
+ [ 0x2f5, 0x4e60, 0xfff8, 0 ],
+ [ 0x1f9, 0x4cb8, 0xffbf, 0 ],
+ [ 0x1e9, 0x4cb9, 0xffbf, 0 ],
+ [ 0x30b, 0x4e50, 0xfff8, 0 ],
+ [ 0x1fb, 0x41fb, 0xf1ff, 0 ],
+ [ 0x1fb, 0x41f0, 0xf1f8, 0 ],
+ [ 0x2f2, 0x41fa, 0xf1ff, 0 ],
+ [ 0x2f2, 0x41e8, 0xf1f8, 0 ],
+ [ 0x2f1, 0x41d0, 0xf1f8, 0 ],
+ [ 0x1f5, 0x4cbb, 0xffbf, 0 ],
+ [ 0x1f5, 0x4cb0, 0xffb8, 0 ],
+ [ 0x127, 0x4c90, 0xffb8, 0 ],
+ [ 0x1fd, 0x4cba, 0xffbf, 0 ],
+ [ 0x1fd, 0x4ca8, 0xffb8, 0 ],
+ [ 0x275, 0x41f8, 0xf1ff, 0 ],
+ [ 0x3e4, 0x41f9, 0xf1ff, 0 ],
+ [ 0x1f3, 0x4ebb, 0xffff, 0 ],
+ [ 0x1f3, 0x4eb0, 0xfff8, 0 ],
+ [ 0x2b0, 0x4eba, 0xffff, 0 ],
+ [ 0x2b0, 0x4ea8, 0xfff8, 0 ],
+ [ 0x273, 0x4e90, 0xfff8, 0 ],
+ [ 0x293, 0x4eb8, 0xffff, 0 ],
+ [ 0x1f2, 0x4eb9, 0xffff, 0 ],
+ [ 0x1f7, 0x4efb, 0xffff, 0 ],
+ [ 0x1f7, 0x4ef0, 0xfff8, 0 ],
+ [ 0x2b4, 0x4efa, 0xffff, 0 ],
+ [ 0x2b4, 0x4ee8, 0xfff8, 0 ],
+ [ 0x255, 0x4ed0, 0xfff8, 0 ],
+ [ 0x297, 0x4ef8, 0xffff, 0 ],
+ [ 0x1f6, 0x4ef9, 0xffff, 0 ],
+ [ 0x0ea, 0x003c, 0x003f, 2 ],
+ [ 0x0a7, 0x003c, 0x003f, 1 ],
+ [ 0x232, 0x48c0, 0xfff8, 0 ],
+ [ 0x3e3, 0xc188, 0xf1f8, 0 ],
+ [ 0x3e3, 0xc140, 0xf1f0, 0 ],
+ [ 0x0a6, 0x80c0, 0xf1f8, 0 ],
+ [ 0x0ae, 0x81c0, 0xf1f8, 0 ],
+ [ 0x06c, 0x50c8, 0xf0f8, 0 ],
+ [ 0x1d1, 0xb000, 0xf1b0, 0 ],
+ [ 0x1d9, 0xb0c0, 0xf1f0, 0 ],
+ [ 0x1d5, 0xb1c0, 0xf1f0, 0 ],
+ [ 0x1d5, 0xb080, 0xf1f0, 0 ],
+ [ 0x06f, 0xb188, 0xf1f8, 0 ],
+ [ 0x06b, 0xb108, 0xf1b8, 0 ],
+ [ 0x152, 0x4180, 0xf1f8, 0 ],
+ [ 0x3e7, 0x0100, 0xf1f8, 0 ],
+ [ 0x125, 0x4a80, 0xfff8, 0 ],
+ [ 0x3ef, 0x0140, 0xf178, 0 ],
+ [ 0x3eb, 0x0180, 0xf1f8, 0 ],
+ [ 0x06d, 0x4e76, 0xffff, 0 ],
+ [ 0x1d0, 0x4e40, 0xfff0, 0 ],
+ [ 0x345, 0x4ac0, 0xfff8, 0 ],
+ [ 0x363, 0x4e71, 0xffff, 0 ],
+ [ 0x10f, 0x9108, 0xb1b8, 0 ],
+ [ 0x10b, 0x9188, 0xb1f8, 0 ],
+ [ 0x107, 0x8108, 0xb1f8, 0 ],
+ [ 0x1e3, 0x003b, 0x003f, 2 ],
+ [ 0x1e3, 0x0030, 0x0038, 2 ],
+ [ 0x1e7, 0x003b, 0x003f, 1 ],
+ [ 0x1e7, 0x0030, 0x0038, 1 ],
+ [ 0x1c2, 0x003a, 0x003f, 2 ],
+ [ 0x1c2, 0x0028, 0x0038, 2 ],
+ [ 0x1c6, 0x003a, 0x003f, 1 ],
+ [ 0x1c6, 0x0028, 0x0038, 1 ],
+ [ 0x006, 0x0010, 0x0038, 2 ],
+ [ 0x00b, 0x0010, 0x0038, 1 ],
+ [ 0x00a, 0x0038, 0x003f, 2 ],
+ [ 0x00e, 0x0038, 0x003f, 1 ],
+ [ 0x1e2, 0x0039, 0x003f, 2 ],
+ [ 0x1e6, 0x0039, 0x003f, 1 ]
+]
+
+a1_pal_long = [
+ [ 0x9180, 0x9180 ], [ 0x9080, 0x90c0 ], [ 0x8080, 0xa0c0 ], [ 0x5080, 0xf0c0 ],
+ [ 0x4a80, 0xffc0 ], [ 0x4080, 0xf9c0 ], [ 0x2000, 0xf000 ]
+]
+
+a1_pal_byte_short = [
+ [ 0xe0c0, 0xf8c0 ], [ 0x5040, 0xf040 ], [ 0x5000, 0xf080 ], [ 0x9040, 0x9140 ],
+ [ 0x9000, 0x9080 ], [ 0x8040, 0xb040 ], [ 0x8000, 0xb080 ], [ 0x4a40, 0xff40 ],
+ [ 0x4040, 0xf940 ], [ 0x4000, 0xf1c0 ], [ 0x4180, 0xf1c0 ], [ 0x1000, 0xd000 ],
+ [ 0x0100, 0xf100 ]
+]
+
+def simple_pal_test(ir, pal):
+ for i in range(0, len(pal)):
+ if (ir & pal[i][1]) == pal[i][0]:
+ return True
+ return False
+
+def a1_pal_test(ir, line, a1pl, a1psw):
+ if (ir & a1_pal[line][2]) != a1_pal[line][1]:
+ return False
+ if a1_pal[line][3] == 1 and not a1pl:
+ return False
+ if a1_pal[line][3] == 2 and not a1psw:
+ return False
+ if len(a1_pal[line]) > 4:
+ for i in range(0, len(a1_pal[line][4])):
+ if a1_pal_test(ir, line + a1_pal[line][4][i], a1pl, a1psw):
+ return False
+ return True
+
+def a1_pal_apply(ir):
+ a1pl = simple_pal_test(ir, a1_pal_long)
+ a1psw = simple_pal_test(ir, a1_pal_byte_short)
+ for i in range(0, len(a1_pal)):
+ if a1_pal_test(ir, i, a1pl, a1psw):
+ return a1_pal[i][0]
+ return 0x3ff
+
+# a2/3 pal
+
+a23_pal = [
+ [ 0x15b, 0x15a, 0xc0c0, 0xf0c0, 0 ],
+ [ 0x1d9, 0x1cf, 0xb0c0, 0xf1c0, 0 ],
+ [ 0x1d1, 0x1d3, 0xb000, 0xf180, 0 ],
+ [ 0x1d5, 0x1d7, 0xb1c0, 0xf1c0, 0 ],
+ [ 0x2f8, 0x38b, 0x1100, 0xd1c0, 0 ],
+ [ 0x0ae, 0x0ac, 0x81c0, 0xf1c0, 0 ],
+ [ 0x0a6, 0x0a4, 0x80c0, 0xf1c0, 0 ],
+ [ 0x1c5, 0x1cb, 0x91c0, 0xb1c0, 0 ],
+ [ 0x2fe, 0x3af, 0x10c0, 0xd1c0, 0 ],
+ [ 0x1c9, 0x1c7, 0x90c0, 0xb1c0, 0 ],
+ [ 0x1c1, 0x1c3, 0x8000, 0xa180, 0 ],
+ [ 0x3ff, 0x380, 0x50c0, 0xf0c0, 0 ],
+ [ 0x3ff, 0x2f7, 0x5080, 0xf0c0, 0 ],
+ [ 0x3ff, 0x2f3, 0x5000, 0xf080, 0 ],
+ [ 0x152, 0x151, 0x4180, 0xf1c0, 0 ],
+ [ 0x3ff, 0x343, 0x4ac0, 0xffc0, 0 ],
+ [ 0x3ff, 0x29d, 0x8180, 0x81c0, 0 ],
+ [ 0x3ff, 0x3c3, 0x4a00, 0xff80, 0 ],
+ [ 0x3ff, 0x15c, 0x4800, 0xffc0, 0 ],
+ [ 0x301, 0x159, 0x44c0, 0xfdc0, 0 ],
+ [ 0x3ff, 0x3a1, 0x40c0, 0xffc0, 0 ],
+ [ 0x1ea, 0x32b, 0x13c0, 0xdfc0, 0 ],
+ [ 0x3ff, 0x2b8, 0x4000, 0xf980, 0 ],
+ [ 0x1ee, 0x30f, 0x23c0, 0xffc0, 0 ],
+ [ 0x2dd, 0x38c, 0x21c0, 0xffc0, 0 ],
+ [ 0x1ef, 0x29c, 0x2180, 0xf1c0, 0 ],
+ [ 0x2de, 0x38e, 0x2140, 0xf1c0, 0 ],
+ [ 0x2fc, 0x38f, 0x2100, 0xf1c0, 0 ],
+ [ 0x2fd, 0x3ad, 0x20c0, 0xf1c0, 0 ],
+ [ 0x121, 0x29b, 0x1000, 0xd1c0, 0 ],
+ [ 0x129, 0x29f, 0x2000, 0xf180, 0 ],
+ [ 0x279, 0x158, 0x3040, 0xf1c0, 0 ],
+ [ 0x2d9, 0x388, 0x11c0, 0xdfc0, 0 ],
+ [ 0x1eb, 0x298, 0x1180, 0xd1c0, 0 ],
+ [ 0x2da, 0x38a, 0x1140, 0xd1c0, 0 ],
+ [ 0x1d5, 0x1d7, 0xb000, 0xf000, 2 ],
+ [ 0x1c5, 0x1cb, 0x8000, 0xa000, 2 ],
+ [ 0x2fa, 0x3ab, 0x1000, 0xd000, 2 ],
+ [ 0x3ff, 0x2bc, 0x4000, 0xf800, 2 ],
+ [ 0x2f9, 0x3a9, 0x2000, 0xf000, 2 ],
+ [ 0x3ff, 0x3cb, 0x4a00, 0xfe00, 2 ],
+ [ 0x3ff, 0x29d, 0x0000, 0x0000, 3, [ 2, 3 ] ],
+ [ 0x3ff, 0x069, 0x0180, 0x01c0, 1 ],
+ [ 0x3ff, 0x08f, 0x0c00, 0x0e00, 3 ],
+ [ 0x3ff, 0x069, 0x0800, 0x0e00, 3 ],
+ [ 0x3ff, 0x3c7, 0xe0c0, 0xf8c0, 0 ],
+ [ 0x3ff, 0x299, 0x8100, 0x8180, 0 ],
+ [ 0x3ff, 0x299, 0x0000, 0x0180, 1, [ 1, 3, 4 ] ],
+ [ 0x3ff, 0x087, 0x0c00, 0x0f80, 1 ],
+ [ 0x3ff, 0x081, 0x0140, 0x0140, 1 ],
+ [ 0x3ff, 0x081, 0x0840, 0x0f40, 1 ],
+ [ 0x3ff, 0x215, 0x0800, 0x0fc0, 1 ],
+ [ 0x0ab, 0x215, 0x0100, 0x01c0, 1 ],
+ [ 0x104, 0x3ff, 0x0c00, 0x0e38, 3 ],
+ [ 0x10c, 0x3ff, 0x0000, 0x0038, 3, [ -1, 1 ] ],
+ [ 0x3eb, 0x3ff, 0x0800, 0x0e38, 3 ],
+ [ 0x1cc, 0x3ff, 0x003c, 0x01bf, 1 ],
+ [ 0x100, 0x3ff, 0x0000, 0x01b8, 1, [ 1, 2, 3 ] ],
+ [ 0x3ef, 0x3ff, 0x0840, 0x0f78, 1 ],
+ [ 0x3e7, 0x3ff, 0x0800, 0x0ff8, 1 ],
+ [ 0x108, 0x3ff, 0x0c00, 0x0fb8, 1 ],
+ [ 0x1e2, 0x3ff, 0x0039, 0x013f, 1, [ 1 ] ],
+ [ 0x1e6, 0x3ff, 0x0039, 0x003f, 3, [ 14 ] ],
+ [ 0x00a, 0x3ff, 0x0038, 0x013f, 1, [ 1 ] ],
+ [ 0x00e, 0x3ff, 0x0038, 0x003f, 3, [ 12 ] ],
+ [ 0x1e3, 0x3ff, 0x0030, 0x0138, 1, [ 2 ] ],
+ [ 0x1e3, 0x3ff, 0x083b, 0x0fff, 1 ],
+ [ 0x1e7, 0x3ff, 0x0030, 0x0038, 3, [ 9 ] ],
+ [ 0x1c2, 0x3ff, 0x0028, 0x0138, 1, [ 2 ] ],
+ [ 0x1c2, 0x3ff, 0x083a, 0x0fff, 1 ],
+ [ 0x1c6, 0x3ff, 0x0028, 0x0038, 3, [ 6 ] ],
+ [ 0x103, 0x3ff, 0x0020, 0x0138, 1, [ 1 ] ],
+ [ 0x179, 0x3ff, 0x0020, 0x0038, 3, [ 4 ] ],
+ [ 0x21c, 0x3ff, 0x0018, 0x0138, 1, [ 1 ] ],
+ [ 0x00f, 0x3ff, 0x0018, 0x0038, 3, [ 2 ] ],
+ [ 0x006, 0x3ff, 0x0010, 0x0138, 1, [ 2 ] ],
+ [ 0x3ff, 0x3ff, 0x0800, 0x0e00, 3 ],
+ [ 0x00b, 0x3ff, 0x0010, 0x0038, 3, [ -1 ] ]
+]
+
+a23_pal_sub_1 = [ [ 0x0000, 0xf000 ] ]
+
+a23_pal_sub_2 = [ [ 0x0080, 0x01c0 ], [ 0x0000, 0x0000, [ -1 ] ] ]
+
+def a23_pal_test(ir, line, a23p1, a23p2):
+ if (ir & a23_pal[line][3]) != a23_pal[line][2]:
+ return False
+ if (a23_pal[line][4] & 1) != 0 and not a23p1:
+ return False
+ if (a23_pal[line][4] & 2) != 0 and not a23p2:
+ return False
+ if len(a23_pal[line]) > 5:
+ for i in range(0, len(a23_pal[line][5])):
+ if a23_pal_test(ir, line + a23_pal[line][5][i], a23p1, a23p2):
+ return False
+ return True
+
+def a23_pal_apply(ir):
+ a23p1 = (ir & a23_pal_sub_1[0][1]) == a23_pal_sub_1[0][0]
+ a23p2 = (ir & a23_pal_sub_2[0][1]) == a23_pal_sub_2[0][0]
+ r1 = 0x3ff
+ r2 = 0x3ff
+ for i in range(0, len(a23_pal)):
+ if a23_pal_test(ir, i, a23p1, a23p2):
+ r1 = r1 & a23_pal[i][0]
+ r2 = r2 & a23_pal[i][1]
+ return r1, r2
+
+# 1.111..1........
+# .1...11.11......
+
+# 1.11...11...11.1
+# .1..111..111....
+
+# 1.11...11...11..
+# .1..111..111..1.
+
+# 1111.1.11.....11
+# .........11111..
+
+# 1.11...11..1....
+# .1..111..11.....
+
+priv_pal = [ [ 0x46c0, 0xffc0 ], [ 0x4e70, 0xfffd ], [ 0x4e72, 0xfffe ], [ 0x007c, 0xf5ff ], [ 0x4e60, 0xfff0 ] ]
+
+def priv_test(ir):
+ return simple_pal_test(ir, priv_pal)
+
+
+# Condition codes
+cbc_names = [
+ "i11", "auz", "c", "z", "nz1", "n", "nz2", "ms0",
+ "m01", "cc", "ze", "nv", "d4", "v", "enl", "?0f",
+ "?10", "auz'", "c'", "?13", "?14", "n'", "?16", "?17",
+ "?18", "cc'", "?1a", "?1b", "d4'", "?1d", "enl'", "?1f"
+]
+
+cbc_slots = [
+ [ 0, 3 ], [ 3, 1 ], [ 1, 0 ], [ 0, 3 ], [ 2, 1, 3 ], [ 1, 3 ], [ 3, 1 ], [ 3, 1, 2 ],
+ [ 0, 1, 2, 3 ], [ 1, 3 ], [ 3, 0 ], [ 3, 0 ], [ 3, 1 ], [ 3, 0 ], [ 2, 3, 0], [],
+ [], [ 3, 0 ], [ 3, 2 ], [], [], [ 2, 3 ], [], [],
+ [], [ 2, 3 ], [], [], [ 3, 2 ], [], [ 2, 3, 1 ], []
+]
+
+class CBC(IntEnum):
+ i11 = 0x00
+ auz = 0x01
+ c = 0x02
+ z = 0x03
+ nz1 = 0x04
+ n = 0x05
+ nz2 = 0x06
+ ms0 = 0x07
+ m01 = 0x08
+ cc = 0x09
+ ze = 0x0a
+ nv = 0x0b
+ d4 = 0x0c
+ v = 0x0d
+ enl = 0x0e
+ auzi = 0x11
+ ci = 0x12
+ ni = 0x15
+ cci = 0x19
+ d4i = 0x1c
+ enli = 0x1e
+
+
+# Instruction names
+
+microcode_instruction_names = [
+ "rstp1", "halt1", "rstp3", "bser1", "abll3", "adrl2", "adrw1", "dbcc5", "ablw3", "abll2", "abwl1", "adrl1", "adsl2", "ablw2", "abww1", "pinl1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "mulm6", "ldmx3", "trpv3", "dvum3", "adrw2", "mmrw2", "adsl3", "ldmx1", "mmxw2", "jsrx2", "adsw2", "ldmx2", "mmxl2", "jmpx2", "ldmx5", "stmx3",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "asbb5", "dvs16", "dvs07", "push3", "btsr3", "bbci2", "dbcc2", "asxl6", "asxl2", "dvs20", "asxw4", "smaw3", "asxl5", "dvs17", "asbb4", "sccb3",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "mulm3", "asxl7", "asxl8", "dvs05", "rset5", "asxw5", "leaa2", "bclm2", "bbcw1", "bclm1", "bcsr2", "cmmw1", "dbcc1", "trpv1", "bclr2", "cmml1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "dvumf", "bcsm1", "bcsm2", "push5", "bcsr3", "bbcw3", "cmmw2", "cpdw1", "bser6", "bsri1", "dvs1f", "roaw2", "bclr3", "rcal3", "cmml2", "cpdl1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "mulm5", "bcsr5", "bser4", "dvs04", "dvum1", "stmr5", "dvur1", "e#l1", "bsri3", "bsrw1", "bsrw3", "btsi1", "dvs01", "stmr6", "dvs02", "lmal2",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "dvumd", "dvs1d", "dvs10", "push4", "bcsr4", "bbci3", "dbcc6", "dbcc4", "bclr5", "dvs03", "dvs1e", "sccr2", "bclr4", "dvs1a", "dvs1b", "sccb2",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "mulm4", "ldmx4", "trpv2", "dvur2", "rset3", "stmr4", "dvuma", "btsr2", "mmxw3", "jsrx3", "e#w1", "itlx4", "mmxl3", "jmpx3", "lmal3", "trap5",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "roaw1", "mmxw1", "bsri2", "pdcw1", "rcal1", "rmxl1", "peax6", "asbb1", "rcaw1", "rmxw1", "paaw2", "asxl1", "roal1", "mmxl1", "bsrw2", "asxw1",
+ "chkr3", "ldmr2", "smal2", "asbb6", "rset4", "popm2", "rts2", "nbcr2", "itlx6", "unlk1", "trap7", "rbrb2", "trap9", "zzz00", "rstpa", "zzz01",
+ "aixl2", "rrgw1", "cmmw3", "popm1", "aixw2", "tsrl1", "rts1", "ldmr1", "rmxw2", "rrgl1", "rtr1", "rtr2", "rmxl2", "tsrw1", "cmml4", "zzz02",
+ "leax2", "asxw2", "asxw3", "nnrw1", "peax2", "asbb2", "asbb3", "nnrl1", "stmx4", "asxl3", "asxl4", "nbcr1", "zzz03", "zzz04", "zzz05", "zzz06",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "chkr4", "chkm1", "chkr1", "chkr2", "cmml3", "cmml5", "cmml6", "cmml7", "mrgm1", "mstw1", "mulm1", "mulr1", "nbcm1", "nnml2", "nnrl2", "paal2",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "cmmw4", "cpdl2", "cpml2", "cprl2", "cprm2", "dbcc3", "dvs06", "dvs11", "paaw1", "pdcl1", "pdcl2", "pdcw2", "peaa1", "pead1", "pead2", "pead3",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "trac1", "rorw1", "adsw1", "romw1", "itlx1", "rorl1", "adsl1", "romm1", "rstp2", "rorm1", "mpow1", "roml1", "stiw1", "rbrb1", "mpol1", "cpmm1",
+ "trap1", "cprw1", "mpiw1", "cpmw1", "zzz08", "cprl1", "mpil1", "cpml1", "zzz09", "cprm1", "zzz0a", "zzz0b", "zzz0c", "zzz0d", "zzz0e", "zzz0f",
+ "aixl5", "malw3", "abll1", "aixl0", "aixw4", "smal1", "ablw1", "aixw0", "rmxw3", "lmal1", "ralw1", "rmxw0", "rmxl3", "smaw1", "rall1", "rmxl0",
+ "leax3", "stmd1", "jsal1", "jsrx0", "peax3", "ldmx0", "jmal1", "jmpx0", "stmx5", "lmaw1", "paal1", "leax0", "zzz10", "ldmd1", "unlk2", "peax0",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "dvs14", "dvs15", "dvum0", "dvum2", "dvs12", "btsm1", "dvs08", "dvur3", "peax4", "peax5", "pinl2", "pinl3", "pinw1", "pinw2", "push2", "push5",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "susp1", "exge2", "extr1", "extr2", "itlx2", "itlx3", "itlx5", "ldmd4", "rbrb3", "rcal2", "rcaw2", "rlql1", "rmil2", "rmil3", "rmml2", "rmrl2",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "dvum9", "dvs1c", "dvum8", "nbcr3", "dvs13", "jmpa1", "jsal2", "srrl4", "rmrl3", "roal2", "roal3", "roal4", "roml2", "roml3", "rorl3", "rorm3",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "jsaw1", "jsaw2", "jsaw3", "jsra1", "jsrd2", "laaw1", "ldmd3", "ldmx6", "rrgl2", "rrgm1", "rrgw2", "rset2", "unlk3", "unlk4", "rstp5", "rstp6",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "dvume", "dvum5", "itlx7", "jsaw0", "dvs0f", "dvs09", "rstp4", "jmaw1", "mmxw0", "morw1", "mpiw2", "mrgw1", "mmxl0", "morl1", "mpil2", "mrgl1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "jsrd1", "jsrd3", "jsrx1", "jmal2", "jmpd1", "link2", "jmpx1", "trap8", "nnmw1", "o#w1", "rall3", "ralw2", "nnml1", "laal2", "rmdl2", "rall2",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "dvum6", "dvum4", "dvum7", "srrw3", "dvs0a", "dvumz", "dvs0c", "srrl3", "raqw1", "raww1", "rmdw1", "rmdw2", "raql1", "rawl1", "rmdl1", "rmdl3",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "ldmr5", "leaa1", "lead1", "maqw1", "popm5", "lusp1", "ldmd2", "maql1", "rmmw1", "rmrl1", "rmrw1", "rstp7", "rmml1", "rmil1", "rmiw1", "rstp8",
+ "rstp9", "rstw1", "rtr4", "rts3", "stmw2", "smal3", "srrl5", "stiw2", "bbci1", "lead2", "leax4", "link1", "link3", "link4", "lmaw2", "mall1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "stiw3", "stiw4", "stmd3", "stmr2", "sftm2", "stmx1", "stmx2", "aaa01", "mmaw2", "mall2", "mall3", "malw1", "popm6", "dvs0e", "malw2", "mawl2",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "strw2", "swap1", "swap2", "tasm1", "tasm2", "tasr1", "tasr2", "trap2", "mawl3", "mmiw2", "mmml2", "mmmw2", "mmrw3", "morl2", "mpil3", "mpil4",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "trap4", "tsml2", "tsrl2", "b", "zzz11", "zzz12", "zzz13", "trap6", "mpiw3", "dvumc", "mpiw4", "mpol2", "mpol3", "mpow2", "mpow3", "mrgl2",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "sccb1", "srrw1", "sriw1", "srrw2", "sccr1", "srrl1", "sril1", "srrl2", "maww1", "maww2", "mmdw1", "mmmw1", "mawl1", "morw2", "mmdl1", "mmml1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "stmr1", "stmw1", "stop1", "trac2", "push1", "strw1", "rset1", "bser2", "ldmr4", "mmrl1", "mmrl2", "mmrw1", "popm4", "mmil1", "mmil2", "mmiw1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "rorl2", "smaw2", "trap3", "tsmw1", "mulm2", "rtr3", "bser5", "sftm1", "rorm2", "stmd2", "bser3", "tsml1", "zzz14", "zzz15", "zzz16", "zzz17",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
+ "o#l1", "zzz18", "aixl1", "exge1", "laal1", "zzz19", "aixw1", "btsr1", "ldmr3", "dvumb", "leax1", "bclr1", "popm3", "dvs0d", "peax1", "bcsr1",
+ "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"
+]
+
+
+# Register list and dependencies masks
+
+class R(IntEnum):
+ axl = auto()
+ dxl = auto()
+ ayl = auto()
+ dyl = auto()
+ rzl = auto()
+ a7l = auto()
+ sspl = auto()
+ uspl = auto()
+ dtl = auto()
+ aul = auto()
+ atl = auto()
+ pcl = auto()
+ aobl = auto()
+ moveml = auto()
+
+ axh = auto()
+ dxh = auto()
+ ayh = auto()
+ dyh = auto()
+ rzh = auto()
+ a7h = auto()
+ ssph = auto()
+ usph = auto()
+ dth = auto()
+ auh = auto()
+ ath = auto()
+ pch = auto()
+ aobh = auto()
+ movemh = auto()
+
+ alue = auto()
+ alub = auto()
+ dbin = auto()
+ dbout = auto()
+ aluo = auto()
+ dcr = auto()
+ dcro = auto()
+ dcro8 = auto()
+ ftu = auto()
+ ir = auto()
+ irc = auto()
+ ird = auto()
+ edb = auto()
+ sr = auto()
+ movemr = auto()
+
+class DEP(IntEnum):
+ dregl = 0x000001
+ dregh = 0x000002
+ aregl = 0x000004
+ aregh = 0x000008
+ irc = 0x000010
+ dt = 0x000020
+ au = 0x000040
+ atl = 0x000080
+ ath = 0x000100
+ pc = 0x000200
+ aob = 0x000400
+ alue = 0x000800
+ alub = 0x001000
+ dbin = 0x002000
+ aluo = 0x004000
+ dcr = 0x008000
+ ftu = 0x010000
+ ir = 0x020000
+ ird = 0x040000
+ sr = 0x080000
+
+regname = [
+ None,
+ "m_da[rx]", "m_da[rx]", "m_da[ry]", "m_da[ry]", "m_da[map_sp(m_irc >> 12)]", "m_da[m_sp]", "m_da[16]", "m_da[15]", "m_dt", "m_au", "m_at", "m_pc", "m_aob", "m_da[m_movems]",
+ "m_da[rx]", "m_da[rx]", "m_da[ry]", "m_da[ry]", "m_da[map_sp(m_irc >> 12)]", "m_da[m_sp]", "m_da[16]", "m_da[15]", "m_dt", "m_au", "m_at", "m_pc", "m_aob", "m_da[m_movems]",
+ "m_alue", "m_alub", "m_dbin", "m_dbout", "m_aluo", "m_dcr", "m_dcro", "m_dcro8", "m_ftu", "m_ir", "m_irc", "m_ird", "m_edb", "m_sr", "m_movemr"
+ ]
+
+regdep = [
+ None,
+ DEP.aregl, DEP.dregl, DEP.aregl, DEP.dregl, DEP.aregl|DEP.dregl|DEP.irc, DEP.aregl, DEP.aregl, DEP.aregl, DEP.dt, DEP.au, DEP.atl, DEP.pc, DEP.aob, DEP.aregl|DEP.dregl,
+ DEP.aregh, DEP.dregh, DEP.aregh, DEP.dregh, DEP.aregh|DEP.dregh|DEP.irc, DEP.aregh, DEP.aregh, DEP.aregh, DEP.dt, DEP.au, DEP.ath, DEP.pc, DEP.aob, DEP.aregh|DEP.dregh,
+ DEP.alue, DEP.alub, DEP.dbin, 0, DEP.aluo, DEP.dcr, DEP.dcr, DEP.dcr, DEP.ftu, DEP.ir, DEP.irc, DEP.ird, 0, DEP.sr, 0
+ ]
+
+def reg_mergeable(rh, rl):
+ return rh != None and rl != None and rl <= R.moveml and rh <= R.movemh and rl + (R.axh - R.axl) == rh
+
+def maybe_merge(rh, rl):
+ if type(rh) == list and rh[0] == "ext32h" and rh[1] == rl:
+ return ["ext32", rl]
+ if reg_mergeable(rh, rl):
+ return rl
+ return ["merge", rh, rl]
+
+def reg_high16(rh):
+ return rh > R.moveml and rh <= R.movemh
+
+
+# ALU operations and decode table
+
+class ALU(IntEnum):
+ none = 0
+ and_ = auto()
+ sub = auto()
+ subx = auto()
+ add = auto()
+ ext = auto()
+ sbcd = auto()
+ not_ = auto()
+ or_ = auto()
+ eor = auto()
+ subc = auto()
+ addc = auto()
+ addx = auto()
+ asl = auto()
+ asr = auto()
+ lsl = auto()
+ lsr = auto()
+ rol = auto()
+ ror = auto()
+ roxl = auto()
+ roxr = auto()
+ sla0 = auto()
+ sla1 = auto()
+ abcd = auto()
+ over = auto()
+
+alu_single_param = [ False, False, False, False, False, True, False, True, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, False, True ]
+
+alu_ops = [
+ ALU.none, ALU.and_, ALU.none, ALU.none, ALU.none, ALU.ext, ALU.none, ALU.none, # 0
+ ALU.none, ALU.and_, ALU.sub, ALU.subc, ALU.sla0, ALU.over, ALU.sla1, ALU.none, # 1
+ ALU.none, ALU.and_, ALU.add, ALU.addc, ALU.asr, ALU.ext, ALU.none, ALU.none, # 2
+ ALU.none, ALU.and_, ALU.abcd, ALU.add, ALU.asl, ALU.ext, ALU.none, ALU.none, # 3
+ ALU.and_, ALU.and_, ALU.and_, ALU.and_, ALU.lsl, ALU.ext, ALU.and_, ALU.and_, # 4
+ ALU.none, ALU.and_, ALU.sub, ALU.subc, ALU.lsr, ALU.ext, ALU.none, ALU.none, # 5
+ ALU.none, ALU.and_, ALU.sub, ALU.subc, ALU.lsr, ALU.ext, ALU.none, ALU.none, # 6
+ ALU.none, ALU.and_, ALU.sub, ALU.add, ALU.roxr, ALU.ext, ALU.none, ALU.none, # 7
+ ALU.none, ALU.and_, ALU.ext, ALU.and_, ALU.roxr, ALU.ext, ALU.none, ALU.none, # 8
+ ALU.none, ALU.and_, ALU.sbcd, ALU.sbcd, ALU.rol, ALU.ext, ALU.none, ALU.none, # 9
+ ALU.none, ALU.and_, ALU.subx, ALU.subc, ALU.ror, ALU.ext, ALU.none, ALU.none, # 10
+ ALU.none, ALU.and_, ALU.not_, ALU.not_, ALU.roxl, ALU.ext, ALU.none, ALU.none, # 11
+ ALU.addx, ALU.and_, ALU.addx, ALU.addx, ALU.addx, ALU.ext, ALU.addx, ALU.addx, # 12
+ ALU.eor, ALU.and_, ALU.eor, ALU.eor, ALU.eor, ALU.ext, ALU.eor, ALU.eor, # 13
+ ALU.or_, ALU.and_, ALU.or_, ALU.or_, ALU.eor, ALU.ext, ALU.or_, ALU.or_, # 14
+ ALU.or_, ALU.and_, ALU.or_, ALU.add, ALU.or_, ALU.ext, ALU.or_, ALU.or_ # 15
+ ]
+
+alu_masks = [
+ [
+ 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00,
+ 0x00, 0x0f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 0x0f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 0x0f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x1f, 0x1f, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x1f, 0x1f, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 0x0f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ ],
+ [
+ 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00,
+ 0x00, 0x0c, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x0f, 0x0f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x0f, 0x0f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x1f, 0x1f, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x1f, 0x1f, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x0f, 0x0f, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ]
+ ]
+
+alu_opnames = [
+ "none", "and", "sub", "subx", "add", "ext", "sbcd", "not", "or", "eor", "subc", "addc", "addx", "asl", "asr", "lsl", "lsr", "rol", "ror", "roxl", "roxr", "sla0", "sla1", "abcd", "over"
+ ]
+
+class ALUInfo(IntEnum):
+ is_byte = 0x0001
+ is_long = 0x0002
+ is_mul = 0x0004
+ is_div = 0x0008
+ is_rox_and = 0x0010
+ init = 0x0020
+ finish = 0x0040
+ mul_signed = 0x0080
+ arx = 0x0100
+
+# Handler generation modes
+
+class GEN(IntEnum):
+ direct = 0x0001
+ full = 0x0002
+ mcu = 0x0004
+ m68008 = 0x0008
+
+# Load the instruction list
+
+instructions = []
+for instr in open(sys.argv[2], "r"):
+ r = instr.strip().split()
+ instructions.append([int(r[0], base=16), int(r[1], base=16), r[2:]])
+
+# Extract bits from nanocode
+
+def nanox(nano, start, count=1):
+ res = 0
+ for i in range(0, count):
+ bit = start + i
+ base = nano[0] if bit >= 64 else nano[1] if bit >= 32 else nano[2]
+ if base & (1 << (bit & 31)):
+ res = res | (1 << i)
+ return res
+
+
+# Create the graph of forward links from the microcode addresses (a1=a0 for special states)
+
+def generate_forward_graph(a1, a2, a3, ir, irmask):
+ seen = []
+ tosee = [a1]
+ graph = []
+ success = False
+ while len(tosee) != 0:
+ madr = tosee[0]
+ tosee = tosee[1:]
+ if madr in seen:
+ continue
+ seen.append(madr)
+ frame = [madr, None]
+ micro = microcode_table[madr]
+ nmadr = ((micro >> 5) & 0x300) | ((micro << 1) & 0x0c0) | ((micro >> 5) & 0x03c) | ((micro >> 11) & 0x003)
+ if (micro & 0x00002) != 0:
+ # conditional
+ cond_id = (micro >> 2) & 0x1f
+ frame[-1] = cond_id
+ next_base = nmadr & 0x33f
+
+ # Special handling of conditions where some of the bits
+ # come from ird. We pre-solve them.
+ # enl/enl' (movem register list test): ird gives move as word or long, other with is whether list is empty
+ # ms0 (multiply start): ird gives signed/unsigned, other is bit 0 of alue
+ # m01 (multiply cont): decides whethez to stop, add, sub the multiplier, or go the next bit, depending on ird, au and alue. sub is not a possible case for mulu
+
+ if cond_id == CBC.enl or cond_id == CBC.enli:
+ frame.append(next_base | (cbc_slots[cond_id][1 if ir & 0x0040 else 0] << 6))
+ frame.append(next_base | (cbc_slots[cond_id][2] << 6))
+ elif cond_id == CBC.ms0:
+ frame.append(next_base | (cbc_slots[cond_id][0] << 6))
+ frame.append(next_base | (cbc_slots[cond_id][2 if ir & 0x0100 else 1] << 6))
+ elif cond_id == CBC.m01 and not (ir & 0x100):
+ frame.append(next_base | (cbc_slots[cond_id][0] << 6))
+ frame.append(next_base | (cbc_slots[cond_id][1] << 6))
+ frame.append(next_base | (cbc_slots[cond_id][3] << 6))
+ else:
+ for i in range(0, len(cbc_slots[cond_id])):
+ frame.append(next_base | (cbc_slots[cond_id][i] << 6))
+
+ elif (micro & 0x0000c) != 0:
+ # a1/a2/a3
+ aslot = (micro >> 2) & 3
+ if aslot == 1:
+ success = True
+ if aslot == 2:
+ frame.append(a2)
+ elif aslot == 3:
+ frame.append(a3)
+
+ else:
+ frame.append(nmadr)
+ graph.append(frame)
+ for a in frame[2:]:
+ tosee.append(a)
+ return graph, success
+
+
+# Compute the dependencies masks from a code line
+
+def code_find_deps(ci):
+ def expr_deps(ci):
+ if type(ci) != list:
+ if ci == None or ci == "ftu-i" or ci == "trap-tvn" or ci == "int-tvn":
+ return 0
+ if ci == "ftu-ssw":
+ return DEP.ftu
+ return regdep[ci]
+ elif ci[0] == "+c" or ci[0] == "+1/2" or ci[0] == "-1/2" or ci[0] == "ext32" or ci[0] == "ext32h":
+ return expr_deps(ci[1])
+ elif ci[0] == "+r" or ci[0] == "merge":
+ return expr_deps(ci[1]) | expr_deps(ci[2])
+ elif ci[0] == 'c':
+ return 0
+ elif len(ci) == 1:
+ return expr_deps(ci[0])
+ else:
+ print(ci)
+ sys.exit(1)
+
+ if ci[0] == 'i':
+ return [0, 0]
+ elif ci[0] == "=":
+ t = regdep[ci[1]]
+ if t & DEP.aregl:
+ t |= DEP.aregh
+ if t & DEP.dregl:
+ t |= DEP.dregh
+ if t & DEP.atl:
+ t |= DEP.ath
+ return [t, expr_deps(ci[2:])]
+ elif ci[0] == "=sr" or ci[0] == "=srd" or ci[0] == "=ccr" or ci[0] == "=8" or ci[0] == "=8h" or ci[0] == "=8xh" or ci[0] == "=8xl" or ci[0] == "=16l" or ci[0] == "=16h":
+ return [regdep[ci[1]], expr_deps(ci[2:])]
+ elif ci[0] == "=sri" or ci[0] == "=sri7":
+ return [regdep[R.sr], 0]
+ elif ci[0] == "alu":
+ if len(ci) == 5:
+ return [DEP.aluo, expr_deps(ci[4])]
+ else:
+ return [DEP.aluo, expr_deps(ci[4]) | expr_deps(ci[5])]
+ elif ci[0] == "trap":
+ return [0, expr_deps(ci[1:])]
+ print(ci)
+ sys.exit(1)
+
+
+# Generate the code for a specific microcode address within the
+# context of an instruction
+
+def generate_base_code_for_microcode(ir, irmask, madr, tvn, group01):
+ # Order generated code lines using the dependencies so that it
+ # simulates a parallel assign
+
+ def sort_and_append(code_to_sort, code):
+ cl = []
+ for c in code_to_sort:
+ cl.append([code_find_deps(c), c])
+ while len(cl) != 0:
+ slot = None
+ for i in range(len(cl)):
+ nodep = True
+ for j in range(len(cl)):
+ if i != j and (cl[i][0][0] & cl[j][0][1]):
+ nodep = False
+ break
+ if nodep:
+ slot = i
+ break
+ if slot == None:
+ code.append(["i", "FAIL"])
+ print("Cross-dependency %s" % cl)
+ slot = 0
+ code.append(cl[slot][1])
+ cl = cl[:slot] + cl[slot+1:]
+
+ code = []
+ code.append(["i", "// %03x %s" % (madr, microcode_instruction_names[madr])])
+# code.append(["i", "logerror(\"%s\\n\");" % (microcode_instruction_names[madr])])
+ conditional = None
+
+ micro = microcode_table[madr]
+ nano = nanocode_table[madr]
+
+ # decode in the instruction
+ ir_is_pc_rel = (ir & 0x003e) == 0x003a and ((ir & 0xf000) != 0xe000 or (ir & 0x00c0) == 0x00c0)
+ is_tas = (ir & 0xffc0) == 0x4ac0
+ implicit_sp = (ir & 0xffc0) == 0x4840 or (ir & 0xff00) == 0x4e00 or (ir & 0xff00) == 0x6100
+ to_ccr = (ir & 0xf1c0) == 0x0000 or (ir & 0xffc0) == 0x44c0 or ir == 0x4e77
+ rx_is_dt = (ir & 0xf100) == 0x0000 or (ir & 0xf000) == 0x5000
+ ry_is_dt = (ir & 0x003a) == 0x0038 and ((ir & 0xf000) != 0xe000 or (ir & 0x00c0) == 0x00c0)
+ rx_is_usp = (ir & 0xfff0) == 0x4e60
+ rx_is_movem = (ir & 0xf100) == 0x4000 and (ir & 0xffc0) != 0x4840 and (ir & 0xff00) != 0x4e00
+ movem_pre_decr = (ir & 0xf138) == 0x4020 and (ir & 0xffc0) != 0x4840 and (ir & 0xff00) != 0x4e00
+ is_byte = (((((ir & 0x01c0) == 0x0000 or (ir & 0x0038) != 0x0000) and (ir & 0xf0c0) == 0x0000) and (ir & 0x0ff0) != 0x0800)
+ or (ir & 0xf1f8) == 0x0148
+ or ((ir & 0xf100) == 0x0100 and (ir & 0x0030) != 0x0000)
+ or ((ir & 0xff00) == 0x0800 and (ir & 0x0030) != 0x0000)
+ or (ir & 0xf000) == 0x1000
+ or (ir & 0xe0c0) == 0x4000
+ or (ir & 0xe0c0) == 0x8000
+ or (ir & 0xf0c0) == 0xb000
+ or (ir & 0xf0c0) == 0xb000
+ or (ir & 0xe0c0) == 0xc000
+ or (ir & 0xf0c0) == 0xe000
+ or (ir & 0xffc0) == 0x4ac0
+ or (ir & 0xf0f8) == 0x50c0
+ or (ir & 0xf0f0) == 0x50d0
+ or (ir & 0xf0e0) == 0x50e0)
+ is_movep = (ir & 0xf138) == 0x0108
+ rx_is_areg = (((ir & 0x3000) != 0x0000 and (ir & 0xc000) == 0x0000 and (ir & 0x01c0) >= 0x0040)
+ or (ir & 0xf1c0) == 0x41c0
+ or (ir & 0xff00) == 0x6100
+ or (ir & 0xa1b8) == 0x8108
+ or ((ir & 0x90c0) == 0x90c0 and (ir & 0xf000) != 0xf000)
+ or (ir & 0xd138) == 0x9108
+ or (ir & 0xf138) == 0xd108)
+ ry_is_areg = (((ir & 0x6000) != 0x6000 and (ir & 0x0038) != 0x0000 and (ir & 0x0038) != 0x0038 and (ir & 0xf0f8) != 0x50c8)
+ or ((ir & 0xf000) == 0xf000 and (ir & 0x0038) != 0x0000 and (ir & 0x0038) != 0x0038)
+ or (ir & 0xf0c0) == 0xe0c0)
+ macro_tvn = (6 if (ir & 0xf040) == 0x4000 else
+ "trap-tvn" if (ir & 0xf060) == 0x4040 else
+ 7 if (ir & 0xf060) == 0x4060 else
+ 5)
+ inhibit_ccr = (ir & 0xe1c0) == 0x2040 or (ir & 0xf038) == 0x5008 or (ir & 0xb0c0) == 0x90c0
+
+ # decode of the instruction for the ALU
+ alu_row = 0
+ if (ir & 0xf0c0) == 0x80c0:
+ alu_row = 1
+ if ((ir & 0xff00) == 0x0600
+ or ((ir & 0xc000) == 0x0000 and (ir & 0x3000) != 0x0000)
+ or ((ir & 0xf100) == 0x5000 and (ir & 0x00c0) != 0x00c0)
+ or (ir & 0xf000) == 0x7000
+ or ((ir & 0xf000) == 0xd000 and ((ir & 0x0100) == 0x0000 or (ir & 0x00c0) == 0x00c0 or (ir & 0x0030) != 0x0000))
+ or ((ir & 0xf118) == 0xe000 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf7c0) == 0xe0c0)):
+ alu_row = 2
+ if (((ir & 0xf130) == 0xc100 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf118) == 0xe100 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf7c0) == 0xe1c0)):
+ alu_row = 3
+ if ((ir & 0xbf00) == 0x0200
+ or ((ir & 0xf130) == 0xc000 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf000) == 0xc000 and (ir & 0x00c0) != 0x00c0 and (ir & 0x0030) != 0x0000)
+ or ((ir & 0xf118) == 0xe108 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf7c0) == 0xe3c0)):
+ alu_row = 4
+ if ((ir & 0xbf00) == 0x0400
+ or ((ir & 0xf100) == 0x5100 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf000) == 0x9000 and ((ir & 0x0100) == 0x0000 or (ir & 0x00c0) == 0x00c0 or (ir & 0x0030) != 0x0000))
+ or ((ir & 0xf118) == 0xe008 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf7c0) == 0xe2c0)):
+ alu_row = 5
+ if ((ir & 0xff00) == 0x0c00
+ or (ir & 0xf100) == 0x4100
+ or ((ir & 0xf000) == 0xb000 and ((ir & 0x0100) == 0x0000 or (ir & 0x0038) == 0x0008 or (ir & 0x00c0) == 0x00c0))):
+ alu_row = 6
+ if (ir & 0xf0c0) == 0xc0c0:
+ alu_row = 7
+ if ((ir & 0xff80) == 0x4880
+ or ((ir & 0xf118) == 0xe010 and (ir & 0x00c0) != 0x00c0)
+ or (ir & 0xf7c0) == 0xe4c0):
+ alu_row = 8
+ if ((ir & 0xff80) == 0x4800
+ or ((ir & 0xf130) == 0x8100 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf118) == 0xe118 and (ir & 0x00c0) != 0x00c0)
+ or (ir & 0xf7c0) == 0xe7c0):
+ alu_row = 9
+ if ((ir & 0xff00) == 0x4000
+ or ((ir & 0xf130) == 0x9100 and (ir & 0x00c0) != 0x00c0)
+ or ((ir & 0xf118) == 0xe018 and (ir & 0x00c0) != 0x00c0)
+ or (ir & 0xf7c0) == 0xe6c0):
+ alu_row = 10
+ if ((ir & 0xff00) == 0x4600
+ or ((ir & 0xf118) == 0xe110 and (ir & 0x00c0) != 0x00c0)
+ or (ir & 0xf7c0) == 0xe5c0):
+ alu_row = 11
+ if ((ir & 0xf130) == 0xd100 and (ir & 0x00c0) != 0x00c0):
+ alu_row = 12
+ if ((ir & 0xf180) == 0x0100
+ or (ir & 0xff80) == 0x0800
+ or (ir & 0xff00) == 0x0a00
+ or ((ir & 0xf100) == 0xb100 and (ir & 0x00c0) != 0x00c0 and (ir & 0x0038) != 0x0008)):
+ alu_row = 13
+ if ((ir & 0xff00) == 0x0000
+ or (ir & 0xf180) == 0x0180
+ or (ir & 0xff80) == 0x0880
+ or ((ir & 0xf000) == 0x8000 and (ir & 0x00c0) != 0x00c0 and (ir & 0x0130) != 0x0100)):
+ alu_row = 14
+ if ((ir & 0xff00) == 0x4a00
+ or (ir & 0xf0c0) == 0x50c0):
+ alu_row = 15
+
+ no_ccr_en = ((ir & 0xe1c0) == 0x2040
+ or (ir & 0xf038) == 0x5008
+ or (ir & 0xb0c0) == 0x90c0)
+
+ # decode on the nanocode
+ perm_start = nanox(nano, 63, 2) != 0
+ wait_bus_finish = nanox(nano, 1) or nanox(nano, 7) or nanox(nano, 11) or nanox(nano, 14)
+ is_write = nanox(nano, 11) or nanox(nano, 14)
+ bus_byte = nanox(nano, 25)
+ is_rmc = is_tas and nanox(nano, 25)
+ no_low_byte = nanox(nano, 12)
+ no_high_byte = nanox(nano, 13)
+ upd_tpend = nanox(nano, 39, 4) == 1
+ clr_tpend = nanox(nano, 39, 4) == 14
+ tvn_to_ftu = nanox(nano, 39, 4) == 13
+ const_to_ftu = nanox(nano, 39, 4) == 1
+ ftu_to_dbl = nanox(nano, 39, 4) == 4 or nanox(nano, 39, 4) == 6
+ ftu_to_abl = nanox(nano, 39, 4) == 8
+ abl_to_ftu = nanox(nano, 39, 4) == 12
+ upd_movem = nanox(nano, 39, 4) == 10
+ inl_to_psw = nanox(nano, 39, 4) == 6
+ ftu_to_sr = nanox(nano, 39, 4) == 2
+ sr_to_ftu = nanox(nano, 39, 4) == 7
+ ftu_to_ccr = nanox(nano, 5, 2) == 3
+ psw_i_to_ftu = nanox(nano, 39, 4) == 5
+ ird_to_ftu = nanox(nano, 39, 4) == 9
+ ssw_to_ftu = nanox(nano, 39, 4) == 11
+ init_s_t = nanox(nano, 39, 4) == 6 or nanox(nano, 39, 4) == 14 or nanox(nano, 39, 4) == 15
+ ir_to_ird = nanox(nano, 0)
+ au_clk_en = not nanox(nano, 48)
+ no_sp_align = nanox(nano, 66, 2) == 3
+ au_cntrl = nanox(nano, 49, 3)
+ to_dbin = nanox(nano, 7)
+ to_irc = nanox(nano, 1)
+ dbl_to_atl = nanox(nano, 36, 3) == 2
+ abl_to_atl = nanox(nano, 36, 3) == 1
+ atl_to_abl = nanox(nano, 36, 3) == 5
+ atl_to_dbl = nanox(nano, 36, 3) == 6
+ abh_to_ath = nanox(nano, 56, 3) == 4 or nanox(nano, 56, 3) == 5
+ dbh_to_ath = nanox(nano, 56, 3) == 1
+ ath_to_dbh = nanox(nano, 56, 3) == 3
+ ath_to_abh = nanox(nano, 56, 3) == 6
+ db_to_aob = nanox(nano, 63, 2) == 1
+ ab_to_aob = nanox(nano, 63, 2) == 2
+ au_to_aob = nanox(nano, 63, 2) == 3
+ aob_to_ab = nanox(nano, 56, 3) == 5
+ upd_ssw = nanox(nano, 56, 3) == 5
+ dob_ctrl = (nanox(nano, 14) << 1) | nanox(nano, 11)
+ abh_to_reg = nanox(nano, 60)
+ abl_to_reg = nanox(nano, 31)
+ reg_to_abl = nanox(nano, 30)
+ reg_to_abh = nanox(nano, 59)
+ dbh_to_reg = nanox(nano, 62)
+ dbl_to_reg = nanox(nano, 34)
+ reg_to_dbl = nanox(nano, 35)
+ reg_to_dbh = nanox(nano, 61)
+ ssp = nanox(nano, 43)
+ pch_dbh = nanox(nano, 66, 2) == 2 or (ir_is_pc_rel and not nanox(nano, 24) and not nanox(nano, 45))
+ pcl_dbl = nanox(nano, 28) or (ir_is_pc_rel and not nanox(nano, 24) and not nanox(nano, 27))
+ pcl_abl = nanox(nano, 26) or (ir_is_pc_rel and not nanox(nano, 24) and nanox(nano, 27))
+ pch_abh = nanox(nano, 66, 2) == 1 or (ir_is_pc_rel and not nanox(nano, 24) and nanox(nano, 45))
+ rxh_to_dbh = reg_to_dbh and not pch_dbh and nanox(nano, 45)
+ rxh_to_abh = reg_to_abh and not pch_abh and not nanox(nano, 45)
+ dbl_to_rxl = dbl_to_reg and not pcl_dbl and nanox(nano, 27)
+ dbh_to_rxh = dbh_to_reg and not pch_dbh and nanox(nano, 45)
+ rxl_to_db = reg_to_dbl and not pcl_dbl and nanox(nano, 27)
+ rxl_to_ab = reg_to_abl and not pcl_abl and not nanox(nano, 27)
+ abl_to_rxl = abl_to_reg and not pcl_abl and not nanox(nano, 27)
+ abh_to_rxh = abh_to_reg and not pch_abh and not nanox(nano, 45)
+ dbh_to_ryh = dbh_to_reg and not pch_dbh and not nanox(nano, 45)
+ abh_to_ryh = abh_to_reg and not pch_abh and nanox(nano, 45)
+ ryl_to_db = reg_to_dbl and not pcl_dbl and not nanox(nano, 27)
+ ryl_to_ab = reg_to_abl and not pcl_abl and nanox(nano, 27)
+ ryh_to_dbh = reg_to_dbh and not pch_dbh and not nanox(nano, 45)
+ ryh_to_abh = reg_to_abh and not pch_abh and nanox(nano, 45)
+ dbl_to_ryl = dbl_to_reg and not pcl_dbl and not nanox(nano, 27)
+ abl_to_ryl = abl_to_reg and not pcl_abl and nanox(nano, 27)
+ rz = nanox(nano, 24)
+ rxl_dbl = nanox(nano, 27)
+ alu_column = (nanox(nano, 4) << 2) | (nanox(nano, 3) << 1) | nanox(nano, 2)
+ alu_dctrl = nanox(nano, 15, 2)
+ alu_actrl = nanox(nano, 17)
+ abd_to_dcr = nanox(nano, 9, 2) == 3
+ dcr_to_dbd = nanox(nano, 8, 2) == 3
+ dbd_to_alue = nanox(nano, 8, 2) == 1
+ alue_to_dbd = nanox(nano, 9, 2) == 2
+ dbd_to_alub = nanox(nano, 18)
+ abd_to_alub = nanox(nano, 19)
+ alu_to_dbd = nanox(nano, 23)
+ alu_to_abd = nanox(nano, 22)
+ au_to_db = nanox(nano, 46, 2) == 2
+ au_to_ab = nanox(nano, 46, 2) == 1
+ au_to_pc = nanox(nano, 46, 2) == 3
+ dbin_to_abd = nanox(nano, 21)
+ dbin_to_dbd = nanox(nano, 20)
+ ext_dbh = nanox(nano, 55)
+ ext_abh = nanox(nano, 54)
+ abl_abd = nanox(nano, 32)
+ abl_abh = nanox(nano, 53)
+ dbl_dbd = nanox(nano, 33)
+ dbl_dbh = nanox(nano, 52)
+ adb_is_byte = nanox(nano, 29)
+
+ # Alu op and mask selection from row/column
+ alu_info = 0
+ if is_byte:
+ alu_info |= ALUInfo.is_byte
+
+ if alu_row == 7:
+ alu_info |= ALUInfo.is_mul
+
+ if alu_row == 1:
+ alu_info |= ALUInfo.is_div
+
+ if (ir & 0x00c0) == 0x80 or (alu_info & (ALUInfo.is_div|ALUInfo.is_mul)):
+ alu_info |= ALUInfo.is_long
+
+ if alu_column == 1 and (alu_row == 8 or alu_row == 11):
+ alu_info |= ALUInfo.is_rox_and
+
+ if nanox(nano, 5, 2) == 2:
+ alu_info |= ALUInfo.init
+
+ if nanox(nano, 5, 2) == 1:
+ alu_info |= ALUInfo.finish
+
+ if ir & 0x0100:
+ alu_info |= ALUInfo.mul_signed
+
+ if ((ir & 0xf000) == 0x4000 or (ir & 0xf000) == 0x9000 or(ir & 0xf000) == 0xd000) and (alu_row == 10 or alu_row == 12):
+ alu_info |= ALUInfo.arx
+
+ alu_op = alu_ops[alu_row*8 + alu_column]
+ alu_mask = alu_masks[1 if alu_info & ALUInfo.finish else 0][alu_row*8 + alu_column]
+
+ if alu_op == ALU.abcd or alu_op == ALU.sbcd:
+ alu_info |= ALUInfo.arx
+
+ # Conditional
+ cond = (micro >> 2) & 0x1f if micro & 0x00002 else None
+
+ # Exception latches
+ drop_critical = (micro & 0x00003) == 0x00003 or (micro & 0x00011) == 0x00001
+
+ # register selection for x and y channels
+ if ssp:
+ rx = R.sspl
+ elif rx_is_usp:
+ rx = R.uspl
+ elif implicit_sp:
+ rx = R.a7l
+ elif rx_is_dt:
+ rx = R.dtl
+ elif rx_is_movem:
+ rx = R.moveml
+ elif rx_is_areg:
+ rx = R.axl
+ else:
+ rx = R.dxl
+
+ if rz:
+ ry = R.rzl
+ elif ry_is_dt:
+ ry = R.dtl
+ elif ry_is_areg:
+ ry = R.ayl
+ else:
+ ry = R.dyl
+
+ # Sub-buses drivers
+ if rxl_to_db and not (ssp or rx_is_usp or implicit_sp or rx_is_areg):
+ dbd_in = rx
+ elif ryl_to_db and not ry_is_areg:
+ dbd_in = ry
+ elif alue_to_dbd:
+ dbd_in = R.alue
+ elif dbin_to_dbd:
+ dbd_in = R.dbin
+ elif alu_to_dbd:
+ dbd_in = R.aluo
+ elif dcr_to_dbd:
+ dbd_in = R.dcro8 if is_byte else R.dcro
+ else:
+ dbd_in = None
+
+ if rxl_to_db and (ssp or rx_is_usp or implicit_sp or rx_is_areg):
+ dbl_in = rx
+ elif ryl_to_db and ry_is_areg:
+ dbl_in = ry
+ elif ftu_to_dbl:
+ dbl_in = R.ftu
+ elif au_to_db:
+ dbl_in = R.aul
+ elif atl_to_dbl:
+ dbl_in = R.atl
+ elif reg_to_dbl and pcl_dbl:
+ dbl_in = R.pcl
+ else:
+ dbl_in = None
+
+ if rxh_to_dbh:
+ dbh_in = rx + (R.axh - R.axl)
+ elif ryh_to_dbh:
+ dbh_in = ry + (R.axh - R.axl)
+ elif au_to_db:
+ dbh_in = R.auh
+ elif ath_to_dbh:
+ dbh_in = R.ath
+ elif reg_to_dbh and pch_dbh:
+ dbh_in = R.pch
+ else:
+ dbh_in = None
+
+ if rxl_to_ab and not (ssp or rx_is_usp or implicit_sp or rx_is_areg):
+ abd_in = rx
+ elif ryl_to_ab and not ry_is_areg:
+ abd_in = ry
+ elif alu_to_abd:
+ abd_in = R.aluo
+ elif dbin_to_abd:
+ abd_in = R.dbin
+ else:
+ abd_in = None
+
+ if rxl_to_ab and (ssp or rx_is_usp or implicit_sp or rx_is_areg):
+ abl_in = rx
+ elif ryl_to_ab and ry_is_areg:
+ abl_in = ry
+ elif ftu_to_abl:
+ abl_in = R.ftu
+ elif au_to_ab:
+ abl_in = R.aul
+ elif aob_to_ab:
+ abl_in = R.aobl
+ elif atl_to_abl:
+ abl_in = R.atl
+ elif reg_to_abl and pcl_abl:
+ abl_in = R.pcl
+ else:
+ abl_in = None
+
+ if rxh_to_abh:
+ abh_in = rx + (R.axh - R.axl)
+ elif ryh_to_abh:
+ abh_in = ry + (R.axh - R.axl)
+ elif au_to_ab:
+ abh_in = R.auh
+ elif aob_to_ab:
+ abh_in = R.aobh
+ elif ath_to_abh:
+ abh_in = R.ath
+ elif reg_to_abh and pch_abh:
+ abh_in = R.pch
+ else:
+ abh_in = None
+
+ # Sub-buses cross-connections
+ dbd = dbd_in if dbd_in else dbl_in if dbl_in and dbl_dbd else dbh_in if dbh_in and dbl_dbd and dbl_dbh else None
+ dbl = dbl_in if dbl_in else dbd_in if dbd_in and dbl_dbd else dbh_in if dbh_in and dbl_dbh else None
+ dbh = dbh_in if dbh_in else dbl_in if dbl_in and dbl_dbh else dbd_in if dbd_in and dbl_dbd and dbl_dbh else None
+ abd = abd_in if abd_in else abl_in if abl_in and abl_abd else abh_in if abh_in and abl_abd and abl_abh else None
+ abl = abl_in if abl_in else abd_in if abd_in and abl_abd else abh_in if abh_in and abl_abh else None
+ abh = abh_in if abh_in else abl_in if abl_in and abl_abh else abd_in if abd_in and abl_abd and abl_abh else None
+
+# code.append(["i", "// ab*: d=%s l=%s h=%s ld=%d lh=%d -> d=%s l=%s h=%s" % (abd_in, abl_in, abh_in, abl_abd, abl_abh, abd, abl, abh)])
+
+ # Sign extension
+ if ext_dbh:
+ assert(not dbh)
+ dbh = ["ext32h", dbl]
+ if ext_abh:
+ assert(not abh)
+ abh = ["ext32h", abl]
+
+ # T1
+ if madr == 0x2b9 and ir == 0x0c80: # o#w1 -- implement the cps2 cmpi.l #v, dn detection
+ code.append(["i", "if(!m_cmpild_instr_callback.isnull()) (m_cmpild_instr_callback)(ry, (m_dt & 0xffff0000) | m_dbin);"])
+ if madr == 0x12a and ir == 0x4e73: # rtr1 -- implement the cps2 rte detection
+ code.append(["i", "if(!m_rte_instr_callback.isnull()) (m_rte_instr_callback)(1);"])
+
+ if au_to_aob or (au_to_db and db_to_aob):
+ code.append(["=", R.aobl, R.aul])
+ elif db_to_aob:
+ code.append(["=", R.aobl, maybe_merge(dbh, dbl)])
+ elif ab_to_aob:
+ code.append(["=", R.aobl, maybe_merge(abh, abl)])
+
+ if ir_to_ird:
+ code.append(["=", R.ird, R.ir])
+ code.append(["i", "if(m_next_state != S_TRACE) m_next_state = m_int_next_state;"])
+ elif micro & 0x00001:
+ code.append(["=", R.ir, R.irc])
+
+ if abl_to_ftu:
+ # Also used for dbin_to_movem
+ code.append(["=", R.movemr, R.dbin])
+
+ if perm_start:
+ micro15 = micro & 0x08000
+ micro16 = micro & 0x10000
+ fc0 = ((not ir_is_pc_rel) and not micro16) or micro15
+ fc1 = (ir_is_pc_rel and not micro15) or micro16
+ code.append(["bus", 2 if fc0 and fc1 else 0 if fc1 else 1 if fc0 else 3, bus_byte and (is_byte or is_movep), dob_ctrl, no_high_byte, no_low_byte, group01, is_rmc])
+
+ code.append(["lines", (micro & 0x08000) and not perm_start, (micro & 0x10000) and not perm_start])
+
+ if init_s_t:
+ code.append(["i", "m_sr = (m_sr & ~SR_T) | SR_S;"])
+ code.append(["i", "update_user_super();"])
+ code.append(["i", "update_interrupt();"])
+
+ if cond == CBC.i11:
+ code.append(["=t", "m_irc & 0x0800"])
+ elif cond == CBC.d4 or cond == CBC.d4i:
+ code.append(["=t", "m_dcr & 0x10"])
+ elif cond == CBC.nv:
+ code.append(["=t", "!(m_isr & (SR_V|SR_N))"])
+ elif cond == CBC.n or cond == CBC.ni:
+ code.append(["=t", "m_isr & SR_N"])
+ elif cond == CBC.auz or cond == CBC.auzi:
+ code.append(["=t", "!(m_au & 0x3f)"])
+ elif cond == CBC.v:
+ code.append(["=t", "m_isr & SR_V"])
+ elif cond == CBC.cc or cond == CBC.cci:
+ c = ((ir >> 8) & 15)
+ if c == 0x0:
+ code.append(["=t", "1"])
+ elif c == 0x1:
+ code.append(["=t", "0"])
+ elif c == 0x2:
+ code.append(["=t", "(m_sr & (SR_C|SR_Z)) == 0"])
+ elif c == 0x3:
+ code.append(["=t", "(m_sr & (SR_C|SR_Z)) != 0"])
+ elif c == 0x4:
+ code.append(["=t", "!(m_sr & SR_C)"])
+ elif c == 0x5:
+ code.append(["=t", "m_sr & SR_C"])
+ elif c == 0x6:
+ code.append(["=t", "!(m_sr & SR_Z)"])
+ elif c == 0x7:
+ code.append(["=t", "m_sr & SR_Z"])
+ elif c == 0x8:
+ code.append(["=t", "!(m_sr & SR_V)"])
+ elif c == 0x9:
+ code.append(["=t", "m_sr & SR_V"])
+ elif c == 0xa:
+ code.append(["=t", "!(m_sr & SR_N)"])
+ elif c == 0xb:
+ code.append(["=t", "m_sr & SR_N"])
+ elif c == 0xc:
+ code.append(["=t", "((m_sr & (SR_N|SR_V)) == (SR_N|SR_V)) || ((m_sr & (SR_N|SR_V)) == 0)"])
+ elif c == 0xd:
+ code.append(["=t", "((m_sr & (SR_N|SR_V)) == SR_N) || ((m_sr & (SR_N|SR_V)) == SR_V)"])
+ elif c == 0xe:
+ code.append(["=t", "((m_sr & (SR_N|SR_V|SR_Z)) == (SR_N|SR_V)) || ((m_sr & (SR_N|SR_V|SR_Z)) == 0)"])
+ else:
+ code.append(["=t", "(m_sr & SR_Z) || ((m_sr & (SR_N|SR_V)) == SR_N) || ((m_sr & (SR_N|SR_V)) == SR_V)"])
+ elif cond == CBC.z or cond == CBC.ze:
+ code.append(["=t", "m_isr & SR_Z"])
+ elif cond == CBC.c or cond == CBC.ci:
+ code.append(["=t", "m_isr & SR_C"])
+ elif cond == CBC.n or cond == CBC.ni:
+ code.append(["=t", "m_isr & SR_N"])
+ elif cond == CBC.nz1:
+ code.append(["=t", "(m_isr & SR_Z) ? 2 : (m_isr & SR_N) ? 1 : 0"])
+ elif cond == CBC.nz2:
+ code.append(["=t", "(m_isr & (SR_Z|SR_N)) != 0"])
+ elif cond == CBC.enl or cond == CBC.enli:
+ code.append(["=t", "!m_movemr"])
+ elif cond == CBC.ms0:
+ code.append(["=t", "m_alue & 1"])
+ elif cond == CBC.m01 and not (ir & 0x0100):
+ code.append(["=t", "!(m_au & 0x3f) ? 0 : m_alue & 2 ? 1 : 2"])
+ elif cond == CBC.m01 and (ir & 0x0100):
+ code.append(["=t", "!(m_au & 0x3f) ? 0 : (m_alue & 3) == 1 ? 1 : (m_alue & 3) == 2 ? 2 : 3"])
+ elif cond != None:
+ code.append(["=t", "0"])
+ code.append(["i", "// cond %s" % cbc_names[cond]])
+
+ # T3
+ if dob_ctrl != 0:
+ sm = "=8xl" if no_high_byte or is_byte else "=8xh" if no_low_byte else "="
+ if dob_ctrl == 1:
+ code.append([sm, R.dbout, abd])
+ elif dob_ctrl == 2:
+ code.append([sm, R.dbout, dbd])
+ elif dob_ctrl == 3:
+ code.append([sm, R.dbout, R.aluo])
+
+ if upd_ssw:
+ code.append(["update_ssw"])
+
+ if drop_critical:
+ code.append(["drop_critical"])
+
+ if tvn_to_ftu:
+ if tvn != None:
+ code.append(["trap", tvn])
+ else:
+ code.append(["trap", macro_tvn])
+
+ dbl_to_pcl = dbl_to_reg and pcl_dbl
+ dbh_to_pch = dbh_to_reg and pch_dbh
+ abl_to_pcl = abl_to_reg and pcl_abl
+ abh_to_pch = abh_to_reg and pch_abh
+
+ code_to_sort = []
+
+ if dbd_to_alub:
+ code_to_sort.append(["=", R.alub, dbd])
+ elif abd_to_alub:
+ code_to_sort.append(["=", R.alub, abd])
+
+ if dbd_to_alue:
+ code_to_sort.append(["=", R.alue, dbd])
+
+ if au_to_pc:
+ code_to_sort.append(["=", R.pcl, R.aul])
+ elif dbl_to_pcl and dbh_to_pch:
+ code_to_sort.append(["=", R.pcl, maybe_merge(dbh, dbl)])
+ elif abl_to_pcl and abh_to_pch:
+ code_to_sort.append(["=", R.pcl, maybe_merge(abh, abl)])
+ else:
+ if dbl_to_pcl and dbl:
+ code_to_sort.append(["=16l", R.pcl, dbl])
+ if abl_to_pcl and abl:
+ code_to_sort.append(["=16l", R.pcl, abl])
+ if dbh_to_pch and dbl:
+ code_to_sort.append(["=16h", R.pch, dbh])
+ if abh_to_pch and abl:
+ code_to_sort.append(["=16h", R.pch, abh])
+
+ if abd_to_dcr:
+ # missing byte width -> & 7
+ code_to_sort.append(["=", R.dcr, abd])
+
+ if abl_to_atl and abh_to_ath:
+ code_to_sort.append(["=", R.atl, maybe_merge(abh, abl)])
+ elif dbl_to_atl and dbh_to_ath:
+ code_to_sort.append(["=", R.atl, maybe_merge(dbh, dbl)])
+ else:
+ if dbl_to_atl and dbl:
+ code_to_sort.append(['=16l', R.atl, dbl])
+ if abl_to_atl and abl:
+ code_to_sort.append(['=16l', R.atl, abl])
+ if dbh_to_ath and dbh:
+ code_to_sort.append(['=16h', R.ath, dbh])
+ if abh_to_ath and abh:
+ code_to_sort.append(['=16h', R.ath, abh])
+
+ byte_access = adb_is_byte and is_byte
+
+ if dbl_to_rxl:
+ if rx == R.dxl:
+ if dbh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(dbh, dbd)])
+ elif abh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(abh, dbd)])
+ else:
+ code_to_sort.append(["=16l", rx, dbd])
+ else:
+ if dbh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(dbh, dbl)])
+ elif abh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(abh, dbl)])
+ else:
+ code_to_sort.append(["=16l", rx, dbl])
+ elif abl_to_rxl:
+ if rx == R.dxl:
+ if byte_access:
+ code_to_sort.append(["=8", rx, abd])
+ elif abh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(abh, abd)])
+ elif dbh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(dbh, abd)])
+ else:
+ code_to_sort.append(["=16l", rx, abd])
+ else:
+ if abh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(abh, abl)])
+ elif dbh_to_rxh:
+ code_to_sort.append(["=", rx, maybe_merge(dbh, abl)])
+ else:
+ code_to_sort.append(["=16l", rx, abl])
+ elif dbh_to_rxh:
+ code_to_sort.append(["=16h", rx, dbh])
+ elif abh_to_rxh:
+ code_to_sort.append(["=16h", rx, abh])
+
+ if dbl_to_ryl:
+ if ry == R.dyl:
+ if dbh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(dbh, dbd)])
+ elif abh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(abh, dbd)])
+ else:
+ code_to_sort.append(["=16l", ry, dbd])
+ else:
+ if dbh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(dbh, dbl)])
+ elif abh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(abh, dbl)])
+ else:
+ code_to_sort.append(["=16l", ry, dbl])
+ elif abl_to_ryl:
+ if ry == R.dyl:
+ if byte_access:
+ code_to_sort.append(["=8", ry, abd])
+ elif abh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(abh, abd)])
+ elif dbh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(dbh, abd)])
+ else:
+ code_to_sort.append(["=16l", ry, abd])
+ else:
+ if abh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(abh, abl)])
+ elif dbh_to_ryh:
+ code_to_sort.append(["=", ry, maybe_merge(dbh, abl)])
+ else:
+ code_to_sort.append(["=16l", ry, abl])
+ elif dbh_to_ryh:
+ code_to_sort.append(["=16h", ry, dbh])
+ elif abh_to_ryh:
+ code_to_sort.append(["=16h", ry, abh])
+
+ if inl_to_psw:
+ if tvn == "int-tvn":
+ code_to_sort.append(["=sri"])
+ else:
+ code_to_sort.append(["=sri7"])
+
+ if tvn_to_ftu:
+ if tvn != None:
+ if type(tvn) == str:
+ code_to_sort.append(["=", R.ftu, tvn])
+ else:
+ code_to_sort.append(["=", R.ftu, "c", tvn << 2])
+ else:
+ if type(macro_tvn) == str:
+ code_to_sort.append(["=", R.ftu, macro_tvn])
+ else:
+ code_to_sort.append(["=", R.ftu, "c", macro_tvn << 2])
+
+ if ird_to_ftu:
+ code_to_sort.append(["=", R.ftu, R.ird])
+
+ if sr_to_ftu:
+ code_to_sort.append(["=", R.ftu, R.sr])
+
+ if abl_to_ftu:
+ code_to_sort.append(["=", R.ftu, abl])
+
+ if psw_i_to_ftu:
+ code_to_sort.append(["=", R.ftu, "ftu-i"])
+
+ if ssw_to_ftu:
+ code_to_sort.append(["=", R.ftu, "ftu-ssw"])
+
+ if ftu_to_sr and not to_ccr:
+ assert(ftu_to_ccr)
+ if wait_bus_finish:
+ code_to_sort.append(["=srd", R.sr, R.ftu])
+ else:
+ code_to_sort.append(["=sr", R.sr, R.ftu])
+ elif ftu_to_ccr:
+ code_to_sort.append(["=ccr", R.sr, R.ftu])
+
+
+ # T4
+ if au_clk_en:
+# code.append(["i", "// auc=%s dbl=%s dbh=%s (%d %d) abl=%s abh=%s ftuc=%x" % (au_cntrl, dbl, dbh, dbl_dbd, dbl_dbh, abl, abh, nanox(nano, 39, 4))])
+ if au_cntrl == 0:
+ if dbh:
+ code_to_sort.append(["=", R.aul, maybe_merge(dbh, dbl)])
+ else:
+ code_to_sort.append(["=", R.aul, ["ext32", dbl]])
+ elif au_cntrl == 1:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), 2])
+ elif au_cntrl == 2:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), -4])
+ elif au_cntrl == 3:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), -2])
+ elif au_cntrl == 4:
+ if no_sp_align:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), 1])
+ elif not is_byte:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), 2])
+ elif rxl_to_db:
+ code_to_sort.append(["=", R.aul, "+1/2", maybe_merge(dbh, dbl), "rx"])
+ else:
+ code_to_sort.append(["=", R.aul, "+1/2", maybe_merge(dbh, dbl), "ry"])
+ elif au_cntrl == 5:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), 4])
+ elif au_cntrl == 6:
+ code_to_sort.append(["=", R.aul, "+r", maybe_merge(dbh, dbl), maybe_merge(abh, abl)])
+ elif au_cntrl == 7:
+ if no_sp_align:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), -1])
+ elif not is_byte:
+ code_to_sort.append(["=", R.aul, "+c", maybe_merge(dbh, dbl), -2])
+ elif rxl_to_db:
+ code_to_sort.append(["=", R.aul, "-1/2", maybe_merge(dbh, dbl), "rx"])
+ else:
+ code_to_sort.append(["=", R.aul, "-1/2", maybe_merge(dbh, dbl), "ry"])
+
+ if alu_op:
+ if ftu_to_ccr or no_ccr_en or not (alu_info & (ALUInfo.init|ALUInfo.finish)):
+ alu_mask = 0
+ if alu_mask == 0:
+ alu_init = False
+ alu_finish = False
+ if True:
+ code_to_sort.append(["i",
+ "// alu r=%d c=%d m=%c%c%c%c%c i=%c%c%c%c%c%c%c %s a=%s d=%s" %
+ (alu_row, alu_column,
+ 'x' if alu_mask & 0x10 else '.',
+ 'n' if alu_mask & 0x08 else '.',
+ 'z' if alu_mask & 0x04 else '.',
+ 'v' if alu_mask & 0x02 else '.',
+ 'c' if alu_mask & 0x01 else '.',
+ 'b' if alu_info & ALUInfo.is_byte else '.',
+ 'l' if alu_info & ALUInfo.is_long else '.',
+ 'm' if alu_info & ALUInfo.is_mul else '.',
+ 'd' if alu_info & ALUInfo.is_div else '.',
+ 'r' if alu_info & ALUInfo.is_rox_and else '.',
+ 'i' if alu_info & ALUInfo.init else '.',
+ 'f' if alu_info & ALUInfo.finish else '.',
+ alu_op,
+ "alub" if alu_actrl else "%s:%s" % (abd, regname[abd]) if abd != None else "none",
+ ("%s:%s" % (dbd, regname[dbd]) if dbd != None else "none") if alu_dctrl == 0 else "0" if alu_dctrl == 2 else "-1" if alu_dctrl == 3 else "?")])
+ if (alu_actrl or abd != None or alu_op == ALU.over) and alu_single_param[alu_op]:
+ code_to_sort.append(["alu", alu_op, alu_mask, alu_info, (abd if abd else ["c", 0]) if alu_op == ALU.over else R.alub if alu_actrl else abd])
+ elif (alu_actrl or abd != None) and (alu_dctrl == 2 or alu_dctrl == 3 or (alu_dctrl == 0 and dbd != None)):
+ code_to_sort.append(["alu", alu_op, alu_mask, alu_info, R.alub if alu_actrl else abd, dbd if alu_dctrl == 0 else ["c", 0] if alu_dctrl == 2 else ["c", 0xffff]])
+ elif alu_op == ALU.and_ and alu_dctrl == 2:
+ code_to_sort.append(["alu", alu_op, alu_mask, alu_info, ["c", 0], ["c", 0]])
+
+ sort_and_append(code_to_sort, code)
+
+ if wait_bus_finish:
+ code.append(["bus_end", ftu_to_sr and not to_ccr])
+
+ if to_irc:
+ code.append(["=", R.irc, R.edb])
+
+ if to_dbin:
+ if no_high_byte:
+ code.append(["=8", R.dbin, R.edb])
+ elif no_low_byte:
+ code.append(["=8h", R.dbin, R.edb])
+ else:
+ code.append(["=", R.dbin, R.edb])
+
+ if const_to_ftu:
+ code.append(["i", "set_ftu_const();"])
+
+
+ if upd_movem:
+ if movem_pre_decr:
+ code.append(["i", "step_movem_predec();"])
+ else:
+ code.append(["i", "step_movem();"])
+
+ if not (perm_start or wait_bus_finish):
+ code.append(["istep"])
+
+ if upd_tpend:
+ code.append(["set_trace"])
+ elif clr_tpend:
+ code.append(["clear_trace"])
+
+ return code
+
+
+# Check if rx or ry is used in generated code and if it targets a data
+# or address register
+
+def analyze_register_usage(code):
+ def from_reg(r, usage):
+ if r == R.axl or r == R.axh:
+ if usage['rx'] == 'd':
+ print("Collision d -> a on rx", file=sys.stderr)
+ sys.exit(1);
+ usage['rx'] = 'a'
+ if r == R.dxl or r == R.dxh:
+ if usage['rx'] == 'a':
+ print("Collision a -> d on rx", file=sys.stderr)
+ sys.exit(1);
+ usage['rx'] = 'd'
+ if r == R.ayl or r == R.ayh:
+ if usage['ry'] == 'd':
+ print("Collision d -> a on ry", file=sys.stderr)
+ sys.exit(1);
+ usage['ry'] = 'a'
+ if r == R.dyl or r == R.dyh:
+ if usage['ry'] == 'a':
+ print("Collision a -> d on ry", file=sys.stderr)
+ sys.exit(1);
+ usage['ry'] = 'd'
+
+ def in_expression(ci, usage):
+ if type(ci) != list:
+ from_reg(ci, usage)
+ elif ci[0] == "+c" or ci[0] == "+1/2" or ci[0] == "-1/2" or ci[0] == "ext32" or ci[0] == "ext32h":
+ in_expression(ci[1], usage)
+ elif ci[0] == "+r" or ci[0] == "merge":
+ in_expression(ci[1], usage)
+ in_expression(ci[2], usage)
+ elif len(ci) == 1:
+ in_expression(ci[0], usage)
+
+ usage = { 'rx': False, 'ry': False, 't': False }
+ for cib in code:
+ for ci in cib:
+ if ci[0] == "=" or ci[0] == "=sr" or ci[0] == "=srd" or ci[0] == "=ccr" or ci[0] == "=8" or ci[0] == "=16l" or ci[0] == "=16h" or ci[0] == "=8xl" or ci[0] == "=8xh" or ci[0] == "=8h":
+ from_reg(ci[1], usage)
+ in_expression(ci[2:], usage)
+ if ci[0] == "=t":
+ usage['t'] = True
+ elif ci[0] == "=sri" or ci[0] == "=sri7":
+ from_reg(R.sr, usage)
+ elif ci[0] == "alu":
+ in_expression(ci[4], usage)
+ if len(ci) > 5:
+ in_expression(ci[5], usage)
+ return usage
+
+
+
+
+# Generate the block structure from the microcode links
+
+def generate_blocks(fwd):
+ def find_fwd(ma, fwd):
+ return next((_ for _ in fwd if _[0] == ma), None)
+
+ # Find the edges, which are defined as either the first block or the target of a condition
+ edges = {}
+ edges[fwd[0][0]] = True
+ for f in fwd:
+ if len(f) > 3:
+ for ma in f[2:]:
+ edges[ma] = True
+
+ # Also count the incoming links, since more than one requires a block too
+ bcount = {}
+ for f in fwd:
+ for ma in f[2:]:
+ bcount[ma] = 1 if ma not in bcount else bcount[ma] + 1
+
+ # Extract the blocks roots (first element) from the edges
+ blocks = {}
+ for ma in edges.keys():
+ blocks[ma] = [ma]
+
+ # Add the block roots from the incoming links
+ for ma, v in bcount.items():
+ if v > 1:
+ blocks[ma] = [ma]
+
+ # Build the next elements in order for each block
+ for ma in blocks.keys():
+ ma1 = ma
+ while True:
+ f = find_fwd(ma1, fwd)
+ if len(f) <= 2 or f[2] in blocks:
+ break
+ ma1 = f[2]
+ blocks[ma].append(ma1)
+
+ # Order the blocks, and create the final structure
+ bids = {}
+ oblocks = []
+ toadd = [fwd[0][0]]
+ bids[toadd[0]] = 0
+ cid = 1
+ while len(toadd) != 0:
+ n = toadd[0]
+ toadd = toadd[1:]
+ bids[n] = len(oblocks)
+ last = find_fwd(blocks[n][-1], fwd)
+ for nx in last[2:]:
+ if nx not in bids:
+ toadd.append(nx)
+ bids[nx] = cid
+ cid += 1
+ oblocks.append([n, blocks[n], last[1], [bids[_] for _ in last[2:]]])
+ return oblocks
+
+
+# Show the generated blocks
+
+def show_blocks(blocks):
+ print("Blocks:")
+ for i,b in enumerate(blocks):
+ print(" - %d: %-5s: %s [%s : %s]" % (i, microcode_instruction_names[b[0]], ' '.join("%s" % microcode_instruction_names[_] for _ in b[1]), "always" if b[2] == None else cbc_names[b[2]], ' '.join("%d" % _ for _ in b[3])))
+
+
+# Generate code from the blocks
+
+def generate_code_from_blocks(blocks, ir, irmask, tvn, priv, group01):
+ def label_name(madr):
+ return microcode_instruction_names[madr]
+
+ code = []
+ for ib,b in enumerate(blocks):
+ cb = []
+ if ib != 0:
+ cb.append(["label", label_name(b[0])])
+ elif priv:
+ cb.append(["priv"])
+ for madr in b[1]:
+ cb += generate_base_code_for_microcode(ir, irmask, madr, tvn, group01)
+ if b[2] == None:
+ if len(b[3]) == 0:
+ if cb[-1][0] != "set_trace":
+ # stop #nnnn case, which loops on itself transparently
+ cb.append(["next_stop"])
+ else:
+ cb[-1][0] = "next_trace"
+ elif b[3][0] == ib:
+ assert(cb[-1][0] == "istep")
+ cb[-1][0] = "halt"
+ else:
+ cb.append(["goto", label_name(blocks[b[3][0]][0])])
+ else:
+ cb.append(["cgoto", [label_name(blocks[_][0]) for _ in b[3]]])
+ code.append(cb)
+ return code
+
+
+# Propagate bus accesses from bus initiation to access completion in
+# the code blocks
+
+def propagate_bus_access(blocks, code, critical, gen_mode):
+ def propagate(blocks, code, seen, i, bus_access, bid, critical):
+ if i in seen:
+ return bid, critical
+ seen[i] = True
+ for ci in code[i]:
+ if ci[0] == 'bus':
+ bus_access = ci
+ elif ci[0] == 'bus_end':
+ if bus_access:
+ sr_update = ci.pop()
+ ci.append(bid)
+ ci += bus_access[1:]
+ ci.append(critical)
+ ci.append(sr_update)
+ bus_access = None
+ if (gen_mode & GEN.m68008) and ci[2] != 2 and not ci[3]:
+ bid += 4
+ else:
+ bid += 2
+ elif ci[0] == "drop_critical":
+ critical = False
+ for nc in blocks[i][3]:
+ bid, critical = propagate(blocks, code, seen, nc, bus_access, bid, critical)
+ return bid, critical
+
+ seen = {}
+ propagate(blocks, code, seen, 0, None, 1, critical)
+
+
+# Specific code to detect if we're in the reset opcode and if yes
+# setup the reset line toggling
+
+def detect_reset_toggling(blocks, code):
+ if len(blocks) != 3:
+ return
+ has_reset = False
+ for ci in code[1]:
+ if ci[0] == "lines":
+ has_reset = ci[1]
+ if has_reset:
+ code[0].insert(-1, ["reset", 1])
+ code[2].insert(1, ["reset", 0])
+
+# Generic code generation
+
+def generate_intermediate_code(a1, a2, a3, ir, irmask, tvn, critical, priv, group01, gen_mode, name):
+ fwd, suc = generate_forward_graph(a1, a2, a3, ir, irmask)
+ blocks = generate_blocks(fwd)
+# show_blocks(blocks)
+ code = generate_code_from_blocks(blocks, ir, irmask, tvn, priv, group01)
+ propagate_bus_access(blocks, code, critical, gen_mode)
+ detect_reset_toggling(blocks, code)
+ return code
+
+
+# Generate the code for an instruction
+
+def generate_intermediate_code_from_instruction(ir, irmask, name, gen_mode):
+ # Avoid the rel16 case when looking for rel8
+ if (ir & 0xf000) == 0x6000 and irmask == 0xff00:
+ ir |= 0x0002
+ a1 = a1_pal_apply(ir)
+ a2, a3 = a23_pal_apply(ir)
+ return generate_intermediate_code(a1, a2, a3, ir, irmask, None, False, priv_test(ir), False, gen_mode, name)
+
+# Generate the code for a state
+
+def generate_intermediate_code_from_state(state, gen_mode):
+ return generate_intermediate_code(state[0], 0x3ff, 0x3ff, 0xffff, 0, state[2], state[3], False, True, gen_mode, "state_" + state[1])
+
+
+# Create the base C++ method name for handling a state
+
+def handler_name_for_state(state):
+ return "state_" + state[1]
+
+# Create the base C++ method name for handling an instruction
+
+def handler_name_for_instruction(ii):
+ name = ii[2][0].replace('.', '_')
+ if ii[2][1] != '-':
+ name += '_' + ii[2][1]
+ if ii[2][2] != '-':
+ name += '_' + ii[2][2]
+ return name
+
+
+# Generate C++ source from the code
+
+def generate_source_from_code(code, gen_mode):
+ def make_expression(ci):
+ if ci == None:
+ return "0"
+
+ if type(ci) != list:
+ if ci == R.dcro:
+ return "1 << (m_dcr & 15)"
+ if ci == R.dcro8:
+ return "1 << (m_dcr & 7)"
+ if ci == "ftu-i":
+ return "0xfff1 | ((m_next_state >> 23) & 0xe)" if gen_mode & GEN.m68008 else "0xfff0 | ((m_next_state >> 23) & 0xe)"
+ if ci == "ftu-ssw":
+ return "(m_ftu & ~0x1f) | m_ssw"
+ if ci == "trap-tvn":
+ return "0x80 | ((m_ird & 0xf) << 2)"
+ if ci == "int-tvn":
+ return "m_int_vector"
+ return "high16(%s)" % regname[ci] if reg_high16(ci) else regname[ci]
+
+ if ci[0] == "c":
+ return "0x%04x" % ci[1]
+ elif ci[0] == "+c":
+ if ci[2] < 0:
+ return "%s - %d" % (make_expression(ci[1]), -ci[2])
+ else:
+ return "%s + %d" % (make_expression(ci[1]), ci[2])
+ elif ci[0] == "+1/2":
+ return "%s + (%s < 15 ? 1 : 2)" % (make_expression(ci[1]), ci[2])
+ elif ci[0] == "-1/2":
+ return "%s - (%s < 15 ? 1 : 2)" % (make_expression(ci[1]), ci[2])
+ elif ci[0] == "+r":
+ return "%s + %s" % (make_expression(ci[1]), make_expression(ci[2]))
+ elif ci[0] == "q8":
+ return "s8(m_ird)"
+ elif ci[0] == "merge":
+ return "merge_16_32(%s, %s)" % (make_expression(ci[1]), make_expression(ci[2]))
+ elif ci[0] == "ext32":
+ return "ext32(%s)" % (make_expression(ci[1]))
+ elif ci[0] == "ext32h":
+ return "ext32h(%s)" % (make_expression(ci[1]))
+ elif ci[0] == "c":
+ return "%d" % ci[1]
+ elif len(ci) == 1:
+ return make_expression(ci[0])
+ else:
+ print("unknown expression type %s" % ci[0])
+ sys.exit(1)
+
+ def aluname(op, mask, info):
+ n = "alu_" + alu_opnames[op]
+ if info & ALUInfo.is_long and (op == ALU.asl or op == ALU.asr or op == ALU.lsl or op == ALU.lsr or op == ALU.rol or op == ALU.ror or op == ALU.roxl or op == ALU.roxr):
+ n += '32'
+ if info & ALUInfo.is_mul:
+ n += 'ms' if info & ALUInfo.mul_signed else 'mu'
+ elif info & ALUInfo.is_byte and op != ALU.ext:
+ n += '8'
+ if op == ALU.and_ and info & ALUInfo.is_rox_and:
+ n += 'x'
+ f = None
+ if mask != 0:
+ f = ''
+ if mask & 0x10:
+ f += 'x'
+ if mask & 0x08:
+ f += 'n'
+ if mask & 0x04:
+ f += 'z'
+ if mask & 0x02:
+ f += 'v'
+ if mask & 0x01:
+ f += 'c'
+ if info & (ALUInfo.finish|ALUInfo.arx):
+ f += '_u' # Update the Z flag instead of replacing it
+ return n, f
+
+ source = []
+ usage = analyze_register_usage(code)
+ if usage['rx'] == 'd':
+ source.append("\tint rx = (m_irdi >> 9) & 7;")
+ elif usage['rx'] == 'a':
+ source.append("\tint rx = map_sp(((m_irdi >> 9) & 7) | 8);")
+ if usage['ry'] == 'd':
+ source.append("\tint ry = m_irdi & 7;")
+ elif usage['ry'] == 'a':
+ source.append("\tint ry = map_sp((m_irdi & 7) | 8);")
+
+ if not (gen_mode & GEN.full):
+ source.append("\tswitch(m_inst_substate) {")
+ source.append("\tcase 0:")
+ for cib in code:
+ for ci in cib:
+ if ci[0] == "priv":
+ source.append("\tif(!(m_sr & SR_S)) {")
+ source.append("\t\tm_inst_state = S_PRIVILEDGE;")
+ source.append("\t\treturn;")
+ source.append("\t}")
+ elif ci[0] == "bus" or ci[0] == "drop_critical" or ci[0] == "lines":
+ pass
+ elif ci[0] == "reset":
+ source.append("\tm_reset_cb(%d);" % ci[1])
+ elif ci[0] == "bus_end":
+ assert(len(ci) != 1)
+ ssw = "\tm_base_ssw = "
+ ssw += ["SSW_PROGRAM", "SSW_DATA", "SSW_CPU"][ci[2]]
+ if not ci[4]:
+ ssw += " | SSW_R"
+ if ci[7]:
+ ssw += " | SSW_N"
+ if ci[9]:
+ ssw += " | SSW_CRITICAL"
+ ssw += ";"
+ source.append(ssw)
+ is_interrupt_vector_lookup = not ci[4] and ci[2] == 2
+ if is_interrupt_vector_lookup:
+ source.append("\tstart_interrupt_vector_lookup();")
+ access_steps = 2 if (gen_mode & GEN.m68008) and ci[2] != 2 and not ci[3] else 1
+ cid = ci[1]
+ for access_step in range(access_steps):
+ if not (gen_mode & GEN.full):
+ source.append("\t[[fallthrough]]; case %d:" % (cid))
+ if ci[4]:
+ if ci[3]:
+ if ci[8]:
+ source.append("\tif(!m_tas_write_callback.isnull())")
+ source.append("\t\tm_tas_write_callback(m_aob, m_dbout);")
+ source.append("\telse")
+ if gen_mode & GEN.m68008:
+ if gen_mode & GEN.direct:
+ source.append("\t\t%s.write_interruptible(m_aob, m_dbout);" % (["m_opcodes8", "m_program8"][ci[2]]))
+ else:
+ source.append("\t\tm_mmu8->write_%s(m_aob, m_dbout);" % (["program", "data"][ci[2]]))
+ else:
+ if gen_mode & GEN.direct:
+ source.append("\t\t%s.write_interruptible(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
+ else:
+ source.append("\t\tm_mmu->write_%s(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
+ elif gen_mode & GEN.m68008:
+ if gen_mode & GEN.direct:
+ source.append("\t%s.write_interruptible(m_aob, m_dbout);" % (["m_opcodes8", "m_program8"][ci[2]]))
+ else:
+ source.append("\tm_mmu8->write_%s(m_aob, m_dbout);" % (["program", "data"][ci[2]]))
+ else:
+ if gen_mode & GEN.direct:
+ source.append("\t%s.write_interruptible(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
+ else:
+ source.append("\tm_mmu->write_%s(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
+ elif gen_mode & GEN.m68008:
+ if gen_mode & GEN.direct:
+ source.append("\t%s.write_interruptible(m_aob%s, m_dbout%s);" % (["m_opcodes8", "m_program8"][ci[2]], " | 1" if access_step == 1 else " & ~1", "" if access_step == 1 else " >> 8"))
+ else:
+ source.append("\tm_mmu8->write_%s(m_aob%s, m_dbout%s);" % (["program", "data"][ci[2]], " | 1" if access_step == 1 else " & ~1", "" if access_step == 1 else " >> 8"))
+ else:
+ if gen_mode & GEN.direct:
+ source.append("\t%s.write_interruptible(m_aob & ~1, m_dbout);" % (["m_opcodes", "m_program"][ci[2]]))
+ else:
+ source.append("\tm_mmu->write_%s(m_aob & ~1, m_dbout, 0xffff);" % (["program", "data"][ci[2]]))
+ else:
+ if ci[2] == 2:
+ # cpu space access, e.g. interrupt vector lookup
+ if gen_mode & GEN.m68008:
+ if gen_mode & GEN.direct:
+ source.append("\tm_edb = m_cpu_space8.read_interruptible(m_aob);")
+ else:
+ source.append("\tm_edb = m_mmu8->read_cpu(m_aob);")
+ else:
+ if gen_mode & GEN.direct:
+ source.append("\tm_edb = m_cpu_space.read_interruptible(m_aob);")
+ else:
+ source.append("\tm_edb = m_mmu->read_cpu(m_aob, 0xffff);")
+ elif ci[3]:
+ if gen_mode & GEN.m68008:
+ if gen_mode & GEN.direct:
+ source.append("\tm_edb = %s.read_interruptible(m_aob);" % (["m_opcodes8", "m_program8"][ci[2]]))
+ else:
+ source.append("\tm_edb = m_mmu8->read_%s(m_aob);" % (["program", "data"][ci[2]]))
+ else:
+ if gen_mode & GEN.direct:
+ source.append("\tm_edb = %s.read_interruptible(m_aob & ~1, m_aob & 1 ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
+ else:
+ source.append("\tm_edb = m_mmu->read_%s(m_aob & ~1, m_aob & 1 ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
+ source.append("\tif(!(m_aob & 1))")
+ source.append("\t\tm_edb >>= 8;")
+ else:
+ if gen_mode & GEN.m68008:
+ if access_step == 1:
+ if gen_mode & GEN.direct:
+ source.append("\tm_edb |= %s.read_interruptible(m_aob | 1);" % (["m_opcodes8", "m_program8"][ci[2]]))
+ else:
+ source.append("\tm_edb |= m_mmu8->read_%s(m_aob | 1);" % (["program", "data"][ci[2]]))
+ else:
+ if gen_mode & GEN.direct:
+ source.append("\tm_edb = %s.read_interruptible(m_aob & ~1) << 8;" % (["m_opcodes8", "m_program8"][ci[2]]))
+ else:
+ source.append("\tm_edb = m_mmu8->read_%s(m_aob & ~1) << 8;" % (["program", "data"][ci[2]]))
+ else:
+ if gen_mode & GEN.direct:
+ source.append("\tm_edb = %s.read_interruptible(m_aob & ~1);" % (["m_opcodes", "m_program"][ci[2]]))
+ else:
+ source.append("\tm_edb = m_mmu->read_%s(m_aob & ~1, 0xffff);" % (["program", "data"][ci[2]]))
+ source.append("\tm_icount -= 4;")
+ if ci[8]:
+ if ci[4]:
+ source.append("\tif(m_icount <= %s) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
+ source.append("\t\tif(access_to_be_redone()) {")
+ source.append("\t\t\tm_icount += 4;")
+ source.append("\t\t\tm_inst_substate = %d;" % (cid-2))
+ source.append("\t\t} else")
+ source.append("\t\t\tm_inst_substate = %d;" % (cid+1))
+ source.append("\t\treturn;")
+ source.append("\t}")
+ else:
+ source.append("\tif(m_icount <= %s && access_to_be_redone()) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
+ source.append("\t\tm_icount += 4;")
+ source.append("\t\tm_inst_substate = %d;" % cid)
+ source.append("\t\treturn;")
+ source.append("\t}")
+ else:
+ source.append("\tif(m_icount <= %s) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
+ source.append("\t\tif(access_to_be_redone()) {")
+ source.append("\t\t\tm_icount += 4;")
+ source.append("\t\t\tm_inst_substate = %d;" % cid)
+ source.append("\t\t} else")
+ source.append("\t\t\tm_inst_substate = %d;" % (cid+1))
+ source.append("\t\treturn;")
+ source.append("\t}")
+ if not (gen_mode & GEN.full):
+ source.append("\t[[fallthrough]]; case %d:" % (cid+1))
+ if ci[10]:
+ source.append("\tm_sr = m_new_sr;")
+ source.append("\tupdate_user_super();")
+ source.append("\tupdate_interrupt();")
+ cid += 2
+ if is_interrupt_vector_lookup:
+ source.append("\tend_interrupt_vector_lookup();")
+ if not ci[3] and (ci[2] != 2 or not (gen_mode & GEN.m68008)):
+ source.append("\tif(m_aob & 1) {")
+ source.append("\t\tm_icount -= 4;")
+ source.append("\t\tm_inst_state = %s;" % ("S_DOUBLE_FAULT" if ci[8] else "S_ADDRESS_ERROR"));
+ if not (gen_mode & GEN.full):
+ source.append("\t\tm_inst_substate = 0;")
+ source.append("\t\treturn;")
+ source.append("\t}")
+ elif ci[0] == "=":
+ source.append("\t%s = %s;" % (regname[ci[1]], make_expression(ci[2:])))
+ elif ci[0] == "=srd":
+ source.append("\tm_new_sr = m_isr = %s & (SR_CCR|SR_SR);" % make_expression(ci[2:]))
+ elif ci[0] == "=sr":
+ source.append("\t%s = m_isr = %s & (SR_CCR|SR_SR);" % (regname[ci[1]], make_expression(ci[2:])))
+ source.append("\tupdate_user_super();")
+ source.append("\tupdate_interrupt();")
+ elif ci[0] == "=sri7":
+ source.append("\t%s |= 0x0700;" % (regname[R.sr]))
+ source.append("\tupdate_interrupt();")
+ elif ci[0] == "=sri":
+ source.append("\t%s = (%s & ~SR_I) | ((m_next_state >> 16) & SR_I);" % (regname[R.sr], regname[R.sr]))
+ source.append("\tupdate_interrupt();")
+ elif ci[0] == "=ccr":
+ source.append("\t%s = m_isr = (%s & SR_CCR) | (%s & SR_SR);" % (regname[ci[1]], make_expression(ci[2:]), regname[ci[1]]))
+ elif ci[0] == "=8":
+ source.append("\tset_8(%s, %s);" % (regname[ci[1]], make_expression(ci[2:])))
+ elif ci[0] == "=8h":
+ source.append("\tset_8h(%s, %s);" % (regname[ci[1]], make_expression(ci[2:])))
+ elif ci[0] == "=16l":
+ source.append("\tset_16l(%s, %s);" % (regname[ci[1]], make_expression(ci[2:])))
+ elif ci[0] == "=16h":
+ source.append("\tset_16h(%s, %s);" % (regname[ci[1]], make_expression(ci[2:])))
+ elif ci[0] == "=8xl":
+ source.append("\tset_8xl(%s, %s);" % (regname[ci[1]], make_expression(ci[2:])))
+ elif ci[0] == "=8xh":
+ source.append("\tset_8xh(%s, %s);" % (regname[ci[1]], make_expression(ci[2:])))
+ elif ci[0] == "alu":
+ aname, aflags = aluname(ci[1], ci[2], ci[3])
+ if len(ci) == 5:
+ source.append("\t%s(%s);" % (aname, make_expression(ci[4])))
+ else:
+ sec = make_expression(ci[5])
+ # make gcc happy
+ if sec == "0xffff" and ci[3] & ALUInfo.is_byte and (ci[1] != ALU.and_ or (ci[3] & ALUInfo.is_rox_and)):
+ sec = "0xff"
+ source.append("\t%s(%s, %s);" % (aname, make_expression(ci[4]), sec))
+ if aflags != None:
+ source.append("\tsr_%s();" % aflags)
+ elif ci[0] == "=t":
+ source.append("\tm_t = %s;" % ci[1])
+ elif ci[0] == "next_stop" or ci[0] == "next_trace":
+ source.append("\tm_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];")
+ if not (gen_mode & GEN.full):
+ source.append("\tm_inst_substate = 0;")
+ if ci[0] == "next_stop":
+ source.append("\tdebugger_wait_hook();")
+ if ci[0] == "next_trace":
+ source.append("\tif(m_sr & SR_T)")
+ source.append("\t\tm_next_state = S_TRACE;")
+ source.append("\treturn;")
+ elif ci[0] == "set_trace":
+ source.append("\tif(m_sr & SR_T)")
+ source.append("\t\tm_next_state = S_TRACE;")
+ elif ci[0] == "clear_trace":
+ source.append("\tif(m_next_state == S_TRACE)")
+ source.append("\t\tm_next_state = 0;")
+ elif ci[0] == "update_ssw":
+ source.append("\tm_ssw = m_base_ssw | (m_sr & SR_S ? SSW_S : 0);")
+ elif ci[0] == "halt":
+ if gen_mode & GEN.mcu:
+ source.append("\tm_icount = m_bcount;")
+ else:
+ source.append("\tm_icount = 0;")
+ elif ci[0] == "i":
+ source.append("\t" + ci[1])
+ elif ci[0] == "istep":
+ source.append("\tm_icount -= 2;")
+ elif ci[0] == "label":
+ source.append("%s:" % ci[1])
+ elif ci[0] == "goto":
+ source.append("\tgoto %s;" % ci[1])
+ elif ci[0] == "cgoto":
+ if len(ci[1]) == 2:
+ source.append("\tif(m_t)")
+ source.append("\t\tgoto %s;" % ci[1][1])
+ source.append("\telse")
+ source.append("\t\tgoto %s;" % ci[1][0])
+ elif len(ci[1]) == 3:
+ source.append("\tif(m_t == 0)")
+ source.append("\t\tgoto %s;" % ci[1][0])
+ source.append("\telse if(m_t == 1)")
+ source.append("\t\tgoto %s;" % ci[1][1])
+ source.append("\telse")
+ source.append("\t\tgoto %s;" % ci[1][2])
+ elif len(ci[1]) == 4:
+ source.append("\tif(m_t == 0)")
+ source.append("\t\tgoto %s;" % ci[1][0])
+ source.append("\telse if(m_t == 1)")
+ source.append("\t\tgoto %s;" % ci[1][1])
+ source.append("\telse if(m_t == 2)")
+ source.append("\t\tgoto %s;" % ci[1][2])
+ source.append("\telse")
+ source.append("\t\tgoto %s;" % ci[1][3])
+ elif ci[0] == "trap":
+ if type(ci[1]) == str:
+ source.append("\tdebugger_exception_hook((%s) >> 2);" % make_expression(ci[1]))
+ else:
+ source.append("\tdebugger_exception_hook(0x%02x);" % ci[1])
+ else:
+ source.append("\t%s" % ci)
+
+ if not (gen_mode & GEN.full):
+ source.append("\t}")
+
+ return source
+
+
+# List of special states
+
+states = [
+ [0x002, "reset", 0, True],
+ [0x003, "bus_error", 2, True],
+ [0x003, "address_error", 3, True],
+ [0x001, "double_fault", None, False],
+ [0x1c4, "interrupt", "int-tvn", False],
+ [0x1c0, "trace", 9, False],
+ [0x1c0, "illegal", 4, False],
+ [0x1c0, "priviledge", 8, False],
+ [0x1c0, "linea", 10, False],
+ [0x1c0, "linef", 11, False]
+ ]
+
+# Generate a full handler C++ source file
+
+def generate_source_file(fname, cmd, gen_mode):
+ out = open(fname, "wt")
+ suf = 'd' if gen_mode & GEN.direct else 'i'
+ suf += 'f' if gen_mode & GEN.full else 'p'
+ suf += 'm' if gen_mode & GEN.mcu else ''
+ suf += '8' if gen_mode & GEN.m68008 else ''
+
+ print("Generating %s" % suf)
+
+ cpu = "m68008" if gen_mode & GEN.m68008 else "m68000_mcu" if gen_mode & GEN.mcu else "m68000"
+ head = "m68008" if gen_mode & GEN.m68008 else "m68000mcu" if gen_mode & GEN.mcu else "m68000"
+
+ print("// Instruction handlers for the m68000 (%s, %s, %s)" % ("direct" if gen_mode & GEN.direct else "indirect", "full" if gen_mode & GEN.full else "partial", "mcu" if gen_mode & GEN.mcu else "cpu"), file=out)
+ print("//", file=out)
+ print("// Generated by m68000gen.py %s" % cmd, file=out)
+ print("", file=out)
+ print("#include \"emu.h\"", file=out)
+ print("#include \"%s.h\"" % head, file=out)
+ print("", file=out)
+
+ for st in states:
+# print(handler_name_for_state(st))
+ code = generate_intermediate_code_from_state(st, gen_mode)
+ source = generate_source_from_code(code, gen_mode)
+ print("void %s_device::%s_%s()" % (cpu, handler_name_for_state(st), suf), file=out)
+ print("{", file=out)
+ for l in source:
+ print(l, file=out)
+ print("}", file=out)
+ print("", file=out)
+
+ for ii in instructions:
+ if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
+ continue
+# print(handler_name_for_instruction(ii))
+ code = generate_intermediate_code_from_instruction(ii[0], ii[1], " ".join(ii[2]), gen_mode)
+ source = generate_source_from_code(code, gen_mode)
+ print("void %s_device::%s_%s() // %04x %04x" % (cpu, handler_name_for_instruction(ii), suf, ii[0], ii[1]), file=out)
+ print("{", file=out)
+ for l in source:
+ print(l, file=out)
+ print("}", file=out)
+ print("", file=out)
+
+ print("const %s_device::%s %s_device::s_handlers_%s[] = {" % (cpu, "handler8" if gen_mode & GEN.m68008 else "handlerm" if gen_mode & GEN.mcu else "handler", cpu, suf), file=out)
+ for st in states:
+ name = handler_name_for_state(st)
+ print("\t&%s_device::%s_%s," % (cpu, name, suf), file=out)
+ for ii in instructions:
+ if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
+ continue
+ name = handler_name_for_instruction(ii)
+ print("\t&%s_device::%s_%s," % (cpu, name, suf), file=out)
+ print("};", file=out)
+
+
+#### Main
+
+# Generate C++ code for one instruction
+
+if sys.argv[1] == "i":
+ ir = int(sys.argv[3], base=16)
+ line = None
+ for ii in instructions:
+ if (ir & ii[1]) == ii[0]:
+ line = ii
+ break
+ if line == None or ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
+ print("Illegal instruction")
+ sys.exit(0)
+ code = generate_intermediate_code_from_instruction(ii[0], ii[2], " ".join(ii[2]), 0)
+ source = generate_source_from_code(code, GEN.direct|GEN.full)
+ print("# %s" % handler_name_for_instruction(ii))
+ for l in source:
+ print(l)
+
+# Generate C++ code for one state
+
+if sys.argv[1] == 's':
+ state = None
+ for st in states:
+ if st[1] == sys.argv[3]:
+ state = st
+ code = generate_intermediate_code_from_state(state)
+ source = generate_source_from_code(code, GEN.direct|GEN.full)
+ for l in source:
+ print(l)
+
+# Generate the packed opcode table
+
+if sys.argv[1] == 'decode':
+ out = open(sys.argv[3], 'wt')
+ print("// Instruction decoding table for the m68000", file=out)
+ print("//", file=out)
+ print("// Generated by m68000gen.py %s" % ' '.join(sys.argv[1:]), file=out)
+ print("", file=out)
+ print("#include \"emu.h\"", file=out)
+ print("#include \"m68000.h\"", file=out)
+ print("", file=out)
+ print("const m68000_device::decode_entry m68000_device::s_packed_decode_table[] = {", file=out)
+ idx = len(states)
+ for ii in instructions:
+ if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
+ continue
+ print("\t{ 0x%04x, 0x%04x, %4d }," % (ii[0], ii[1], idx), file=out)
+ idx += 1
+ print("\t{ 0xa000, 0xf000, S_LINEA },", file=out)
+ print("\t{ 0xf000, 0xf000, S_LINEF },", file=out)
+ print("\t{ }", file=out)
+ print("};", file=out)
+
+# Generate the handler header
+
+if sys.argv[1] == 'header':
+ out = open(sys.argv[3], 'wt')
+ print("// Header fragment for the handlers", file=out)
+ print("//", file=out)
+ print("// Generated by m68000gen.py %s" % ' '.join(sys.argv[1:]), file=out)
+ print("", file=out)
+ for variant in ["df", "if", "dp", "ip"]:
+ for st in states:
+ name = handler_name_for_state(st)
+ print("void %s_%s();" % (name, variant), file=out)
+ for ii in instructions:
+ if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
+ continue
+ name = handler_name_for_instruction(ii)
+ print("void %s_%s();" % (name, variant), file=out)
+
+if sys.argv[1] == 'headerm':
+ out = open(sys.argv[3], 'wt')
+ print("// Header fragment for the handlers", file=out)
+ print("//", file=out)
+ print("// Generated by m68000gen.py %s" % ' '.join(sys.argv[1:]), file=out)
+ print("", file=out)
+ for variant in ["dfm", "ifm", "dpm", "ipm"]:
+ for st in states:
+ name = handler_name_for_state(st)
+ print("void %s_%s();" % (name, variant), file=out)
+ for ii in instructions:
+ if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
+ continue
+ name = handler_name_for_instruction(ii)
+ print("void %s_%s();" % (name, variant), file=out)
+
+if sys.argv[1] == 'header8':
+ out = open(sys.argv[3], 'wt')
+ print("// Header fragment for the handlers", file=out)
+ print("//", file=out)
+ print("// Generated by m68000gen.py %s" % ' '.join(sys.argv[1:]), file=out)
+ print("", file=out)
+ for variant in ["df8", "if8", "dp8" ,"ip8"]:
+ for st in states:
+ name = handler_name_for_state(st)
+ print("void %s_%s();" % (name, variant), file=out)
+ for ii in instructions:
+ if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
+ continue
+ name = handler_name_for_instruction(ii)
+ print("void %s_%s();" % (name, variant), file=out)
+
+# Generate the handler source files
+
+if sys.argv[1] == 'sdf':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.direct|GEN.full)
+
+if sys.argv[1] == 'sif':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.full)
+
+if sys.argv[1] == 'sdp':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.direct)
+
+if sys.argv[1] == 'sip':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), 0)
+
+if sys.argv[1] == 'sdfm':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.mcu|GEN.direct|GEN.full)
+
+if sys.argv[1] == 'sifm':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.mcu|GEN.full)
+
+if sys.argv[1] == 'sdpm':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.mcu|GEN.direct)
+
+if sys.argv[1] == 'sipm':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.mcu)
+
+if sys.argv[1] == 'sdf8':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.direct|GEN.full|GEN.m68008)
+
+if sys.argv[1] == 'sif8':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.full|GEN.m68008)
+
+if sys.argv[1] == 'sdp8':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.direct|GEN.m68008)
+
+if sys.argv[1] == 'sip8':
+ generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.m68008)