mirror of
https://github.com/libretro/FBNeo.git
synced 2024-11-23 17:09:43 +00:00
add TMS9928a video chip to devices
This commit is contained in:
parent
65881cfdd9
commit
008ceba738
@ -76,7 +76,7 @@ depobj := $(drvobj) \
|
||||
tiles_generic.o timer.o vector.o \
|
||||
\
|
||||
8255ppi.o 8257dma.o eeprom.o nmk004.o kaneko_tmap.o pandora.o seibusnd.o sknsspr.o slapstic.o t5182.o timekpr.o tms34061.o \
|
||||
v3021.o vdc.o \
|
||||
v3021.o vdc.o tms9928a.o \
|
||||
\
|
||||
ay8910.o burn_y8950.o burn_ym2151.o burn_ym2203.o burn_ym2413.o burn_ym2608.o burn_ym2610.o burn_ym2612.o \
|
||||
burn_ym3526.o burn_ym3812.o burn_ymf278b.o c6280.o dac.o es5506.o es8712.o flt_rc.o fm.o fmopl.o ics2115.o iremga20.o \
|
||||
|
702
src/burn/devices/tms9928a.cpp
Normal file
702
src/burn/devices/tms9928a.cpp
Normal file
@ -0,0 +1,702 @@
|
||||
#include "tiles_generic.h"
|
||||
#include "tms9928a.h"
|
||||
|
||||
static int TMS9928A_palette[16] = {
|
||||
0x000000, 0x000000, 0x21c842, 0x5edc78, 0x5455ed, 0x7d76fc, 0xd4524d, 0x42ebf5,
|
||||
0xfc5554, 0xff7978, 0xd4c154, 0xe6ce80, 0x21b03b, 0xc95bba, 0xcccccc, 0xffffff
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned char ReadAhead;
|
||||
unsigned char Regs[8];
|
||||
unsigned char StatusReg;
|
||||
unsigned char FirstByte;
|
||||
unsigned char latch;
|
||||
unsigned char INT;
|
||||
int Addr;
|
||||
int colour;
|
||||
int pattern;
|
||||
int nametbl;
|
||||
int spriteattribute;
|
||||
int spritepattern;
|
||||
int colourmask;
|
||||
int patternmask;
|
||||
|
||||
unsigned char *vMem;
|
||||
unsigned char *dBackMem;
|
||||
unsigned short *tmpbmp;
|
||||
int vramsize;
|
||||
int model;
|
||||
|
||||
int max_x;
|
||||
int min_x;
|
||||
int max_y;
|
||||
int min_y;
|
||||
|
||||
int LimitSprites;
|
||||
int top_border;
|
||||
int bottom_border;
|
||||
|
||||
void (*INTCallback)(int);
|
||||
} TMS9928A;
|
||||
|
||||
static TMS9928A tms;
|
||||
|
||||
static unsigned int Palette[16]; // high color support
|
||||
|
||||
static void TMS89928aPaletteRecalc()
|
||||
{
|
||||
for (int i = 0; i < 16; i++) {
|
||||
Palette[i] = BurnHighCol(TMS9928A_palette[i] >> 16, TMS9928A_palette[i] >> 8, TMS9928A_palette[i] >> 0 , 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void change_register(int reg, unsigned char val)
|
||||
{
|
||||
static const unsigned char Mask[8] = { 0x03, 0xfb, 0x0f, 0xff, 0x07, 0x7f, 0x07, 0xff };
|
||||
|
||||
val &= Mask[reg];
|
||||
tms.Regs[reg] = val;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (val & 2) {
|
||||
tms.colour = ((tms.Regs[3] & 0x80) * 64) & (tms.vramsize - 1);
|
||||
tms.colourmask = (tms.Regs[3] & 0x7f) * 8 | 7;
|
||||
tms.pattern = ((tms.Regs[4] & 4) * 2048) & (tms.vramsize - 1);
|
||||
tms.patternmask = (tms.Regs[4] & 3) * 256 |
|
||||
(tms.colourmask & 255);
|
||||
} else {
|
||||
tms.colour = (tms.Regs[3] * 64) & (tms.vramsize - 1);
|
||||
tms.pattern = (tms.Regs[4] * 2048) & (tms.vramsize - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
int b = (val & 0x20) && (tms.StatusReg & 0x80);
|
||||
if (b != tms.INT) {
|
||||
tms.INT = b;
|
||||
if (tms.INTCallback) tms.INTCallback (tms.INT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
tms.nametbl = (val * 1024) & (tms.vramsize - 1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
if (tms.Regs[0] & 2) {
|
||||
tms.colour = ((val & 0x80) * 64) & (tms.vramsize - 1);
|
||||
tms.colourmask = (val & 0x7f) * 8 | 7;
|
||||
} else {
|
||||
tms.colour = (val * 64) & (tms.vramsize - 1);
|
||||
}
|
||||
tms.patternmask = (tms.Regs[4] & 3) * 256 | (tms.colourmask & 255);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
if (tms.Regs[0] & 2) {
|
||||
tms.pattern = ((val & 4) * 2048) & (tms.vramsize - 1);
|
||||
tms.patternmask = (val & 3) * 256 | 255;
|
||||
} else {
|
||||
tms.pattern = (val * 2048) & (tms.vramsize - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
tms.spriteattribute = (val * 128) & (tms.vramsize - 1);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
tms.spritepattern = (val * 2048) & (tms.vramsize - 1);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* The backdrop is updated at TMS9928A_refresh() */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TMS9928AReset()
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
tms.Regs[i] = 0;
|
||||
|
||||
tms.StatusReg = 0;
|
||||
tms.nametbl = tms.pattern = tms.colour = 0;
|
||||
tms.spritepattern = tms.spriteattribute = 0;
|
||||
tms.colourmask = tms.patternmask = 0;
|
||||
tms.Addr = tms.ReadAhead = tms.INT = 0;
|
||||
tms.FirstByte = 0;
|
||||
tms.latch = 0;
|
||||
}
|
||||
|
||||
void TMS9928AInit(int model, int vram, int borderx, int bordery, void (*INTCallback)(int))
|
||||
{
|
||||
GenericTilesInit();
|
||||
|
||||
tms.model = model;
|
||||
|
||||
tms.INTCallback = INTCallback;
|
||||
|
||||
tms.top_border = ((tms.model == TMS9929) || (tms.model == TMS9929A)) ? 51 : 27;
|
||||
tms.bottom_border = ((tms.model == TMS9929) || (tms.model == TMS9929A)) ? 51 : 24;
|
||||
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
|
||||
tms.min_x = 15 - MIN(borderx, 15);
|
||||
tms.max_x = 15 + 32*8 - 1 + MIN(borderx, 15);
|
||||
tms.min_y = tms.top_border - MIN(bordery, tms.top_border);
|
||||
tms.max_y = tms.top_border + 24*8 - 1 + MIN(bordery, tms.bottom_border);
|
||||
|
||||
#undef MIN
|
||||
|
||||
tms.vramsize = vram;
|
||||
tms.vMem = (unsigned char*)malloc(tms.vramsize);
|
||||
|
||||
tms.dBackMem = (unsigned char*)malloc(256 * 192);
|
||||
|
||||
tms.tmpbmp = (unsigned short*)malloc(256 * 192 * sizeof(short));
|
||||
|
||||
TMS9928AReset ();
|
||||
tms.LimitSprites = 1;
|
||||
}
|
||||
|
||||
void TMS9928AExit()
|
||||
{
|
||||
TMS9928AReset();
|
||||
|
||||
GenericTilesExit();
|
||||
|
||||
free (tms.tmpbmp);
|
||||
free (tms.vMem);
|
||||
free (tms.dBackMem);
|
||||
}
|
||||
|
||||
void TMS9928APostLoad()
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
change_register(i, tms.Regs[i]);
|
||||
|
||||
if (tms.INTCallback) tms.INTCallback(tms.INT);
|
||||
}
|
||||
|
||||
unsigned char TMS9928AReadVRAM()
|
||||
{
|
||||
int b = tms.ReadAhead;
|
||||
tms.ReadAhead = tms.vMem[tms.Addr];
|
||||
tms.Addr = (tms.Addr + 1) & (tms.vramsize - 1);
|
||||
tms.latch = 0;
|
||||
return b;
|
||||
}
|
||||
|
||||
void TMS9928AWriteVRAM(int data)
|
||||
{
|
||||
tms.vMem[tms.Addr] = data;
|
||||
tms.Addr = (tms.Addr + 1) & (tms.vramsize - 1);
|
||||
tms.ReadAhead = data;
|
||||
tms.latch = 0;
|
||||
}
|
||||
|
||||
unsigned char TMS9928AReadRegs()
|
||||
{
|
||||
int b = tms.StatusReg;
|
||||
tms.StatusReg = 0x1f;
|
||||
if (tms.INT) {
|
||||
tms.INT = 0;
|
||||
if (tms.INTCallback) tms.INTCallback (tms.INT);
|
||||
}
|
||||
tms.latch = 0;
|
||||
return b;
|
||||
}
|
||||
|
||||
void TMS9928AWriteRegs(int data)
|
||||
{
|
||||
if (tms.latch) {
|
||||
if (data & 0x80) {
|
||||
change_register(data & 0x07, tms.FirstByte);
|
||||
} else {
|
||||
tms.Addr = ((unsigned short)data << 8 | tms.FirstByte) & (tms.vramsize - 1);
|
||||
if (!(data & 0x40)) {
|
||||
TMS9928AReadVRAM();
|
||||
}
|
||||
}
|
||||
|
||||
tms.latch = 0;
|
||||
} else {
|
||||
tms.FirstByte = data;
|
||||
tms.latch = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void TMS9928ASetSpriteslimit(int limit)
|
||||
{
|
||||
tms.LimitSprites = limit;
|
||||
}
|
||||
|
||||
static void draw_mode0(unsigned short *bitmap)
|
||||
{
|
||||
unsigned char *patternptr;
|
||||
|
||||
for (int y = 0, name = 0; y < 24; y++)
|
||||
{
|
||||
for (int x = 0; x < 32; x++, name++)
|
||||
{
|
||||
int charcode = tms.vMem[tms.nametbl+name];
|
||||
|
||||
patternptr = tms.vMem + tms.pattern + charcode*8;
|
||||
|
||||
int color = tms.vMem[tms.colour+charcode/8];
|
||||
|
||||
int fg = color >> 4;
|
||||
int bg = color & 0x0f;
|
||||
|
||||
for (int yy = 0; yy < 8; yy++)
|
||||
{
|
||||
int bits = *patternptr++;
|
||||
|
||||
for (int xx = 0; xx < 8; xx++, bits<<=1)
|
||||
{
|
||||
bitmap[(y * 8 + yy) * 256 + (x * 8 + xx)] = (bits & 0x80) ? fg : bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_mode1(unsigned short *bitmap)
|
||||
{
|
||||
int pattern,x,y,yy,xx,name,charcode;
|
||||
UINT8 fg,bg,*patternptr;
|
||||
|
||||
fg = tms.Regs[7] / 16;
|
||||
bg = tms.Regs[7] & 15;
|
||||
|
||||
for (y = 0; y < 191; y++) {
|
||||
for (x = 0; x < 7; x++) {
|
||||
bitmap[y * 256 + x + 248] = bitmap[y * 256 + x] = bg;
|
||||
}
|
||||
}
|
||||
|
||||
name = 0;
|
||||
|
||||
for (y=0;y<24;y++) {
|
||||
for (x=0;x<40;x++) {
|
||||
charcode = tms.vMem[tms.nametbl+name];
|
||||
name++;
|
||||
patternptr = tms.vMem + tms.pattern + (charcode*8);
|
||||
for (yy=0;yy<8;yy++) {
|
||||
pattern = *patternptr++;
|
||||
for (xx=0;xx<6;xx++) {
|
||||
bitmap[(y * 8 + yy) * 256 + (8 + x*6+xx)] = (pattern & 0x80) ? fg : bg;
|
||||
pattern *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_mode12(unsigned short *bitmap)
|
||||
{
|
||||
int pattern,x,y,yy,xx,name,charcode;
|
||||
UINT8 fg,bg,*patternptr;
|
||||
|
||||
fg = tms.Regs[7] / 16;
|
||||
bg = tms.Regs[7] & 15;
|
||||
|
||||
for (y = 0; y < 191; y++) {
|
||||
for (x = 0; x < 7; x++) {
|
||||
bitmap[y * 256 + x + 248] = bitmap[y * 256 + x] = bg;
|
||||
}
|
||||
}
|
||||
|
||||
name = 0;
|
||||
for (y=0;y<24;y++) {
|
||||
for (x=0;x<40;x++) {
|
||||
charcode = (tms.vMem[tms.nametbl+name]+(y/8)*256)&tms.patternmask;
|
||||
name++;
|
||||
patternptr = tms.vMem + tms.pattern + (charcode*8);
|
||||
for (yy=0;yy<8;yy++) {
|
||||
pattern = *patternptr++;
|
||||
for (xx=0;xx<6;xx++) {
|
||||
bitmap[(y * 8 + yy) * 256 + (8 + x*6+xx)] = (pattern & 0x80) ? fg : bg;
|
||||
pattern *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_mode2(unsigned short *bitmap)
|
||||
{
|
||||
int colour,name,x,y,yy,pattern,xx,charcode;
|
||||
UINT8 fg,bg;
|
||||
UINT8 *colourptr,*patternptr;
|
||||
|
||||
name = 0;
|
||||
for (y=0;y<24;y++) {
|
||||
for (x=0;x<32;x++) {
|
||||
charcode = tms.vMem[tms.nametbl+name]+(y/8)*256;
|
||||
name++;
|
||||
colour = (charcode&tms.colourmask);
|
||||
pattern = (charcode&tms.patternmask);
|
||||
patternptr = tms.vMem+tms.pattern+colour*8;
|
||||
colourptr = tms.vMem+tms.colour+pattern*8;
|
||||
for (yy=0;yy<8;yy++) {
|
||||
pattern = *patternptr++;
|
||||
colour = *colourptr++;
|
||||
fg = colour / 16;
|
||||
bg = colour & 15;
|
||||
for (xx=0;xx<8;xx++) {
|
||||
bitmap[(y * 8 + yy) * 256 + (x*8+xx)] = (pattern & 0x80) ? fg : bg;
|
||||
pattern *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_mode3(unsigned short *bitmap)
|
||||
{
|
||||
int x,y,yy,yyy,name,charcode;
|
||||
UINT8 fg,bg,*patternptr;
|
||||
|
||||
name = 0;
|
||||
for (y=0;y<24;y++) {
|
||||
for (x=0;x<32;x++) {
|
||||
charcode = tms.vMem[tms.nametbl+name];
|
||||
name++;
|
||||
patternptr = tms.vMem+tms.pattern+charcode*8+(y&3)*2;
|
||||
for (yy=0;yy<2;yy++) {
|
||||
fg = (*patternptr / 16);
|
||||
bg = ((*patternptr++) & 15);
|
||||
for (yyy=0;yyy<4;yyy++) {
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+0)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+1)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+2)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+3)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+4)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+5)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+6)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+7)] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_mode23(unsigned short *bitmap)
|
||||
{
|
||||
int x,y,yy,yyy,name,charcode;
|
||||
UINT8 fg,bg,*patternptr;
|
||||
|
||||
name = 0;
|
||||
for (y=0;y<24;y++) {
|
||||
for (x=0;x<32;x++) {
|
||||
charcode = tms.vMem[tms.nametbl+name];
|
||||
name++;
|
||||
patternptr = tms.vMem + tms.pattern +
|
||||
((charcode+(y&3)*2+(y/8)*256)&tms.patternmask)*8;
|
||||
for (yy=0;yy<2;yy++) {
|
||||
fg = (*patternptr / 16);
|
||||
bg = ((*patternptr++) & 15);
|
||||
for (yyy=0;yyy<4;yyy++) {
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+0)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+1)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+2)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+3)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+4)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+5)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+6)] = fg;
|
||||
bitmap[(y*8+yy*4+yyy) * 256 + (x*8+7)] = fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_modebogus(unsigned short *bitmap)
|
||||
{
|
||||
UINT8 fg,bg;
|
||||
int x,y,n,xx;
|
||||
|
||||
fg = tms.Regs[7] / 16;
|
||||
bg = tms.Regs[7] & 15;
|
||||
|
||||
for (y=0;y<192;y++) {
|
||||
xx=0;
|
||||
n=8; while (n--) bitmap[y * 256 + (xx++)] = bg;
|
||||
for (x=0;x<40;x++) {
|
||||
n=4; while (n--) bitmap[y * 256 + (xx++)] = fg;
|
||||
n=2; while (n--) bitmap[y * 256 + (xx++)] = bg;
|
||||
}
|
||||
n=8; while (n--) bitmap[y * 256 + (xx++)] = bg;
|
||||
}
|
||||
}
|
||||
|
||||
static void (*const ModeHandlers[])(unsigned short *bitmap) = {
|
||||
draw_mode0, draw_mode1, draw_mode2, draw_mode12,
|
||||
draw_mode3, draw_modebogus, draw_mode23,
|
||||
draw_modebogus
|
||||
};
|
||||
|
||||
static void draw_sprites()
|
||||
{
|
||||
UINT8 *attributeptr,*patternptr,c;
|
||||
int p,x,y,size,i,j,large,yy,xx,limit[192],
|
||||
illegalsprite,illegalspriteline;
|
||||
UINT16 line,line2;
|
||||
|
||||
attributeptr = tms.vMem + tms.spriteattribute;
|
||||
size = (tms.Regs[1] & 2) ? 16 : 8;
|
||||
large = (int)(tms.Regs[1] & 1);
|
||||
|
||||
for (x=0;x<192;x++) limit[x] = 4;
|
||||
tms.StatusReg = 0x80;
|
||||
illegalspriteline = 255;
|
||||
illegalsprite = 0;
|
||||
|
||||
memset (tms.dBackMem, 0, 256 * 192);
|
||||
|
||||
for (p=0;p<32;p++) {
|
||||
y = *attributeptr++;
|
||||
if (y == 208) break;
|
||||
if (y > 208) {
|
||||
y=-(~y&255);
|
||||
} else {
|
||||
y++;
|
||||
}
|
||||
x = *attributeptr++;
|
||||
patternptr = tms.vMem + tms.spritepattern +
|
||||
((size == 16) ? *attributeptr & 0xfc : *attributeptr) * 8;
|
||||
attributeptr++;
|
||||
c = (*attributeptr & 0x0f);
|
||||
if (*attributeptr & 0x80) x -= 32;
|
||||
attributeptr++;
|
||||
|
||||
if (!large) {
|
||||
/* draw sprite (not enlarged) */
|
||||
for (yy=y;yy<(y+size);yy++) {
|
||||
if ( (yy < 0) || (yy > 191) ) continue;
|
||||
if (limit[yy] == 0) {
|
||||
/* illegal sprite line */
|
||||
if (yy < illegalspriteline) {
|
||||
illegalspriteline = yy;
|
||||
illegalsprite = p;
|
||||
} else if (illegalspriteline == yy) {
|
||||
if (illegalsprite > p) {
|
||||
illegalsprite = p;
|
||||
}
|
||||
}
|
||||
if (tms.LimitSprites) continue;
|
||||
} else limit[yy]--;
|
||||
line = 256*patternptr[yy-y] + patternptr[yy-y+16];
|
||||
for (xx=x;xx<(x+size);xx++) {
|
||||
if (line & 0x8000) {
|
||||
if ((xx >= 0) && (xx < 256)) {
|
||||
if (tms.dBackMem[yy*256+xx]) {
|
||||
tms.StatusReg |= 0x20;
|
||||
} else {
|
||||
tms.dBackMem[yy*256+xx] = 0x01;
|
||||
}
|
||||
if (c && ! (tms.dBackMem[yy*256+xx] & 0x02))
|
||||
{
|
||||
tms.dBackMem[yy*256+xx] |= 0x02;
|
||||
pTransDraw[(tms.top_border+yy) * nScreenWidth + (15 + xx)] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
line *= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* draw enlarged sprite */
|
||||
for (i=0;i<size;i++) {
|
||||
yy=y+i*2;
|
||||
line2 = 256*patternptr[i] + patternptr[i+16];
|
||||
for (j=0;j<2;j++) {
|
||||
if ( (yy >= 0) && (yy <= 191) ) {
|
||||
if (limit[yy] == 0) {
|
||||
/* illegal sprite line */
|
||||
if (yy < illegalspriteline) {
|
||||
illegalspriteline = yy;
|
||||
illegalsprite = p;
|
||||
} else if (illegalspriteline == yy) {
|
||||
if (illegalsprite > p) {
|
||||
illegalsprite = p;
|
||||
}
|
||||
}
|
||||
if (tms.LimitSprites) continue;
|
||||
} else limit[yy]--;
|
||||
line = line2;
|
||||
for (xx=x;xx<(x+size*2);xx+=2) {
|
||||
if (line & 0x8000) {
|
||||
if ((xx >=0) && (xx < 256)) {
|
||||
if (tms.dBackMem[yy*256+xx]) {
|
||||
tms.StatusReg |= 0x20;
|
||||
} else {
|
||||
tms.dBackMem[yy*256+xx] = 0x01;
|
||||
}
|
||||
if (c && ! (tms.dBackMem[yy*256+xx] & 0x02))
|
||||
{
|
||||
tms.dBackMem[yy*256+xx] |= 0x02;
|
||||
pTransDraw[(tms.top_border+yy) * nScreenWidth + (15 + xx)] = c;
|
||||
}
|
||||
}
|
||||
if (((xx+1) >=0) && ((xx+1) < 256)) {
|
||||
if (tms.dBackMem[yy*256+xx+1]) {
|
||||
tms.StatusReg |= 0x20;
|
||||
} else {
|
||||
tms.dBackMem[yy*256+xx+1] = 0x01;
|
||||
}
|
||||
if (c && ! (tms.dBackMem[yy*256+xx+1] & 0x02))
|
||||
{
|
||||
tms.dBackMem[yy*256+xx+1] |= 0x02;
|
||||
pTransDraw[(tms.top_border+yy) * nScreenWidth + (15 + xx + 1)] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
line *= 2;
|
||||
}
|
||||
}
|
||||
yy++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (illegalspriteline == 255) {
|
||||
tms.StatusReg |= (p > 31) ? 31 : p;
|
||||
} else {
|
||||
tms.StatusReg |= 0x40 + illegalsprite;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int TMS9928ADraw()
|
||||
{
|
||||
int BackColour = tms.Regs[7] & 15;
|
||||
|
||||
if (!BackColour) BackColour=1;
|
||||
|
||||
TMS89928aPaletteRecalc();
|
||||
Palette[0] = Palette[BackColour];
|
||||
|
||||
if (!(tms.Regs[1] & 0x40))
|
||||
{
|
||||
for (int i = 0; i < nScreenWidth * nScreenHeight; i++) {
|
||||
pTransDraw[i] = BackColour;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int mode = ((((tms.model == TMS99x8A) || (tms.model == TMS9929A)) ? (tms.Regs[0] & 2) : 0) | ((tms.Regs[1] & 0x10)>>4) | ((tms.Regs[1] & 8)>>1));
|
||||
|
||||
(*ModeHandlers[mode])(tms.tmpbmp);
|
||||
|
||||
{
|
||||
for (int y = 0; y < 192; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
pTransDraw[(y + tms.top_border) * nScreenWidth + x + 15] = tms.tmpbmp[y * 256 + x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (int y = 0; y < tms.top_border; y++) { // top
|
||||
for (int x = 0; x < 15 + 256 + 15; x++) {
|
||||
pTransDraw[y * nScreenWidth + x] = BackColour;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = tms.top_border+192; y < tms.top_border+192+tms.bottom_border; y++) { // bottom
|
||||
for (int x = 0; x < 15 + 256 + 15; x++) {
|
||||
pTransDraw[y * nScreenWidth + x] = BackColour;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int y = tms.top_border; y < tms.top_border+192; y++) { // left
|
||||
for (int x = 0; x < 15; x++) {
|
||||
pTransDraw[y * nScreenWidth + x] = BackColour;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = tms.top_border; y < tms.top_border+192; y++) { // right
|
||||
for (int x = 15+256; x < 15 + 256 + 15; x++) {
|
||||
pTransDraw[y * nScreenWidth + x] = BackColour;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((tms.Regs[1] & 0x50) == 0x40)
|
||||
draw_sprites();
|
||||
}
|
||||
|
||||
BurnTransferCopy(Palette);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TMS9928AInterrupt()
|
||||
{
|
||||
int b = (tms.Regs[1] & 0x20) != 0;
|
||||
|
||||
tms.StatusReg |= 0x80;
|
||||
|
||||
if (b != tms.INT) {
|
||||
tms.INT = b;
|
||||
if (tms.INTCallback) tms.INTCallback (tms.INT);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
int TMS9928AScan(int nAction, int *pnMin)
|
||||
{
|
||||
struct BurnArea ba;
|
||||
|
||||
if (pnMin) {
|
||||
*pnMin = 0x029708;
|
||||
}
|
||||
|
||||
if (nAction & ACB_VOLATILE) {
|
||||
// memset(&ba, 0, sizeof(ba));
|
||||
|
||||
ba.Data = tms.vMem;
|
||||
ba.nLen = tms.vramsize;
|
||||
ba.szName = "video ram";
|
||||
BurnAcb(&ba);
|
||||
|
||||
ba.Data = tms.Regs;
|
||||
ba.nLen = 8;
|
||||
ba.szName = "tms registers";
|
||||
BurnAcb(&ba);
|
||||
|
||||
SCAN_VAR(tms.ReadAhead);
|
||||
SCAN_VAR(tms.StatusReg);
|
||||
SCAN_VAR(tms.FirstByte);
|
||||
SCAN_VAR(tms.latch);
|
||||
SCAN_VAR(tms.INT);
|
||||
SCAN_VAR(tms.Addr);
|
||||
SCAN_VAR(tms.colour);
|
||||
SCAN_VAR(tms.pattern);
|
||||
SCAN_VAR(tms.nametbl);
|
||||
SCAN_VAR(tms.spriteattribute);
|
||||
SCAN_VAR(tms.spritepattern);
|
||||
SCAN_VAR(tms.colourmask);
|
||||
SCAN_VAR(tms.patternmask);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
28
src/burn/devices/tms9928a.h
Normal file
28
src/burn/devices/tms9928a.h
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
#define TMS9928A_PALETTE_SIZE 16
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TMS_INVALID_MODEL,
|
||||
TMS99x8,
|
||||
TMS9929,
|
||||
TMS99x8A,
|
||||
TMS9929A
|
||||
} tms9928a_model;
|
||||
|
||||
|
||||
int TMS9928AInterrupt();
|
||||
void TMS9928AInit(int model, int vram, int borderx, int bordery, void (*INTCallback)(int));
|
||||
void TMS9928AReset();
|
||||
void TMS9928AExit();
|
||||
int TMS9928ADraw();
|
||||
|
||||
void TMS9928ASetSpriteslimit(int limit);
|
||||
|
||||
void TMS9928AWriteRegs(int data);
|
||||
unsigned char TMS9928AReadRegs();
|
||||
|
||||
void TMS9928AWriteVRAM(int data);
|
||||
unsigned char TMS9928AReadVRAM();
|
||||
|
||||
int TMS9928AScan(int nAction, int *pnMin);
|
Loading…
Reference in New Issue
Block a user