#include #include #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; }