BizHawk/BizHawk.Emulation.Cores/Consoles/Fairchild/ChannelF/F8/F3850.Disassembler.cs

348 lines
7.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
{
/// <summary>
/// Disassembler
/// </summary>
public sealed partial class F3850 : IDisassemblable
{
static string Result(string format, Func<ushort, byte> read, ref ushort addr)
{
//d immediately succeeds the opcode
//n immediate succeeds the opcode and the displacement (if present)
//nn immediately succeeds the opcode and the displacement (if present)
if (format.IndexOf("nn") != -1)
{
format = format.Replace("nn", read(addr++)
.ToString("X2") + read(addr++)
.ToString("X2") + "h"); // MSB is read first
}
if (format.IndexOf("n") != -1) format = format.Replace("n", $"{read(addr++):X2}h");
if (format.IndexOf("+d") != -1) format = format.Replace("+d", "d");
if (format.IndexOf("d") != -1)
{
var b = unchecked((sbyte)read(addr++));
format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h");
}
return format;
}
readonly static string[] mnemonics = new string[]
{
"LR A, KU", // 0x00
"LR A, KL", // 0x01
"LR A, QU", // 0x02
"LR A, QL", // 0x03
"LR KU, A", // 0x04
"LR KL, A", // 0x05
"LR QU, A", // 0x06
"LR QL, A", // 0x07
"LR K, P", // 0x08
"LR P, K", // 0x09
"LR A, IS", // 0x0A
"LR IS, A", // 0x0B
"PK", // 0x0C
"LR P0, Q", // 0x0D
"LR Q, DC", // 0x0E
"LR DC, Q", // 0x0F
"LR DC, H", // 0x10
"LR H, DC", // 0x11
"SR 1", // 0x12
"SL 1", // 0x13
"SR 4", // 0x14
"SL 4", // 0x15
"LM", // 0x16
"ST", // 0x17
"COM", // 0x18
"LNK", // 0x19
"DI", // 0x1A
"EI", // 0x1B
"POP", // 0x1C
"LR W, J", // 0x1D
"LR J, W", // 0x1E
"INC", // 0x1F
"LI n", // 0x20
"NI n", // 0x21
"OI n", // 0x22
"XI n", // 0x23
"AI n", // 0x24
"CI n", // 0x25
"IN n", // 0x26
"OUT n", // 0x27
"PI nn", // 0x28
"JMP nn", // 0x29
"DCI nn", // 0x2A
"NOP", // 0x2B
"XDC", // 0x2C
"ILLEGAL", // 0x2D
"ILLEGAL", // 0x2E
"ILLEGAL", // 0x2F
"DS r00", // 0x30
"DS r01", // 0x31
"DS r02", // 0x32
"DS r03", // 0x33
"DS r04", // 0x34
"DS r05", // 0x35
"DS r06", // 0x36
"DS r07", // 0x37
"DS r08", // 0x38
"DS r09", // 0x39
"DS r10", // 0x3A
"DS r11", // 0x3B
"DS ISAR", // 0x3C
"DS ISAR INC", // 0x3D
"DS ISAR DEC", // 0x3E
"ILLEGAL", // 0x3F
"LR A, r00", // 0x40
"LR A, r01", // 0x41
"LR A, r02", // 0x42
"LR A, r03", // 0x43
"LR A, r04", // 0x44
"LR A, r05", // 0x45
"LR A, r06", // 0x46
"LR A, r07", // 0x47
"LR A, r08", // 0x48
"LR A, r09", // 0x49
"LR A, r10", // 0x4A
"LR A, r11", // 0x4B
"LR A, (ISAR)", // 0x4C
"LR A, (ISAR) INC", // 0x4D
"LR A, (ISAR) DEC", // 0x4E
"ILLEGAL", // 0x4F
"LR r00, A", // 0x50
"LR r01, A", // 0x51
"LR r02, A", // 0x52
"LR r03, A", // 0x53
"LR r04, A", // 0x54
"LR r05, A", // 0x55
"LR r06, A", // 0x56
"LR r07, A", // 0x57
"LR r08, A", // 0x58
"LR r09, A", // 0x59
"LR r10, A", // 0x5A
"LR r11, A", // 0x5B
"LR ((ISAR)), A", // 0x5C
"LR (ISAR), A INC", // 0x5D
"LR (ISAR), A DEC", // 0x5E
"ILLEGAL", // 0x5F
"LISU 0", // 0x60
"LISU 1", // 0x61
"LISU 2", // 0x62
"LISU 3", // 0x63
"LISU 4", // 0x64
"LISU 5", // 0x65
"LISU 6", // 0x66
"LISU 7", // 0x67
"LISL 0", // 0x68
"LISL 1", // 0x69
"LISL 2", // 0x6A
"LISL 3", // 0x6B
"LISL 4", // 0x6C
"LISL 5", // 0x6D
"LISL 6", // 0x6E
"LISL 7", // 0x6F
"LIS 0", // 0x70
"LIS 1", // 0x71
"LIS 2", // 0x72
"LIS 3", // 0x73
"LIS 4", // 0x74
"LIS 5", // 0x75
"LIS 6", // 0x76
"LIS 7", // 0x77
"LIS 8", // 0x78
"LIS 9", // 0x79
"LIS A", // 0x7A
"LIS B", // 0x7B
"LIS C", // 0x7C
"LIS D", // 0x7D
"LIS E", // 0x7E
"LIS F", // 0x7F
"BT NOBRANCH", // 0x80
"BP d", // 0x81
"BC d", // 0x82
"BP or C d", // 0x83
"BZ d", // 0x84
"BP d", // 0x85
"BZ or C d", // 0x86
"BP or C d", // 0x87
"AM", // 0x88
"AMD", // 0x89
"NM", // 0x8A
"OM", // 0x8B
"XM", // 0x8C
"CM", // 0x8D
"ADC", // 0x8E
"BR7 n", // 0x8F
"BF UNCON d", // 0x90
"BN d", // 0x91
"BNC d", // 0x92
"BNC & deg d", // 0x93
"BNZ d", // 0x94
"BN d", // 0x95
"BNC & dZ d", // 0x96
"BNC & deg d", // 0x97
"BNO d", // 0x98
"BN & dO d", // 0x99
"BNO & dC d", // 0x9A
"BNO & dC & deg d", // 0x9B
"BNO & dZ d", // 0x9C
"BN & dO d", // 0x9D
"BNO & dC & dZ d", // 0x9E
"BNO & dC & deg d", // 0x9F
"INS 0", // 0xA0
"INS 1", // 0xA1
"ILLEGAL", // 0xA2
"ILLEGAL", // 0xA3
"INS 4", // 0xA4
"INS 5", // 0xA5
"INS 6", // 0xA6
"INS 7", // 0xA7
"INS 8", // 0xA8
"INS 9", // 0xA9
"INS 10", // 0xAA
"INS 11", // 0xAB
"INS 12", // 0xAC
"INS 13", // 0xAD
"INS 14", // 0xAE
"INS 16", // 0xAF
"OUTS 0", // 0xB0
"OUTS 1", // 0xB1
"ILLEGAL", // 0xB2
"ILLEGAL", // 0xB3
"OUTS 4", // 0xB4
"OUTS 5", // 0xB5
"OUTS 6", // 0xB6
"OUTS 7", // 0xB7
"OUTS 8", // 0xB8
"OUTS 9", // 0xB9
"OUTS 10", // 0xBA
"OUTS 11", // 0xBB
"OUTS 12", // 0xBC
"OUTS 13", // 0xBD
"OUTS 14", // 0xBE
"OUTS 15", // 0xBF
"AS r00", // 0xC0
"AS r01", // 0xC1
"AS r02", // 0xC2
"AS r03", // 0xC3
"AS r04", // 0xC4
"AS r05", // 0xC5
"AS r06", // 0xC6
"AS r07", // 0xC7
"AS r08", // 0xC8
"AS r09", // 0xC9
"AS r10", // 0xCA
"AS r11", // 0xCB
"AS ISAR", // 0xCC
"AS ISAR INC", // 0xCD
"AS ISAR DEC", // 0xCE
"ILLEGAL", // 0xCF
"ASD r00", // 0xD0
"ASD r01", // 0xD1
"ASD r02", // 0xD2
"ASD r03", // 0xD3
"ASD r04", // 0xD4
"ASD r05", // 0xD5
"ASD r06", // 0xD6
"ASD r07", // 0xD7
"ASD r08", // 0xD8
"ASD r09", // 0xD9
"ASD r10", // 0xDA
"ASD r11", // 0xDB
"ASD ISAR", // 0xDC
"ASD ISAR INC", // 0xDD
"ASD ISAR DEC", // 0xDE
"ILLEGAL", // 0xDF
"XS r00", // 0xE0
"XS r01", // 0xE1
"XS r02", // 0xE2
"XS r03", // 0xE3
"XS r04", // 0xE4
"XS r05", // 0xE5
"XS r06", // 0xE6
"XS r07", // 0xE7
"XS r08", // 0xE8
"XS r09", // 0xE9
"XS r10", // 0xEA
"XS r11", // 0xEB
"XS ISAR", // 0xEC
"XS ISAR INC", // 0xED
"XS ISAR DEC", // 0xEE
"ILLEGAL", // 0xEF
"NS r00", // 0xF0
"NS r01", // 0xF1
"NS r02", // 0xF2
"NS r03", // 0xF3
"NS r04", // 0xF4
"NS r05", // 0xF5
"NS r06", // 0xF6
"NS r07", // 0xF7
"NS r08", // 0xF8
"NS r09", // 0xF9
"NS r10", // 0xFA
"NS r11", // 0xFB
"NS ISAR", // 0xFC
"NS ISAR INC", // 0xFD
"NS ISAR DEC", // 0xFE
"ILLEGAL", // 0xFF
};
public string Disassemble(ushort addr, Func<ushort, byte> read, out int size)
{
ushort start_addr = addr;
ushort extra_inc = 0;
byte A = read(addr++);
string format;
format = mnemonics[A];
string temp = Result(format, read, ref addr);
size = addr - start_addr;
if (addr < start_addr)
{
size = (0x10000 + addr) - start_addr;
}
return temp;
}
#region IDisassemblable
#endregion
public string Cpu
{
get { return "F3850"; }
set { }
}
public string PCRegisterName
{
get { return "PC"; }
}
public IEnumerable<string> AvailableCpus
{
get { yield return "F3850"; }
}
public string Disassemble(MemoryDomain m, uint addr, out int length)
{
string ret = Disassemble((ushort)addr, a => m.PeekByte(a), out length);
return ret;
}
}
}