Kaynağa Gözat

emul/8086: add INT hooks

master
Virgil Dupras 3 yıl önce
ebeveyn
işleme
942a50a86d
6 değiştirilmiş dosya ile 116 ekleme ve 78 silme
  1. +2
    -0
      emul/8086/.gitignore
  2. +7
    -5
      emul/8086/Makefile
  3. +19
    -61
      emul/8086/cpu.c
  4. +55
    -1
      emul/8086/cpu.h
  5. +3
    -0
      emul/8086/foo.asm
  6. +30
    -11
      emul/8086/forth.c

+ 2
- 0
emul/8086/.gitignore Dosyayı Görüntüle

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

+ 7
- 5
emul/8086/Makefile Dosyayı Görüntüle

@@ -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)



+ 19
- 61
emul/8086/cpu.c Dosyayı Görüntüle

@@ -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));
}


+ 55
- 1
emul/8086/cpu.h Dosyayı Görüntüle

@@ -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
- 0
emul/8086/foo.asm Dosyayı Görüntüle

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

+ 30
- 11
emul/8086/forth.c Dosyayı Görüntüle

@@ -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;
}
int i = 0;
int c = getc(bfp);
while (c != EOF) {
write86(i++, c);
c = getc(bfp);
}
printregs();
exec86(1);
printregs();
fclose(bfp);
exec86(100);
return 0;
}

Yükleniyor…
İptal
Kaydet