emul/8086: add INT hooks
This commit is contained in:
parent
939c018792
commit
942a50a86d
2
emul/8086/.gitignore
vendored
Normal file
2
emul/8086/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/forth
|
||||
/forth.bin
|
@ -7,14 +7,16 @@ BLKFS = $(CDIR)/blkfs
|
||||
.PHONY: all
|
||||
all: $(TARGETS)
|
||||
|
||||
forth: forth.c $(OBJS)
|
||||
$(CC) forth.c $(OBJS) -lncurses -o $@
|
||||
forth: forth.c forth.bin $(OBJS)
|
||||
$(CC) -DFBIN_PATH=\"`pwd`/forth.bin\" forth.c $(OBJS) -lncurses -o $@
|
||||
|
||||
emul.o: emul.c forth.bin $(BLKFS)
|
||||
emul.o: emul.c $(BLKFS)
|
||||
$(CC) -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/$(BLKFS)\" -c -o emul.o emul.c
|
||||
|
||||
forth.bin: xcomp.fs $(STAGE) $(BLKFS)
|
||||
$(CDIR)/stage < xcomp.fs > $@
|
||||
forth.bin: foo.asm
|
||||
nasm -o $@ foo.asm
|
||||
#forth.bin: xcomp.fs $(STAGE) $(BLKFS)
|
||||
# $(CDIR)/stage < xcomp.fs > $@
|
||||
|
||||
$(BLKFS): $(STAGE)
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "cpu.h"
|
||||
|
||||
// Defines below are from config.h
|
||||
//be sure to only define ONE of the CPU_* options at any given time, or
|
||||
@ -49,58 +50,11 @@
|
||||
#define CPU_SET_HIGH_FLAGS
|
||||
#endif
|
||||
|
||||
#define regax 0
|
||||
#define regcx 1
|
||||
#define regdx 2
|
||||
#define regbx 3
|
||||
#define regsp 4
|
||||
#define regbp 5
|
||||
#define regsi 6
|
||||
#define regdi 7
|
||||
#define reges 0
|
||||
#define regcs 1
|
||||
#define regss 2
|
||||
#define regds 3
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define regal 1
|
||||
#define regah 0
|
||||
#define regcl 3
|
||||
#define regch 2
|
||||
#define regdl 5
|
||||
#define regdh 4
|
||||
#define regbl 7
|
||||
#define regbh 6
|
||||
#else
|
||||
#define regal 0
|
||||
#define regah 1
|
||||
#define regcl 2
|
||||
#define regch 3
|
||||
#define regdl 4
|
||||
#define regdh 5
|
||||
#define regbl 6
|
||||
#define regbh 7
|
||||
#endif
|
||||
|
||||
union _bytewordregs_ {
|
||||
uint16_t wordregs[8];
|
||||
uint8_t byteregs[8];
|
||||
};
|
||||
|
||||
#define StepIP(x) ip += x
|
||||
#define getmem8(x, y) read86(segbase(x) + y)
|
||||
#define getmem16(x, y) readw86(segbase(x) + y)
|
||||
#define putmem8(x, y, z) write86(segbase(x) + y, z)
|
||||
#define putmem16(x, y, z) writew86(segbase(x) + y, z)
|
||||
#define signext(value) (int16_t)(int8_t)(value)
|
||||
#define signext32(value) (int32_t)(int16_t)(value)
|
||||
#define getreg16(regid) regs.wordregs[regid]
|
||||
#define getreg8(regid) regs.byteregs[byteregtable[regid]]
|
||||
#define putreg16(regid, writeval) regs.wordregs[regid] = writeval
|
||||
#define putreg8(regid, writeval) regs.byteregs[byteregtable[regid]] = writeval
|
||||
#define getsegreg(regid) segregs[regid]
|
||||
#define putsegreg(regid, writeval) segregs[regid] = writeval
|
||||
#define segbase(x) ((uint32_t) x << 4)
|
||||
|
||||
#define makeflagsword() \
|
||||
( \
|
||||
@ -174,6 +128,7 @@ static const uint8_t parity[0x100] = {
|
||||
};
|
||||
|
||||
uint8_t RAM[0x100000];
|
||||
INTHOOK INTHOOKS[0x100] = {0};
|
||||
uint8_t opcode, segoverride, reptype, hltstate = 0;
|
||||
uint16_t segregs[4], savecs, saveip, ip, useseg, oldsp;
|
||||
uint8_t tempcf, oldcf, cf, pf, af, zf, sf, tf, ifl, df, of, mode, reg, rm;
|
||||
@ -186,29 +141,29 @@ union _bytewordregs_ regs;
|
||||
|
||||
uint8_t portram[0x10000];
|
||||
|
||||
void intcall86 (uint8_t intnum);
|
||||
void intcall86(uint8_t intnum);
|
||||
|
||||
static void portout (uint16_t portnum, uint8_t value) {}
|
||||
static void portout16 (uint16_t portnum, uint16_t value) {}
|
||||
static uint8_t portin (uint16_t portnum) { return 0; }
|
||||
static uint16_t portin16 (uint16_t portnum) { return 0; }
|
||||
|
||||
static void write86 (uint32_t addr32, uint8_t value) {
|
||||
void write86 (uint32_t addr32, uint8_t value) {
|
||||
tempaddr32 = addr32 & 0xFFFFF;
|
||||
RAM[tempaddr32] = value;
|
||||
}
|
||||
|
||||
static void writew86 (uint32_t addr32, uint16_t value) {
|
||||
write86 (addr32, (uint8_t) value);
|
||||
write86 (addr32 + 1, (uint8_t) (value >> 8) );
|
||||
void writew86 (uint32_t addr32, uint16_t value) {
|
||||
write86(addr32, (uint8_t) value);
|
||||
write86(addr32 + 1, (uint8_t) (value >> 8) );
|
||||
}
|
||||
|
||||
static uint8_t read86 (uint32_t addr32) {
|
||||
uint8_t read86 (uint32_t addr32) {
|
||||
addr32 &= 0xFFFFF;
|
||||
return (RAM[addr32]);
|
||||
}
|
||||
|
||||
static uint16_t readw86 (uint32_t addr32) {
|
||||
uint16_t readw86 (uint32_t addr32) {
|
||||
return ( (uint16_t) read86 (addr32) | (uint16_t) (read86 (addr32 + 1) << 8) );
|
||||
}
|
||||
|
||||
@ -1242,9 +1197,17 @@ static void op_grp5() {
|
||||
}
|
||||
}
|
||||
|
||||
void intcall86 (uint8_t intnum) {
|
||||
void intcall86(uint8_t intnum) {
|
||||
if (intnum == 0) {
|
||||
fprintf(stderr, "INT 0 called, halting\n");
|
||||
hltstate = 1;
|
||||
return;
|
||||
}
|
||||
if (INTHOOKS[intnum] != NULL) {
|
||||
INTHOOKS[intnum]();
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "Unknown INT called: %x\n", intnum);
|
||||
hltstate = 1;
|
||||
/*push (makeflagsword() );
|
||||
push (segregs[regcs]);
|
||||
push (ip);
|
||||
@ -3437,8 +3400,3 @@ void reset86() {
|
||||
ip = 0;
|
||||
hltstate = 0;
|
||||
}
|
||||
|
||||
void printregs() {
|
||||
fprintf(stderr, "AL: %x\n", getreg8(regal));
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,57 @@
|
||||
#pragma once
|
||||
#define regax 0
|
||||
#define regcx 1
|
||||
#define regdx 2
|
||||
#define regbx 3
|
||||
#define regsp 4
|
||||
#define regbp 5
|
||||
#define regsi 6
|
||||
#define regdi 7
|
||||
#define reges 0
|
||||
#define regcs 1
|
||||
#define regss 2
|
||||
#define regds 3
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define regal 1
|
||||
#define regah 0
|
||||
#define regcl 3
|
||||
#define regch 2
|
||||
#define regdl 5
|
||||
#define regdh 4
|
||||
#define regbl 7
|
||||
#define regbh 6
|
||||
#else
|
||||
#define regal 0
|
||||
#define regah 1
|
||||
#define regcl 2
|
||||
#define regch 3
|
||||
#define regdl 4
|
||||
#define regdh 5
|
||||
#define regbl 6
|
||||
#define regbh 7
|
||||
#endif
|
||||
|
||||
#define segbase(x) ((uint32_t) x << 4)
|
||||
#define getmem8(x, y) read86(segbase(x) + y)
|
||||
#define getmem16(x, y) readw86(segbase(x) + y)
|
||||
#define putmem8(x, y, z) write86(segbase(x) + y, z)
|
||||
#define putmem16(x, y, z) writew86(segbase(x) + y, z)
|
||||
#define getreg16(regid) regs.wordregs[regid]
|
||||
#define getreg8(regid) regs.byteregs[byteregtable[regid]]
|
||||
#define putreg16(regid, writeval) regs.wordregs[regid] = writeval
|
||||
#define putreg8(regid, writeval) regs.byteregs[byteregtable[regid]] = writeval
|
||||
|
||||
typedef void (*INTHOOK) ();
|
||||
union _bytewordregs_ {
|
||||
uint16_t wordregs[8];
|
||||
uint8_t byteregs[8];
|
||||
};
|
||||
|
||||
|
||||
void write86 (uint32_t addr32, uint8_t value);
|
||||
void writew86 (uint32_t addr32, uint16_t value);
|
||||
uint8_t read86 (uint32_t addr32);
|
||||
uint16_t readw86 (uint32_t addr32);
|
||||
void exec86(int execloops);
|
||||
void reset86();
|
||||
void printregs();
|
||||
|
3
emul/8086/foo.asm
Normal file
3
emul/8086/foo.asm
Normal file
@ -0,0 +1,3 @@
|
||||
mov al, 'X'
|
||||
int 1
|
||||
hlt
|
@ -2,21 +2,40 @@
|
||||
#include <stdio.h>
|
||||
#include "cpu.h"
|
||||
|
||||
extern uint8_t RAM[0x100000];
|
||||
#ifndef FBIN_PATH
|
||||
#error FBIN_PATH needed
|
||||
#endif
|
||||
|
||||
extern uint8_t byteregtable[8];
|
||||
extern union _bytewordregs_ regs;
|
||||
extern INTHOOK INTHOOKS[0x100];
|
||||
|
||||
/* we have a fake INT API:
|
||||
INT 1: EMIT. AL = char to spit
|
||||
INT 2: KEY. AL = char read
|
||||
*/
|
||||
|
||||
void int1() {
|
||||
putchar(getreg8(regal));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
int ch = 0;
|
||||
|
||||
INTHOOKS[1] = int1;
|
||||
reset86();
|
||||
ch = getchar();
|
||||
while (ch != EOF) {
|
||||
RAM[i++] = ch;
|
||||
ch = getchar();
|
||||
// initialize memory
|
||||
FILE *bfp = fopen(FBIN_PATH, "r");
|
||||
if (!bfp) {
|
||||
fprintf(stderr, "Can't open forth.bin\n");
|
||||
return 1;
|
||||
}
|
||||
printregs();
|
||||
exec86(1);
|
||||
printregs();
|
||||
int i = 0;
|
||||
int c = getc(bfp);
|
||||
while (c != EOF) {
|
||||
write86(i++, c);
|
||||
c = getc(bfp);
|
||||
}
|
||||
fclose(bfp);
|
||||
exec86(100);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user