Author |
Topic: Compiling ASM program containing array labels (Read 2279 times) |
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Compiling ASM program containing array labels
« Reply #4 on: Jun 1st, 2009, 10:07pm » |
|
Quote:| The 'structure members as labels' solution sounds nice for a small set of routines, but GFXLIB has over a hundred routines (I think) |
|
I don't know exactly how you tried to use the array-element method but I presume you didn't use one large array for all the labels but instead a separate array for each routine or small group of routines. In that case I would have thought a straightforward search-and-replace of (0) to .a, (1) to .b etc. would have done most of the conversion.
Of course you'd also have to replace each array declaration with an equivalent structure declaration, but assuming the size of each array is quite small (say fewer than 20 elements) that should be pretty easy too. You would necessarily need to use the same member names for each structure (otherwise the method offers no advantage over separate labels) so again a search-and-replace will do most of the work.
So maybe converting to the structure-member method wouldn't be too much effort after all.
Richard.
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: Compiling ASM program containing array labels
« Reply #5 on: Jun 1st, 2009, 10:37pm » |
|
on Jun 1st, 2009, 10:07pm, Richard Russell wrote:| I don't know exactly how you tried to use the array-element method but I presume you didn't use one large array for all the labels but instead a separate array for each routine or small group of routines. In that case I would have thought a straightforward search-and-replace of (0) to .a, (1) to .b etc. would have done most of the conversion. |
|
I used a two-dimensional array: label%( numRoutines%-1, 9 ), allowing each of the main routines to have upto 10 'sub-labels'.
Just to illustrate, here's one routine from GFXLIB (routine #24):
Code: ;REM.
;REM. ****************|******************************************************************************
;REM. * | *
;REM. * Routine | (24) Plot *
;REM. * | *
;REM. * Purpose | Plots a raw 32bpp bitmap (or 'sprite') *
;REM. * | *
;REM. * Entry params | dispVars, bmAddr, bmW, bmH, bmX, bmY *
;REM. * | *
;REM. * Example | SYS GFXLIB_Plot, dispVars{}, ballspr%, 32, 32, ballx%, bally% *
;REM. * | *
;REM. * Notes | Black pixels (i.e. those of value &xx000000) are ignored (i.e. not plotted) *
;REM. * | *
;REM. ****************|******************************************************************************
;REM.
.GFXLIB_Plot
;
; SYS GFXLIB_Plot, dispVars, bmAddr, bmW, bmH, bmX, bmY
;
pushad
;REM. ESP+36 = dispVars
;REM. ESP+40 = bmAddr
;REM. ESP+44 = bmW
;REM. ESP+48 = bmH
;REM. ESP+52 = bmX
;REM. ESP+56 = bmY
;REM. --------------------------------------------------------------
;REM. Setup the entry calling params for the bitmap clipping routine
;REM. --------------------------------------------------------------
mov eax, [esp+36] ; EAX = ptr to params blk
cmp dword [eax+28], TRUE
jne near label%(24,0) ; .GFXLIB_Plot__exit
;REM. copy GFXLIB_Plot's entry vars from the stack to varsblk (makes life somewhat easier)
mov ebx,[esp+40] : mov [varsblk+64],ebx ; varsblk+64 = bmAddr
mov ebx,[esp+44] : mov [varsblk+68],ebx ; varsblk+68 = bmW
mov ebx,[esp+48] : mov [varsblk+72],ebx ; varsblk+72 = bmH
mov ebx,[esp+52] : mov [varsblk+76],ebx ; varsblk+76 = bmX
mov ebx,[esp+56] : mov [varsblk+80],ebx ; varsblk+80 = bmY
;REM. Call the clipping routine (GFXLIB_clip) after PUSHing the required vars onto the stack
;REM. SYS GFXLIB_clip, dispVars, bmW, bmH, bmX, bmY, clipValsBlk
push (varsblk+128) ; ptr to clipValsBlk
push dword [varsblk+80] ; bmY
push dword [varsblk+76] ; bmX
push dword [varsblk+72] ; bmH
push dword [varsblk+68] ; bmW
push eax ; ptr to params blk
call GFXLIB_clip
;REM.
;REM. clipValsBlk
;REM.
;REM. +128 plotFlag (TRUE or FALSE) - if FALSE, do not attempt to plot/display bitmap
;REM. +132 clipFlag (TRUE or FALSE) - if TRUE then clipping is required
;REM. +136 startX
;REM. +140 startY
;REM. +144 numRows
;REM. +148 rowLen
;REM. +152 skipRows
;REM. +156 skipPxls
;REM.
cmp [varsblk+128], dword TRUE ; check plotFlag
jne label%(24,0) ; GFXLIB_Plot__exit ; exit if plotFlag=FALSE
;REM.
;REM. bmBuffO% = bmBuffAddr% + 4*(params.bmBuffW%*clipvals.startY% + clipvals.startX%)
;REM. bmW4% = 4*bmW%
;REM. bmBuffW4% = 4*bmBuffW%
;REM. bmAddr% += 4*(clipvals.skipRows% + clipvals.skipPxls%)
;REM.
;REM. FOR Y%=clipvals.numRows%-1 TO 0 STEP -1
;REM. FOR X%=clipvals.rowLen%-1 TO 0 STEP -1
;REM. bmBuffO%!(4*X%) = bmAddr%!(4*X%)
;REM. NEXT X%
;REM. bmAddr% += bmW4%
;REM. bmBuffO% += bmBuffW4%
;REM. NEXT Y%
;REM.
;----*----*----*----*----*----*----*----|
; compute initial/starting offset into the 'bmp buffer' (bmBuffO)
; EAX = ptr to params blk
mov ebx, [eax + 0] ; load base addr of 'bmp buffer' (bmpBuffAddr)
mov ecx, [varsblk + 140] ; startY
imul ecx, [eax + 4] ; = startY*bmpBuffW
add ecx, [varsblk + 136] ; = startY*bmpBuffW + startX
shl ecx, 2 ; = 4*(startY*bmpBuffW + startX)
add ecx, ebx ; = bmpBuffAddr + 4*(startY*bmpBuffW + startX)
mov edi, [varsblk + 64] ; bmAddr
mov ebx, [varsblk + 152] ; skipRows
add ebx, [varsblk + 156] ; skipRows+skipPxls
shl ebx, 2 ; 4*(skipRows + skipPxls)
add edi, ebx ; bmAddr += 4*(skipRows + skipPxls)
mov ebp, [varsblk + 68] ; bmW
shl ebp, 2 ; = 4*bmW
mov eax, [eax + 4] ; bmBuffW
shl eax, 2 ; = 4*bmBuffW
mov esi, [varsblk + 144] ; numRows (Y-loop counter)
dec esi ; numRows -= 1
.label%(24,1) ; .GFXLIB_Plot__yloop
push esi ; preserve ESI (Y-loop counter)
mov esi, [varsblk + 148] ; rowLen (X-loop counter)
dec esi ; rowLen -= 1
.label%(24,2) ; .GFXLIB_Plot__xloop
mov edx, [edi + 4*esi] ; load dword from source bitmap
test edx, &00FFFFFF ; is it 0 ?
jz label%(24,3) ; GFXLIB_Plot__next_pxl ; skip (i.e. don't plot) if so
mov [ecx + 4*esi], edx ; write dword to destination bitmap buffer
.label%(24,3) ; .GFXLIB_Plot__next_pxl
dec esi ; X -= 1
jge label%(24,2) ; GFXLIB_Plot__xloop ; loop if X >= 0
add edi, ebp ; bmAddr += 4*bmW
add ecx, eax ; bmBuffAddr += 4*bmBuffW
pop esi ; recover numRows (Y-loop)
dec esi ; Y -= 1
jge label%(24,1) ; GFXLIB_Plot__yloop ; loop if Y >= 0
.label%(24,0) ; .GFXLIB_Plot__exit
popad
ret (6*4)
I would have been perfectly happy with the 2D-array approach if only the Compiler was happy with it.
David.
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Compiling ASM program containing array labels
« Reply #6 on: Jun 2nd, 2009, 08:34am » |
|
Quote:| I used a two-dimensional array |
|
OK. Personally I'm not keen on that approach, partly because it runs somewhat contrary to the principle of 'information hiding' (having a data structure shared between more than one routine that needn't be) and partly because it makes the labels so 'anonymous' (all called 'label' something!).
I think my preferred approach (had it worked!) would have been to use a separate array for each routine, perhaps with the same name as the routine itself. So the routine GFXLIB_Plot would have had labels GFXLIB_Plot(0), GFXLIB_Plot(1) etc.
If I was faced with converting what you've got to a structure-member approach (which again I'd want to be self-contained to each routine) I'd write a little utility in BASIC to do it!
Richard.
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: Compiling ASM program containing array labels
« Reply #7 on: Jun 2nd, 2009, 10:04am » |
|
on Jun 2nd, 2009, 08:34am, Richard Russell wrote:| OK. Personally I'm not keen on that approach, partly because it runs somewhat contrary to the principle of 'information hiding' (having a data structure shared between more than one routine that needn't be) and partly because it makes the labels so 'anonymous' (all called 'label' something!). |
|
You've probably noticed that I tend to comment my code verbosely! So, for me personally, the 'anonymous' label names aren't a problem because I always include an informative comment on the same line:
Code:.label%(37,3) ; .GFXLIB_AlphaBlend__skip
jmp label%(37,5) ; GFXLIB_AlphaBlend__exit
etc.
on Jun 2nd, 2009, 08:34am, Richard Russell wrote:| If I was faced with converting what you've got to a structure-member approach (which again I'd want to be self-contained to each routine) I'd write a little utility in BASIC to do it! |
|
Well, again, thanks for another excellent suggestion, but I best channel my energy into improving the efficiency of existing routines, developing new ones, writing more examples, and finishing the currently very poor documentation.
David.
|
|
Logged
|
|
|
|
|