; CONSTANTS

MOVEM EQU 0
RTGMASTER EQU 1
DOUBLEBUFFER EQU 2
FCOPY EQU 3
WAIT EQU 0
NOWAIT EQU 1
POINTER EQU 0
NOPOINTER EQU 1
LSHIFT EQU 1
RSHIFT EQU 2
CAPSLOCK EQU 4
CONTROL EQU 8
LALT EQU 16
RALT EQU 32
LCOMMAND EQU 64
RCOMMAND EQU 128
NUMERICPAD EQU 256
MIDBUTTON EQU 512
RBUTTON EQU 1024
LEFTBUTTON EQU 2048
MEMF_FAST EQU 4
MEMF_CLEAR EQU 65536
AttnFlags EQU 296
TAG_USER EQU $80000000
smr_MinWidth EQU TAG_USER+1
smr_MaxWidth EQU TAG_USER+2
smr_MinHeight EQU TAG_USER+3
smr_MaxHeight EQU TAG_USER+4
smr_ChunkySupport EQU TAG_USER+9
smr_PlanarSupport EQU TAG_USER+10
smr_ProgramUsesC2P EQU TAG_USER+12
smr_Buffers EQU TAG_USER+11
rtg_Buffers EQU TAG_USER+1
grd_Width EQU TAG_USER+1
grd_Height EQU TAG_USER+2
grd_Depth EQU TAG_USER+5
grd_BytesPerRow EQU TAG_USER+7
rdcmp_MouseX EQU 8
rdcmp_MouseY EQU 12
sq_ScreenMode EQU 0
sm_ChunkySupport EQU 80

_LVOOpenRtgScreen       EQU     -30
_LVOCloseRtgScreen      EQU     -36
_LVOSwitchScreens       EQU     -42
_LVOLoadRGBRtg  EQU     -48
_LVOLockRtgScreen       EQU     -54
_LVOUnlockRtgScreen     EQU     -60
_LVOGetBufAdr   EQU     -66
_LVOGetRtgScreenData    EQU     -72
_LVORtgScreenModeReq    EQU     -96
_LVOFreeRtgScreenModeReq        EQU     -102
_LVOCopyRtgPixelArray   EQU     -144
_LVODrawRtgLine EQU     -156
_LVOWaitTOF EQU -180
_LVORtgText EQU -270
_LVORtgSetFont EQU -276
_LVORtgSetPointer EQU -288
_LVORtgSetTextMode EQU -294
_LVORtgOpenFont EQU -300
_LVORtgCloseFont EQU -306
_LVOSetTextModeRGB EQU -312
_LVORtgInitRDCMP EQU -318
_LVORtgGetMsg EQU -330
_LVORtgReplyMsg EQU -336
me_rawkey EQU 0
me_mouse EQU 2
me_qualifier EQU 4
me_x EQU 6
me_y EQU 8
IDCMP_MOUSEBUTTONS      EQU     $00000008
IDCMP_RAWKEY            EQU     $00000400
im_Class EQU 20
im_Code EQU 24
im_Qualifier EQU 26
im_MouseX EQU 32
im_MouseY EQU 34

; Variables

proctype: dc.l 0

; Some Help functions (called by the real functions)

OpenRequester:
    movem.l d1-d2/a0-a2/a6,-(sp)
    move.l $4,a6
    lea rtgname,a1
    moveq #0,d0
    jsr -408(a6)
    move.l d0,rtgbase
    cmp.l #0,d0
    beq or_AGA
    lea pcxname,a1
    moveq #0,d0
    jsr -408(a6)
    move.l d0,pcxbase
    cmp.l #0,d0
    beq or_AGA
    lea dosname,a1
    moveq #0,d0
    jsr -408(a6)
    move.l d0,dosbase
    move.l rtgbase,a6
    lea srtags,a0
    jsr _LVORtgScreenModeReq(a6)
    move.l d0,smode
    move.l d0,a0
    move.l sq_ScreenMode(a0),a0
    cmp.l #0,sm_ChunkySupport(a0)
    beq or_AGA
    movem.l (sp)+,d1-d2/a0-a2/a6
    rts
or_AGA:
    move.l #0,d0
    movem.l (sp)+,d1-d2/a0-a2/a6
    rts
srtags:
    dc.l smr_MinWidth,320
    dc.l smr_MinHeight,200      ; Minimum : 320x200
    dc.l smr_MaxWidth,640
    dc.l smr_MaxHeight,480     ; Maximum : 640x480
    dc.l smr_ChunkySupport,512 ; Chunky 8 Bit is possible
    dc.l smr_PlanarSupport,128 ; Planar 8 Bit is possible
    dc.l smr_ProgramUsesC2P,0  ; No rtgmaster c2p is used
    dc.l smr_Buffers,2         ; 2 Buffers
    dc.l 0,0
rtgbase:
    dc.l 0
pcxbase:
    dc.l 0
rtgname:
    dc.b 'rtgmaster.library',0
pcxname:
    dc.b 'pcxload.library',0
dosname:
    dc.b 'dos.library',0
    even
dosbase:
    dc.l 0
smode:
    dc.l 0

OpenScreen:
    movem.l a0-a3/a6,-(sp)
    move.l a0,a3
    move.l smode,a0
    move.l d0,pointer
    lea sctags,a1
    move.l rtgbase,a6
    jsr _LVOOpenRtgScreen(a6)
    move.l d0,rtgscreen
    move.l d0,a0
    jsr _LVORtgInitRDCMP(a6)
    move.l d0,rtgport
    move.l pointer,d0
    cmp.l #POINTER,d0
    beq os_pointer
    move.l rtgscreen,a0
    lea clearpointer,a1
    move.l #16,d0
    move.l #16,d1
    move.l #-15,d2
    move.l #-7,d3
    jsr _LVORtgSetPointer(a6)
os_pointer:
    move.l rtgscreen,a0
    lea tags,a1
    jsr _LVOGetRtgScreenData(a6)
    move.l rtgscreen,a0
    jsr _LVOLockRtgScreen(a6)
    move.l d0,MapA
    move.l rtgscreen,a0
    move.l #1,d0
    jsr _LVOGetBufAdr(a6)
    move.l d0,MapB
    move.l rtgscreen,d0
    move.l MapA,d1
    move.l MapB,d2
    move.l Width,d3
    move.l Height,d4
    move.l Depth,d5
    move.l Bytes,d6
    move.l #0,currentbuffer
    movem.l a0-a2/d0-d2,-(sp)
    move.l dosbase,a6
    move.l #fcopyname,d1
    ;jsr -150(a6)
    lsl.l #2,d0
    move.l d0,fcopyadr

    ;add.l #24,d0
    move.l d0,a0
    move.l (a0),d0
    move.l 4(a0),d0
    move.l 8(a0),d0
    move.l 12(a0),d0
    move.l 16(a0),d0
    move.l 20(a0),d0
    move.l 24(a0),d0


    move.l #loadpcxname,d1
    ;jsr -150(a6)
    lsl.l #2,d0
    move.l d0,loadpcxadr
    movem.l (sp)+,a0-a2/d0-d2
    movem.l (sp)+,a0-a3/a6
    rts
clearpointer:
    dc.w 0,0,0,0,0,0,0,0,0
    dc.w 0,0,0,0,0,0,0,0,0
    dc.w 0,0,0,0,0,0,0,0,0
    dc.w 0,0,0,0,0,0,0,0,0

rtgport: dc.l 0
pointer: dc.l 0
sctags:
    dc.l rtg_Buffers,2,0,0
tags:
    dc.l grd_Width
Width:
    dc.l 0
    dc.l grd_Height
Height:
    dc.l 0
    dc.l grd_Depth
Depth:
    dc.l 0
    dc.l grd_BytesPerRow
Bytes:
    dc.l 0,0,0
rtgscreen:
    dc.l 0
MapA:
    dc.l 0
MapB:
    dc.l 0
currentbuffer:
    dc.l 0
fcopyname:
    dc.b 'fcopy',0
loadpcxname:
    dc.b 'loadpcx',0
    even
fcopyadr:
    dc.l 0
loadpcxadr:
    dc.l 0

CloseScreen:
    movem.l d0-d2/a0-a2/a6,-(sp)
    move.l rtgbase,a6
    jsr _LVOCloseRtgScreen(a6)
    move.l smode,a0
    jsr _LVOFreeRtgScreenModeReq(a6)
    move.l $4,a6
    move.l rtgbase,a1
    jsr -414(a6)
    move.l pcxbase,a1
    jsr -414(a6)
    move.l fcopyadr,d1
    lsr.l #2,d1
    move.l dosbase,a6
    ;jsr -156(a6)
    move.l loadpcxadr,d1
    lsr.l #2,d1
    ;jsr -156(a6)
    move.l $4,a6
    move.l dosbase,a1
    jsr -414(a6)
    movem.l (sp)+,d0-d2/a0-a2/a6
    rts

; Now the real functions start

_PLOT:

;
; SYNTAX : PLOT realbitmaphandle,x,yoffset,color
;
; yoffset = y*320
;
; So, if you have in BlitzBasic a PLOT 100,200,50,
; you have to transform this to a PLOT 100,200*320,50 !!!
; I cannot do this multiplication inside the code, because this
; would need a 32 Bit Multiplication, which is only available on 020+,
; and BlitzBasic Inline ASM does not support 020+ opcodes. So you
; have to multiply with BlitzBasic before calling PLOT.
;
; IMPORTANT DIFFERENCE TO BLITZBASIC:
; Under BlitzBasic you chose with USE BITMAP to which Bitmap to write,
; and then do PLOT. Under rtgmaster, you do not have a USE BITMAP
; command, instead, you specify an additional parameter about to
; which bitmap you want to write. NOTE: i use the term
; realbitmaphandle for Bitmaps in Video and the term bitmaphandle
; for Fastram Buffers. (The realbitmaps are the Video RAM Buffer
; returned in d1/d2 by the SCREEN command).
;
; PARAMETERS :
;
; a0 = Bitmap to access
; d0 = x
; d1 = yoffset
; d2 = color
;
    move.l a0,-(sp)
    add.l d0,a0
    add.l d1,a0
    move.b d2,(a0)
    move.l (sp)+,a0
    rts

_SCREEN:

;
; SYNTAX : SCREEN screenhandle MapA MapB Width Height Depth Bytes
;
; SOME NOTES: screenhandle is not a screennr, like in BlitzBasic anymore, instead
; it is a rtgmaster Screenhandle. This is an ADDRESS in memory instead of
; a single number. Do NEVER do stuff like if (screennr == 1) with it. It
; is no number !!!
;
; The only valid checking is if screennr is 0. If it is 0, no GFX Board was
; found, and you should start your normal BlitzBasic code. If it is something
; DIFFERENT from 0, then a GFX Board was found, and the screen did IN FACT
; open.
;
; I set the stuff
; to open a Screenmode-Requester with Screenmodes between 320x200 and
; 640x480 to be opened.
;
; Parameters:
;
; d0 : rtgmaster screenhandle will be returned here (or 0 if no GFX Board Found)
; d1 : VideoRAM Address of Video RAM Buffer 0 is returned here (the default one)
; d2 : VideoRAM Adress of Video RAM Buffer 1 is returned here (the back one)
; The 3rd buffer is not used by this code, but i could change the code to use it,
; if you need a 3rd Buffer... i recommend using FastRAM Buffers, though.
; d3 : Width of the Screen
; d4 : Height of the Screen
; d5 : Depth of the Screen
; d6 : Bytes Per Row of the Screen (is the same like the Width for MOST
;      Boards, for Cybervision64 this differs)

; NOTE: This code is NOT suited for letting ONE program open TWO screens. Only open
; ONE Screen !!!

  movem.l a0-a2/a6,-(sp)
  move.l $4,a6
  move.w AttnFlags(a6),d0
  btst #3,d0
  bne m_68040
proc_rueck:
  jsr OpenRequester
  cmp.l #0,d0
  beq NoBoard
  move.l #POINTER,d0
  jsr OpenScreen
  movem.l (sp)+,a0-a2/a6
  rts
NoBoard:
  movem.l (sp)+,a0-a2/a6
  move.l #0,d0
  rts

m_68040:
  move.l #1,proctype
  bra proc_rueck


_SCREENSBITMAP:

;
; SYNTAX SCREENSBITMAP bitmaphandle,size
;
; NOTES: bitmaphandle has NOTHING to do with the numbers
; in Blitzbasic, it is the ADDRESSES of the Bitmap.
; This function allocates a Fastram-Chunky-Buffer in the size of the
; Screen. The Chunkybuffer is cleared.
; MORE NOTES: As BlitzBasic Inline Assembler does not support 32 Bit
; multiplications, you have to provide the SIZE of the Bitmap manually
; (size = screenwidth*screenheight)
;
; Parameters :
; d0 = Bitmaphandle will be returned here
; d1 = Size

  movem.l d1-d2/a0-a2/a6,-(sp)
  move.l $4,a6
  move.l d1,d0
  move.l #MEMF_FAST|MEMF_CLEAR,d1
  jsr -198(a6)
  movem.l (sp)+,d1-d2/a0-a2/a6
  rts

_BITMAP:

;
; SYNTAX BITMAP bitmaphandle,size
;
; NOTES: bitmaphandle has NOTHING to do with the numbers
; in Blitzbasic, it is the ADDRESSES of the Bitmap.
; This function allocates a Fastram-Chunky-Buffer in the wished size
; The Chunkybuffer is cleared.
; MORE NOTES: As BlitzBasic Inline Assembler does not support 32 Bit
; multiplications, you have to provide the SIZE of the Bitmap manually
; (size = screenwidth*screenheight)
;
; Parameters :
; d0 = Bitmaphandle will be returned here
; d1 = Size

  movem.l d1-d2/a0-a2/a6,-(sp)
  move.l $4,a6
  move.l d1,d0
  move.l #MEMF_FAST|MEMF_CLEAR,d1
  jsr -198(a6)
  movem.l (sp)+,d1-d2/a0-a2/a6
  rts

_SHOWPALETTE:

;
; SYNTAX SHOWPALETTE screenhandle,palette
;
; NOTE: Screenhandle is a rtgmaster screenhandle, NOT a BlitzBasic Screennumber
;
; ANOTHER NOTE: Palette is NOT in the format of BlitzBasic, but in the format of
; rtgmaster which is the same like the palette format of AmigaDOS, which is :
;
;

***************************************************
* dc.w Number of Colors,Starting Color            *
* dc.l R_Color0,G_Color0,B_Color0                 *
* dc.l R_Color1,G_Color1,B_Color1                 *
* ...                                             *
* dc.w 0 ; End                                    *
* For example:                                    *
* dc.w 4,0                                        *
* dc.l $FFFFFFFF,0,0 ; Red                        *
* dc.l $C0C0C0C0,0,0 ; darker red                 *
* dc.l 0,$50505050,0 ; darker green               *
* dc.l 0,0,$10101010 ; dark blue                  *
* dc.w 0             ; end                        *
* You will notice, that you have to repeat the    *
* R,G,B values 4 times... Commodore defined it    *
* this way for LoadRGB32...                       *
*                                                 *
***************************************************

;
; Parameters:
; a0 = Screenhandle
; a1 = pointer to the palette
;
; Note: There is no difference between SHOWPALETTE and USE PALETTE on rtgmaster.
; So only use SHOWPALETTE. Leave out USE PALETTE.
; Also you have to load your palette file to the memory yourselves, still.
; There are tools like BtoC32 on Aminet that create a fitting palette file
; out of an iff image. The Format to use (there are several palette formats
; in AmigaDOS, but only one is usable for rtgmaster) is the LoadRGB32 Format.

    movem.l d0-d2/a0-a2/a6,-(sp)
    move.l rtgbase,a6
    jsr _LVOLoadRGBRtg(a6)
    movem.l (sp)+,d0-d2/a0-a2/a6
    rts

_LINE:

;
; SYNTAX LINE realbitmap,x1,y1,x2,y2,color
;
; NOTE: x1/y1 HAS TO BE <= x2/y2 !!!
; NOTE: Realbitmap means this is a Bitmap in VideoRAM (the bitmaps returned in d1/d2 by the SCREEN Command)
;
; PARAMETER:
; a0 = Bitmaphandle of the Bitmap to write to.
; d0 = x1
; d1 = y1
; d2 = x2
; d3 = y2
; d4 = color

    movem.l d0-d2/a0-a2/a6,-(sp)
    move.l rtgbase,a6
    move.l a0,a1
    move.l rtgscreen,a0
    move.l d0,-(sp)
    move.l d4,d0
    move.l d3,d4
    move.l d2,d3
    move.l d1,d2
    move.l (sp)+,d1
    jsr _LVODrawRtgLine(a6)
    movem.l (sp)+,d0-d2/a0-a2/a6
    rts


_CLOSESCREEN:

;
; SYNTAX CLOSESCREEN screenhandle
;
; This closes the specified Screen again.
; It also closes the MapA/MapB Bitmap Handles, but
; NOT the Fastram Buffers allocated with
; SCREENSBITMAP or BITMAP.
;
; Parameters:
;
; a0 = screenhandle
;

   jsr CloseScreen
   rts

_CLOSEBITMAP:

; SYNTAX CLOSEBITMAP bitmaphandle size
;
; Closes a Bitmap (Fastram Buffer) allocated with
; SCREENSBITMAP or BITMAP. The size of the Bitmap
; has to be provided as parameter also !!!
;
; Parameters:
;
; a0 = bitmaphandle
; d0 = size
;
   movem.l d0-d2/a0-a2/a6,-(sp)
   move.l $4,a6
   move.l a0,a1
   jsr -210(a6)
   movem.l (sp)+,d0-d2/a0-a2/a6
   rts

_SHOWBITMAP:
;
; SYNTAX SHOWBITMAP screenhandle bitmapnumber
;
; This function shows a bitmap. (Doublebuffering). It
; ONLY works with the two Bitmaps MapA and MapB, that
; were provided by SCREEN. If you want to switch to
; MapA provide 0 as parameter, if you want to switch to
; MapB provide 1 as parameter. This time it REALLY is
; the bitmapnumber, not the bitmaphandle. USE BITMAP
; was removed, instead, the functions that access the
; Video RAM have an additional parameter, to which
; Bitmap of the two they want to write.
;
; NOTE: At least on Z2 Boards it is faster to use a Fastram
; Buffer, Chunky Copy and ONE Bitmap instead of Doublebuffering,
; as you then do not have to render over the Zorro Bus. This
; might also be TRUE on SOME Z3 GFX Boards or maybe even all
; (though the difference is not that big there). Chunky-Copy
; is fast enough to update a whole screen without flickering.
;
; PARAMETER:
;
; a0 = screenhandle
; d0 = bitmapnumber
;
  movem.l d0-d2/a0-a2/a6,-(sp)
  move.l rtgbase,a6
  jsr _LVOSwitchScreens(a6)
  movem.l (sp)+,d0-d2/a0-a2/a6
  rts

_INPUT:

;
; SYNTAX INPUT screenhandle,myevent
;
; This function does keyboard/Mouse handling, using the rtgmaster functions.
; It takes the Screenhandle of the screen to be handled as input parameter,
; and it outputs a MyEvent structure that describes if the user has
; given some input and what input this was. The structure looks like that :
;
; me_rawkey: dc.w 0
; me_mouse: dc.w 0
; me_qualifier: dc.w 0
; me_x: dc.w 0
; me_y: dc.w 0
;
; if me_rawkey contains something which is not 0, after the call, it contains
; the RAWKEY (not ASCII) value of the pressed/released key.
; if me_mouse contains something which is not 0, after the call, it contains
; the data for the pressed/released mousekey (look at the constants above)
; me_qualifier contains qualifier bits (ALT, SHIFT,ESC,...). me_x/me_y ALWAYS
; contain the current mouse position after the call, even if the user did NOT
; give any input. The function quits as soon as it provided me_x/me_y if the
; user did not give input, it does NOT WAIT.

    movem.l a0-a1/a6/d1,-(sp)
    move.l rtgbase,a6
    jsr _LVORtgGetMsg(a6)
    cmp.l #0,d0
    beq se_quit
    move.l d0,a0
    move.l im_Class(a0),d0
    sub.l d1,d1
    move.w im_Code(a0),d1
    lea events,a1
    move.l #0,(a1)
    move.l #0,4(a1)
    move.w #0,8(a1)
    move.w im_Qualifier(a0),4(a1)
    move.w im_MouseX(a0),6(a1)
    move.w im_MouseY(a0),8(a1)
    move.l a0,a1
    move.l rtgscreen,a0
    movem.l d0/d1,-(sp)
    jsr _LVORtgReplyMsg(a6)
    movem.l (sp)+,d0/d1
    move.l d0,-(sp)
    and.l #IDCMP_RAWKEY+IDCMP_MOUSEBUTTONS,d0
    cmp.l #0,d0
    beq se_quit2
    move.l (sp)+,d0
    and.l #IDCMP_MOUSEBUTTONS,d0
    cmp.l #0,d0
    bne se_mouse
    lea events,a0
    move.w d1,(a0)
    move.l a0,d0
    movem.l (sp)+,a0-a1/a6/d1
    rts
se_mouse:
   lea events,a0
   move.w d1,2(a0)
   move.l a0,d0
   movem.l (sp)+,a0-a1/a6/d1
   rts
se_quit2:
    move.l (sp)+,d0
se_quit:
    lea events,a0
    move.l rtgport,a1
    move.l a2,-(sp)
    move.l rdcmp_MouseY(a1),a2
    move.l rdcmp_MouseX(a1),a1
    move.w (a1),6(a0)
    move.w (a2),8(a0)
    move.l (sp)+,a2
    move.l a0,d0
    movem.l (sp)+,a0-a1/a6/d1
    rts
events:
    dc.w 0
    dc.w 0,0
    dc.w 0,0


_BLIT:

;
; SYNTAX BLIT src,dest,srcx,srcy,destx,desty,width,height,srcbytes,destbytes
;
; Well, this are some more parameters, than with BlitzBasic, as we do
; not have a Shape structure here... this is a Blitting function without
; clipping, BTW, but you should be able to change it to clipping, easily.
;
; Parameters:
;
; a0 = rtgscreen = Screenhandle
; a1 = dest      = Destination Bitmap or Fastram Buffer
; a2 = src       = Source Bitmap or Fastram Buffer
; d0 = copymode  = see below
; d1 = wait      = Should the application wait on the ray after the operation ?
; d2 = destx     = Destination X Position (For FCOPY also Source !!!)
; d3 = desty     = Destination Y Position (For FCOPY also Source !!!)
; d4 = Width     = Width of the Rectangle to Copy
; d5 = Height    = Height of the Rectangle to Copy


; There are some different Copymodes :
;
; FCOPY
;
; uses 040/060 optimized Copy-Function, if a 040 is available.
; does not work on the Cybervision64, AFAIK (because of the
; Destination Offset Problems of this Board). This function
; needs that srcx=destx and srcy=desty, else it will do very
; strange stuff. If no 040/060 is available, this function
; will do MOVEM. As MOVEM does not have the srcx=destx and srcy=desty
; condition you should at best ONLY use FCOPY for Fullscreen
; Screen refreshed (srcx=destx=srcy=desty=0 !!!)
;
; Conditions: Width and srcx and src and dest have to be divisible
; by 16 !!! (dest is divisible by 16 on MOST GFX BOARDS).
;
; NOTE: In order to make FCOPY work, you have to install pcxload.library
; The stuff about the file fcopy was removed, as using a library is a
; better solution.
;
; MOVEM
;
; use this mode ONLY if the width is divisible by 64.
;
; RTGMASTER
;
; This is the standard rtgmaster function that always works. It is a bit
; slower than MOVEM, and definitely slower than FCOPY, but then it works
; ALWAYS, no matter how the width is and such stuff. It needs the destination
; being one of the "real bitmaps" (the stuff SCREEN returned in d1/d2), it
; cannot write to Fastram Buffers. For writing to Fastram Buffers, you have
; to use the other functions (or write some functions yourselves, which is
; quite easy...)
;
; DOUBLEBUFFER
;
; This is no Copy-Functions, but instead it performs Doublebuffering. Of course
; this is always fullscreen. It does the same like SHOWBITMAP, principially...

    movem.l a0-a3/a6/d0-d2,-(sp)
    cmp.l #WAIT,d1
    bne cb_nowait
    movem.l d0-d2/a0-a2,-(sp)
    move.l rtgbase,a6
    jsr _LVOWaitTOF(a6)
    movem.l (sp)+,d0-d2/a0-a2
cb_nowait:
    cmp.l #DOUBLEBUFFER,d0
    beq cb_DBuffer
    cmp.l #RTGMASTER,d0
    beq cb_Rtgmaster
    cmp.l #MOVEM,d0
    beq cb_Movem
    move.l proctype,d0
    cmp.l #0,fcopyadr
    beq cb_Movem
    cmp.l #1,d0
    beq cb_FCopy
cb_Rtgmaster:
    move.l d2,d0
    move.l d3,d1
    move.l d4,d2
    move.l d5,d3
    move.l #0,d4
    move.l #0,d5
    jsr _LVOCopyRtgPixelArray(a6)
    jmp cb_quit
cb_Movem:
    movem.l d3-d7,-(sp)
    move.l a2,a0
    move.l d3,d1
    move.l Bytes,d7
    mulu.w d7,d1
    add.l d1,a1
    move.l d2,d0
    add.l d0,a1
    move.l d4,d2
    move.l d5,d3
    move.l Bytes,d0
    sub.l d2,d0
    lsr.l #6,d2
    sub.l #1,d2
    sub.l #1,d3
    move.l d2,d1
cb_loop:
    Movem.l (A0)+,d4-d7
    Movem.l d4-d7,(A1)
    Movem.l (A0)+,d4-d7
    Movem.l d4-d7,16*1(A1)
    Movem.l (A0)+,d4-d7
    Movem.l d4-d7,16*2(A1)
    Movem.l (A0)+,d4-d7
    Movem.l d4-d7,16*3(A1)
    lea 64(a1),a1
    dbra d1,cb_loop
    move.l d2,d1
    add.l d0,a0
    add.l d0,a1
    dbra d3,cb_loop
    movem.l (sp)+,d3-d7
    jmp cb_quit

cb_DBuffer:
    move.l #1,d0
    sub.l currentbuffer,d0
    jsr _LVOSwitchScreens(a6)
    move.l rtgscreen,a0
    move.l currentbuffer,d0
    jsr _LVOGetBufAdr(a6)
    move.l d0,cb_bufferadr
    move.l #1,d0
    sub.l currentbuffer,d0
    move.l d0,currentbuffer
    move.l rtgscreen,a0
    move.l currentbuffer,d0
    jsr _LVOGetBufAdr(a6)
    move.l d0,a0
    move.l cb_bufferadr,a1
    jmp cb_quit
cb_bufferadr:
    dc.l 0
cb_FCopy:
    move.l a2,a0
    move.l d2,d0
    move.l Bytes,d2
    move.l d3,d1
    move.l d4,d3
    move.l d5,d4
    move.l pcxbase,a6
    jsr -36(a6)         ; FCopy now included to pcxload.library !!!
cb_quit:
    movem.l (sp)+,a0-a3/a6/d0-d2
    rts

_LOADGFX:

; SYNTAX LOADGFX filename,pcxdata
;
; Well, this function looks quite different to Blitz Basic, it ALSO
; looks quite different to the GFX Board Function Docs i gave you before.
; It loads a PCX Image to Memory (you can convert iff files to pcx files
; using programs like AdPro or ImageFX or Photogenics). The data is not
; directly saved in a Fastram Buffer or Video RAM Buffer, like i promised,
; though, and it is not possible to load the data to a different position
; than 0/0 either... if you want to put the data to a Fastram or Video RAM
; buffer you have to COPY it from the PCX Data structure there, using the
; _BLIT function !!!
;
; The PCX structure (you have to provide a pointer to a correctly allocated
; PCX structure, when you call LOADGFX !!!)
;
; pcxdata:
; ds.b 128,0 ; 128 Bytes to be ignored
;bitmap:
; dc.l 0 ; The actual image data (see below)
;palette:
; ds.b 768,0 ; The palette, WON'T be read out by this function !!!
;imagebytes:
; dc.l 0 ; Width*Height will be found here
;width:
; dc.l 0 ; Width of the image
;height:
; dc.l 0 ; Height of the image
;
; So you have to allocate 912 Bytes for the pcxdata structure,
; then you call _LOADGFX. While running, _LOADGFX will allocate a FASTRAM
; BUFFER and put its bitmap handle to bitmap. Here you will find the actual
; image data after the function, also you will find width, height, and
; width*height saved. You can Blit the image like usual out of the
; Fastram Buffer. When your program quits, or when you do not need the
; allocated pcxdata structure anymore, you should call CLOSEBITMAP for
; the bitmap of the pcxdata (the size is found in imagebytes), and THEN
; free the allocated memory for the pcxdata structure again.
; If there are still quesions, please mail me. For a C and ASM programmer
; all this pointer stuff is easy stuff, but then, i do not know, if a
; Blitz Basic programmer also knows pointers... and sorry, that this
; function does not use the interface i planned first.
;
; This function needs the pcxload.library installed. (SCREEN will open this
; library automatically)
;
; Parameters:
; a0 = Pointer to the filename
; a1 = Pointer to the initialized pcxdata structure

    movem.l d0-d2/a0-a2/a6,-(sp)
    move.l pcxbase,a6
    jsr -30(a6)    ; Call it from pcxload.library
    movem.l (sp)+,d0-d2/a0-a2/a6
    rts

    END
