Code donations?

Programming, for all ages and all languages.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Here's version 2.0 of inc\dec. (Attached)
Add this to main:

Code: Select all

InstallOp(0xFE,inc_dec_r8);
And this to base:

Code: Select all

void inc_dec_r8();

SPEED_UP unsigned short add16(unsigned short base,unsigned short adder);
SPEED_UP unsigned short sub16(unsigned short base,unsigned short subt);
SPEED_UP unsigned char sub8(unsigned char base,unsigned char subt);
SPEED_UP unsigned char add8(unsigned char base,unsigned char adder);
It does 8\16bit register inc's and dec's.

No, I'm not on any of those, actually. I'm more of a forums person myself. Uhh, what about the sourceforge forums for Open86? Also, there's private messages through osdev if it's not public.
Attachments
inc_dec.c
(1013 Bytes) Downloaded 67 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..

the only problem I see is that that isn't just dec and inc though, it is a "group" it uses a modrm byte to determine what opcode it is..
there are 6 more opcodes in that one byte other than inc and dec so, evenutally I will support those and well...you should get the point..but anyway...

now then..
the inc_r16 and dec_r16 look good...

I think I'll have to write a tutorial of some sort for anyone to understand the modrm system...think I'll write something of some sort...

oh wait..you may have misread your opcode documents..that inc_r/8 should be inc_mod/rm8 mod rm bytes are bytes that consist of 3 fields of data: mod(2bits), rm(3bits), and extra(3bits)
unless mod is less than 4 then it refers to a memory address, I won't go over all of these different memory address computation combo's but basically what you are doing is assuming that mod is 4 which would be correct for what you written, but it doesn't check!

ok I will show you what that inc and dec would have looked like if I had done it..
(I describe things best in code..)

Code: Select all

void group_fe(){
    mod_rm rm[1];
    unsigned char *ptr;
    unsigned char *ptr2;
    unsigned char *to_be_used; //this is the contents of the interpreted modrm
    unsigned int tmp;
    ip++;
    MemRead8(CS,ip,rm); //store rm because we need 'extra'(sometimes)
    tmp=GetModRM_write8(&ptr); //note it isn't always write8 for each group!
    //pointer now contains the memory address that should be used(unless tmp==opcode_specific)
    if(tmp==0){ //is normal and ptr contains the memory address
        ptr=(unsigned long)ptr+(unsigned long)core;
        to_be_used=ptr;
    }
    if(tmp==OPCODE_SPECIFIC){
        to_be_used=gregs8[rm[0].rm];
    }
	//actually you can ignore above this line!
    //do opcode specific stuff...
    switch(rm[0].extra){ //check opcode
    	case 0: //inc modrm8
		//now you do your thing, except for instead of reg, you use *to_be_used;
		tmp=flags->cf;
		*to_be_used=add8(*to_be_used,1);
		flags->cf=tmp;
		//this one is inc!
		break;
		case 1: //dec modrm8
		//now you do your thing with dec, except for instead of reg, you use *to_be_used;
		//you fill out this one!

		//this one is dec!
		break;
        default:
        panic("Unsupported opcode! at rm\n");
        break;
    }

}

edit:
no, I didn't have anything private to say, just prefer IM for talking to one person..(different with multiple people)
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

A question on the above. Does:

Code: Select all

tmp=GetModRM_write8(&ptr);
Find what the argument is for the instruction? So if I had

Code: Select all

mov [0xb8000], 12
It would return 0xb8000?
Are my assumptions correct?

Also, a design question: There is a group (#2 here) that consists of (C0..C1h) and (D0..D3h). Would I be able to just create one group for all of these, and then connect all of their opcodes to the one group in main?
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

actually there is no [0xb8000] in the 8086 instruction set
so I'll use this:

Code: Select all

mov ax,0xB800
mov ds,ax
mov bx,0
mov [bx],byte 12
then GetModRM_write8(&ptr) will add (DS<<4)+bx and put that in *ptr..
another thing it will do is make sure that you can write to that address...(hence you don't have to worry about it..)

what GetModRM.. returns is basically a control/error code, if it is 0 then everything is normal and &ptr is the target memory; if it returns OPCODE_SPECIFIC then it's not sure what to do because it is opcode specific, but under most(but not all) it should use a general register instead so the rm field contains what register to use(8 bit)

as far as those groups..
I really have no idea, I don't really understand that question...
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Okay, after getting segfaults for an hour, I think I got somewhat of a draft of the shr and shl instructions. They are in a group like function, as suggested. It is attached. (I do believe that I set all of the required flags..maybe?....Please alert me if I missed anything....)
Attachments
shift.c
(3.29 KiB) Downloaded 73 times
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

dear God! what a complicated group!

there is only a bit of something wrong with your modrm code..

because there are two different bitsizes of where modrm points, you need to do this:
if(bit_type= = 8 ){
tmp=GetModRM_write8(&ptr);
}else{
tmp=GetModRM_write16(&ptr);
}

also when checking for what bitsize, if the bit size is either one or the other, then it would probably be faster to do a if(op ==0xD0 ||...){ bit_size=8;}ELSE{ bit_size=16} this would make it a tiny bit faster...
(I don't know if you can do else with that wierd no {}'s syntax of if..)


and you set most of the hard flags..
here is some simple precoded things for you, and ZF should be a bit obvious

Code: Select all

inline unsigned char shr8(unsigned char op1,unsigned char op2) {
	unsigned char tmp_count = op2 & 0x1f;
	unsigned char tmp_dest = op1;
	
	while(tmp_count > 0) {
		op1 = op1 >> 1;
		unsigned char lsb = tmp_dest & 0x01;
		flags->cf = lsb;
		tmp_count--;
	}

	if(op2 == 1) {
		unsigned char msb = tmp_dest & 0x80;
		flags->of = msb;
	}
	
	CalculatePF8(op1); //this will set PF for you
	CalculateSF8(op1); //this will set SF for you
	if(op1==0){flags->zf=1;}else{flags->zf=0;}
	return op1;
}

inline unsigned short shr16(unsigned short op1,unsigned char op2) {
	unsigned char tmp_count = op2 & 0x1f;
	unsigned short tmp_dest = op1;
	
	while(tmp_count > 0) {
		op1 = op1 >> 1;
		unsigned char lsb = op1 & 0x01;
		flags->cf = lsb;
		tmp_count--;
	}

	if(tmp_count == 1) {
		unsigned short msb = tmp_dest & 0x8000;
		flags->of = msb;
	}
	CalculatePF16(op1); //this will set PF for you
	CalculateSF16(op1); //this will set SF for you
	if(op1==0){flags->zf=1;}else{flags->zf=0;}
	return op1;
}

where are you getting your documentation? if your having trouble finding which flags should be set, then you can maybe try this little website on for size.. http://www.ousob.com/ng/iapx86/index.php ..it is my favorite..


I think I should eventually document that helpers.c file...

just found a bit of a bug...you kept to_be_used as a char * even though it is used as a 16bit data type... the simplest way to fix that would just be put some casting on where it should be 16bit

btw did you test that?(beyond segmentation faults)


edit:
I lol at your website...very random...and I just happen to like random....
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Okay, I think I got the bugs fixed....I think it works....I tested it..You might want to test it to double check.....It''s attached....Why am I writing like this?

What other instructions\group are next in line of importance, so I can implement them? I think I've gotten the system somewhat down.
Attachments
shift.c
(3.94 KiB) Downloaded 38 times
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

...it looks pretty good, the only thing I ask is that for things like the set_flags8 thing, use the attribute SPEED_UP on the function, this is replaced with inline if memory isn't a problem, or is left outlined if we have LOW_MEMORY defined(this is for future use mostly)

do you know how to test these?
what you can do is make a binary test file(from asm) and then copy it to the trunk and rename/replace it to tester.bin..then just type "open86 test_config.o86" and it will run that file

and does open86 run on your pc!? I would be very suprised if it does, as I didn't think it was built portably enough to work in 64bit..

Code: Select all

else if(bit_type == 16) 
					*to_be_used = shl16((unsigned short)*to_be_used, iw);[/code
does that work? does shl16 returning unsigned short, override the default type of to_be_used(which is unsigned char) otherwise it will still only write one byte rather than a word...

edit:
as far as next things to do..
there are the things like movs, and other string operations(already have cmps implemented) btw, no need to worry about rep stuff..
umm..immediant maths like
sub modrm16, imm16 
and add modrm16, imm16

as far as your shift stuff, I will probably move it to a different file..(it will be in bitwise.c)

edit2:
Could you please provide the InstallOp things for that group..I'm not for sure if it takes from C0 to D0 or what..?
Last edited by earlz on Sun Feb 25, 2007 4:42 pm, edited 1 time in total.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

hckr83 wrote:do you know how to test these?
what you can do is make a binary test file(from asm) and then copy it to the trunk and rename/replace it to tester.bin..then just type "open86 test_config.o86" and it will run that file

and does open86 run on your pc!? I would be very suprised if it does, as I didn't think it was built portably enough to work in 64bit..
:) Of course it does! How else would I be testing these instructions? (Although, I am using an SVN version from a day or two ago.)
hckr83 wrote:

Code: Select all

else if(bit_type == 16) 
					*to_be_used = shl16((unsigned short)*to_be_used, iw);
does that work? does shl16 returning unsigned short, override the default type of to_be_used(which is unsigned char) otherwise it will still only write one byte rather than a word...
Oh.....I see your point......What about using a void* for to_be_used?
hckr83 wrote: edit:
as far as next things to do..
there are the things like movs, and other string operations

Okay, I'll start working on string operations. Sounds good to me.
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

could you provide the InstallOp code things for that group?
I don't entirely understand how that group works, is it just a few values or is it completely from C0 to D3?
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Here ya go:

Code: Select all

	  InstallOp(0xC0,group_c0_through_d3);	
	  InstallOp(0xC1,group_c0_through_d3);
	  InstallOp(0xD0,group_c0_through_d3);
	  InstallOp(0xD1,group_c0_through_d3);
	  InstallOp(0xD2,group_c0_through_d3);
	  InstallOp(0xD3,group_c0_through_d3);
Edit: Wow, MOVS, STOS, SCAS, and LODS have easy opcodes....I'm pretty excited..... :)
C8H10N4O2 | #446691 | Trust the nodes.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

you can look at sub_add.c and then use cmps() as a template...
the only thing to make sure to do is rather than use DS, use CurrentSegment..this will allow me to later implement segment overrides

edit:
I will be away from here a bit(2 weeks) so if you could, post source code on my SF.net project page..(in the forum there) ...it is a bit easier and faster for me to access there...
Post Reply