Small 68k asm conversion..

14 posts / 0 new
Last post
afxgroup
afxgroup's picture
Offline
Last seen: 5 months 1 week ago
Joined: 2011-02-03 15:26
Small 68k asm conversion..

Hello,
Can anyone translate me this 68k code into C (or ppc asm..)

  1. putreg(REG_D1, 0);
  2. do {
  3. *bw = *(UWORD *)((UBYTE *)*plane-- + offset) >> shift;
  4. putreg(REG_A0, (long)bw);
  5. __emit(0xE4D0); /* ROXR.W (A0) */
  6. __emit(0xE351); /* ROXL.W #1,D1 */
  7. ++bw;
  8. }
  9. while (--d > 0);

The first one seems a simply shift? or i ame wrong?

thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
Well, it is not a "simple"

Well, it is not a "simple" shift because the bit which is shifted out on the right is moved into the X status bit. The second instruction shifts to the left and the new LSB is not just 0 but becomes the value of the X bit.

One could translate this into

X = (*A0) & 1; (*A0) >>= 1;
D1 = (D1 << 1) | X;

or a bit optimised

D1 = (D1 << 1) | ((*A0) & 1);
(*A0) >>= 1;

afxgroup
afxgroup's picture
Offline
Last seen: 5 months 1 week ago
Joined: 2011-02-03 15:26
unlucky it doesn't seems

unlucky it doesn't seems works as expected.. at least seeing the original 68k version..

But maybe could be this one the problem.

  1. d = FloodDepth;
  2. putreg(REG_A0, (long)BWord);
  3. putreg(REG_D1, 0);
  4. do {
  5. __emit(0xE4D8); /* ROXR.W (A0)+ */
  6. __emit(0xE351); /* ROXL.W #1,D1 */
  7. }
  8. while (--d > 0);
  9.  
  10. pix = getreg(REG_D1);

I've used your code in this way:

  1. D1 = (D1 << 1) | ((*BWord) & 1);
  2. (*BWord) >>= 1;
  3. (*BWord)++;

Is this right? That instruction seems to have a post increment.
And also. Is this correct to use the code in that way? (also for the original post)

  1. D1 = 0;
  2. do {
  3. *bw = *(UWORD *)((UBYTE *)*plane-- + offset) >> shift;
  4. D1 = (D1 << 1) | ((*bw) & 1);
  5. (*bw) >>= 1;
  6. ++bw;
  7. }
  8. while (--d > 0);
thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
You still have difficulties

You still have difficulties understanding the difference between BWord and *BWord, haven't you?

Firstly, the original code moves BWord into A0 and then modifies A0 in a loop but it never moves the modified A0 back to BWord. This means you should not modify BWord in your code.

And secondly (A0)+ means that it accesses the address to which A0 points and then increments A0. The increment should be translated into A0++ and not into (*A0)++ like you do.

afxgroup
afxgroup's picture
Offline
Last seen: 5 months 1 week ago
Joined: 2011-02-03 15:26
damned copy & paste.. i

damned copy & paste.. i didn't spot the missing "*"...
so it will became

  1. D1 = (D1 << 1) | (BWord & 1);
  2. BWord >>= 1;
  3. BWord++;

is this correct? (i didn't test it.. i'm at work..)

but is the increment needed or not? from your words "This means you should not modify BWord in your code." i understand that i shouldn't touch it. But if so.. when the increment is done?

salass00
salass00's picture
Offline
Last seen: 6 months 1 week ago
Joined: 2011-02-03 11:27
This code: d =

This code:

  1. d = FloodDepth;
  2. putreg(REG_A0, (long)BWord);
  3. putreg(REG_D1, 0);
  4. do {
  5. __emit(0xE4D8); /* ROXR.W (A0)+ */
  6. __emit(0xE351); /* ROXL.W #1,D1 */
  7. }
  8. while (--d > 0);
  9.  
  10. pix = getreg(REG_D1);

turned into C should be:

  1. d = FloodDepth;
  2. UWORD *A0 = (UWORD *)BWord;
  3. UWORD D1 = 0;
  4. do {
  5. D1 = (D1 << 1)|(*A0 & 1);
  6. *A0 >>= 1; A0++;
  7. } while (--d > 0);
  8. pix = D1;
afxgroup
afxgroup's picture
Offline
Last seen: 5 months 1 week ago
Joined: 2011-02-03 15:26
all seems working correctly..

all seems working correctly.. but i think there is this function that is needed even if i've used the ReadPixel from gfx library.. but it seems not correct:

  1. static UWORD ReadPixelFunc[] =
  2. {
  3. 0x48E7,0x3000, // movem.l d2-d3,-(sp)
  4. 0x3429,0x0000, // move.w bm_BytesPerRow(a1),d2
  5. 0xC2C2, // mulu d2,d1 ; offset (d1) = bytesperrow * y
  6. 0x2400, // move.l d0,d2
  7. 0xE682, // asr.l #3,d2
  8. 0xD282, // add.l d2,d1 ; offset += x >> 3
  9. 0x0240,0x0007, // andi.w #7,d0
  10. 0x7407, // moveq #7,d2
  11. 0x9440, // sub.w d0,d2 ; bit (d2) = 7 - (x & 7)
  12. 0x48C2, // ext.l d2
  13. 0x7600, // moveq #0,d3
  14. 0x1629,0x0005, // move.b bm_Depth(a1),d3
  15. 0x5343, // subq #1,d3 ; plane (d3) = depth - 1
  16. 0x2003, // move.l d3,d0
  17. 0xE580, // asl.l #2,d0
  18. 0x5080, // addq.l #bm_Planes,d0
  19. 0xD3C0, // adda.l d0,a1 ; planes (a1) = &bmap->Planes[plane]
  20. 0x7000, // moveq #0,d0 ; color (d0) = 0
  21. 0x2051,// pxloop: movea.l (a1),a0
  22. 0xD1C1, // adda.l d1,a0
  23. 0x0510, // btst.b d2,(a0)
  24. 0x6702, // beq.b notset
  25. 0x07C0, // bset.l d3,d0
  26. 0x5949,// notset: subq #4,a1
  27. 0x51CB,0xFFF2, // dbra d3,pxloop
  28. 0x4CDF,0x000C, // movem.l (sp)+,d2-d3
  29. 0x4E75 // rts
  30. };
  31. static UBYTE __asm (*ReadPix)(register __a1 struct BitMap *, register __d0 SHORT, register __d1 SHORT)
  32. = (UBYTE __asm (*)(register __a1 struct BitMap *, register __d0 SHORT, register __d1 SHORT))ReadPixelFunc;

my ReadPix is:

  1. UBYTE ReadPix(struct BitMap *bmap, SHORT x, SHORT y)
  2. {
  3. struct RastPort tmpras;
  4. UBYTE retval;
  5. InitRastPort(&tmpras);
  6. tmpras.BitMap = bmap;
  7. retval = ReadPixel(&tmpras, x, y);
  8. printf("ReadPix (%ld)\n",retval);
  9. return retval;
  10. }

But the pixel read from the program seems wrong..

salass00
salass00's picture
Offline
Last seen: 6 months 1 week ago
Joined: 2011-02-03 11:27
Since the assembler code is

Since the assembler code is done as a data array a very simple, although not so efficient solution would be to just call the m68k emulator on it like so:

  1. UBYTE ReadPix(struct BitMap *bmap, SHORT x, SHORT y) {
  2. return EmulateTags(ReadPixelFunc,
  3. ET_RegisterA1, bmap,
  4. ET_RegisterD0, x,
  5. ET_RegisterD1, y,
  6. TAG_END);
  7. }
afxgroup
afxgroup's picture
Offline
Last seen: 5 months 1 week ago
Joined: 2011-02-03 15:26
uh.. just tried.. i get a DSI

uh.. just tried.. i get a DSI when the function is called. And the stack trace points to 68k code.

salass00
salass00's picture
Offline
Last seen: 6 months 1 week ago
Joined: 2011-02-03 11:27
Well from a quick look at the

Well from a quick look at the assembler code this should be a suitable C replacement:

  1. UBYTE ReadPix(struct BitMap *bmap, SHORT x, SHORT y) {
  2. ULONG byte = (y * bmap->BytesPerRow) + (x >> 3);
  3. ULONG bit = 7 - (x & 7);
  4. ULONG i, res = 0;
  5. UBYTE *plane;
  6. for (i = 0; i < bmap->Depth; i++) {
  7. plane = (UBYTE *)bmap->Planes[i];
  8. if ((plane[byte] >> bit) & 1) {
  9. res |= (1 << i);
  10. }
  11. }
  12. return res;
  13. }

It's not identical in that the assembler code handles the bitplanes in the opposite order but the end result should be the same.

afxgroup
afxgroup's picture
Offline
Last seen: 5 months 1 week ago
Joined: 2011-02-03 15:26
ok mate.. line 9 was: res |=

ok mate.. line 9 was: res |= (1 << *plane) but it works.. like the other soultion (EmulateTags). I've found the problem of the DSI...my error..
So now i'm 100% sure that ReadPix function works because i can see the color under mouse position and is the correct one..
So the problem is for sure in that other file. And so in the that two functions. Your function seems to work correctly but this one:

  1. putreg(REG_D1, 0);
  2. do {
  3. *bw = *(UWORD *)((UBYTE *)*plane-- + offset) >> shift;
  4. putreg(REG_A0, (long)bw);
  5. __emit(0xE4D0); /* ROXR.W (A0) */
  6. __emit(0xE351); /* ROXL.W #1,D1 */
  7. ++bw;
  8. }
  9. while (--d > 0);

seems always wrong..

salass00
salass00's picture
Offline
Last seen: 6 months 1 week ago
Joined: 2011-02-03 11:27
@afxgroup That line 9 should

@afxgroup

That line 9 should have been "res |= (1 << i);". I've fixed it in the post above. While working on the code I changed around the names of the variables and simply forgot to change it in this one line.

Just a thought, where does the bitmap come from that is passed to ReadPix()? The function as it is now will only work with a planar bitmap and will DSI and return completely wrong results if passed a chunky bitmap.

salass00
salass00's picture
Offline
Last seen: 6 months 1 week ago
Joined: 2011-02-03 11:27
100% C version of this

100% C version of this code:

  1. putreg(REG_D1, 0);
  2. do {
  3. *bw = *(UWORD *)((UBYTE *)*plane-- + offset) >> shift;
  4. putreg(REG_A0, (long)bw);
  5. __emit(0xE4D0); /* ROXR.W (A0) */
  6. __emit(0xE351); /* ROXL.W #1,D1 */
  7. ++bw;
  8. }
  9. while (--d > 0);

should be:

  1. ULONG D1 = 0;
  2. UWORD *A0;
  3. do {
  4. *bw = *(UWORD *)((UBYTE *)*plane-- + offset) >> shift;
  5. A0 = (UWORD *)bw;
  6. D1 = (D1 << 1)|(*A0 & 1)
  7. *A0 >>= 1;
  8. ++bw;
  9. } while (--d > 0);
afxgroup
afxgroup's picture
Offline
Last seen: 5 months 1 week ago
Joined: 2011-02-03 15:26
Yes the funcion is called

Yes the funcion is called only when there is a planar bitmap.

Log in or register to post comments