mirror of
https://github.com/hsoft/collapseos.git
synced 2024-12-26 17:28:06 +11:00
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
|
.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)
|
||||||
|
|
||||||
|
@ -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;
|
||||||
@ -186,29 +141,29 @@ union _bytewordregs_ regs;
|
|||||||
|
|
||||||
uint8_t portram[0x10000];
|
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 portout (uint16_t portnum, uint8_t value) {}
|
||||||
static void portout16 (uint16_t portnum, uint16_t value) {}
|
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) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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);
|
fprintf(stderr, "Unknown INT called: %x\n", intnum);
|
||||||
hltstate = 1;
|
|
||||||
/*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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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
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 <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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user