Code donations?

Programming, for all ages and all languages.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Code donations?

Post by earlz »

ok, I am making an x86 emulator..
currently I only am trying to get all of the 8086 opcodes..

if anyone knows something about x86 archietecture such as modrm and such...

attached is a fairly updated list of what all opcodes I have implemented..

now I know that it is hard to just step into a project and code stuff for it...so I will allow basic incorrect stuff that I will have to make minor modifications to

here's a short list of how to do a bit of stuff

memory stuff:
MemRead8(short segment,short offset) for reading memory(and change 8 to 16 or whatever)
MemWrite8(short segment,short offset, byte) for writing memory

flags:
just use something like
to set CF use flags->cf=1; and IF use flags->_if=1; (prevent the if conflict)

registers:
use *gregs8[register] for 8bit registers such as
*gregs8[AH]=0xFF; and this will set AH to 0xff..(make sure not to forget the *)
and then use gregs8[register] for 16bit registers such as
gregs16[AX]=0xFFFF; and this will set AX to 0xFFFF
finally, for segment registers use sregs[segment] such as
sregs[DS]=0xFFFF; adn this will set DS to 0xFFFF

if I have an opcode listed that is similar to what you want to implement, then I probably already have a simple "template" stub function, such as..
for sub al,imm8 I have a function called result=sub8(char base,char subtractor);
so instead of doing all the flag stuff for sub, you can just use that function..


for the SVN code goto http://sourceforge.net/projects/open86

you can either submit a patch file to the SF project site, or you can post your code here..


now then!
if you want to go EVEN further!
for modrm you can use these fairly simple templates..

Code: Select all

/******MODRM templates!!!!
these are some simple templates to make using modrm instructions much easier to use
void template_modrm16_r16(){
    unsigned short *ptr;
    unsigned int tmp;
    mod_rm rm[1];
    ip++;
    MemRead8(CS,ip,rm); //store rm because we need 'extra'
    tmp=GetModRM_write16(&ptr);
    if(tmp==0){ //is normal and ptr contains the memory address
        (unsigned long)ptr=(unsigned long)ptr+(unsigned long)core;
        //*ptr is the destination, gregs16[rm[0].extra] is the source/operand
        return;
    }
    if(tmp==OPCODE_SPECIFIC){
        //gregs16[rm[0].rm] is the destination, gregs16[rm[0].extra] is the source/operand
        return;
    }
    panic("errors not yet handled!!");
}

void template_modrm8_r8(){
    unsigned char *ptr;
    unsigned int tmp;
    mod_rm rm[1];
    ip++;
    MemRead8(CS,ip,rm); //store rm because we need 'extra'
    tmp=GetModRM_write8(&ptr);
    if(tmp==0){ //is normal and ptr contains the memory address
        ptr=ptr+(unsigned long)core;
        //*ptr is the destination, *gregs8[rm[0].extra] is the source/operand
        return;
    }
    if(tmp==OPCODE_SPECIFIC){
        //*gregs8[rm[0].rm] is the destination, *gregs8[rm[0].extra] is the source/operand
        return;
    }
    panic("errors not yet handled!!");
}


void template_r8_modrm8(){
    unsigned char *ptr;
    unsigned int tmp;
    mod_rm rm[1];
    ip++;
    MemRead8(CS,ip,rm); //store rm because we need 'extra'
    tmp=GetModRM_read8(&ptr);
    if(tmp==0){ //is normal and ptr contains the memory address
        ptr=ptr+(unsigned long)core;
        //*gregs8[rm[0].extra] is the destination, *ptr is source/operand
        return;
    }
    if(tmp==OPCODE_SPECIFIC){
        //*gregs8[rm[0].extra] is the destination, *gregs8[rm[0].rm] is the source/operand
        return;
    }
    panic("errors not yet handled!!");
}

void template_r16_modrm16(){
    unsigned short *ptr;
    unsigned int tmp;
    mod_rm rm[1];
    ip++;
    MemRead8(CS,ip,rm); //store rm because we need 'extra'
    tmp=GetModRM_read16(&ptr);
    if(tmp==0){ //is normal and ptr contains the memory address
        (unsigned long)ptr=(unsigned long)ptr+(unsigned long)core;
        //gregs16[rm[0].extra] is the destination, *ptr is source/operand
        return;
    }
    if(tmp==OPCODE_SPECIFIC){
        //gregs16[rm[0].extra] is the destination, gregs16[rm[0].rm] is the source/operand
        return;
    }
    panic("errors not yet handled!!");
}

void template_sreg16_modrm16(){
    unsigned short *ptr;
    unsigned int tmp;
    mod_rm rm[1];
    ip++;
    MemRead8(CS,ip,rm); //store rm because we need 'extra'
    tmp=GetModRM_read16(&ptr);
    if(tmp==0){ //is normal and ptr contains the memory address
        (unsigned long)ptr=(unsigned long)ptr+(unsigned long)core;
        //sregs[rm[0].extra] is the destination, *ptr is source/operand
        return;
    }
    if(tmp==OPCODE_SPECIFIC){
        //gregs16 should USUALLY be the proper one, but being opcode specific this could be
        //other things..
        //sregs[rm[0].extra] is the destination, gregs16[rm[0].rm] is the source/operand
        return;
    }
    panic("errors not yet handled!!");
}


void template_modrm16_sreg16(){
    unsigned short *ptr;
    unsigned int tmp;
    mod_rm rm[1];
    ip++;
    MemRead8(CS,ip,rm); //store rm because we need 'extra'
    tmp=GetModRM_write16(&ptr);
    if(tmp==0){ //is normal and ptr contains the memory address
        (unsigned long)ptr=(unsigned long)ptr+(unsigned long)core;
        //*ptr is the destination, sregs[rm[0].extra] is the source/operand
        return;
    }
    if(tmp==OPCODE_SPECIFIC){
        //gregs16 should USUALLY be the proper one, but being opcode specific this could be
        //other things..(including an invalid opcode exception)
        //gregs16[rm[0].rm] is the destination, sregs[rm[0].extra] is the source/operand
        return;
    }
    panic("errors not yet handled!!");
}

there a bit hard to understand maybe..but you should get the just of it..
btw, put your code in the "if(tmp==..){" (right after the comments but before the "}"
Attachments
progress.txt
open86 progress
(2.57 KiB) Downloaded 71 times
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

I would help(if I could.) but I can't get the thing to compile. First off, I got nearly 20 illegal lvalue errors. (Which I fixed by deleting the casts on the lvalues.) Now, it compiles, but does not link. ld can't find some '.objs/res.o', and when I delete that from the makefile, ld still can't find 'ldl.a'. Uhh.....How to?
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

hmmm...

-ldl.a should be "-ldl.a" which should expand to libdl.a ?

illegal lvalues? are you using 64bit? I haven't tested it with 64bit..

the .objs thing I know what's wrong...a bit of carelessness on my part..(stupid me)

gimme a sec and I'll commit a (should be) working version..

edit:
ok try the latest revision..it should work now..still dunno about the lvalues though..
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

libdl(.so/.a) is the library Linux uses for functions like dlopen, dlclose, dlsym, dlctl, dlerror, dladdr...

I'm very surprised you didn't know this Alboin :lol:

On OpenBSD the dl functions are simply in the C library.. 8)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Brynet-Inc wrote:I'm very surprised you didn't know this Alboin :lol:
Yeah, yeah....For some reason the output from ld looked like some library called 'lda'. I don't know why....I think I need more tea...

In other news...I got the makefile working...My system didn't like the static version of dl so I changed it to the shared version. (Also, it wasn't needed in CFLAGS. So I removed it from there.)

I am on 64-bit, so I had to remove the lvalue casts. If those aren't needed on 32-bit, I suggest you remove them. I'll work on it....

Toodles..
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

give me a line/file that gave you errors...I don't know which are the real problem..

I know I have a problem with somehting like

Code: Select all

void *core;
unsigned int bah=4;

..
core=core+bah;  //I think this was it..

... //that would cause an error of improper casting or whatever so I did this:
(unsigned long)core=(unsigned long)core+(unsigned long)bah;
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Wherever there was something like:

Code: Select all

(unsigned long)ptr=(unsigned long)ptr+(unsigned long)core;
I had to change it to:

Code: Select all

ptr=(unsigned long)ptr+(unsigned long)core;
About the actual program: What to do? Instructions? Or attempt something like an SDL monitor type device?
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

instructions are always welcome!
I personally wouldn't recommend doing devices right now as I still need to write a lot of the external device framework...though you could write something like FDD or whatever, you just may have to change it up a bit later on...plus my device system right now is almost completely undocumented..

also, thanks for that little tip, I'll change all those (unsigned long) ptr=...
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

also, if anyone has any idea on how to do a C method of communication for external devices(using dlls, so's, ect.) then please post them..I think I will probably have to redesign my whole system right now as it is poorly designed..
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

I've been examining your communication\driver code stuffs, and realized that if the monitor driver controls SDL in itself, then how is the mouse driver to access its events? Or the keyboard its? Shouldn't the SDL be in the program itself?
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

...
can SDL be run from mutliple SO's at one time?

The GUI should provide all of the keyboard, mouse, and such "interface" events or whatever.. though there should be a mouse hardware controller type device that handles all of the ports and such...

really hard to explain, but rember that that GlobalDevice stuff isn't nearly complete
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

This is my first test instructions that I've implemented. If these are somewhat correct, I'll attempt some bigger ones and finish these. (8bit support.) They're attached.

This is added to main.

Code: Select all

InstallOp(0x40,inc_r16);
	  InstallOp(0x41,inc_r16);
	  InstallOp(0x42,inc_r16);
	  InstallOp(0x43,inc_r16);
	  InstallOp(0x44,inc_r16);
	  InstallOp(0x45,inc_r16);
	  InstallOp(0x46,inc_r16);
	  InstallOp(0x47,inc_r16);

	  InstallOp(0x48,dec_r16);
	  InstallOp(0x49,dec_r16);
	  InstallOp(0x4A,dec_r16);
	  InstallOp(0x4B,dec_r16);
	  InstallOp(0x4C,dec_r16);
	  InstallOp(0x4D,dec_r16);
	  InstallOp(0x4E,dec_r16);
	  InstallOp(0x4F,dec_r16);
And this to base.h:

Code: Select all

void inc_r16();
void dec_r16();
How are they?
Attachments
inc_dec.c
inc\dec
(449 Bytes) Downloaded 89 times
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

Thanks for this!!...even an attempt at something is great to me...

I'll test it now..

btw, the latest SVN revision has all the (unsigned long)ptr= problems fixed..



edit:
they work, but they don't set the flags as would be expected, notice that inc and dec set flags according to the result. I have an reg=add16(reg,1); (and I have a sub16 also) that will set the flags properly, except for you will have to either copy that code to make a inc16 type function that doesn't set CF or you will have to save CF and then restore it after add...
note I don't have the sub16 and add16 and such functions prototyped, so you can either prototype them in _base.h or mov inc and dec to the sub_add.c file..

btw, can you get open86 to compile on your PC?
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Errors I currently get:

Code: Select all

instructions/push_pop.c:41: error: invalid lvalue in assignment
instructions/ints.c:102: error: invalid lvalue in assignment
instructions/ints.c:107: error: invalid lvalue in assignment
config_files.c:69: error: invalid lvalue in assignment
main.c:157: error: invalid lvalue in assignment
Also, in the makefile I have to change

Code: Select all

g++ -o Open86.elf $(_OBJS) libdl.a
To

Code: Select all

g++ -o Open86.elf $(_OBJS) -ldl
On the things not being set....You mean setting OF, SF, ZF, AF, and PF, right? I'll try using a modified version of add. Or what about creating a function that both add, and inc can use, that doesn't set CF?
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

ok, check latest revision..I think I got all those errors fixed, plus removed the .elf extension thing

what you could do on the flags is do

tmp=flags->cf;
reg=add16(reg,1);
flags->cf=tmp;

so that they are saved..

btw you got aim, yahoo, or gtalk?
Post Reply