# Path: awake/opcodedispatcher.py
# class OpcodeDispatcher(object):
# 
#     def __init__(self, opcodeFormats):
#         self.dispatchTable = dict()
#         for bit_format in opcodeFormats:
#             if not bit_format:
#                 continue
# 
#             decoder = SingleOpcodeDecoder(bit_format)
#             for i in range(256):
#                 byte = i & 0xFF
#                 if decoder.match(byte):
#                     self.dispatchTable[byte] = decoder
# 
#     def decode(self, proj, addr):
#         entry = proj.rom.get(addr)
#         if entry not in self.dispatchTable:
#             print('WARN: bad opcode', addr)
#             return BadOpcode([entry], addr), None
#         decoder = self.dispatchTable[entry]
#         opcodes = proj.rom.read(addr, decoder.length())
#         return decoder.decode(proj, opcodes, addr)


from awake.opcodedispatcher import OpcodeDispatcher
00110111 1 SCF                        @ read:            write: FC:1; FN:0; FH:0;
00111111 1 CCF                        @ read: FC         write: FC:(FC^1); FN:0; FH:0;
11110011 1 DI                         @ read:            write: IME:0; sideeffects;
11111011 1 EI                         @ read:            write: IME:1; sideeffects;

11QQ0001 3 POP   #Q                   @ read: SP mem     write: #Q:popval(SP); SP:popst(SP);
11QQ0101 3 PUSH  #Q                   @ read: SP #Q      write: SP:push(SP, #Q); mem;

00000000 1 NOP                        @ read:            write:
00010000 1 STOP                       @ read:            write: sideeffects;
01110110 1 HALT                       @ read:            write: sideeffects;
"""

cb_ops = """
00000SSS 2 RLC  #S                    @ read: #S         write: FC:(#S>>7); #S:((#S<<1)|(#S>>7)); FZ:(#S == 0); FH:0; FN:0;
00001SSS 2 RRC  #S                    @ read: #S         write: FC:(#S & 1); #S:((#S>>1)|(#S<<7)); FZ:(#S == 0); FH:0; FN:0;
00010SSS 2 RL   #S                    @ read: #S FC      write: #S:((#S<<1)|FC); FZ:(#S == 0); FC; FH:0; FN:0;
00011SSS 2 RR   #S                    @ read: #S FC      write: #S:((#S>>1)|(FC<<7)); FZ:(#S == 0); FC; FH:0; FN:0;
00100SSS 2 SLA  #S                    @ read: #S         write: FC:(#S>>7); #S:(#S<<1); FZ:(#S == 0); FH:0; FN:0;
00101SSS 2 SRA  #S                    @ read: #S         write: FC:(#S & 1); #S:((#S>>1) | (#S & 0x80)); FZ:(#S == 0); FH:0; FN:0;
00110SSS 2 SWAP #S                    @ read: #S         write: #S:((#S>>4) | (#S<<4)); FZ:(#S == 0); FC:0; FH:0; FN:0;
00111SSS 2 SRL  #S                    @ read: #S         write: FC:(#S & 1); #S:(#S>>1); FZ:(#S == 0); FH:0; FN:0;
01IIISSS 2 BIT  #I, #S                @ read: #S         write: FZ:((#S & (1<<#I)) == 0); FH:1; FN:0;
10IIISSS 2 RES  #I, #S                @ read: #S         write: #S:(#S & (0xFF ^ (1<<#I)));
11IIISSS 2 SET  #I, #S                @ read: #S         write: #S:(#S | (1<<#I));
"""

class Z80Disasm(object):
    def __init__(self, proj):
        self.proj = proj

# Path: awake/opcodedispatcher.py
# class OpcodeDispatcher(object):
# 
#     def __init__(self, opcodeFormats):
#         self.dispatchTable = dict()
#         for bit_format in opcodeFormats:
#             if not bit_format:
#                 continue
# 
#             decoder = SingleOpcodeDecoder(bit_format)
#             for i in range(256):
#                 byte = i & 0xFF
#                 if decoder.match(byte):
#                     self.dispatchTable[byte] = decoder
# 
#     def decode(self, proj, addr):
#         entry = proj.rom.get(addr)
#         if entry not in self.dispatchTable:
#             print('WARN: bad opcode', addr)
#             return BadOpcode([entry], addr), None
#         decoder = self.dispatchTable[entry]
#         opcodes = proj.rom.read(addr, decoder.length())
#         return decoder.decode(proj, opcodes, addr)


# Path: awake/disasm.py
from awake.opcodedispatcher import OpcodeDispatcher

00110111 1 SCF                        @ read:            write: FC:1; FN:0; FH:0;
00111111 1 CCF                        @ read: FC         write: FC:(FC^1); FN:0; FH:0;
11110011 1 DI                         @ read:            write: IME:0; sideeffects;
11111011 1 EI                         @ read:            write: IME:1; sideeffects;

11QQ0001 3 POP   #Q                   @ read: SP mem     write: #Q:popval(SP); SP:popst(SP);
11QQ0101 3 PUSH  #Q                   @ read: SP #Q      write: SP:push(SP, #Q); mem;

00000000 1 NOP                        @ read:            write:
00010000 1 STOP                       @ read:            write: sideeffects;
01110110 1 HALT                       @ read:            write: sideeffects;
"""

cb_ops = """
00000SSS 2 RLC  #S                    @ read: #S         write: FC:(#S>>7); #S:((#S<<1)|(#S>>7)); FZ:(#S == 0); FH:0; FN:0;
00001SSS 2 RRC  #S                    @ read: #S         write: FC:(#S & 1); #S:((#S>>1)|(#S<<7)); FZ:(#S == 0); FH:0; FN:0;
00010SSS 2 RL   #S                    @ read: #S FC      write: #S:((#S<<1)|FC); FZ:(#S == 0); FC; FH:0; FN:0;
00011SSS 2 RR   #S                    @ read: #S FC      write: #S:((#S>>1)|(FC<<7)); FZ:(#S == 0); FC; FH:0; FN:0;
00100SSS 2 SLA  #S                    @ read: #S         write: FC:(#S>>7); #S:(#S<<1); FZ:(#S == 0); FH:0; FN:0;
00101SSS 2 SRA  #S                    @ read: #S         write: FC:(#S & 1); #S:((#S>>1) | (#S & 0x80)); FZ:(#S == 0); FH:0; FN:0;
00110SSS 2 SWAP #S                    @ read: #S         write: #S:((#S>>4) | (#S<<4)); FZ:(#S == 0); FC:0; FH:0; FN:0;
00111SSS 2 SRL  #S                    @ read: #S         write: FC:(#S & 1); #S:(#S>>1); FZ:(#S == 0); FH:0; FN:0;
01IIISSS 2 BIT  #I, #S                @ read: #S         write: FZ:((#S & (1<<#I)) == 0); FH:1; FN:0;
10IIISSS 2 RES  #I, #S                @ read: #S         write: #S:(#S & (0xFF ^ (1<<#I)));
11IIISSS 2 SET  #I, #S                @ read: #S         write: #S:(#S | (1<<#I));
"""

class Z80Disasm(object):
    def __init__(self, proj):
        self.proj = proj

        self.main = OpcodeDispatcher(main_ops.splitlines())