/**
 *  Sega Saturn Cartridge Firmware Flash Utility
 *  by cafe-alpha.
 *  WWW: http://ppcenter.free.fr/pskai/
 *
 *  Made from "Sega Saturn cartridge flash tool", by Anders Montonen.
 *
 *  See LICENSE file for details.
**/

#ifndef VDP2_H_
#define VDP2_H_

#include <stdio.h>

#define VDP2_BASE           0x25e00000
#define VDP2_VRAM           VDP2_BASE
#define VDP2_CRAM           (VDP2_BASE+0x100000)
#define VDP2_REGISTER_BASE  (VDP2_BASE+0x180000)

#define VDP2_VRAM_A0 0x25e00000
#define VDP2_VRAM_A1 0x25e20000
#define VDP2_VRAM_B0 0x25e40000
#define VDP2_VRAM_B1 0x25e60000


#define TVMD    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x00))
#define DISP    (1<<15)
#define BDCLMD  (1<<8)
#define LSMD1   (1<<7)
#define LSMD0   (1<<6)
#define VRESO1  (1<<5)
#define VRESO0  (1<<4)
#define HRESO2  (1<<2)
#define HRESO1  (1<<1)
#define HRESO0  (1<<0)
/* Display modes. Only TV modes. */
#define NOINTERLACE     (0)
#define SINGLEINTERLACE (LSMD1)
#define DOUBLEINTERLACE (LSMD1|LSMD0)
#define VRES224         (0)
#define VRES240         (VRESO0)
/* 256 lines in PAL, 240 lines in NTSC */
#define VRES256         (VRESO1|VRESO0)
#define HRES320         (0)
#define HRES352         (HRESO0)
#define HRES640         (HRESO1)
#define HRES704         (HRESO1|HRESO0)

#define EXTEN   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x02))
#define EXLTEN  (1<<9)
#define EXSYEN  (1<<8)
#define DASEL   (1<<1)
#define EXBGEN  (1<<0)

#define TVSTAT  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x04))
#define EXLTFG  (1<<9)
#define EXSYFG  (1<<8)
#define VBLANK  (1<<3)
#define HBLANK  (1<<2)
#define ODD     (1<<1)
#define PAL     (1<<0)
/* Sync macros */
#define WaitForVBLANKIn()  while(!(TVSTAT&VBLANK));
#define WaitForVBLANKOut() while(TVSTAT&VBLANK);
#define WaitForHBLANKIn()  while(!(TVSTAT&HBLANK));
#define WaitForHBLANKOut() while(TVSTAT&HBLANK);

#define WaitForVBLANK() while(!(TVSTAT&VBLANK));
#define WaitForHBLANK() while(!(TVSTAT&HBLANK));
#define WaitForVBLANKExit() while(TVSTAT&VBLANK);

#define VRSIZE  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x06))
#define VRAMSZ  (1<<15)

#define HCNT    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x08))
#define VCNT    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x0a))
#define RAMCTL  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x0e))
#define CYCA0L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x10))
#define CYCA0U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x12))
#define CYCA1L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x14))
#define CYCA1U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x16))
#define CYCB0L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x18))
#define CYCB0U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x1a))
#define CYCB1L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x1c))
#define CYCB1U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x1e))
#define BGON    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x20))
#define R0TPON  (1<<12)
#define N3TPON  (1<<11)
#define N2TPON  (1<<10)
#define N1TPON  (1<<9)
#define N0TPON  (1<<8)
#define R1ON    (1<<5)
#define R0ON    (1<<4)
#define N3ON    (1<<3)
#define N2ON    (1<<2)
#define N1ON    (1<<1)
#define N0ON    (1<<0)

#define MZCTL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x22))
#define SFSEL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x24))
#define SFCODE  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x26))
#define CHCTLA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x28))
#define CHCTLB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x2a))
#define BMPNA   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x2c))
#define BMPNB   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x2e))
#define PNCN0   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x30))
#define PNCN1   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x32))
#define PNCN2   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x34))
#define PNCN3   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x36))
#define PNCR    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x38))
#define PLSZ    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x3a))
#define MPOFN   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x3c))
#define MPOFR   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x3e))
#define MPABN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x40))
#define MPCDN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x42))
#define MPABN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x44))
#define MPCDN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x46))
#define MPABN2  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x48))
#define MPCDN2  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x4a))
#define MPABN3  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x4c))
#define MPCDN3  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x4e))
#define MPABRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x50))
#define MPCDRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x52))
#define MPEFRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x54))
#define MPGHRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x56))
#define MPIJRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x58))
#define MPKLRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x5a))
#define MPMNRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x5c))
#define MPOPRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x5e))
#define MPABRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x60))
#define MPCDRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x62))
#define MPEFRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x64))
#define MPGHRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x66))
#define MPIJRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x68))
#define MPKLRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x6a))
#define MPMNRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x6c))
#define MPOPRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x6e))
#define SCXIN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x70))
#define SCXDN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x72))
#define SCYIN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x74))
#define SCYDN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x76))
#define ZMXN0   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0x78))
#define ZMXIN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x78))
#define ZMXDN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x7a))
#define ZMYN0   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0x7c))
#define ZMYIN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x7c))
#define ZMYDN0  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x7e))
#define SCXIN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x80))
#define SCXDN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x82))
#define SCYIN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x84))
#define SCYDN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x86))
#define ZMXN1   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0x88))
#define ZMXIN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x88))
#define ZMXDN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x8a))
#define ZMYN1   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0x8c))
#define ZMYIN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x8c))
#define ZMYDN1  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x8e))
#define SCXN2   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x90))
#define SCYN2   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x92))
#define SCXN3   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x94))
#define SCYN3   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x96))
#define ZMCTL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x98))
#define SCRCTL  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x9a))
#define VCSTA   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0x9c))
#define VCSTAU  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x9c))
#define VCSTAL  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x9e))
#define LSTA0   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0xa0))
#define LSTA0U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xa0))
#define LSTA0L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xa2))
#define LSTA1   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0xa4))
#define LSTA1U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xa4))
#define LSTA1L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xa6))
#define LCTA    (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0xa8))
#define LCTAU   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xa8))
#define LCTAL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xaa))
#define BKTAU   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xac))
#define BKTAL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xae))
#define RPMD    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xb0))
#define RPRCTL  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xb2))
#define KTCTL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xb4))
#define KTAOF   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xb6))
#define OVPNRA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xb8))
#define OVPNRB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xba))
#define RPTA    (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0xbc))
#define RPTAU   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xbc))
#define RPTAL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xbe))
#define WPSX0   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xc0))
#define WPSY0   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xc2))
#define WPEX0   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xc4))
#define WPEY0   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xc6))
#define WPSX1   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xc8))
#define WPSY1   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xca))
#define WPEX1   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xcc))
#define WPEY1   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xce))
#define WCTLA   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xd0))
#define WCTLB   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xd2))
#define WCTLC   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xd4))
#define WCTLD   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xd6))
#define LWTA0   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0xd8))
#define LWTA0U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xd8))
#define LWTA0L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xda))
#define LWTA1   (*(volatile unsigned long  *)(VDP2_REGISTER_BASE+0xdc))
#define LWTA1U  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xdc))
#define LWTA1L  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xde))
#define SPCTL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xe0))
#define SPCCCS1 (1<<13)
#define SPCCCS0 (1<<12)
#define SPCCN2  (1<<10)
#define SPCCN1  (1<<9)
#define SPCCN0  (1<<8)
#define SPCLMD  (1<<5)
#define SPWINEN (1<<4)
#define SPTYPE3 (1<<3)
#define SPTYPE2 (1<<2)
#define SPTYPE1 (1<<1)
#define SPTYPE0 (1<<0)
#define SPRITETYPE0 (0)
#define SPRITETYPE1 (SPTYPE0)
#define SPRITETYPE2 (SPTYPE1)
#define SPRITETYPE3 (SPTYPE1|SPTYPE0)
#define SPRITETYPE4 (SPTYPE2)
#define SPRITETYPE5 (SPTYPE2|SPTYPE0)
#define SPRITETYPE6 (SPTYPE2|SPTYPE1)
#define SPRITETYPE7 (SPTYPE2|SPTYPE1|SPTYPE0)
#define SPRITETYPE8 (SPTYPE3)
#define SPRITETYPE9 (SPTYPE3|SPTYPE0)
#define SPRITETYPEA (SPTYPE3|SPTYPE1)
#define SPRITETYPEB (SPTYPE3|SPTYPE1|SPTYPE0)
#define SPRITETYPEC (SPTYPE3|SPTYPE2)
#define SPRITETYPED (SPTYPE3|SPTYPE2|SPTYPE0)
#define SPRITETYPEE (SPTYPE3|SPTYPE2|SPTYPE1)
#define SPRITETYPEF (SPTYPE3|SPTYPE2|SPTYPE1|SPTYPE0)

#define SDCTL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xe2))
#define CRAOFA  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xe4))
#define CRAOFB  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xe6))
#define LNCLEN  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xe8))
#define SFPRMD  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xea))
#define CCCTL   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xec))
#define SFCCMD  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xee))
#define PRISA   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xf0))
#define PRISB   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xf2))
#define PRISC   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xf4))
#define PRISD   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xf6))
#define PRINA   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xf8))
#define PRINB   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xfa))
#define PRIR    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0xfc))
#define CCRSA   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x100))
#define CCRSB   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x102))
#define CCRSC   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x104))
#define CCRSD   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x106))
#define CCRNA   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x108))
#define CCRNB   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x10a))
#define CCRR    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x10c))
#define CCRLB   (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x10e))
#define CLOFEN  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x110))
#define CLOFSL  (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x112))
#define COAR    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x114))
#define COAG    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x116))
#define COAB    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x118))
#define COBR    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x11a))
#define COBG    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x11c))
#define COBB    (*(volatile unsigned short *)(VDP2_REGISTER_BASE+0x11e))

#endif /* VDP2_H_ */
