emulating 8086 subset.

185 views
Skip to first unread message

luser droog

unread,
Jun 27, 2015, 3:34:56 AM6/27/15
to
Brain going numb trying to overdesign this apl jiterpreter,
and reading this tutorial on category theory for programmers.
So I tried a little fun project to rewrite my postscript
8086 emulator to (superterse) C.

And then I got stumped. I'm trying to handle the decoding
of the mod-reg-reg/mod byte, and I want to represent it
as a "tuple" of {destination-pointer, left-opand, right-op},
but I'm getting hung up trying to define this structure
so it handles byte or word data conveniently.

I want to have the arguments and result available for
calculating flags, hence the "tuple" idea. But, well,
hopefully the English here explains where I'm stumped.
The code, ... ....

cat a8086.c
#include<stdio.h>
#include<sys/stat.h>
#include<unistd.h>
#define P printf
#define R return
#define T typedef
T int I;
T unsigned U;
T short S;
T unsigned short US;
T char C;
T unsigned char UC;
U w;
UC halt,reg[20],mem[0xffff]={ 1 };
#ifdef BIGENDIAN
# define H(_)_(ah)_(al)_(ch)_(cl)_(dh)_(dl)_(bh)_(bl)
#else
# define H(_)_(al)_(ah)_(cl)_(ch)_(dl)_(dh)_(bl)_(bh)
#endif
#define X(_)_(ax)_(cx)_(dx)_(bx)_(sp)_(bp)_(si)_(di)_(ip)_(fl)
#define HR(_)_=(UC*)(reg+i++);
#define XR(_)_=(US*)(reg+i);i+=2;
#define HD(_)UC*_;
#define XD(_)US*_;
H(HD)X(XD)init(){I i=0;H(HR)i=0;X(XR)}
load(C*f){struct stat s; FILE*fp=fopen(f,"rb");
fstat(fileno(fp),&s); fread(mem,s.st_size,1,fp);
*sp=0x100;}
U get_b(U p){R mem[p];}
U get_w(U p){R mem[p]+(mem[p+1]<<8);}
U get(U p,I w){R w?get_w(p):get_b(p);}
U fetchb(){R get_b((*ip)++);}
U fetchw(){I w=fetchb();R w+(fetchb()<<8);}
storeb(U p,UC b){mem[p]=b;}
storew(U p,US w){mem[p]=w&0xff;mem[p+1]=w>>8;}
store(U p,U x,U w){w?storew(p,x):storeb(p,x);}
#define HP(_)P(#_ ":%02x ",*_);
#define XP(_)P(#_ ":%04x ",*_);
dump(){ //H(HP)P("\n");
X(XP)P("\n"); }
T struct tup{UC*d,*l,*r;}tup;
struct tup mrm(U m,I w){
U rm=m&07, re=(m>>3)&07, mo=(m>>6)&03;
R(tup){ };
}

#define MRM(w) tup t=mrm(fetchb(),w);
#define OP(_)\
_(addbf, MRM(0) ) \
_(hlt, halt=1)
#define OPF(a,b)void a(){b;}
#define OPN(a,b)a,
OP(OPF)void(*tab[])()={OP(OPN)};

run(){while(!halt){dump();tab[w=fetchb()]();}}

I main(I c,C**v){
init();
if(c){//load(v[1]);
run();}
R 0;}


Message has been deleted

luser droog

unread,
Jun 27, 2015, 4:28:14 AM6/27/15
to
Forgot the link and s#!%. This is the source that I'm "porting".
http://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu/9065#9065
The question at the top describes the subset I'm targeting.
If you're new to 8086 machine code, don't bother with my chickenscratch
above, and don't click any of those links except the 1979 manual.
Everything else on the net is polluted with 32bit stuff which is not
needed here. Hope to see more programs posted. It is not a code-golf
competition. Your code does not need to look like mine.

Ian Collins

unread,
Jun 27, 2015, 5:38:34 AM6/27/15
to
luser droog wrote:
> Brain going numb trying to overdesign this apl jiterpreter,
> and reading this tutorial on category theory for programmers.
> So I tried a little fun project to rewrite my postscript
> 8086 emulator to (superterse) C.
>
> And then I got stumped. I'm trying to handle the decoding
> of the mod-reg-reg/mod byte, and I want to represent it
> as a "tuple" of {destination-pointer, left-opand, right-op},
> but I'm getting hung up trying to define this structure
> so it handles byte or word data conveniently.
>
> I want to have the arguments and result available for
> calculating flags, hence the "tuple" idea. But, well,
> hopefully the English here explains where I'm stumped.
> The code, ... ....
>
> cat a8086.c
> #include<stdio.h>
> #include<sys/stat.h>
> #include<unistd.h>
> #define P printf
> #define R return
> #define T typedef

I'm sure most readers switch off at this point...

--
Ian Collins

luser droog

unread,
Jun 27, 2015, 5:51:44 AM6/27/15
to
Understood, but I'm in so deep I fear only a brave few
may save me. But, if you stop there, you miss the
X macro.

#define X(_)_(ax)_(cx)_(dx)_(bx)_(sp)_(bp)_(si)_(di)_(ip)_(fl)

--
The X makes it sound cool. -john dimaggio

Rick C. Hodgin

unread,
Jun 27, 2015, 6:07:40 AM6/27/15
to
This is currently setup for i686, but you could
modify it for 8086 only. I modified it one time
so I could debug my floppy boot loader:

https://github.com/RickCHodgin/libsf/tree/master/source/unsorted/DebiX86Disassembler

Best regards,
Rick C. Hodgin

Rick C. Hodgin

unread,
Jun 27, 2015, 6:58:42 AM6/27/15
to
Here's the original assembly version that C code
is based upon:

https://github.com/RickCHodgin/libsf-full/tree/master/_exodus/source/x86

Richard Heathfield

unread,
Jun 27, 2015, 8:02:37 AM6/27/15
to
On 27/06/15 10:51, luser droog wrote:
> On Saturday, June 27, 2015 at 4:38:34 AM UTC-5, Ian Collins wrote:
>> luser droog wrote:
>> > Brain going numb trying to overdesign this apl jiterpreter,
>> > and reading this tutorial on category theory for programmers.
>> > So I tried a little fun project to rewrite my postscript
>> > 8086 emulator to (superterse) C.
>> >
>> > And then I got stumped. I'm trying to handle the decoding
>> > of the mod-reg-reg/mod byte, and I want to represent it
>> > as a "tuple" of {destination-pointer, left-opand, right-op},
>> > but I'm getting hung up trying to define this structure
>> > so it handles byte or word data conveniently.
>> >
>> > I want to have the arguments and result available for
>> > calculating flags, hence the "tuple" idea. But, well,
>> > hopefully the English here explains where I'm stumped.
>> > The code, ... ....
>> >
>> > cat a8086.c
>> > #include<stdio.h>
>> > #include<sys/stat.h>
>> > #include<unistd.h>
>> > #define P printf
>> > #define R return
>> > #define T typedef
>>
>> I'm sure most readers switch off at this point...

I did.

> Understood, but I'm in so deep I fear only a brave few
> may save me. But, if you stop there, you miss the
> X macro.

I did.

But I like to imagine myself as being one of the brave few, so I *will*
at least try to save you, and here's how:

*Lose the macros*. They're not helping you. The only possible
justification for them is in an IOCCC entry.

--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

Ben Bacarisse

unread,
Jun 27, 2015, 9:25:34 AM6/27/15
to
I went all the way through, and I still had no idea what was being
asked.

>> Understood, but I'm in so deep I fear only a brave few
>> may save me. But, if you stop there, you miss the
>> X macro.
>
> I did.
>
> But I like to imagine myself as being one of the brave few, so I
> *will* at least try to save you, and here's how:
>
> *Lose the macros*. They're not helping you. The only possible
> justification for them is in an IOCCC entry.

In a way it is. Not specifically IOCCC but it is a game -- the aim
being to be make the source code compact.

It's not a metric that interests me. I'm fine with smallest object
code, fastest execution, clearest exposition, neatest design and so one,
but the most compact source is just a negative objective -- it obscures
the code without any corresponding gain. Lots of other people seem to
like the game, though.

--
Ben.

luser droog

unread,
Jun 29, 2015, 12:21:10 AM6/29/15
to
On Saturday, June 27, 2015 at 3:28:14 AM UTC-5, luser droog wrote:
> On Saturday, June 27, 2015 at 2:34:56 AM UTC-5, luser droog wrote:
> > Brain going numb trying to overdesign this apl jiterpreter,
> > and reading this tutorial on category theory for programmers.
> > So I tried a little fun project to rewrite my postscript
> > 8086 emulator to (superterse) C.
> >
> > And then I got stumped. I'm trying to handle the decoding
> > of the mod-reg-reg/mod byte, and I want to represent it
> > as a "tuple" of {destination-pointer, left-opand, right-op},
> > but I'm getting hung up trying to define this structure
> > so it handles byte or word data conveniently.
> >
> > I want to have the arguments and result available for
> > calculating flags, hence the "tuple" idea. But, well,
> > hopefully the English here explains where I'm stumped.
> > The code, ... ....
> >
>
> Forgot the link and s#!%. This is the source that I'm "porting".
> http://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu/9065#9065
> The question at the top describes the subset I'm targeting.
> If you're new to 8086 machine code, don't bother with my chickenscratch
> above, and don't click any of those links except the 1979 manual.
> Everything else on the net is polluted with 32bit stuff which is not
> needed here. Hope to see more programs posted. It is not a code-golf
> competition. Your code does not need to look like mine.


Following my source material more closely shewed the way.
There was nothing more to write in that "tup" function because its job
was already done. And in fact the whole "tup" thing was unnecessary.
The place to store the values I needed is ... variables. It's like
they were /designed/ to hold values so they can be used in subsequent
expressions.


So, here's some progress. 4 opcodes. Read it + weep.

josh@Z1 ~
$ cat a8086.c
#include<stdint.h>
#include<stdio.h>
#include<sys/stat.h>
#include<unistd.h>
#define P printf
#define R return
#define T typedef
T intptr_t I; T uintptr_t U;
T short S; T unsigned short US;
T char C; T unsigned char UC;
U w,x,y,z;
void *p;
UC halt,trace=1,reg[20],mem[0xffff]={
1, (3<<6), // ADD ax,ax
1, (3<<6)+(4<<3), // ADD ax,sp
3, (3<<6)+(4<<3), // ADD sp,ax
4 //HLT
};
#ifdef BIGENDIAN
# define H(_)_(ah)_(al)_(ch)_(cl)_(dh)_(dl)_(bh)_(bl)
#else
# define H(_)_(al)_(ah)_(cl)_(ch)_(dl)_(dh)_(bl)_(bh)
#endif
#define X(_)_(ax)_(cx)_(dx)_(bx)_(sp)_(bp)_(si)_(di)_(ip)_(fl)
#define HR(_)_=(UC*)(reg+i++);
#define XR(_)_=(US*)(reg+i);i+=2;
#define HD(_)UC*_;
#define XD(_)US*_;
H(HD)X(XD)init(){I i=0;H(HR)i=0;X(XR)}
enum { CF=1, AF=1<<4, ZF=1<<6, SF=1<<7, OF=1<<11 };

#define HP(_)P(#_ ":%02x ",*_);
#define XP(_)P(#_ ":%04x ",*_);
dump(){ //H(HP)P("\n");
X(XP)P("\n"); }

U get_b(U p){R mem[p];}
U get_w(U p){R mem[p]+(mem[p+1]<<8);}
U get(U p,I w){R w?get_w(p):get_b(p);}
U fetchb(){R get_b((*ip)++);}
U fetchw(){I w=fetchb();R w+(fetchb()<<8);}
storeb(U p,UC b){mem[p]=b;}
storew(U p,US w){mem[p]=w&0xff;mem[p+1]=w>>8;}
store(U p,U x,U w){w?storew(p,x):storeb(p,x);}

T struct rm{U mod,reg,r_m;}rm;
rm mrm(U m){ R(rm){ (m>>6)&3, (m>>3)&7, m&7 }; }
U decreg(U reg,U w){
if (w)R (U)((US*[]){ax,cx,dx,bx,sp,bp,si,di}[reg]);
else R (U)((UC*[]){al,cl,dl,bl,ah,ch,dh,bh}[reg]); }
U decrm(rm r,U w){
U x=(U[]){*bx+*si,*bx+*di,*bp+*si,*bp+*di,*si,*di, *bp,*bx}[r.r_m];
switch(r.mod){ case 0: if (r.r_m==6) R fetchw(); break;
case 1: x+=fetchb(); break;
case 2: x+=fetchw(); break;
case 3: R decreg(r.r_m,w); }
R (U)(mem+x); }

#define MRM(d,w) rm r=mrm(fetchb());\
x=decreg(r.reg,w); \
y=decrm(r,w); \
if(trace){ \
P("%s:\n",__func__); \
if(trace>1){ P("x:%d\n",x); P("y:%d\n",y); } \
} \
p=d?(void*)x:(void*)y; \
x=w?*(US*)x:*(UC*)x; \
y=w?*(US*)y:*(UC*)y; \
if(trace){ \
P("x:%d\n",x); P("y:%d\n",y); \
} \

#define LOGFLAGS(w) *fl=0; \
*fl |= ( (z&(w?0x8000:0x80)) ?SF:0) \
| ( (z&(w?0xffff:0xff)) ?ZF:0) ;
#define MATHFLAGS(w) *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) \
| ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) \
| ( ((x^y^z)&0x10) ?AF:0) ;
#define RESULT(w) if(w)*(US*)p=z;else*(UC*)p=z;

#define ADD(w) z=x+y; LOGFLAGS(w) MATHFLAGS(w) RESULT(w)
#define OR(w) z=x|y; LOGFLAGS(w) RESULT(w)

#define OP(_)\
_(addbf, MRM(0,0) ADD(0) ) \
_(addwf, MRM(0,1) ADD(1) ) \
_(addbt, MRM(1,0) ADD(0) ) \
_(addwt, MRM(1,1) ADD(1) ) \
_(hlt, halt=1)
#define OPF(a,b)void a(){b;}
#define OPN(a,b)a,
OP(OPF)void(*tab[])()={OP(OPN)};

I load(C*f){struct stat s; FILE*fp;
R (fp=fopen(f,"rb")) && fstat(fileno(fp),&s) || fread(mem,s.st_size,1,fp); }

run(){while(!halt){if(trace)dump(); tab[w=fetchb()]();}}

I main(I c,C**v){
init();
if(c){//load(v[1]);
*sp=0x100;
run();}
R 0;}


josh@Z1 ~
$ wc !$
wc a8086.c
105 316 3253 a8086.c

josh@Z1 ~
$ !m&&!.
make a8086&&./a8086
cc a8086.c -o a8086
ax:0000 cx:0000 dx:0000 bx:0000 sp:0100 bp:0000 si:0000 di:0000 ip:0000 fl:0000
addwf:
x:0
y:0
ax:0000 cx:0000 dx:0000 bx:0000 sp:0100 bp:0000 si:0000 di:0000 ip:0002 fl:0000
addwf:
x:256
y:0
ax:0100 cx:0000 dx:0000 bx:0000 sp:0100 bp:0000 si:0000 di:0000 ip:0004 fl:0040
addwt:
x:256
y:256
ax:0100 cx:0000 dx:0000 bx:0000 sp:0200 bp:0000 si:0000 di:0000 ip:0006 fl:0040

josh@Z1 ~
$

--
+ is bitwise OR on boolean predicates.

luser droog

unread,
Jun 29, 2015, 1:50:50 AM6/29/15
to
On Saturday, June 27, 2015 at 3:28:14 AM UTC-5, luser droog wrote:
> On Saturday, June 27, 2015 at 2:34:56 AM UTC-5, luser droog wrote:
> > Brain going numb trying to overdesign this apl jiterpreter,
> > and reading this tutorial on category theory for programmers.
> > So I tried a little fun project to rewrite my postscript
> > 8086 emulator to (superterse) C.
> >
...
> Forgot the link and s#!%. This is the source that I'm "porting".
> http://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu/9065#9065
> The question at the top describes the subset I'm targeting.
> If you're new to 8086 machine code, don't bother with my chickenscratch
> above, and don't click any of those links except the 1979 manual.
> Everything else on the net is polluted with 32bit stuff which is not
> needed here. Hope to see more programs posted. It is not a code-golf
> competition. Your code does not need to look like mine.

I forgot in this thread to extoll the virtue of the goldfish^H^H^H^H^H^H^H^H
golf-ish coding style, not in general but for this program in particular.
If you open your books (8086 Family User's Manual)
http://matthieu.benoit.free.fr/cross/data_sheets/Intel_8086_users_manual.htm
to page 180 and have a look at table 4-14, the Machine Instruction
Encoding Matrix. It's a concise summary of the entire ISA. Now, you
already know what I'm gonna say, and I already know you're not trying to
hear it, na'thless it must be said.

Golfing it up lets format of the code match the specification format.
That's what I did in postscript.

/OPTAB{
{b f rm ADD}{w f rm ADD}{b t rm ADD}{w t rm ADD}{b ia ADD}{w ia ADD}{ES PUSH}{ES POP} %00-07
{b f rm OR}{w f rm OR}{b t rm OR}{w t rm OR}{b ia OR}{w ia OR}{CS PUSH}{} %08-0F
{b f rm ADC}{w f rm ADC}{b t rm ADC}{w t rm ADC}{b ia ADC}{w ia ADC}{SS PUSH}{SS POP} %10-17
{b f rm SBB}{w f rm SBB}{b t rm SBB}{w t rm SBB}{b ia SBB}{w ia SBB}{DS PUSH}{DS POP}%18-1F
{b f rm AND}{w f rm AND}{b t rm AND}{w t rm AND}{b ia AND}{w ia AND}{ES SEG}{DAA} %20-27
{b f rm SUB}{w f rm SUB}{b t rm SUB}{w t rm SUB}{b ia SUB}{w ia SUB}{CS SEG}{DAS} %28-2F
{b f rm XOR}{w f rm XOR}{b t rm XOR}{w t rm XOR}{b ia XOR}{w ia XOR}{SS SEG}{AAA} %30-37
{b f rm CMP}{w f rm CMP}{b t rm CMP}{w t rm CMP}{b ia CMP}{w ia CMP}{DS SEG}{AAS} %38-3F
{w AX INC}{w CX INC}{w DX INC}{w BX INC}{w SP INC}{w BP INC}{w SI INC}{w DI INC} %40-47
{w AX DEC}{w CX DEC}{w DX DEC}{w BX DEC}{w SP DEC}{w BP DEC}{w SI DEC}{w DI DEC} %48-4F
{AX PUSH}{CX PUSH}{DX PUSH}{BX PUSH}{SP PUSH}{BP PUSH}{SI PUSH}{DI PUSH} %50-57
{AX POP}{CX POP}{DX POP}{BX POP}{SP POP}{BP POP}{SI POP}{DI POP} %58-5F
{}{}{}{}{}{}{}{} {}{}{}{}{}{}{}{} %60-6F
{JO}{JNO}{JB}{JNB}{JZ}{JNZ}{JBE}{JNBE} {JS}{JNS}{JP}{JNP}{JL}{JNL}{JLE}{JNLE} %70-7F

{b f immed}{w f immed}{b f immed}{is f immed}{b TEST}{w TEST}{b rmp XCHG}{w rmp XCHG} %80-87
{b f rm pMOV}{w f rm pMOV}{b t rm pMOV}{w t rm pMOV} %88-8B
{sr f rm pMOV}{LEA}{sr t rm pMOV}{w mrm decrm POP} %8C-8F
{NOP}{CX AXCH}{DX AXCH}{BX AXCHG}{SP AXCH}{BP AXCH}{SI AXCH}{DI AXCH} %90-97
{CBW}{CWD}{far CALL}{WAIT}{PUSHF}{POPF}{SAHF}{LAHF} %98-9F
{b AL m MOV}{w AX m MOV}{b m AL MOV}{b AX m MOV}{MOVS}{MOVS}{CMPS}{CMPS} %A0-A7
{b i a TEST}{w i a TEST}{STOS}{STOS}{LODS}{LODS}{SCAS}{SCAS} %A8-AF
{b AL i MOV}{b CL i MOV}{b DL i MOV}{b BL i MOV} %B0-B3
{b AH i MOV}{b CH i MOV}{b DH i MOV}{b BH i MOV} %B4-B7
{w AX i MOV}{w CX i MOV}{w DX i MOV}{w BX i MOV} %B8-BB
{w SP i MOV}{w BP i MOV}{w SI i MOV}{w DI i MOV} %BC-BF
{}{}{fetchw RET}{0 RET}{LES}{LDS}{b f rm i mMOV}{w f rm i mMOV} %C0-B7
{}{}{fetchw RET}{0 RET}{3 INT}{fetchb INT}{INTO}{IRET} %C8-CF
{b Shift}{w Shift}{b v Shift}{w v Shift}{AAM}{AAD}{}{XLAT} %D0-D7
{0 ESC}{1 ESC}{2 ESC}{3 ESC}{4 ESC}{5 ESC}{6 ESC}{7 ESC} %D8-DF
{LOOPNZ}{LOOPZ}{LOOP}{JCXZ}{b IN}{w IN}{b OUT}{w OUT} %E0-E7
{CALL}{JMP}{far JMP}{sJMP}{v b IN}{v w IN}{v b OUT}{v w OUT} %E8-EF
{LOCK}{}{REP}{z REP}{HLT}{CMC}{b Grp1}{w Grp} %F0-F7
{CLC}{STC}{CLI}{STI}{CLD}{STD}{b Grp2}{w Grp2} %F8-FF
}cvlit

That's what I intend to do to C. It permits a close
visual verification that the program matches the spec.
You may advise if you wish, admonish if you must,
daydream if it's like /literally literally/ unreadable
and your fovea just will not sit still on that tight
cluster of shapes or use `indent` if you're interested.

I think it's fun. I wish to share the fun that I have.

--
As a simple proposal, let's just eat your babies.

luser droog

unread,
Jul 1, 2015, 6:36:14 PM7/1/15
to
Almost halfway through the opcodes and now I do have a question.
Is it possible to generate symbols automatically with the preprocessor
somehow?

I'm building the opcode table as a function-pointer array with X-Macros.
But then I wondered if I could just lose the function name, since it only
serves as a placeholder to populate the table?

#define FTAB(_) \
_(FNAME, BODY)
#define DEFFUNC(name, body) \
void name(void){ body; }
#define FUNCNAME(name, body) \
name ,
FTAB(DEFFUNC) // define actual functions
void (*tab[])(void) = { FTAB(FUNCNAME) }; // define and populate table

If instead I use a switch statement, then I still need two generators
to define the symbols separately.

#define DOBODY(name, body) \
case name: body; break;
enum { FTAB(FUNCNAME) };

...
switch(opcode){ FTAB(DOBODY) }
...

So, I just need a ... gensym, or a way to generate an integer sequence
of the appro... or just a successor function that expands to an
appropriate number of 1+1+1+1+1, peano style.

Can the preprocessor do that? Specifically, I want to eliminate the
enum in the second snippet, and replace the 'name:' in the case label
with an automatically generated symbol or 0-255 sequence of integers.


ok. It's that time again. Hide the babies.

josh@Z1 ~
$ cat a8*c
#include<stdint.h>
#include<stdio.h>
#include<sys/stat.h>
#include<unistd.h>
#define P printf
#define R return
#define T typedef
T intptr_t I; T uintptr_t U;
T short S; T unsigned short US;
T char C; T unsigned char UC;
U o,d,w,x,y,z,f;
void *p;
UC halt,trace=1,reg[20],null[2],mem[0xffff]={
1, (3<<6), // ADD ax,ax
1, (3<<6)+(4<<3), // ADD ax,sp
3, (3<<6)+(4<<3), // ADD sp,ax
0x70 //HLT
};
#ifdef BIGENDIAN
# define H(_)_(ah)_(al)_(ch)_(cl)_(dh)_(dl)_(bh)_(bl)
#else
# define H(_)_(al)_(ah)_(cl)_(ch)_(dl)_(dh)_(bl)_(bh)
#endif
#define X(_)_(ax)_(cx)_(dx)_(bx)_(sp)_(bp)_(si)_(di)_(ip)_(fl)_(cs)_(ds)_(ss)_(es)
#define HR(_)_=(UC*)(reg+i++);
#define XR(_)_=(US*)(reg+i);i+=2;
#define HD(_)UC*_;
#define XD(_)US*_;
H(HD)X(XD)init(){I i=0;H(HR)i=0;X(XR)}
enum { CF=1, AF=1<<4, ZF=1<<6, SF=1<<7, OF=1<<11 };

#define HP(_)P(#_ ":%02x ",*_);
#define XP(_)P(#_ ":%04x ",*_);
dump(){ //H(HP)P("\n");
X(XP)P("\n"); }

U get_(void*p,U w){R w? *(UC*)p + (((UC*)p)[1]<<8) :*(UC*)p;}
put_(void*p,U x,U w){ if(w){ *(UC*)p=x; ((UC*)p)[1]; }else *(UC*)p=x; }
U fetchb(){R get_(mem+(*ip)++,0);}
U fetchw(){I w=fetchb();R w+(fetchb()<<8);}

T struct rm{U mod,reg,r_m;}rm;
rm mrm(U m){ R(rm){ (m>>6)&3, (m>>3)&7, m&7 }; }
U decreg(U reg,U w){
if (w)R (U)((US*[]){ax,cx,dx,bx,sp,bp,si,di}[reg]);
else R (U)((UC*[]){al,cl,dl,bl,ah,ch,dh,bh}[reg]); }
U decrm(rm r,U w){
U x=(U[]){*bx+*si,*bx+*di,*bp+*si,*bp+*di,*si,*di, *bp,*bx}[r.r_m];
switch(r.mod){ case 0: if (r.r_m==6) R (U)(mem+fetchw()); break;
case 1: x+=fetchb(); break;
case 2: x+=fetchw(); break;
case 3: R decreg(r.r_m,w); }
R (U)(mem+x); }

#define DW if(trace){ P("%s:\n",__func__); } \
d=!!(o&2); \
w=o&1;
#define RM rm r=mrm(fetchb());\
x=decreg(r.reg,w); \
y=decrm(r,w); \
if(trace>1){ P("x:%d\n",x); P("y:%d\n",y); } \
p=d?(void*)x:(void*)y; \
x=get_((void*)x,w); \
y=get_((void*)y,w); \
if(trace){ \
P("x:%d\n",x); P("y:%d\n",y); \
}

#define IA x=(U)(p=w?(UC*)ax:al); \
x=get_((void*)x,w); \
y=w?fetchw():fetchb();

#define LOGFLAGS *fl=0; \
*fl |= ( (z&(w?0x8000:0x80)) ?SF:0) \
| ( (z&(w?0xffff:0xff)) ?ZF:0) ;
#define MATHFLAGS *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) \
| ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) \
| ( ((x^y^z)&0x10) ?AF:0) ;
#define RESULT put_(p,z,w);

#define PUSH(x) put_(mem+(*sp-=2),*x,1)
#define POP(x) *x=get_(mem+*sp,1); *sp+=2;
#define ADD z=x+y; LOGFLAGS MATHFLAGS RESULT
#define ADC x+=(*fl&CF); ADD
#define SUB z=d?y-x:x-y; LOGFLAGS MATHFLAGS RESULT
#define SBB d?x+=*fl&CF:(y+=*fl&CF); SUB
#define CMP p=null; SUB
#define AND z=x&y; LOGFLAGS RESULT
#define OR z=x|y; LOGFLAGS RESULT
#define XOR z=x^y; LOGFLAGS RESULT
#define INC(r) w=1; d=1; p=r; x=*r; y=1; f=*fl&CF; ADD *fl=(*fl&~CF)|f;
#define DEC(r) w=1; d=1; p=r; x=*r; y=1; f=*fl&CF; SUB *fl=(*fl&~CF)|f;

#define OP(_)\
/*dw:bf wf bt wt */ \
_(addbf, RM ADD) _(addwf, RM ADD) _(addbt, RM ADD) _(addwt, RM ADD) /*00-03*/\
_(addbi, IA ADD) _(addwi, IA ADD) _(pushes, PUSH(es)) _(popes, POP(es)) /*04-07*/\
_(orbf, RM OR) _(orwf, RM OR) _(orbt, RM OR) _(orwt, RM OR) /*08-0b*/\
_(orbi, IA OR) _(orwi, IA OR) _(pushcs, PUSH(cs)) _(nop0, ) /*0c-0f*/\
_(adcbf, RM ADC) _(adcwf, RM ADC) _(adcbt, RM ADC) _(adcwt, RM ADC) /*10-13*/\
_(adcbi, IA ADC) _(adcwi, IA ADC) _(pushss, PUSH(ss)) _(popss, POP(ss)) /*14-17*/\
_(sbbbf, RM SBB) _(sbbwf, RM SBB) _(sbbbt, RM SBB) _(sbbwt, RM SBB) /*18-1b*/\
_(sbbbi, IA SBB) _(sbbwi, IA SBB) _(pushds, PUSH(ds)) _(popds, POP(ds)) /*1c-1f*/\
_(andbf, RM AND) _(andwf, RM AND) _(andbt, RM AND) _(andwt, RM AND) /*20-23*/\
_(andbi, IA AND) _(andwi, IA AND) _(esseg, ) _(daa, ) /*24-27*/\
_(subbf, RM SUB) _(subwf, RM SUB) _(subbt, RM SUB) _(subwt, RM SUB) /*28-2b*/\
_(subbi, IA SUB) _(subwi, IA SUB) _(csseg, ) _(das, ) /*2c-2f*/\
_(xorbf, RM XOR) _(xorwf, RM XOR) _(xorbt, RM XOR) _(xorwt, RM XOR) /*30-33*/\
_(xorbi, IA XOR) _(xorwi, IA XOR) _(ssseg, ) _(aaa, ) /*34-37*/\
_(cmpbf, RM CMP) _(cmpwf, RM CMP) _(cmpbt, RM CMP) _(cmpwt, RM CMP) /*38-3b*/\
_(cmpbi, IA CMP) _(cmpwi, IA CMP) _(dsseg, ) _(aas, ) /*3c-3f*/\
_(incax, INC(ax)) _(inccx, INC(cx)) _(incdx, INC(dx)) _(incbx, INC(bx)) /*40-43*/\
_(incsp, INC(sp)) _(incbp, INC(bp)) _(incsi, INC(si)) _(incdi, INC(di)) /*44-47*/\
_(decax, DEC(ax)) _(deccx, DEC(cx)) _(decdx, DEC(dx)) _(decbx, DEC(bx)) /*48-4b*/\
_(decsp, DEC(sp)) _(decbp, DEC(bp)) _(decsi, DEC(si)) _(decdi, DEC(di)) /*4c-4f*/\
_(pushax, PUSH(ax)) _(pushcx, PUSH(cx)) _(pushdx, PUSH(dx)) _(pushbx, PUSH(bx)) /*50-53*/\
_(pushsp, PUSH(sp)) _(pushbp, PUSH(bp)) _(pushsi, PUSH(si)) _(pushdi, PUSH(di)) /*54-57*/\
_(popax, POP(ax)) _(popcx, POP(cx)) _(popdx, POP(dx)) _(popbx, POP(bx)) /*58-5b*/\
_(popsp, POP(sp)) _(popbp, POP(bp)) _(popsi, POP(si)) _(popdi, POP(di)) /*5c-5f*/\
_(nop1, ) _(nop2, ) _(nop3, ) _(nop4, ) _(nop5, ) _(nop6, ) _(nop7, ) _(nop8, ) /*60-67*/\
_(nop9, ) _(nopA, ) _(nopB, ) _(nopC, ) _(nopD, ) _(nopE, ) _(nopF, ) _(nopG, ) /*68-6f*/\
_(hlt, halt=1) //70
#define OPF(a,b)void a(){DW b;}
#define OPN(a,b)a,
OP(OPF)void(*tab[])()={OP(OPN)};
run(){while(!halt){if(trace)dump(); tab[o=fetchb()]();}}

I load(C*f){struct stat s; FILE*fp;
R (fp=fopen(f,"rb"))
&& fstat(fileno(fp),&s) || fread(mem,s.st_size,1,fp); }

I main(I c,C**v){
init();
if(c){//load(v[1]);

luser droog

unread,
Jul 1, 2015, 7:02:45 PM7/1/15
to
There is a way that I've done this before.

If, instead of a switch, the selection used an if/else chain, then
the sequencing can be supplied by incrementing a variable in each
condition.
http://codegolf.stackexchange.com/questions/19151/build-interpreter-for-non-existent-language/19240#19240
But I don't want to pay the runtime "penalty".

Rick C. Hodgin

unread,
Jul 1, 2015, 7:11:54 PM7/1/15
to

luser droog

unread,
Jul 1, 2015, 7:52:32 PM7/1/15
to
Ah. But for this challenge the rules explicitly say "no two-byte ops".
I will need to know this later if/when I extend it.

Rick C. Hodgin

unread,
Jul 1, 2015, 7:56:57 PM7/1/15
to
Look at the debi.cpp code. It uses one-byte opcode
for first branch. If it's a two-byte opcode, it uses the
second. There are two-byte opcodes in x86.

Rick C. Hodgin

unread,
Jul 2, 2015, 1:12:32 AM7/2/15
to

luser droog

unread,
Jul 10, 2015, 1:52:01 PM7/10/15
to
On Saturday, June 27, 2015 at 2:34:56 AM UTC-5, luser droog wrote:
> Brain going numb trying to overdesign this apl jiterpreter,
> and reading this tutorial on category theory for programmers.
> So I tried a little fun project to rewrite my postscript
> 8086 emulator to (superterse) C.

Posted!
http://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu/52902#52902

It mostly works. still some bugs I need to track down.
Fortunately, I have the other working version I can test
against by running both step by step in parallel (by
which I mean two xterm windows and repeated sequences
of ALT-TAB ENTER).

luser droog

unread,
Jul 11, 2015, 3:51:58 AM7/11/15
to
On Saturday, June 27, 2015 at 7:02:37 AM UTC-5, somebody wrote:
>
> *Lose the macros*.

non-wrapped at:
https://gist.github.com/luser-dr00g/aef0342cb4a63d682c13

#include<ctype.h>
#include<stdint.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<unistd.h>
typedef intptr_t I; typedef uintptr_t U;
typedef short S; typedef unsigned short US;
typedef signed char C; typedef unsigned char UC;
typedef void V;
U o,w,d,f;
U x,y,z;
void *p;
UC halt,debug=0,trace=2,reg[28],null[2],mem[0xffff]={
1, (3<<6),
1, (3<<6)+(4<<3),
3, (3<<6)+(4<<3),
0xf4
};
UC*al;UC*ah;UC*cl;UC*ch;UC*dl;UC*dh;UC*bl;UC*bh;US*ax;US*cx;US*dx;US*bx;US*sp;US*bp;US*si;US*di;US*ip;US*fl;US*cs;US*ds;US*ss;US*es;V init(){I i=0;al=(UC*)(reg+i++);ah=(UC*)(reg+i++);cl=(UC*)(reg+i++);ch=(UC*)(reg+i++);dl=(UC*)(reg+i++);dh=(UC*)(reg+i++);bl=(UC*)(reg+i++);bh=(UC*)(reg+i++);i=0;ax=(US*)(reg+i);i+=2;cx=(US*)(reg+i);i+=2;dx=(US*)(reg+i);i+=2;bx=(US*)(reg+i);i+=2;sp=(US*)(reg+i);i+=2;bp=(US*)(reg+i);i+=2;si=(US*)(reg+i);i+=2;di=(US*)(reg+i);i+=2;ip=(US*)(reg+i);i+=2;fl=(US*)(reg+i);i+=2;cs=(US*)(reg+i);i+=2;ds=(US*)(reg+i);i+=2;ss=(US*)(reg+i);i+=2;es=(US*)(reg+i);i+=2;}
enum { CF=1, AF=1<<4, ZF=1<<6, SF=1<<7, OF=1<<11 };
V dump(){
printf("\n"); printf("ax" ":%04x ",*ax);printf("cx" ":%04x ",*cx);printf("dx" ":%04x ",*dx);printf("bx" ":%04x ",*bx);printf("sp" ":%04x ",*sp);printf("bp" ":%04x ",*bp);printf("si" ":%04x ",*si);printf("di" ":%04x ",*di);printf("ip" ":%04x ",*ip);printf("fl" ":%04x ",*fl);
if(trace)printf("%s %s %s %s ",*fl&CF?"CA":"NC",*fl&OF?"OV":"NO",*fl&SF?"SN":"NS",*fl&ZF?"ZR":"NZ");
printf("\n");
}
I get_(void*p,U w){return w? *(UC*)p + (((UC*)p)[1]<<8) :*(UC*)p;}
V put_(void*p,U x,U w){ if(w){ *(UC*)p=x; ((UC*)p)[1]=x>>8; }else *(UC*)p=x; }
UC fetchb(){ U x = get_(mem+(*ip)++,0); if(trace)printf("%02x(%03o) ",x,x); return x; }
US fetchw(){I w=fetchb();return w|(fetchb()<<8);}
typedef struct rm{U mod,reg,r_m;}rm;
rm mrm(U m){ return(rm){ (m>>6)&3, (m>>3)&7, m&7 }; }
U decreg(U reg,U w){
if (w)return (U)((US*[]){ax,cx,dx,bx,sp,bp,si,di}[reg]);
else return (U)((UC*[]){al,cl,dl,bl,ah,ch,dh,bh}[reg]); }
U decrm(rm r,U w){
U x=(U[]){*bx+*si,*bx+*di,*bp+*si,*bp+*di,*si,*di, *bp,*bx}[r.r_m];
switch(r.mod){ case 0: if (r.r_m==6) return (U)(mem+fetchw()); break;
case 1: x+=fetchb(); break;
case 2: x+=fetchw(); break;
case 3: return decreg(r.r_m,w); }
return (U)(mem+x); }
void addbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void addwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void addbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void addwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void addbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void addwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void pushes(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(es),1);} void popes(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(es)=get_(mem+(*sp+=2)-2,1);} void orbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void orwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void orbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void orwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void orbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void orwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void pushcs(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(cs),1);} void nop0(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void adcbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void adcwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void adcbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void adcwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void adcbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void adcwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void pushss(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(ss),1);} void popss(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(ss)=get_(mem+(*sp+=2)-2,1);} void sbbbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void sbbwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void sbbbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void sbbwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void sbbbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void sbbwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void pushds(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(ds),1);} void popds(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(ds)=get_(mem+(*sp+=2)-2,1);} void andbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void andwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void andbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void andwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void andbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void andwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void esseg(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void daa(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void subbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void subwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void subbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void subwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void subbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void subwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void csseg(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void das(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void xorbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void xorwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void xorbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void xorwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void xorbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void xorwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void ssseg(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void aaa(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void cmpbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void cmpwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void cmpbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void cmpwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void cmpbi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void cmpwi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void dsseg(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void aas(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void incax(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)ax; x=(S)*ax; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void inccx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)cx; x=(S)*cx; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void incdx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)dx; x=(S)*dx; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void incbx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)bx; x=(S)*bx; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void incsp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)sp; x=(S)*sp; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void incbp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)bp; x=(S)*bp; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void incsi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)si; x=(S)*si; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void incdi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)di; x=(S)*di; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void decax(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)ax; x=(S)*ax; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void deccx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)cx; x=(S)*cx; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void decdx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)dx; x=(S)*dx; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void decbx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)bx; x=(S)*bx; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void decsp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)sp; x=(S)*sp; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void decbp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)bp; x=(S)*bp; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void decsi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)si; x=(S)*si; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void decdi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; d=1; p=(V*)di; x=(S)*di; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;;} void pushax(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(ax),1);} void pushcx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(cx),1);} void pushdx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(dx),1);} void pushbx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(bx),1);} void pushsp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(sp),1);} void pushbp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(bp),1);} void pushsi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(si),1);} void pushdi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(di),1);} void popax(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(ax)=get_(mem+(*sp+=2)-2,1);} void popcx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(cx)=get_(mem+(*sp+=2)-2,1);} void popdx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(dx)=get_(mem+(*sp+=2)-2,1);} void popbx(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(bx)=get_(mem+(*sp+=2)-2,1);} void popsp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(sp)=get_(mem+(*sp+=2)-2,1);} void popbp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(bp)=get_(mem+(*sp+=2)-2,1);} void popsi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(si)=get_(mem+(*sp+=2)-2,1);} void popdi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(di)=get_(mem+(*sp+=2)-2,1);} void nop1(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop2(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop3(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop4(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop5(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop6(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop7(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop8(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nop9(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopA(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopB(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopC(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopD(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopE(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopF(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopG(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void jo(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", of); if(of)*ip+=(S)y;;} void jno(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", !(of)); if(!(of))*ip+=(S)y;;} void jb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", cf); if(cf)*ip+=(S)y;;} void jnb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", !(cf)); if(!(cf))*ip+=(S)y;;} void jz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", zf); if(zf)*ip+=(S)y;;} void jnz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", !(zf)); if(!(zf))*ip+=(S)y;;} void jbe(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", cf|zf); if(cf|zf)*ip+=(S)y;;} void jnbe(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", !(cf|zf)); if(!(cf|zf))*ip+=(S)y;;} void js(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", sf); if(sf)*ip+=(S)y;;} void jns(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", !(sf)); if(!(sf))*ip+=(S)y;;} void jp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void jnp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void jl(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", sf^of); if(sf^of)*ip+=(S)y;;} void jnl_(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", !(sf^of)); if(!(sf^of))*ip+=(S)y;;} void jle(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", (sf^of)|zf); if((sf^of)|zf)*ip+=(S)y;;} void jnle(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; U cf=!!(*fl&CF),of=!!(*fl&OF),sf=!!(*fl&SF),zf=!!(*fl&ZF); y=(S)(C)fetchb(); if(trace)printf("<%d> ", !((sf^of)|zf)); if(!((sf^of)|zf))*ip+=(S)y;;} void immb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); p=(void*)(y=decrm(r,w)); x=w?fetchw():fetchb(); d=0; y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(trace){ printf("%s ", (C*[]){"ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"}[r.reg]); } switch(r.reg){case 0:z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 1:z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 2:x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 3:d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 4:z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 5:z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 6:z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 7:p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; };} void immw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); p=(void*)(y=decrm(r,w)); x=w?fetchw():fetchb(); d=0; y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(trace){ printf("%s ", (C*[]){"ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"}[r.reg]); } switch(r.reg){case 0:z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 1:z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 2:x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 3:d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 4:z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 5:z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 6:z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 7:p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; };} void immb1(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); p=(void*)(y=decrm(r,w)); x=w?fetchw():fetchb(); d=0; y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(trace){ printf("%s ", (C*[]){"ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"}[r.reg]); } switch(r.reg){case 0:z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 1:z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 2:x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 3:d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 4:z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 5:z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 6:z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 7:p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; };} void immis(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); p=(void*)(y=decrm(r,w)); w=0; x=w?fetchw():fetchb(); w=1;x=(S)(C)x; d=0; y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(trace){ printf("%s ", (C*[]){"ADD","OR","ADC","SBB","AND","SUB","XOR","CMP"}[r.reg]); } switch(r.reg){case 0:z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 1:z=x|y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 2:x+=(*fl&CF); z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 3:d?y+=*fl&CF:(x+=*fl&CF); z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 4:z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 5:z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 6:z=x^y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; case 7:p=null; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); break; };} void testb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ;;} void testw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ;;} void xchgb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void xchgw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void movbf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?y:x; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void movwf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?y:x; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void movbt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?y:x; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void movwt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } z=d?y:x; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void movsegf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } ;} void lea(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; z=((UC*)y)-mem; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w);;} void movsegt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } ;} void poprm(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } *((US*)p)=get_(mem+(*sp+=2)-2,1);} void nopH(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void xchgac(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)ax; y=(U)(cx); w=1; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void xchgad(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)ax; y=(U)(dx); w=1; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void xchgab(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)ax; y=(U)(bx); w=1; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void xchgasp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)ax; y=(U)(sp); w=1; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void xchabp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)ax; y=(U)(bp); w=1; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void xchgasi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)ax; y=(U)(si); w=1; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void xchadi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)ax; y=(U)(di); w=1; f=x;z=y; x=get_((void*)x,w); y=get_((void*)y,w); if(trace){ printf("x:%d\n",x); printf("y:%d\n",y); } if(w){*(US*)f=y;*(US*)z=x;}else{*(UC*)f=y;*(UC*)z=x;};} void cbw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *ax=(S)(C)*al;;} void cwd(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; z=(I)(S)*ax; *dx=z>>16;;} void farcall(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void wait(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void pushf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; put_(mem+(*sp-=2),*(fl),1);} void popf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(fl)=get_(mem+(*sp+=2)-2,1);} void sahf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void lahf(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void movalb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; if(d){ x=get_(mem+fetchw(),w); if(w)*ax=x; else*al=x; } else { put_(mem+fetchw(),w?*ax:*al,w); };} void movaxw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; if(d){ x=get_(mem+fetchw(),w); if(w)*ax=x; else*al=x; } else { put_(mem+fetchw(),w?*ax:*al,w); };} void movbal(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; if(d){ x=get_(mem+fetchw(),w); if(w)*ax=x; else*al=x; } else { put_(mem+fetchw(),w?*ax:*al,w); };} void movwax(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; if(d){ x=get_(mem+fetchw(),w); if(w)*ax=x; else*al=x; } else { put_(mem+fetchw(),w?*ax:*al,w); };} void movsb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void movsw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void cmpsb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void cmpsw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void testaib(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ;;} void testaiw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(U)(p=w?(UC*)ax:al); x=get_((void*)x,w); y=w?fetchw():fetchb(); z=x&y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ;;} void stosb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void stosw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void lodsb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void lodsw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void scasb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void scasw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void movali(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*al)=fetchb();;} void movcli(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*cl)=fetchb();;} void movdli(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*dl)=fetchb();;} void movbli(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*bl)=fetchb();;} void movahi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*ah)=fetchb();;} void movchi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*ch)=fetchb();;} void movdhi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*dh)=fetchb();;} void movbhi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*bh)=fetchb();;} void movaxi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*ax)=fetchw();;} void movcxi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*cx)=fetchw();;} void movdxi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*dx)=fetchw();;} void movbxi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*bx)=fetchw();;} void movspi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*sp)=fetchw();;} void movbpi(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*bp)=fetchw();;} void movsii(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*si)=fetchw();;} void movdii(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; (*di)=fetchw();;} void nopI(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopJ(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void reti(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(ip)=get_(mem+(*sp+=2)-2,1); if(fetchw())*sp+=fetchw()*2;;} void retz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(ip)=get_(mem+(*sp+=2)-2,1); if(0)*sp+=0*2;;} void les(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void lds(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void movimb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; if(w){(*(US*)y)=fetchw();}else{(*(UC*)y)=fetchb();};} void movimw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); x=decreg(r.reg,w); y=decrm(r,w); if(trace>1){ printf("x:%d\n",x); printf("y:%d\n",y); } p=d?(void*)x:(void*)y; if(w){(*(US*)y)=fetchw();}else{(*(UC*)y)=fetchb();};} void nopK(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopL(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void freti(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(cs)=get_(mem+(*sp+=2)-2,1); *(ip)=get_(mem+(*sp+=2)-2,1); if(fetchw())*sp+=fetchw()*2;;} void fretz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *(cs)=get_(mem+(*sp+=2)-2,1); *(ip)=get_(mem+(*sp+=2)-2,1); if(0)*sp+=0*2;;} void int3(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void inti(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void int0(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void iret(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void shiftb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void shiftw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void shiftbv(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void shiftwv(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void aam(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void aad(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopM(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void xlat(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc0(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc1(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc2(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc3(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc4(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc5(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc6(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void esc7(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void loopnz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void loopz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void loop(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void jcxz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void inb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void inw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void outb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void outw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void call(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; w=1; x=w?fetchw():(S)(C)fetchb(); put_(mem+(*sp-=2),*(ip),1); (*ip)+=(S)x;;} void jmp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=fetchw(); *ip+=(S)x;;} void farjmp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void sjmp(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; x=(S)(C)fetchb(); *ip+=(S)x;;} void invb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void invw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void outvb(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void outvw(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void lock(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void nopN(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void rep(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void repz(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void hlt(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; halt=1;} void cmc(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *fl=(*fl&~CF)|((*fl&CF)^1);;} void grp1b(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void grp1w(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void clc(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *fl=*fl&~CF;;} void stc(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; *fl=*fl|CF;;} void cli(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void sti(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void cld(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void std(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; ;} void grp2b(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); y=decrm(r,w); if(trace)printf("%s ", (C*[]){"INC","DEC","CALL","CALL","JMP","JMP","PUSH"}[r.reg]); switch(r.reg){case 0: w=1; d=1; p=(V*)(S*)y; x=(S)*(S*)y; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;; break; case 1: w=1; d=1; p=(V*)(S*)y; x=(S)*(S*)y; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;; break; case 2: x=w?fetchw():(S)(C)fetchb(); put_(mem+(*sp-=2),*(ip),1); (*ip)+=(S)x;; break; case 3: x=w?fetchw():(S)(C)fetchb(); put_(mem+(*sp-=2),*(ip),1); (*ip)+=(S)x;; break; case 4: *ip+=(S)y; break; case 5: x=fetchw(); *ip+=(S)x;; break; case 6: put_(mem+(*sp-=2),*((S*)y),1); break; };} void grp2w(){if(trace){ printf("%s:\n",__func__); } d=!!(o&2); w=o&1; rm r=mrm(fetchb()); y=decrm(r,w); if(trace)printf("%s ", (C*[]){"INC","DEC","CALL","CALL","JMP","JMP","PUSH"}[r.reg]); switch(r.reg){case 0: w=1; d=1; p=(V*)(S*)y; x=(S)*(S*)y; y=1; f=*fl&CF; z=x+y; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;; break; case 1: w=1; d=1; p=(V*)(S*)y; x=(S)*(S*)y; y=1; f=*fl&CF; z=d?x-y:y-x; *fl=0; *fl |= ( (z&(w?0x8000:0x80)) ?SF:0) | ( (z&(w?0xffff:0xff))==0 ?ZF:0) ; *fl |= ( (z&(w?0xffff0000:0xff00)) ?CF:0) | ( ((z^x)&(z^y)&(w?0x8000:0x80)) ?OF:0) | ( ((x^y^z)&0x10) ?AF:0) ; if(trace)printf(w?"->%04x ":"->%02x ",z); put_(p,z,w); *fl=(*fl&~CF)|f;; break; case 2: x=w?fetchw():(S)(C)fetchb(); put_(mem+(*sp-=2),*(ip),1); (*ip)+=(S)x;; break; case 3: x=w?fetchw():(S)(C)fetchb(); put_(mem+(*sp-=2),*(ip),1); (*ip)+=(S)x;; break; case 4: *ip+=(S)y; break; case 5: x=fetchw(); *ip+=(S)x;; break; case 6: put_(mem+(*sp-=2),*((S*)y),1); break; };}void(*tab[])()={addbf, addwf, addbt, addwt, addbi, addwi, pushes, popes, orbf, orwf, orbt, orwt, orbi, orwi, pushcs, nop0, adcbf, adcwf, adcbt, adcwt, adcbi, adcwi, pushss, popss, sbbbf, sbbwf, sbbbt, sbbwt, sbbbi, sbbwi, pushds, popds, andbf, andwf, andbt, andwt, andbi, andwi, esseg, daa, subbf, subwf, subbt, subwt, subbi, subwi, csseg, das, xorbf, xorwf, xorbt, xorwt, xorbi, xorwi, ssseg, aaa, cmpbf, cmpwf, cmpbt, cmpwt, cmpbi, cmpwi, dsseg, aas, incax, inccx, incdx, incbx, incsp, incbp, incsi, incdi, decax, deccx, decdx, decbx, decsp, decbp, decsi, decdi, pushax, pushcx, pushdx, pushbx, pushsp, pushbp, pushsi, pushdi, popax, popcx, popdx, popbx, popsp, popbp, popsi, popdi, nop1, nop2, nop3, nop4, nop5, nop6, nop7, nop8, nop9, nopA, nopB, nopC, nopD, nopE, nopF, nopG, jo, jno, jb, jnb, jz, jnz, jbe, jnbe, js, jns, jp, jnp, jl, jnl_, jle, jnle, immb, immw, immb1, immis, testb, testw, xchgb, xchgw, movbf, movwf, movbt, movwt, movsegf, lea, movsegt, poprm, nopH, xchgac, xchgad, xchgab, xchgasp, xchabp, xchgasi, xchadi, cbw, cwd, farcall, wait, pushf, popf, sahf, lahf, movalb, movaxw, movbal, movwax, movsb, movsw, cmpsb, cmpsw, testaib, testaiw, stosb, stosw, lodsb, lodsw, scasb, scasw, movali, movcli, movdli, movbli, movahi, movchi, movdhi, movbhi, movaxi, movcxi, movdxi, movbxi, movspi, movbpi, movsii, movdii, nopI, nopJ, reti, retz, les, lds, movimb, movimw, nopK, nopL, freti, fretz, int3, inti, int0, iret, shiftb, shiftw, shiftbv, shiftwv, aam, aad, nopM, xlat, esc0, esc1, esc2, esc3, esc4, esc5, esc6, esc7, loopnz, loopz, loop, jcxz, inb, inw, outb, outw, call, jmp, farjmp, sjmp, invb, invw, outvb, outvw, lock, nopN, rep, repz, hlt, cmc, grp1b, grp1w, clc, stc, cli, sti, cld, std, grp2b, grp2w,};
V clean(C*s){I i;
for(i=0;i<80;i++)
if(!isprint(s[i]))
s[i]=' ';
}
V video(){I i;
C buf[81]="";
for(i=0;i<28;i++)
memcpy(buf, mem+0x8000+i*80, 80),
clean(buf),
printf("\n%s",buf);
printf("\n");
}
static I ct;
V run(){while(!halt){if(trace)dump();
if(!ct--){ct=10; video();}
tab[o=fetchb()]();}}
V dbg(){
while(!halt){
C c;
if(!ct--){ct=10; video();}
if(trace)dump();
fgetc(stdin);
tab[o=fetchb()]();
}
}
I load(C*f){struct stat s; FILE*fp;
return (fp=fopen(f,"rb"))
&& fstat(fileno(fp),&s) || fread(mem,s.st_size,1,fp); }
I main(I c,C**v){
init();
if(c>1){
load(v[1]);
}
*sp=0x100;
if(debug) dbg();
else run();
video();
return 0;}


--
with assistance from cpp -P (manually withholding headers)

Rick C. Hodgin

unread,
Jul 11, 2015, 4:54:57 AM7/11/15
to
Do you code like this with no whitespaces?

luser droog

unread,
Jul 11, 2015, 4:58:53 AM7/11/15
to
I wrote it with lots of macros.
Here's a version processed by indent:
https://gist.github.com/luser-dr00g/e907e5beb79fb1edafda
5810 lines

Rick C. Hodgin

unread,
Jul 11, 2015, 4:59:09 AM7/11/15
to
You should take it to the next level and code it
in Verilog, creating the logic for real hardware.
Altera's FPGAs will run it for you. Get help in
comp.arch.

luser droog

unread,
Jul 11, 2015, 5:14:07 AM7/11/15
to
On Saturday, July 11, 2015 at 3:59:09 AM UTC-5, Rick C. Hodgin wrote:
> You should take it to the next level and code it
> in Verilog, creating the logic for real hardware.
> Altera's FPGAs will run it for you. Get help in
> comp.arch.
>

That is something I'm interested in, but my goals
for this code are to build upward (and forwards in
time. After filling out the 8086 instructions, it'll
be a long slog adding 186 then 286 then 386 extensions.

There's also that big BIG_ENDIAN red herring to gut
and pickle.

Rick C. Hodgin

unread,
Jul 11, 2015, 5:34:31 AM7/11/15
to
I believe the 186 was an 86 with hard-wired
external interrupt vectors.

x86 is inherently little endian. What is your
strategy for introducing big endian?

You should see my Li386-x40 project, a 40-bit
80386 with limited ARM support and custom
ISA and architectural extensions:

https://github.com/RickCHodgin/libsf/tree/master/li386/li386-documentation/images

http://www.libsf.org/li386/indexmain.html

Bartc

unread,
Jul 11, 2015, 5:38:43 AM7/11/15
to
On 11/07/2015 08:51, luser droog wrote:
> On Saturday, June 27, 2015 at 7:02:37 AM UTC-5, somebody wrote:
>>
>> *Lose the macros*.
>
> non-wrapped at:
> https://gist.github.com/luser-dr00g/aef0342cb4a63d682c13

It hasn't really helped! Now there are the pointless typedefs. And (I
haven't followed the thread) presumably the original macros have been
expanded, but resulting in a large, unformatted lines or blocks of code.

Isn't there a tool that can take such code and format it properly? (But
somehow I doubt that will help.)

It's not clear what the aims are here: to make something as fast as
possible or as compact as possible. It's certainly not readability!

> typedef intptr_t I; typedef uintptr_t U;

Nobody uses I or U. Enough people i32, u32 etc that at least it will not
look totally alien.

> typedef signed char C; typedef unsigned char UC;

And here 'byte' is better. At least it looks like a type!

> UC*al;UC*ah;UC*cl;UC*ch;UC*dl;UC*dh;UC*bl;UC*bh;US*ax;US*cx;US*dx;US*bx;US*sp;US*bp;US*si;US*di;US*ip;US*fl;US*cs;US*ds;US*ss;US*es;V init(){I i=0;al=(UC*)(reg+i++);ah=(UC*)(reg+i++);cl=(UC*)(reg+i++);ch=(UC*)(reg+i++);dl=(UC*)(reg+i++);dh=(UC*)(reg+i++);bl=(UC*)(reg+i++);bh=(UC*)(reg+i++);i=0;ax=(US*)(reg+i);i+=2;cx=(US*)(reg+i);i+=2;dx=(US*)(reg+i);i+=2;bx=(US*)(reg+i);i+=2;sp=(US*)(reg+i);i+=2;bp=(US*)(reg+i);i+=2;si=(US*)(reg+i);i+=2;di=(US*)(reg+i);i+=2;ip=(US*)(reg+i);i+=2;fl=(US*)(reg+i);i+=2;cs=(US*)(reg+i);i+=2;ds=(US*)(reg+i);i+=2;ss=(US*)(reg+i);i+=2;es=(US*)(reg+i);i+=2;}

Let me guess, a macro expansion? How would you write it if you had to do
by hand?

My point is that as written, it's not really human readable. I'm not
sure it even counts calling it C, even if it makes legitimate use of the
macro preprocessor.

>ch=(UC*)(reg+i++);dl=(UC*)(reg+i++);dh=(UC*)(reg+i++);bl=(UC*)
>(reg+i++);bh=(UC*)(reg+i++);i=0;ax=(US*)(reg+i);i+=2;cx=(US*)(reg+i);
>i+=2;dx=(US*)(reg+i);i+=2;bx=(US*)(reg+i);i+=2;sp=(US*)(reg+i);i+=2;bp=
>(US*)(reg+i);i+=2;si=(US*)(reg+i);i+=2;di=(US*)(reg+i);i+=2;ip=
>....

This looks like it's crying out for these register variables to be
implemented as arrays (which is how it works on the actual chip;
registers are indexed by 0 to 7). With registers such as AX/AL/AH
implemented as unions... But then as I said I don't know what the aims are.

--
Bartc

Bartc

unread,
Jul 11, 2015, 5:50:23 AM7/11/15
to
On 11/07/2015 10:34, Rick C. Hodgin wrote:
> I believe the 186 was an 86 with hard-wired
> external interrupt vectors.

80186 and 80188 were very different from the rest of the x86 series.

They had integrated peripherals such as DMA, interrupt controllers and
timers. This also meant they were incompatible with IBM PCs which used
discrete components, so they didn't catch on.

(I used the 80188 as the basis of a very early laptop project - in 1984!
Very nice processor, I wrote a gorgeous assembler for it as it had many
new features. But the compatibility issue was a problem.)

--
Bartc

Rick C. Hodgin

unread,
Jul 11, 2015, 5:52:41 AM7/11/15
to

Rick C. Hodgin

unread,
Jul 11, 2015, 5:58:25 AM7/11/15
to
Bartc wrote:
> This also meant they were incompatible with
> IBM PCs which used discrete components, so
> they didn't catch on.

Seems they learned their lesson there with future CPUs. :-)
Even Itanium had x86 emulation support in hardware.

I was very surprised Intel sold XScale, however.
Seemed a wrong move.

JohnF

unread,
Jul 11, 2015, 6:07:43 AM7/11/15
to
luser droog <luser...@gmail.com> wrote:
> Brain going numb trying to overdesign this apl jiterpreter,
> and reading this tutorial on category theory for programmers.
<snip>

No comment on your <snip>'ed ps interpreter, but of the several
books I've read about it, and depending on your background and
purpose,
https://mitpress.mit.edu/books/basic-category-theory-computer-scientists
is quite a competent and thorough-yet-concise introduction.
Though that's the one I'd recommend, I'm not familiar with books
written after ~y2k, so similar/better/whatever ones may well exist.

Google doesn't seem to be coughing up a free pdf of it, but if
you're investing enough time to read it, then the $30 bucks is worth it
to invest your time as productively as possible. There does seem
to be a page of reader reviews (beware line-wrapped url),
http://www.goodreads.com/book/show/1810837.Basic_Category_Theory_for_Computer_Scientists
Some of the pure programmer types seem to feel they don't quite
have the prerequisites. I have an ms in physics, and couldn't
just breeze through it, but it wasn't like a 50mph headwind in
my face, either. Pitched just about perfect for me, but obviously ymmv.
--
John Forkosh ( mailto: j...@f.com where j=john and f=forkosh )

luser droog

unread,
Jul 11, 2015, 6:16:42 AM7/11/15
to
On Saturday, July 11, 2015 at 4:38:43 AM UTC-5, Bart wrote:
> On 11/07/2015 08:51, luser droog wrote:
> > On Saturday, June 27, 2015 at 7:02:37 AM UTC-5, somebody wrote:
> >>
> >> *Lose the macros*.
> >
> > non-wrapped at:
> > https://gist.github.com/luser-dr00g/aef0342cb4a63d682c13
>
> It hasn't really helped! Now there are the pointless typedefs. And (I
> haven't followed the thread) presumably the original macros have been
> expanded, but resulting in a large, unformatted lines or blocks of code.
>

Yes. The plan was to make the macros seem more reasonable.
Not sure of the success of that endeavor.

> Isn't there a tool that can take such code and format it properly? (But
> somehow I doubt that will help.)
>

Yes. I've passed it through `indent`.
https://gist.github.com/luser-dr00g/e907e5beb79fb1edafda


> It's not clear what the aims are here: to make something as fast as
> possible or as compact as possible. It's certainly not readability!
>
> > typedef intptr_t I; typedef uintptr_t U;
>
> Nobody uses I or U. Enough people i32, u32 etc that at least it will not
> look totally alien.
>
> > typedef signed char C; typedef unsigned char UC;
>
> And here 'byte' is better. At least it looks like a type!
>
> > UC*al;UC*ah;UC*cl;UC*ch;UC*dl;UC*dh;UC*bl;UC*bh;US*ax;US*cx;US*dx;US*bx;US*sp;US*bp;US*si;US*di;US*ip;US*fl;US*cs;US*ds;US*ss;US*es;V init(){I i=0;al=(UC*)(reg+i++);ah=(UC*)(reg+i++);cl=(UC*)(reg+i++);ch=(UC*)(reg+i++);dl=(UC*)(reg+i++);dh=(UC*)(reg+i++);bl=(UC*)(reg+i++);bh=(UC*)(reg+i++);i=0;ax=(US*)(reg+i);i+=2;cx=(US*)(reg+i);i+=2;dx=(US*)(reg+i);i+=2;bx=(US*)(reg+i);i+=2;sp=(US*)(reg+i);i+=2;bp=(US*)(reg+i);i+=2;si=(US*)(reg+i);i+=2;di=(US*)(reg+i);i+=2;ip=(US*)(reg+i);i+=2;fl=(US*)(reg+i);i+=2;cs=(US*)(reg+i);i+=2;ds=(US*)(reg+i);i+=2;ss=(US*)(reg+i);i+=2;es=(US*)(reg+i);i+=2;}
>
> Let me guess, a macro expansion? How would you write it if you had to do
> by hand?
>
> My point is that as written, it's not really human readable. I'm not
> sure it even counts calling it C, even if it makes legitimate use of the
> macro preprocessor.
>
> >ch=(UC*)(reg+i++);dl=(UC*)(reg+i++);dh=(UC*)(reg+i++);bl=(UC*)
> >(reg+i++);bh=(UC*)(reg+i++);i=0;ax=(US*)(reg+i);i+=2;cx=(US*)(reg+i);
> >i+=2;dx=(US*)(reg+i);i+=2;bx=(US*)(reg+i);i+=2;sp=(US*)(reg+i);i+=2;bp=
> >(US*)(reg+i);i+=2;si=(US*)(reg+i);i+=2;di=(US*)(reg+i);i+=2;ip=
> >....
>
> This looks like it's crying out for these register variables to be
> implemented as arrays (which is how it works on the actual chip;
> registers are indexed by 0 to 7). With registers such as AX/AL/AH
> implemented as unions... But then as I said I don't know what the aims are.
>

They're implemented as overlaying pointers so the guts of the opcode
functions could treat a register or memory identically. Unfortunately,
this destroys my attempt to lay the registers out "native-endian" for
speed (appropriate for registers).

Rick C. Hodgin

unread,
Jul 11, 2015, 6:19:51 AM7/11/15
to
On Saturday, July 11, 2015 at 6:16:42 AM UTC-4, luser droog wrote:
> [snip]

I would like to suggest you use proper human readable names. While
making some of your code longer, it will aid in maintenance in the
long term and is well worth the "extra cost" of the additional
typing. It also aids in editors which have auto-completion, as you
begin typing something and it suggests those which are close based
on context.

In a few years when you come back to this project, having the long
names will serve your aging mind/eyes well. :-)
Reply all
Reply to author
Forward
0 new messages