#ifndef _ATI_H
#define _ATI_H

/*
    Copyright � 2004-2026, The AROS Development Team. All rights reserved.
    $Id$
*/

#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/execbase.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/semaphores.h>
#include <exec/memory.h>
#include <exec/memheaderext.h>
#include <dos/bptr.h>

#include <devices/timer.h>

#include <aros/libcall.h>
#include <aros/asmcall.h>

#include <hidd/gfx.h>

#include <oop/oop.h>

#include <aros/arossupportbase.h>
#include <exec/execbase.h>

#include "radeon.h"

#define IID_Hidd_Gfx_Ati    "hidd.gfx.radeon"
#define IID_Hidd_BitMap_ATI  "hidd.bitmap.radeon"
#define CLID_Hidd_Gfx_Ati   "hidd.gfx.radeon"
#define CLID_Hidd_Display_Ati   "hidd.display.radeon"

extern OOP_AttrBase HiddPCIDeviceAttrBase;
extern OOP_AttrBase HiddBitMapAttrBase;
extern OOP_AttrBase HiddPixFmtAttrBase;
extern OOP_AttrBase HiddSyncAttrBase;
extern OOP_AttrBase HiddGfxAttrBase;
extern OOP_AttrBase HiddDisplayAttrBase;
extern OOP_AttrBase HiddDMEnumAttrBase;
extern OOP_AttrBase HiddATIBitMapAttrBase;
extern OOP_AttrBase HiddI2CAttrBase;
extern OOP_AttrBase HiddI2CDeviceAttrBase;
extern OOP_AttrBase __IHidd_PlanarBM;

struct atiDisplayData
{
};

enum {
    aoHidd_ATIBitMap_Drawable,

    num_Hidd_ATIBitMap_Attrs
};

#define aHidd_ATIBitMap_Drawable (HiddATIBitMapAttrBase + aoHidd_ATIBitMap_Drawable)

#define IS_BM_ATTR(attr, idx) (((idx)=(attr)-HiddBitMapAttrBase) < num_Hidd_BitMap_Attrs)
#define IS_ATIBM_ATTR(attr, idx) (((idx)=(attr)-HiddATIBitMapAttrBase) < num_Hidd_ATIBitMap_Attrs)

typedef struct __bm {
    struct SignalSemaphore bmLock;

    OOP_Object  *BitMap;    // BitMap OOP Object
    IPTR    framebuffer;    // Points to pixel data
    void	**addresses;
    ULONG   width;      // Bitmap width
    ULONG   height;     // Bitmap height
    ULONG   pitch;      // BytesPerRow aligned
    UBYTE   depth;      // Bitmap depth
    UBYTE   bpp;        // BytesPerPixel
    UBYTE   onbm;       // is onbitmap?
    UBYTE   fbgfx;      // is framebuffer in gfx memory
    ULONG   usecount;   // counts BitMap accesses

    ULONG   dp_gui_master_cntl;
    ULONG   dp_gui_master_cntl_clip;
    ULONG   pitch_offset;
    UBYTE   datatype;
/*
    ULONG   surface_format;
    ULONG   pattern_format;
    ULONG   rect_format;
    ULONG   line_format;
*/
    struct CardState *state;
} atiBitMap;

struct ati_staticdata {
    struct SignalSemaphore  HWLock;     /* Hardware exclusive semaphore */
    struct SignalSemaphore  MultiBMLock;    /* To lock more than one bitmap at a time */

    struct MsgPort          mp;
    struct timerequest      tr;

    APTR    memPool;

    struct SignalSemaphore CardMemLock;
    struct MemHeader    CardMem;
    ULONG               *CardMemBmp;
    LONG                 CardMemSize;

    struct MemHeaderExt		managedMem;

    struct Card     Card;
    struct CardState *poweron_state;
    IPTR            scratch_buffer;
    UBYTE           *cpuscratch;

    OOP_Object      *AtiObject;
    OOP_Object      *AtiDisplay;
    OOP_Object      *dmenum;
    OOP_Object      *PCIObject;
    OOP_Object      *PCIDevice;
    OOP_Object      *PCIDriver;

    OOP_Class      *basebm;            /* baseclass for CreateObject */

    OOP_Class       *AtiClass;
    OOP_Class       *AtiDisplayClass;
    OOP_Class       *AtiI2C;
    OOP_Class       *OnBMClass;
    OOP_Class       *OffBMClass;
    OOP_Class       *PlanarBMClass;

    OOP_AttrBase    hiddAttrBase;
    OOP_AttrBase    pciAttrBase;
    OOP_AttrBase    atiBitMapAttrBase;
    OOP_AttrBase    bitMapAttrBase;
    OOP_AttrBase    pixFmtAttrBase;
    OOP_AttrBase    gfxAttrBase;
    OOP_AttrBase    displayAttrBase;
    OOP_AttrBase    dmenumAttrBase;
    OOP_AttrBase    syncAttrBase;
    OOP_AttrBase    i2cAttrBase;
    OOP_AttrBase    i2cDeviceAttrBase;
    OOP_AttrBase    planarAttrBase;

    OOP_MethodID    mid_ReadLong;
    OOP_MethodID    mid_CopyMemBox8;
    OOP_MethodID    mid_CopyMemBox16;
    OOP_MethodID    mid_CopyMemBox32;
    OOP_MethodID    mid_PutMem32Image8;
    OOP_MethodID    mid_PutMem32Image16;
    OOP_MethodID    mid_GetMem32Image8;
    OOP_MethodID    mid_GetMem32Image16;
    OOP_MethodID    mid_GetImage;
    OOP_MethodID    mid_Clear;
    OOP_MethodID    mid_PutMemTemplate8;
    OOP_MethodID    mid_PutMemTemplate16;
    OOP_MethodID    mid_PutMemTemplate32;
    OOP_MethodID    mid_PutMemPattern8;
    OOP_MethodID    mid_PutMemPattern16;
    OOP_MethodID    mid_PutMemPattern32;
    OOP_MethodID    mid_CopyLUTMemBox16;
    OOP_MethodID    mid_CopyLUTMemBox32;

    HIDDT_DPMSLevel dpms;
};

struct atibase {
    struct Library          LibNode;
    struct ati_staticdata   sd;
};

struct planarbm_data
{
    UBYTE   **planes;
    ULONG   planebuf_size;
    ULONG   bytesperrow;
    ULONG   rows;
    UBYTE   depth;
    BOOL    planes_alloced;
};

#define BASE(lib) ((struct atibase*)(lib))

#define SD(cl) (&BASE(cl->UserData)->sd)

#define METHOD(base, id, name) \
  base ## __ ## id ## __ ## name (OOP_Class *cl, OOP_Object *o, struct p ## id ## _ ## name *msg)

#define METHOD_NAME(base, id, name) \
  base ## __ ## id ## __ ## name

#define METHOD_NAME_S(base, id, name) \
  # base "__" # id "__" # name

#define LOCK_HW          { ObtainSemaphore(&sd->HWLock); }
#define UNLOCK_HW        { ReleaseSemaphore(&sd->HWLock); }

#define LOCK_BITMAP      { ObtainSemaphore(&bm->bmLock); }
#define UNLOCK_BITMAP        { ReleaseSemaphore(&bm->bmLock); }

#define LOCK_BITMAP_BM(bm)   { ObtainSemaphore(&(bm)->bmLock); }
#define UNLOCK_BITMAP_BM(bm) { ReleaseSemaphore(&(bm)->bmLock); }

#define LOCK_MULTI_BITMAP    { ObtainSemaphore(&sd->MultiBMLock); }
#define UNLOCK_MULTI_BITMAP  { ReleaseSemaphore(&sd->MultiBMLock); }

//#define LOCK_HW          { while (sd->HWLock.ss_QueueCount) Reschedule(FindTask(NULL)); sd->HWLock.ss_QueueCount=1; }
//#define UNLOCK_HW        { sd->HWLock.ss_QueueCount=0; }
//
//#define LOCK_BITMAP      { while (bm->bmLock.ss_QueueCount) Reschedule(FindTask(NULL)); bm->bmLock.ss_QueueCount=1; }
//#define UNLOCK_BITMAP        { bm->bmLock.ss_QueueCount=0; }
//
//#define LOCK_BITMAP_BM(bm)   { while (bm->bmLock.ss_QueueCount) Reschedule(FindTask(NULL)); bm->bmLock.ss_QueueCount=1; }
//#define UNLOCK_BITMAP_BM(bm) { bm->bmLock.ss_QueueCount=0; }
//
//#define LOCK_MULTI_BITMAP    { while (sd->MultiBMLock.ss_QueueCount) Reschedule(FindTask(NULL)); sd->MultiBMLock.ss_QueueCount=1; }
//#define UNLOCK_MULTI_BITMAP  { sd->MultiBMLock.ss_QueueCount=0; }

#endif /* _ATI_H */
