Bona Fide OS Development
http://forums.osdever.net/

Wanting to use the "hello world" bootloader code
http://forums.osdever.net/viewtopic.php?f=12&t=239
Page 3 of 4

Author:  Terry A. Davis [ Tue Apr 06, 2010 12:31 pm ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

Quote:
First, the return address is popped. Then the parameter is popped into ax to be used with the int 10h. Then the return address is pushed again, so that the ret will use it.

At startup, you can only count on standard BIOS interrupts (10h through 1ah).

The discussion about speed is only relevant for code that executes many times repeatedly (for example, it would be a bad idea speedwise to use the BIOS set pixel service in a loop to fill a rectangle).





64-bit sucka!!!


Code:
public BoolI8 GrRect(GrBitMap *base,I8 _x,I8 _y,I8 w,I8 h)
{  //Clipping but not transformation
  I8 x=_x,y=_y;
  I8 i,i1,i2,i3,j,k1,kk1,w1,h1,w2,h2,plane1,bit_mask,bit_shift,p,p1,dist;
  U2 *ptr1;
  ColorROPU4 color,color_byte,c,dither_colors;
  I8 plane_size1,plane_limit1;
  BoolI1 dither,probability_dither;
  GrBitMap *mask;

  w1=x<0 ?-x:0;
  h1=y<0 ?-y:0;
  w2=w;
  h2=h;

  if (base->flags & BMF_SCREEN_BITMAP) {
    x+=base->win_task->win_pixel_left;
    y+=base->win_task->win_pixel_top;
  }
  if (base->flags & BMF_LOCATE_NEAREST) { //TODO:Untested
    if (base->cur_x>=x && base->cur_y>=y &&
        base->cur_x<=x+w && base->cur_y<=y+h) {
      base->nearest_grelem_num=base->cur_grelem_num;
      base->nearest_dist=0;
    } else {
      dist=DistI8(x+w>>1,y+h>>1,base->cur_x,base->cur_y);
      if (dist<=base->nearest_dist) {
        base->nearest_grelem_num=base->cur_grelem_num;
        base->nearest_dist=dist;
      }
    }
  }
  if (base->flags & BMF_SCREEN_BITMAP) {
    if (x+w1<0) w1=-x;
    if (x+w2>base->win_task->win_pixel_right+1)
      w2=base->win_task->win_pixel_right+1-x;

    if (y+h1<0) h1=-y;
    if (y+h2>base->win_task->win_pixel_bottom+1)
      h2=base->win_task->win_pixel_bottom+1-y;
  }
  if (x+w2>base->width)
    w2=base->width-x;
  if (y+h2>base->height)
    h2=base->height-y;
  if (w1<w2<=w && h1<h2<=h &&
      (!(base->flags & BMF_SCREEN_BITMAP) ||
      base->flags&BMF_ON_TOP ||
      !IsPixelCovered(base->win_task,x+w1,y+h1) &&
      !IsPixelCovered(base->win_task,x+w2,y+h2))) {
    if (base->flags & BMF_RECORD_EXTENTS) {
      if (x+w1<base->min_x) base->min_x=x+w1;
      if (x+w2-1>base->max_x) base->max_x=x+w2-1;
      if (y+h1<base->min_y) base->min_y=y+h1;
      if (y+h2-1>base->max_y) base->max_y=y+h2-1;
    }
    if (base->flags & BMF_DONT_DRAW)
      return TRUE;
    color=base->color;
    if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
      dither=TRUE;
      if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
        probability_dither=TRUE;
        color.c1.rop=color.c0.rop;
        dither_colors=color;
      } else {
        probability_dither=FALSE;
        color.c1.rop=color.c0.rop;
      }
    } else
      dither=FALSE;
    plane_size1=base->plane_size<<3;
    nobound_switch (base->type) {
      case BMT_COLOR4:
        plane_limit1=plane_size1*4;
        break;
      case BMT_MONO:
        plane_limit1=plane_size1;
        break;
    }
    i1= -w1&7;
    if (i1>w2) i1=w2;
    i2=w2-w1-i1;
    if (i2<0)
      i2=0;
    else
      i2>>=3;
    i3=w2-w1-i2<<3-i1;
    bit_shift=x&7;
    bit_mask=-1-255<<bit_shift;
    if (dither) {
      if (probability_dither) {
        if (RandU2<base->dither_probability)
          color.c0=dither_colors.c1;
        else
          color.c0=dither_colors.c0;
      } else
        if (((x+w1)^(y+h1))&1)
        SwapU2(&color.c0,&color.c1);
      if (color.c0.rop==ROPB_COLLISION) {
        color =base->bkcolor.c0.color;
        k1=(h1+y)*base->width_internal+x;
        for (j=h2-h1;j;j--) {
          for (i=w1;i<w2;i++) {
            c=0;
            for (plane1=0,p=1;plane1<plane_limit1;
            plane1+=plane_size1,p<<=1)
              if (Bt(base->body,k1+i+plane1))
                c+=p;
            if (c!=color)
              base->collision_cnt++;
          }
          k1+=base->width_internal;
        }
        } else {
        bit_mask=-1-0x55<<bit_shift;
        for (p1=0,plane1=0;plane1<plane_limit1;
        plane1+=plane_size1,p1++) {
          kk1=(h1+y)*base->width_internal+x+w1+plane1;
          nobound_switch (color.c0.rop) {
            case ROPB_EQU:
            case ROPB_CLEAR_MASK_EQU:
            case ROPB_CLEAR_MASK_TRANSPARENT:
            case ROPB_TRANSPARENT:
              for (j=h2-h1;j;j--) {
                if (Bt(&color,p1))
                  color_byte=0x55<<bit_shift;
                else
                  color_byte=0;
                k1=kk1;
                for (i=0;i<i1;i+=2,k1+=2)
                  BEqu(base->body,k1,color_byte);
                k1-=i1&1;
                ptr1=k1>>3+base->body;
                for (i=0;i<i2;i++,ptr1><(U1 *)++)
                  *ptr1=*ptr1 & bit_mask | color_byte;
                k1+=i2<<3;
                for (i=0;i<i3;i+=2,k1+=2)
                  BEqu(base->body,k1,color_byte);
                kk1+=base->width_internal;
                if (probability_dither) {
                  if (RandU2<base->dither_probability)
                    color.c0=dither_colors.c1;
                  else
                    color.c0=dither_colors.c0;
                } else
                  SwapU2(&color.c0,&color.c1);
              }
              break;
            case ROPB_XOR:
              for (j=h2-h1;j;j--) {
                if (Bt(&color,p1))
                  color_byte=0x55<<bit_shift;
                else
                  color_byte=0;
                if (color_byte) {
                  k1=kk1;
                  for (i=0;i<i1;i+=2,k1+=2)
                    Btc(base->body,k1);
                  k1-=i1&1;
                  ptr1=k1>>3+base->body;
                  for (i=0;i<i2;i++,ptr1><(U1 *)++)
                    *ptr1^=color_byte;
                  k1+=i2<<3;
                  for (i=0;i<i3;i+=2,k1+=2)
                    Btc(base->body,k1);
                  kk1+=base->width_internal;
                }
                if (probability_dither) {
                  if (RandU2<base->dither_probability)
                    color.c0=dither_colors.c1;
                  else
                    color.c0=dither_colors.c0;
                } else
                  SwapU2(&color.c0,&color.c1);
              }
              break;
          }
          if (probability_dither) {
            if (RandU2<base->dither_probability)
              color.c0=dither_colors.c1;
            else
              color.c0=dither_colors.c0;
          } else
            if ((h2-h1)&1)
            SwapU2(&color.c0,&color.c1);
        }
        bit_mask=-1-0xAA<<bit_shift;
        color=base->color;
        color.c1.rop=color.c0.rop;
        if (probability_dither) {
          if (RandU2<base->dither_probability)
            color.c0=dither_colors.c1;
          else
            color.c0=dither_colors.c0;
        } else
          if (((x+w1+1)^(y+h1))&1)
          SwapU2(&color.c0,&color.c1);
        for (p1=0,plane1=0;plane1<plane_limit1;
        plane1+=plane_size1,p1++) {
          kk1=(h1+y)*base->width_internal+x+1+w1+plane1;
          nobound_switch (color.c0.rop) {
            case ROPB_EQU:
            case ROPB_CLEAR_MASK_EQU:
            case ROPB_CLEAR_MASK_TRANSPARENT:
            case ROPB_TRANSPARENT:
              for (j=h2-h1;j;j--) {
                if (Bt(&color,p1))
                  color_byte=0xAA<<bit_shift;
                else
                  color_byte=0;
                k1=kk1;
                for (i=1;i<i1;i+=2,k1+=2)
                  BEqu(base->body,k1,color_byte);
                k1+=i1&1;
                ptr1=(k1-1)>>3+base->body;
                for (i=0;i<i2;i++,ptr1><(U1 *)++)
                  *ptr1=*ptr1 & bit_mask | color_byte;
                k1+=i2<<3;
                for (i=1;i<i3;i+=2,k1+=2)
                  BEqu(base->body,k1,color_byte);
                kk1+=base->width_internal;
                if (probability_dither) {
                  if (RandU2<base->dither_probability)
                    color.c0=dither_colors.c1;
                  else
                    color.c0=dither_colors.c0;
                } else
                  SwapU2(&color.c0,&color.c1);
              }
              break;
            case ROPB_XOR:
              for (j=h2-h1;j;j--) {
                if (Bt(&color,p1))
                  color_byte=0xAA<<bit_shift;
                else
                  color_byte=0;
                if (color_byte) {
                  k1=kk1;
                  for (i=1;i<i1;i+=2,k1+=2)
                    Btc(base->body,k1);
                  k1+=i1&1;
                  ptr1=(k1-1)>>3+base->body;
                  for (i=0;i<i2;i++,ptr1><(U1 *)++)
                    *ptr1^=color_byte;
                  k1+=i2<<3;
                  for (i=1;i<i3;i+=2,k1+=2)
                    Btc(base->body,k1);
                  kk1+=base->width_internal;
                }
                if (probability_dither) {
                  if (RandU2<base->dither_probability)
                    color.c0=dither_colors.c1;
                  else
                    color.c0=dither_colors.c0;
                } else
                  SwapU2(&color.c0,&color.c1);
              }
              break;
          }
          if (probability_dither) {
            if (RandU2<base->dither_probability)
              color.c0=dither_colors.c1;
            else
              color.c0=dither_colors.c0;
          } else
            if ((h2-h1)&1)
            SwapU2(&color.c0,&color.c1);
        }
        }
    } else {
      if (color.c0.rop==ROPB_COLLISION) {
        color =base->bkcolor.c0.color;
        k1=(h1+y)*base->width_internal+x;
        for (j=h2-h1;j;j--) {
          for (i=w1;i<w2;i++) {
            c=0;
            for (plane1=0,p=1;plane1<plane_limit1;
            plane1+=plane_size1,p<<=1)
              if (Bt(base->body,k1+i+plane1))
                c+=p;
            if (c!=color)
              base->collision_cnt++;
          }
          k1+=base->width_internal;
        }
      } else
        for (p1=0,plane1=0;plane1<plane_limit1;
        plane1+=plane_size1,p1++) {
          if (Bt(&color,p1))
            color_byte=255<<bit_shift;
          else
            color_byte=0;
          kk1=(h1+y)*base->width_internal+x+w1+plane1;
          nobound_switch (color.c0.rop) {
            case ROPB_EQU:
            case ROPB_CLEAR_MASK_EQU:
            case ROPB_CLEAR_MASK_TRANSPARENT:
            case ROPB_TRANSPARENT:
              for (j=h2-h1;j;j--) {
                k1=kk1;
                for (i=0;i<i1;i++,k1++)
                  BEqu(base->body,k1,color_byte);
                ptr1=k1>>3+base->body;
                for (i=0;i<i2;i++,ptr1><(U1 *)++)
                  *ptr1=*ptr1 & bit_mask | color_byte;
                k1+=i2<<3;
                for (i=0;i<i3;i++,k1++)
                  BEqu(base->body,k1,color_byte);
                kk1+=base->width_internal;
              }
              break;
            case ROPB_XOR:
              if (color_byte)
                for (j=h2-h1;j;j--) {
                  k1=kk1;
                  for (i=0;i<i1;i++,k1++)
                    Btc(base->body,k1);
                  ptr1=k1>>3+base->body;
                  for (i=0;i<i2;i++,ptr1><(U1 *)++)
                    *ptr1^=color_byte;
                  k1+=i2<<3;
                  for (i=0;i<i3;i++,k1++)
                    Btc(base->body,k1);
                  kk1+=base->width_internal;
                }
                break;
          }
        }
        }
    if (mask=base->mask) {
      mask->brush=base->brush;
      mask->color=WHITE;
      if (base->color.c0.rop==ROPB_CLEAR_MASK_EQU)
        mask->color=ROPB_EQU+BLACK;
      else if (base->color.c0.rop==ROPB_CLEAR_MASK_TRANSPARENT)
        mask->color=ROPB_TRANSPARENT+BLACK;
      else
        mask->color.c0.rop=base->color.c0.rop;
      mask->win_task=base->win_task;
      if (mask->alias)
        mask->alias->flags|=BMF_DIRTY;
      GrRect(mask,_x,_y,w,h);
    }
    return TRUE;
  } else
    return FALSE;
}


Author:  Terry A. Davis [ Tue Apr 06, 2010 12:55 pm ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

Quote:
Hi MosMan,

I have the following suggestions which you should of course take with a grain of salt and investigate tatOS because my memory is short.

For ehci data toggle I use the same code as uhci. In the 2nd dword of your ehci QH you can instruct the controller to take the toggle bit from your TD just like uhci.

Some rules I follow for the data toggle bit:

1) each endpoint maintains its own toggle which alternates between 0 and 1 with each TD

2) on reset host and device set there toggles to 0

3) control transfers have rigid rules for toggle:
* command transport = first TD uses DATA0 then alternates
* data transport = first TD uses DATA1 then alternates
* status transport = first TD uses DATA1 then alternates

4) for bulk transfers you must use a global dataIN and dataOUT variable and alternate
this even across transactions and phases.
i.e. if the previous status transport was an IN=1 then
the next data transport if IN must be 0

5) if NAK do not toggle, instead retry with same

tatOS is actually quite dump about the toggle. If a transaction gets messed up I just reset the controller and port and start over. I usually dont need to do this.

To your second question about transaction length I would just suggest looking at the comments in tatOS/usb/prepareTD.s


See also tatOS/usb/controller.s and /usb/prepareTD.s and /usb/info-TD

Good luck,
TomT


I'm not doing USB unless legacy PS/2 keyboard mice is discontinued. It gains me nothing but worse compatibility.

I did some preliminary testing on USB to get within striking distance. I got signs of life, I can watch the frame counter count, read all the registers and detect hot swapping--I can watch a status change when plugging-in a device or removing it.

I also discovered I can walk through all the packets set-up by the BIOS to facilitate legacy PS/2 mode. Umm... how many ways are there to do it, I wonder? :-)

Author:  Terry A. Davis [ Tue Apr 06, 2010 1:15 pm ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

Quote:
gotcha on all that.
When I was in text mode I used the MMIO at 0xB8000 and every even array element /memory address corrosponded to the value and the odd address corosponded to the attribute (background color etc..)

But now I put my monitor in graphics mode

Code:
06 Graphics 2 80x25 640x200 1 B8000h



I am wondering how to set a given pixel in protected mode since I have switch from real to protected 32bit mode. I am wondering if their is an equivalent MMIO for graphics mode???

Also is their any high resolution for text mode or is it just
80 by 25 or 40 by 25 because it would be nice to have really small texted maybe the only way is to do it in graphics mode....

Also when would you use MMIO at A0000h instead of B8000h ?

Thanks for your help
gotcha on the pop stuff as well .




Way back in 1985 when I was learning interrupts as a kid on the Commodore, we used to use interrupts to change from graphics to text mode when the raster beam hit a certain point. This gave mixed graphics and text. I'm sure you're real proud of knowing interrupts, aren't you?

Here is my compiler's code for a function declared as an interrupt handler.

Code:
          case EC_LEAVE:
            if (fun_class) {
              if (Bt(fun_class->flags,Cf_INTERRUPT))
                IcPopRegs(tempi,CALWAYS_TRASHED_MASK&~(1<<CREG_RBP|1<<CREG_RSP)|fun_class->used_reg_mask&(CREG_VARS_MASK|CREG_NON_PTR_MASK|CSTK_TEMPS_MASK));
              else
                IcPopRegs(tempi,fun_class->used_reg_mask&(CREG_VARS_MASK|CREG_NON_PTR_MASK));
            }
            IcAddRSP(tempi,tempi->ic_data);
            IcPop(tempi,TY_REG+IT_I8,CREG_RBP,0,ip2);
            if (fun_class && Bt(fun_class->flags,Cf_INTERRUPT))
              IcU2(tempi,0xCF48);
            else
              IcU1(tempi,0xC3);
            break;



Here is an interrupt handler:

Code:
U0 KbdPktRead()
{
  U1 j;
  if (GetTimeStamp>kbd_evt_time+time_stamp_freq>>3)
    U1FifoFlush(kbd_fifo);
  kbd_evt_time=GetTimeStamp;
  LowPower(OFF);
  j=InU1(KEYB_PORT);
  if (!U1FifoCnt(kbd_fifo)) {
    U1FifoInsert(kbd_fifo,0x01);
    U1FifoInsert(kbd_fifo,j);
    if (j!=0xE0) {
      while (U1FifoRem(kbd_fifo,&j))
        U1FifoInsert(kbdmouse_fifo,j);
    }
  } else {
    U1FifoInsert(kbd_fifo,j);
    while (U1FifoRem(kbd_fifo,&j))
      U1FifoInsert(kbdmouse_fifo,j);
  }
}

interrupt U0 KbdIntHandler()
{
  Cld;
  OutU1(0x20,0x20);
  if (attempting_mouse_install) {
    reset_kbdmouse=TRUE;
    return;
  }
  KbdPktRead;
}


Author:  Terry A. Davis [ Tue Apr 06, 2010 1:42 pm ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

I save the MMX/SSE state during a task change. It still takes just half a microsecond.

Quote:
FPU/MMX and SSE are almost entirely separate; but they do share the "automatic FPU/MMX/SSE state saving" mechanism (the TS flag in eflags, the device not available exception handler, etc), and an OS that uses this automatic state saving mechanism typically uses FXSAVE to save all FPU/MMX/SSE state (because it'd be a nightmare otherwise).

If the OS doesn't use the automatic state saving mechanism, then it always saves FPU/MMX/SSE state (even when it hasn't been used), so it won't matter how much code uses FPU/MMX/SSE.


Cheers,

Brendan




I think you're getting all excited over an overrated, rarely usable feature. I suggest you actually try to make use of those SIMD instructions before worrying.

http://www.losethos.com/doc/LoseThosSSEMMX.html

They will do two 64-bit operations at once. Big deal.

You want more info in interrupts?

I include info in LoseThos if you want to play with them.
http://www.losethos.com/doc/LoseThosPCIInt.html
http://www.losethos.com/code/PCIInterrupts.html


Quote:
Well, the easy way to do this would just be to use a far pointer in C.

But otherwise it depends on exactly which compiler you are using for the C part of the code. Usually, return values are in EAX -- that is, you should be putting the byte in AL, not AH.





Returns go in RAX. LoseThos is 64-bit, mother fuckers! How many times I have to tell you. You tiny little gnats are annoying me. I wrote a friggin compiler. I'm way above your league.

Author:  Terry A. Davis [ Tue Apr 06, 2010 2:15 pm ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

You might be in the tin-foil hat stage at this point. You'll grow out of it. No alien motherships I know of.


Read about tongues:
http://www.usccb.org/nab/bible/1corinthians/1corinthians14.htm

In a sane world, you'd be sweating from the law of the universe.

God says...
Quote:
gushed schedule Blessedness Here patience worse creatures
speedily beholds posted dejectedness cubit informing exclaim
adorning roving ignoble flows aloud adapt THAT breadth
air dealt inhabitants Even Beauty distributing uphold
teeth blasphemy general GIVE envenomed chastened dismiss
selves unshakenly tendernesses marvelled prevented Viewing


I keep telling you, I'm on the side of law and order. Big time!! Oh, the irony.

Author:  Terry A. Davis [ Tue Apr 06, 2010 3:33 pm ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

Pages like this:

http://forum.osdev.org/viewtopic.php?f=1&t=21799

Pages like that make me wonder if there are sabauteurs.

I don't care. Anyone stupid enough to be mislead doesn't stand a chance anyway. Other things make me wonder, too.

Author:  Terry A. Davis [ Tue Apr 06, 2010 3:57 pm ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

Quote:
Also, where/when are the parameters removed from stack?
For stdcall you should retnw 4 assuming 16bit code...


I'm not fond of popping stack in a return. I donno, I like it in the calling procedure where things are pushed. It reads better and an academic would prefer it. Why do people dislike "goto"? Same sort of thing.

Code:
PUSH RBP
MOV RBP,RSP
SUB RSP,LOCAL_STORAGE_SIZE
push saved regs
....
pop saved regs
ADD RSP,LOCAL_STORAGE_SIZE
POP RBP
RET



PUSH Param2
PUSH Param1
CALL routine
ADD RSP,16   //64-bit stack has 2x8byte at this point



I might do some instruction timings on RET and pop. I'm ambivalent. I could change my compiler.



Code:
          case EC_ENTER:
            IcPush(tempi,TY_REG+IT_I8,CREG_RBP,0,ip2);
            IcMov(tempi,TY_REG+IT_I8,CREG_RBP,0,
                TY_REG+IT_I8,CREG_RSP,0,ip2);
            IcAddRSP(tempi,-tempi->ic_data);
            if (fun_class) {
              if (Bt(fun_class->flags,Cf_INTERRUPT))
                IcPushRegs(tempi,CALWAYS_TRASHED_MASK&~(1<<CREG_RBP|1<<CREG_RSP)|fun_class->used_reg_mask&(CREG_VARS_MASK|CREG_NON_PTR_MASK|CSTK_TEMPS_MASK));
              else {
                if (sys_var_init_flag&1 && i)
                  IcLocalVarInit(tempi);
                IcPushRegs(tempi,fun_class->used_reg_mask&(CREG_VARS_MASK|CREG_NON_PTR_MASK));
              }
            }
            for (i=0;i<NUM_REGS;i++)
              if (register_offsets[i]>0 && register_offsets[i]!=MAX_I8)
                IcMov(tempi,TY_REG+IT_I8,i,0,
                    TY_DISP+IT_I8,CREG_RBP,register_offsets[i],ip2);
            break;
          case EC_ADD_RSP:
            IcAddRSP(tempi,tempi->ic_data);
            break;
          case EC_CALL:
            i=tempi->ic_data-(ip2+5);
            IcU1(tempi,0xE8);
            IcU4(tempi,i);
            tempi->ic_flags&=~ICF_CODE_FINAL;
            break;
          case EC_CALL_EXTERN:
            IcU1(tempi,0xE8);
            IcU4(tempi,0);
            if (buf) {
              tempc=tempi->ic_data;
              tempeu=CAlloc(sizeof(ExternUsage));
              tempeu->next=tempc->ext_list;
              tempc->ext_list=tempeu;
              tempeu->ip=ip2+1;
            }
            tempi->ic_flags&=~ICF_CODE_FINAL;
            break;
          case EC_CALL_INDIRECT:
            if (MIN_I1<=tempi->ic_data<=MAX_I1) {
              IcU3(tempi,0x2454FF);  //CALL disp[RSP]
              IcU1(tempi,tempi->ic_data);
            } else {
              IcU3(tempi,0x2494FF);  //CALL disp[RSP]
              IcU4(tempi,tempi->ic_data);
            }
            break;
          case EC_CALL_INDIRECT2:
            IcU2(tempi,0xBB48);
            if (lx->flags&LF_STATIC_COMPILE) i=ip2+tempi->ic_cnt;
            IcU8(tempi,tempi->ic_data);
            IcU2(tempi,0x13FF);
            if (buf && lx->flags&LF_STATIC_COMPILE&& !(lx->flags&LF_NO_ABSOLUTES)) {
              tempa=CAlloc(sizeof(ExeAbsoluteAddressStruct));
              tempa->next=a->absolutes;
              tempa->type=EAA_ADD_U8;
              a->absolutes=tempa;
              tempa->ip=i;
            }
            tempi->ic_flags&=~ICF_CODE_FINAL;
            break;
          case EC_CALL_IMPORT:
            IcU1(tempi,0xE8);
            IcU4(tempi,-(ip2+5));
            if (buf) {
              tempc=tempi->ic_data;
              tempe=CAlloc(sizeof(ExeImportExportStruct));
              tempe->type=EIE_REL_U4;
              tempe->ip=ip2+tempi->ic_cnt-4;
              tempe->next=tempc->s.list;
              tempc->s.list=tempe;
            }
            tempi->ic_flags&=~ICF_CODE_FINAL;
            break;
          case EC_LEAVE:
            if (fun_class) {
              if (Bt(fun_class->flags,Cf_INTERRUPT))
                IcPopRegs(tempi,CALWAYS_TRASHED_MASK&~(1<<CREG_RBP|1<<CREG_RSP)|fun_class->used_reg_mask&(CREG_VARS_MASK|CREG_NON_PTR_MASK|CSTK_TEMPS_MASK));
              else
                IcPopRegs(tempi,fun_class->used_reg_mask&(CREG_VARS_MASK|CREG_NON_PTR_MASK));
            }
            IcAddRSP(tempi,tempi->ic_data);
            IcPop(tempi,TY_REG+IT_I8,CREG_RBP,0,ip2);
            if (fun_class && Bt(fun_class->flags,Cf_INTERRUPT))
              IcU2(tempi,0xCF48);
            else
              IcU1(tempi,0xC3);
            break;
          case EC_RET:
            IcU1(tempi,0xC3);
            break;
          case EC_RETURN_VAL2:
            break;
          case EC_RETURN_VAL:
          case EC_SET_RAX:
            IcMov(tempi,TY_REG+IT_I8,CREG_RAX,0,
                tempi->p1.type,tempi->p1.reg,tempi->p1.disp,ip2);
            break;



Aren't compilers fun!! The funnest thing was making my compiler.

Author:  Kieran [ Wed Apr 07, 2010 5:34 am ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

Terry, please can you tell me who you are arguing and swearing at here please...

It seems to be a topic full of you and just you since post 8, if you dont have an answer or just want to continue swearing at yourself, i'll just lock the topic.

Author:  Terry A. Davis [ Wed Apr 07, 2010 10:42 am ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

sorry

Author:  Terry A. Davis [ Fri Apr 09, 2010 2:13 am ]
Post subject:  Re: Wanting to use the "hello world" bootloader code

I decided to change my compiler to do the RET instruction that adds to the stack. It shortened my code a lot.

Page 3 of 4 All times are UTC - 6 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/