1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-12-27 03:58:05 +11:00

emul/8086: add INT hooks

This commit is contained in:
Virgil Dupras 2020-10-24 21:50:44 -04:00
parent 939c018792
commit 942a50a86d
6 changed files with 116 additions and 78 deletions

2
emul/8086/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/forth
/forth.bin

View File

@ -7,14 +7,16 @@ BLKFS = $(CDIR)/blkfs
.PHONY: all .PHONY: all
all: $(TARGETS) all: $(TARGETS)
forth: forth.c $(OBJS) forth: forth.c forth.bin $(OBJS)
$(CC) forth.c $(OBJS) -lncurses -o $@ $(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 $(CC) -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/$(BLKFS)\" -c -o emul.o emul.c
forth.bin: xcomp.fs $(STAGE) $(BLKFS) forth.bin: foo.asm
$(CDIR)/stage < xcomp.fs > $@ nasm -o $@ foo.asm
#forth.bin: xcomp.fs $(STAGE) $(BLKFS)
# $(CDIR)/stage < xcomp.fs > $@
$(BLKFS): $(STAGE) $(BLKFS): $(STAGE)

View File

@ -22,6 +22,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "cpu.h"
// Defines below are from config.h // Defines below are from config.h
//be sure to only define ONE of the CPU_* options at any given time, or //be sure to only define ONE of the CPU_* options at any given time, or
@ -49,58 +50,11 @@
#define CPU_SET_HIGH_FLAGS #define CPU_SET_HIGH_FLAGS
#endif #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 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 signext(value) (int16_t)(int8_t)(value)
#define signext32(value) (int32_t)(int16_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 getsegreg(regid) segregs[regid]
#define putsegreg(regid, writeval) segregs[regid] = writeval #define putsegreg(regid, writeval) segregs[regid] = writeval
#define segbase(x) ((uint32_t) x << 4)
#define makeflagsword() \ #define makeflagsword() \
( \ ( \
@ -174,6 +128,7 @@ static const uint8_t parity[0x100] = {
}; };
uint8_t RAM[0x100000]; uint8_t RAM[0x100000];
INTHOOK INTHOOKS[0x100] = {0};
uint8_t opcode, segoverride, reptype, hltstate = 0; uint8_t opcode, segoverride, reptype, hltstate = 0;
uint16_t segregs[4], savecs, saveip, ip, useseg, oldsp; 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; uint8_t tempcf, oldcf, cf, pf, af, zf, sf, tf, ifl, df, of, mode, reg, rm;
@ -193,22 +148,22 @@ static void portout16 (uint16_t portnum, uint16_t value) {}
static uint8_t portin (uint16_t portnum) { return 0; } static uint8_t portin (uint16_t portnum) { return 0; }
static uint16_t portin16 (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; tempaddr32 = addr32 & 0xFFFFF;
RAM[tempaddr32] = value; RAM[tempaddr32] = value;
} }
static void writew86 (uint32_t addr32, uint16_t value) { void writew86 (uint32_t addr32, uint16_t value) {
write86(addr32, (uint8_t) value); write86(addr32, (uint8_t) value);
write86(addr32 + 1, (uint8_t) (value >> 8) ); write86(addr32 + 1, (uint8_t) (value >> 8) );
} }
static uint8_t read86 (uint32_t addr32) { uint8_t read86 (uint32_t addr32) {
addr32 &= 0xFFFFF; addr32 &= 0xFFFFF;
return (RAM[addr32]); 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) ); return ( (uint16_t) read86 (addr32) | (uint16_t) (read86 (addr32 + 1) << 8) );
} }
@ -1243,8 +1198,16 @@ static void op_grp5() {
} }
void intcall86(uint8_t intnum) { void intcall86(uint8_t intnum) {
fprintf(stderr, "Unknown INT called: %x\n", intnum); if (intnum == 0) {
fprintf(stderr, "INT 0 called, halting\n");
hltstate = 1; hltstate = 1;
return;
}
if (INTHOOKS[intnum] != NULL) {
INTHOOKS[intnum]();
return;
}
fprintf(stderr, "Unknown INT called: %x\n", intnum);
/*push (makeflagsword() ); /*push (makeflagsword() );
push (segregs[regcs]); push (segregs[regcs]);
push (ip); push (ip);
@ -3437,8 +3400,3 @@ void reset86() {
ip = 0; ip = 0;
hltstate = 0; hltstate = 0;
} }
void printregs() {
fprintf(stderr, "AL: %x\n", getreg8(regal));
}

View File

@ -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 exec86(int execloops);
void reset86(); void reset86();
void printregs();

3
emul/8086/foo.asm Normal file
View File

@ -0,0 +1,3 @@
mov al, 'X'
int 1
hlt

View File

@ -2,21 +2,40 @@
#include <stdio.h> #include <stdio.h>
#include "cpu.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 main(int argc, char *argv[])
{ {
int i = 0; INTHOOKS[1] = int1;
int ch = 0;
reset86(); reset86();
ch = getchar(); // initialize memory
while (ch != EOF) { FILE *bfp = fopen(FBIN_PATH, "r");
RAM[i++] = ch; if (!bfp) {
ch = getchar(); fprintf(stderr, "Can't open forth.bin\n");
return 1;
} }
printregs(); int i = 0;
exec86(1); int c = getc(bfp);
printregs(); while (c != EOF) {
write86(i++, c);
c = getc(bfp);
}
fclose(bfp);
exec86(100);
return 0; return 0;
} }