开发者

C implementation of Assembler code

开发者 https://www.devze.com 2023-01-13 10:46 出处:网络
I\'m trying to rewrite this asm code in C, but my asm knowledge very bad. struct { union { struct{ WORDShiftZ0;

I'm trying to rewrite this asm code in C, but my asm knowledge very bad.


struct
{
 union
 {
  struct{
  WORD  ShiftZ0;
  WORD  ShiftZ1;
  WORD  ShiftZ2;
  WORD  ShiftZ3; };
  struct{
  DWORD ShiftZ01;
  DWORD ShiftZ23; };
 };
  short ShiftZ0Align;
  short ShiftZ1Align;
  short ShiftZ2Align;
  short ShiftZ3Align;
  int   deltaZ0ToNextLine;
  int   deltaZ1ToNextLine;
  void *Palette;
} AsmDrawData;

inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void video,int no_dot) { __asm { cm开发者_运维技巧p no_dot,0 je end mov esi,zdata mov edi,video mov ebx,zbuffer mov ecx,AsmDrawData.Palette lp: mov eax,AsmDrawData.ShiftZ01 add ax,[esi] cmp ax,[ebx] jle end_out_byte mov [ebx],ax mov edx,data movzx edx,byte ptr [edx] mov DX_REG,[ecx+edx(COLOR_DEPTH/8)] mov [edi],DX_REG end_out_byte: add edi,(COLOR_DEPTH/8) add ebx,2 add esi,2 inc data dec no_dot jg lp end: } }

This is what I write, but this wrong:

inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void *video,int no_dot)     {
  for( int i = 0; i < no_dot; i++ ) { 
   if( ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0 >= ((WORD*)zbuffer)[i] )
    {
        ((WORD*)zbuffer)[i] = ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0;
        ((WORD*)video)[i]   = ((WORD*)AsmDrawData.Palette)[((BYTE*)data)[i]];
    }
  }
}

Where I could be wrong? (sorry for my very very bad english)


This is not a real answer. It's just some ideas and a rewriting of the function as I understand it in hopefully a more clear form.

I highly suspect that your problem was with the line:

 if( ((WORD*)zdata)[i] + AsmDrawData.ShiftZ0 >= ((WORD*)zbuffer)[i] )

In this code you cast the zdata pointer from a byte to a word pointer. That seems odd to me. The assembly does appear to have done the same thing, though. Since you probably know more about how the zdata field gets populated you can probably make a better determination about it.

This zbuffer algorithm appears to be fairly standard, so even without trying to reverse engineer this assembly you should be able to re-implement it in C fairly easily.

I rewrote this, . I like to keep this localized, so I just declare local pointers at the top that have the correct types (and also use the C99 stdint names because they are more portable than WORD).

#include <stdint.h>

inline void AsmDrawWithZ16(BYTE *zdata,BYTE *data,WORD *zbuffer,void *video,int no_dot) {
  uint8_t * zd = zdata;  // Should this be 8 or 16 bit
  uint8_t * dat = data;
  uint16_t * zb = zbuffer;
  uint16_t shz = AsmDrawData.ShiftZ0;
  uint16_t * vid = (uint16_t *)video;

  for( int i = 0; i < no_dot; i++ ) {
    uint16_t X = shz + zd[i];
    if( X >= zb[i] )  // Is this the correct direction of the compare
     {
        zb[i] = zdata[i] + X;  // update the depth
        vid[i] = AsmDrawData.Palette[ dat[i] ]; // update the color
     }
  }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号