#include <u.h>
#include <libc.h>
#include "8i.h"
static long
rreg8(Cpu *cpu, int r, ulong)
{
if(r >= 8)
abort();
if(r < 4) /* AL, BL, CL, DL */
return cpu->reg[r]&0xFF;
return (cpu->reg[r-4]>>8)&0xFF;
}
static void
wreg8(Cpu *cpu, int r, ulong, long v)
{
if(r >= 8)
abort();
if(r < 4){ /* AL, BL, CL, DL */
cpu->reg[r] &= ~0xFF;
cpu->reg[r] |= v&0xFF;
return;
}
cpu->reg[r-4] &= ~0xFF00;
cpu->reg[r-4] |= (v<<8)&0xFF00;
}
static ulong
fetch8(Cpu *cpu, int seg, ulong off)
{
ulong a;
a = (seg&0xFFFF)*16+(off&0xFFFF);
a &= 0xFFFFF;
if(!(cpu->present64k & (1<<(a>>16)))){
cpu->addr = a;
trap(cpu, TSEGFAULT);
}
return cpu->mem[a];
}
static long
fetchs8(Cpu *cpu, int seg, ulong off)
{
return (schar)fetch8(cpu, seg, off);
}
static void
store8(Cpu *cpu, int seg, ulong off, long v)
{
ulong a;
a = (seg&0xFFFF)*16+(off&0xFFFF);
a &= 0xFFFF;
if(!(cpu->present64k & (1<<(a>>16)))){
cpu->addr = a;
trap(cpu, TSEGFAULT);
}
//print("%lx = %x->%x\n", a, cpu->mem[a], v);
cpu->mem[a] = v;
}
Wordop wop8 = {
.rreg= rreg8,
.wreg= wreg8,
.fetch= fetch8,
.fetchs= fetchs8,
.store= store8,
.len= 1,
};
static long
rreg16(Cpu *cpu, int r, ulong)
{
if(r >= NREG)
abort();
//print("rd %d %x...", r, cpu->reg[r]&0xFFFF);
return cpu->reg[r] & 0xFFFF;
}
static void
wreg16(Cpu *cpu, int r, ulong, long v)
{
if(r >= NREG)
abort();
//print("wr %d %x...", r, v&0xFFFF);
cpu->reg[r] &= ~0xFFFF;
cpu->reg[r] |= (v & 0xFFFF);
}
static ulong
fetch16(Cpu *cpu, int seg, ulong off)
{
return fetch8(cpu, seg, off) | (fetch8(cpu, seg, off+1)<<8);
}
static long
fetchs16(Cpu *cpu, int seg, ulong off)
{
return (short)fetch16(cpu, seg, off);
}
static void
store16(Cpu *cpu, int seg, ulong off, long v)
{
store8(cpu, seg, off, v);
store8(cpu, seg, off+1, v>>8);
}
Wordop wop16 = {
.rreg= rreg16,
.wreg= wreg16,
.fetch= fetch16,
.fetchs= fetchs16,
.store= store16,
.len= 2,
};
static long
rreg32(Cpu *cpu, int r, ulong)
{
if(r >= NREG)
abort();
return cpu->reg[r];
}
static void
wreg32(Cpu *cpu, int r, ulong, long v)
{
if(r >= NREG)
abort();
cpu->reg[r] = v;
}
static ulong
fetch32(Cpu *cpu, int seg, ulong off)
{
return fetch8(cpu, seg, off) | (fetch8(cpu, seg, off+1)<<8) |
(fetch8(cpu, seg, off+2)<<16) | (fetch8(cpu, seg, off+3)<<24);
}
static long
fetchs32(Cpu *cpu, int seg, ulong off)
{
return fetch32(cpu, seg, off);
}
static void
store32(Cpu *cpu, int seg, ulong off, long v)
{
store8(cpu, seg, off, v);
store8(cpu, seg, off+1, v>>8);
store8(cpu, seg, off+2, v>>16);
store8(cpu, seg, off+3, v>>24);
}
Wordop wop32 = {
.rreg= rreg32,
.wreg= wreg32,
.fetch= fetch32,
.fetchs= fetchs32,
.store= store32,
.len= 4,
};
void
bumpesdi(Cpu *cpu, Inst *inst, Iarg *arg)
{
int sign;
Wordop *wop;
sign = (cpu->flags & DF) ? -1 : 1;
if(inst->addrsize != 16)
trap(cpu, TBADOP);
switch(inst->opsize){
default:
trap(cpu, TBADOP);
case 8:
case 16:
wop = &wop16;
break;
case 32:
wop = &wop32;
break;
}
wop16.wreg(cpu, RDI, 0, arg->off = wop16.rreg(cpu, RDI, 0)+sign*(inst->opsize/8));
arg->val = wop->fetch(cpu, arg->seg, arg->off);
}
void
bumpdssi(Cpu *cpu, Inst *inst, Iarg *arg)
{
int sign;
Wordop *wop;
sign = (cpu->flags & DF) ? -1 : 1;
switch(inst->opsize){
default:
trap(cpu, TBADOP);
case 8:
case 16:
wop = &wop16;
break;
case 32:
wop = &wop32;
break;
}
wop16.wreg(cpu, RSI, 0, arg->off = wop16.rreg(cpu, RSI, 0)+sign*(inst->opsize/8));
arg->val = wop->fetch(cpu, arg->seg, arg->off);
}
void
putflags(Cpu *cpu, int, ulong, long v)
{
cpu->flags = v;
cpu->flags &= FLAGMASK;
cpu->flags |= FLAGSET;
}
|