;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)