|
|
|
|
@@ -14,6 +14,7 @@
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "nec_debugger.h"
|
|
|
|
|
#include "necintrf.h"
|
|
|
|
|
#include "memory.h"
|
|
|
|
|
|
|
|
|
|
/***
|
|
|
|
|
* Note: the while code to decode instruction is not meant to be optimised, but to be easy to maintain.
|
|
|
|
|
@@ -353,8 +354,8 @@ static inline void get_mod_reg_rm(uint8_t value, uint8_t *mod, uint8_t *reg, uin
|
|
|
|
|
|
|
|
|
|
static int decode_modrm(uint16_t segment, uint16_t offset, modrmValues modrm, bool is8bit, char *buffer, uint32_t bufferLength)
|
|
|
|
|
{
|
|
|
|
|
uint8_t disp8 = cpu_readmem20(MAKE_LINEAR(segment, offset));
|
|
|
|
|
uint16_t disp16 = (cpu_readmem20(MAKE_LINEAR(segment, offset + 1)) << 8) | disp8;
|
|
|
|
|
uint8_t disp8 = mem_readmem20(MAKE_LINEAR(segment, offset));
|
|
|
|
|
uint16_t disp16 = (mem_readmem20(MAKE_LINEAR(segment, offset + 1)) << 8) | disp8;
|
|
|
|
|
char buf[63];
|
|
|
|
|
int offsetReturn = 0;
|
|
|
|
|
|
|
|
|
|
@@ -544,7 +545,7 @@ static int decode_modrm(uint16_t segment, uint16_t offset, modrmValues modrm, bo
|
|
|
|
|
|
|
|
|
|
int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsigned int bufferSize)
|
|
|
|
|
{
|
|
|
|
|
uint8_t opcode = cpu_readmem20(MAKE_LINEAR(segment, offset));
|
|
|
|
|
uint8_t opcode = mem_readmem20(MAKE_LINEAR(segment, offset));
|
|
|
|
|
uint16_t currentOffset = offset;
|
|
|
|
|
int16_t param1, param2;
|
|
|
|
|
uint8_t modrm, reg;
|
|
|
|
|
@@ -562,7 +563,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
{
|
|
|
|
|
/* Need to handle opcode group */
|
|
|
|
|
case OP_IMMED:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
|
|
|
|
switch (reg)
|
|
|
|
|
{
|
|
|
|
|
@@ -631,7 +632,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case OP_SHIFT:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
|
|
|
|
switch (reg)
|
|
|
|
|
{
|
|
|
|
|
@@ -666,7 +667,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case OP_GRP1:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
|
|
|
|
switch (reg)
|
|
|
|
|
{
|
|
|
|
|
@@ -711,7 +712,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case OP_GRP2:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
|
|
|
|
switch (reg)
|
|
|
|
|
{
|
|
|
|
|
@@ -787,7 +788,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
|
|
|
|
|
case OP_MOVG:
|
|
|
|
|
/* Special case for C6 and C7, they are valid ONLY if reg == 0 */
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, NULL);
|
|
|
|
|
if (reg > 0)
|
|
|
|
|
{
|
|
|
|
|
@@ -852,202 +853,202 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
|
|
|
|
|
/******* Immediate values *******/
|
|
|
|
|
case PR_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/******* Register / Immediate *******/
|
|
|
|
|
case PR_AL_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " al, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_AH_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " ah, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_AX_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " ax, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_AX_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " ax, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " ax, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_IM8_AL:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " 0%Xh, al", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_IM8_AX:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " 0%Xh, ax", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_BL_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " bl, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_BH_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " bh, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_BX_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " bx, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " bx, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_CL_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " cl, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_CH_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " ch, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_CX_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " cx, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " cx, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_DL_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " dl, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_DH_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " dh, 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_DX_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " dx, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " dx, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_SP_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " sp, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " sp, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_BP_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " bp, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " bp, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_DI_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " di, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " di, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_SI_IM16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " si, 0%Xh", param1 & 0xFF);
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
snprintf(buf, 63, " si, 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/******* Register / Memory *******/
|
|
|
|
|
case PR_M8_AL:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
/* TODO: If having a list of known label, try to match and display label instead of value */
|
|
|
|
|
snprintf(buf, 63, " byte [0%Xh], al", param1 & 0xFF);
|
|
|
|
|
snprintf(buf, 63, " byte [0%Xh], al", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_M16_AX:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
/* TODO: If having a list of known label, try to match and display label instead of value */
|
|
|
|
|
snprintf(buf, 63, " word [0%Xh], ax", param1 & 0xFF);
|
|
|
|
|
snprintf(buf, 63, " word [0%Xh], ax", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_AL_M8:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
/* TODO: If having a list of known label, try to match and display label instead of value */
|
|
|
|
|
snprintf(buf, 63, " al, byte [0%Xh]", param1 & 0xFF);
|
|
|
|
|
snprintf(buf, 63, " al, byte [0%Xh]", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_AX_M16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
/* TODO: If having a list of known label, try to match and display label instead of value */
|
|
|
|
|
snprintf(buf, 63, " ax, word [0%Xh]", param1 & 0xFF);
|
|
|
|
|
snprintf(buf, 63, " ax, word [0%Xh]", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/******* Address calculation *******/
|
|
|
|
|
case PR_REL8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
param1 = currentOffset + (int8_t)param1;
|
|
|
|
|
/* TODO: If having a list of known label, try to match and display label instead of value */
|
|
|
|
|
@@ -1057,8 +1058,8 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_REL16:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
param1 = currentOffset + (int16_t) param1;
|
|
|
|
|
|
|
|
|
|
@@ -1069,21 +1070,21 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_ABS32:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param2 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 3)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param2 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 3)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
|
|
|
|
/* TODO: If having a list of known label, try to match and display label instead of value */
|
|
|
|
|
snprintf(buf, 63, " 0%Xh:0%Xh", param2, param1);
|
|
|
|
|
snprintf(buf, 63, " 0%Xh:0%Xh", param2 & 0xFFFF, param1 & 0xFFFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 4;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/******* Other cases *******/
|
|
|
|
|
case PR_IM16_IM8:
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param2 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param2 = mem_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
|
|
|
|
|
snprintf(buf, 63, " 0%Xh:0%Xh", param1, param2);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
currentOffset += 3;
|
|
|
|
|
@@ -1093,55 +1094,55 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
************************************************ Complicated cases ************************************************
|
|
|
|
|
******************************************************************************************************************/
|
|
|
|
|
case PR_RM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM16:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
snprintf(buf, 63, ", 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM16_IM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset ++;
|
|
|
|
|
snprintf(buf, 63, ", 0%Xh", param1 & 0xFF);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM_IM16:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
snprintf(buf, 63, ", 0%Xh", param1);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM8_1:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
|
|
|
|
@@ -1149,7 +1150,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM16_1:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
@@ -1157,7 +1158,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM8_CL:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
|
|
|
|
@@ -1165,7 +1166,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM16_CL:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
@@ -1173,7 +1174,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM_R8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
|
|
|
|
|
@@ -1182,7 +1183,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM_R16:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
@@ -1191,7 +1192,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_R_RM8:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
|
|
|
|
snprintf(buf, 63, " %s,", modrmReg8List[reg]);
|
|
|
|
|
@@ -1200,7 +1201,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_R_RM16:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
|
|
|
|
snprintf(buf, 63, " %s,", modrmReg16List[reg]);
|
|
|
|
|
@@ -1209,25 +1210,25 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_RM16_SEG:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
snprintf(buf, 63, ", %s", segmentRegList[reg]);
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PR_SEG_RM16:
|
|
|
|
|
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset++;
|
|
|
|
|
get_mod_reg_rm(param1, NULL, ®, NULL, &modrm);
|
|
|
|
|
snprintf(buf, 63, ", %s", segmentRegList[reg]);
|
|
|
|
|
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
|
|
|
|
|
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
|
|
|
|
|
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
|
|
|
|
|
currentOffset += 2;
|
|
|
|
|
strncat(buffer, buf, bufferSize);
|
|
|
|
|
break;
|
|
|
|
|
@@ -1246,3 +1247,22 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
|
|
|
|
|
|
|
|
|
|
return currentOffset - offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
if ((I.sregs[CS] == 0x0600) /* && (I.ip > 0x0050) */)
|
|
|
|
|
{
|
|
|
|
|
int tmp;
|
|
|
|
|
char buffer[256];
|
|
|
|
|
uint8_t op = mem_readmem20((I.sregs[CS] << 4) + I.ip);
|
|
|
|
|
//Log(TLOG_NORMAL, "NEC v30", "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, instructionsName[op], I.IF);
|
|
|
|
|
printf("AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n",
|
|
|
|
|
I.regs.w[AW], I.regs.w[BW], I.regs.w[CW], I.regs.w[DW],
|
|
|
|
|
I.regs.w[IX], I.regs.w[IY], I.regs.w[SP]);
|
|
|
|
|
printf("CS: %04X, DS: %04X, SS: %04X, ES: %04X\n",
|
|
|
|
|
I.sregs[CS], I.sregs[DS], I.sregs[SS], I.sregs[ES]);
|
|
|
|
|
memset(buffer, 0, 256);
|
|
|
|
|
nec_decode_instruction(I.sregs[CS], I.ip, buffer, 255);
|
|
|
|
|
printf("[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, buffer, I.IF);
|
|
|
|
|
tmp = getchar();
|
|
|
|
|
}
|
|
|
|
|
#endif
|