#ifndef _VDP_H_
#define _VDP_H_


#define GFX_DATA_PORT           0xC00000
#define GFX_CTRL_PORT           0xC00004
#define GFX_HVCOUNTER_PORT      0xC00008

#define VDP_FIFOEMPTY_FLAG      (1 << 9)
#define VDP_FIFOFULL_FLAG       (1 << 8)
#define VDP_VINTPENDING_FLAG    (1 << 7)
#define VDP_SPROVERFLOW_FLAG    (1 << 6)
#define VDP_SPRCOLLISION_FLAG   (1 << 5)
#define VDP_ODDFRAME_FLAG       (1 << 4)
#define VDP_VBLANK_FLAG         (1 << 3)
#define VDP_FBLANK_FLAG         (1 << 2)
#define VDP_DMABUSY_FLAG        (1 << 1)
#define VDP_PALMODE_FLAG        (1 << 0)


#define FONT_LEN                128

#define BITMAP_WIDTH            32
#define BITMAP_HEIGHT           20
#define BITMAP_LEN              (BITMAP_WIDTH * BITMAP_HEIGHT)

#define TILE_SPACE              0xB000
#define TILE_MAXNUM             (TILE_SPACE / 32)
#define TILE_FONT               (TILE_SPACE - (FONT_LEN * 32))
#define TILE_FONTINDEX          (TILE_FONT / 32)
#define TILE_BITMAP             (TILE_FONT - (BITMAP_LEN * 32))
#define TILE_BITMAPINDEX        (TILE_BITMAP / 32)

#define APLAN                   (TILE_SPACE + 0x1000)
#define WPLAN                   (TILE_SPACE + 0x0000)
#define BPLAN                   (TILE_SPACE + 0x3000)
#define SLIST                   (TILE_SPACE + 0x0C00)
#define HSCRL                   (TILE_SPACE + 0x0800)


#define GFX_READ_VRAM_ADDR(adr)     ((0x0000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x00)
#define GFX_READ_CRAM_ADDR(adr)     ((0x0000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x20)
#define GFX_READ_VSRAM_ADDR(adr)    ((0x0000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x10)

#define GFX_WRITE_VRAM_ADDR(adr)    ((0x4000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x00)
#define GFX_WRITE_CRAM_ADDR(adr)    ((0xC000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x00)
#define GFX_WRITE_VSRAM_ADDR(adr)   ((0x4000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x10)

#define GFX_DMA_VRAM_ADDR(adr)      ((0x4000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x80)
#define GFX_DMA_CRAM_ADDR(adr)      ((0xC000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x80)
#define GFX_DMA_VSRAM_ADDR(adr)     ((0x4000 + ((adr) & 0x3FFF)) << 16) + (((adr) >> 14) | 0x90)

#define GFX_VERT_SCROLL(adr)        GFX_WRITE_VSRAM_ADDR(adr)
#define GFX_HORZ_SCROLL(adr)        GFX_WRITE_VRAM_ADDR(adr)

#define GETVDPSTATUS(flag)          ((*(volatile u16*)(GFX_CTRL_PORT)) & (flag))
#define ISPALSYSTEM                 GETVDPSTATUS(VDP_PALMODE_FLAG)

#define GET_HVCOUNTER               (*(volatile u16*)(GFX_HVCOUNTER_PORT))
#define GET_HCOUNTER                (GET_HVCOUNTER & 0xFF)
#define GET_VCOUNTER                (GET_HVCOUNTER >> 8)


void VDP_init();

u8   VDP_getReg(u16 reg);
void VDP_setReg(u16 reg, u8 value);

u16  VDP_getHeight();
u16  VDP_getWidth();
void VDP_setWidth256();
void VDP_setWidth320();

u16  VDP_getPlanWidth();
u16  VDP_getPlanHeight();
void VDP_setPlanSize(u16 w, u16 h);

u16  VDP_getAutoInc();
void VDP_setAutoInc(u8 value);

void VDP_setHInterrupt(u8 value);
void VDP_setHilightShadow(u8 value);

void VDP_waitDMACompletion();
void VDP_waitFIFOEmpty();

void VDP_waitVSync();


#endif // _VDP_H_
