65oo2/disas/main.c
2024-02-23 01:35:53 +01:00

203 lines
3 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include "lib/op.h"
#define OP_ADDR_MODE (OP_ADDR_IMPL | OP_ADDR_REL | OP_ADDR_IND \
| OP_ADDR_IMM | OP_ADDR_ABS)
char *prg_name;
FILE *input;
FILE *output;
uint8_t
readu8(void)
{
uint8_t val;
if (fread(&val, 1, 1, input) != 1)
{
return (-1); /* XXX: TODO */
}
return (val);
}
uint16_t
readu16(void)
{
uint16_t val;
if (fread(&val, 1, 2, input) != 2)
{
return (-1); /* XXX: TODO */
}
return (val);
}
uint32_t
readu32(void)
{
uint32_t val;
if (fread(&val, 1, 4, input) != 4)
{
return (-1); /* XXX: TODO */
}
return (val);
}
int16_t
read16(void)
{
int16_t val;
if (fread(&val, 1, 2, input) != 2)
{
return (-1); /* XXX: TODO */
}
return (val);
}
int32_t
read32(void)
{
int32_t val;
if (fread(&val, 1, 4, input) != 4)
{
return (-1); /* XXX: TODO */
}
return (val);
}
void
fatal(const char *str, ...)
{
va_list ap;
fprintf(stderr, "%s: ", prg_name);
va_start(ap, str);
vfprintf(stderr, str, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
void
decode_imm(uint8_t opcode)
{
uint8_t attr;
attr = readu8();
if ((attr & 0x3) == 0x3)
{
fprintf(output, "???\n");
return;
}
fprintf(output, "%s.", opcode_str[opcode]);
if (attr & 0x4)
{
fprintf(output, "U");
}
switch (attr & 0x3)
{
case 0x0:
fprintf(output, "B #$%X\n", readu8());
break;
case 0x1:
fprintf(output, "W #$%hX\n", readu16());
break;
case 0x2:
fprintf(output, "L #$%X\n", readu32());
break;
default:
break;
}
}
void
decode_ind(uint8_t opcode)
{
uint8_t attr;
attr = readu8();
(void)attr;
}
void
decode_abs(uint8_t opcode)
{
uint8_t attr;
attr = readu8();
(void)attr;
}
void
decode(void)
{
uint8_t opcode;
int16_t relative;
do {
opcode = readu8();
if (feof(input)) return;
switch (opcode_addr[opcode] & OP_ADDR_MODE)
{
case OP_ADDR_IMPL:
fprintf(output, "%s\n", opcode_str[opcode]);
break;
case OP_ADDR_REL:
relative = read16();
fprintf(output, "%s $%hX\n", opcode_str[opcode], relative);
break;
case OP_ADDR_IMM:
decode_imm(opcode);
break;
case OP_ADDR_IND:
decode_ind(opcode);
break;
case OP_ADDR_ABS:
decode_abs(opcode);
break;
default:
fprintf(output, "???\n", opcode);
break;
}
} while (!feof(input));
}
int
main(int argc, char **argv)
{
prg_name = argv[0];
input = stdin;
output = stdout;
if (argc > 2)
{
output = fopen(argv[2], "w");
if (output == NULL) fatal("can't open %s.", argv[2]);
}
if (argc > 1)
{
input = fopen(argv[1], "rb");
if (input == NULL) fatal("can't open %s.", argv[1]);
}
decode();
return (EXIT_SUCCESS);
}