summaryrefslogtreecommitdiff
path: root/arm9/source/spec.c
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2007-04-15 23:55:24 +0000
committerIan C <ianc@noddybox.co.uk>2007-04-15 23:55:24 +0000
commitf39151d7f9bf82e7295c60b89d9da02c781528eb (patch)
treeaca075f0227e1ee8f86cfa1d75dd3b1a56fdd348 /arm9/source/spec.c
parent6701f6a9d4f979cc1eadb673e767b5c46cd2a9c8 (diff)
Development checkin -- not yet working
Diffstat (limited to 'arm9/source/spec.c')
-rw-r--r--arm9/source/spec.c306
1 files changed, 183 insertions, 123 deletions
diff --git a/arm9/source/spec.c b/arm9/source/spec.c
index 70b1931..47524cb 100644
--- a/arm9/source/spec.c
+++ b/arm9/source/spec.c
@@ -27,6 +27,7 @@
#include "spec.h"
#include "spec48_bin.h"
+#include "gui.h"
#ifndef TRUE
#define TRUE 1
@@ -42,6 +43,7 @@
/* ---------------------------------------- STATICS
*/
+static uint16 *pal;
static uint16 *vram;
static const int ROMLEN=0x4000;
@@ -60,13 +62,11 @@ static const int ROM_LOAD=0x562;
#define SCRDATA 0x4000
#define ATTR 0x5800
-#define ATTR_AT(x,y) Z80_MEMORY[ATTR+(x)+((y)/8)*32]
-
Z80Byte Z80_MEMORY[0x10000];
/* Number of cycles per frame
*/
-static Z80Val FRAME_CYCLES=69888;
+#define FRAME_CYCLES 69888
/* GFX vars
@@ -79,35 +79,52 @@ static int flashctr=0;
#define NVAL 25 /* Normal RGB intensity */
#define BVAL 31 /* Bright RGB intensity */
-static Z80Byte *line[SCR_H]; /* Accelerators to screen data */
+/* Accelerators to screen data - start of screen mem that matches an attribute.
+*/
+static Z80Byte *scr_accel[TXT_W * TXT_H];
+static uint16 *vram_accel[TXT_W * TXT_H];
static struct
{
- uint16 col;
int r,g,b;
} coltable[16]=
{
- {0, 0x00,0x00,0x00}, /* BLACK */
- {0, 0x00,0x00,NVAL}, /* BLUE */
- {0, NVAL,0x00,0x00}, /* RED */
- {0, NVAL,0x00,NVAL}, /* MAGENTA */
- {0, 0x00,NVAL,0x00}, /* GREEN */
- {0, 0x00,NVAL,NVAL}, /* CYAN */
- {0, NVAL,NVAL,0x00}, /* YELLOW */
- {0, NVAL,NVAL,NVAL}, /* WHITE */
-
- {0, 0x00,0x00,0x00}, /* BLACK */
- {0, 0x00,0x00,BVAL}, /* BLUE */
- {0, BVAL,0x00,0x00}, /* RED */
- {0, BVAL,0x00,BVAL}, /* MAGENTA */
- {0, 0x00,BVAL,0x00}, /* GREEN */
- {0, 0x00,BVAL,BVAL}, /* CYAN */
- {0, BVAL,BVAL,0x00}, /* YELLOW */
- {0, BVAL,BVAL,BVAL}, /* WHITE */
-
+ {0x00,0x00,0x00}, /* BLACK */
+ {0x00,0x00,NVAL}, /* BLUE */
+ {NVAL,0x00,0x00}, /* RED */
+ {NVAL,0x00,NVAL}, /* MAGENTA */
+ {0x00,NVAL,0x00}, /* GREEN */
+ {0x00,NVAL,NVAL}, /* CYAN */
+ {NVAL,NVAL,0x00}, /* YELLOW */
+ {NVAL,NVAL,NVAL}, /* WHITE */
+
+ {0x00,0x00,0x00}, /* BLACK */
+ {0x00,0x00,BVAL}, /* BLUE */
+ {BVAL,0x00,0x00}, /* RED */
+ {BVAL,0x00,BVAL}, /* MAGENTA */
+ {0x00,BVAL,0x00}, /* GREEN */
+ {0x00,BVAL,BVAL}, /* CYAN */
+ {BVAL,BVAL,0x00}, /* YELLOW */
+ {BVAL,BVAL,BVAL}, /* WHITE */
};
+/* Screen content checkers
+*/
+typedef struct
+{
+ int ink;
+ int paper;
+} ColourCell;
+
+static ColourCell last_attr[TXT_W * TXT_H];
+static Z80Byte last_screen[SCR_W * SCR_H / 8];
+
+/* Lookups for bitmask to screen data
+*/
+static uint16 bitmap_to_screen[256][4];
+
+
/* The keyboard
*/
static Z80Byte matrix[8];
@@ -128,108 +145,118 @@ static struct
{7,0x10}, {7,0x08}, {7,0x04}, {7,0x02}, {7,0x01} /* B - SPACE */
};
-static int debug_matrix = FALSE;
-
/* ---------------------------------------- PRIVATE FUNCTIONS
*/
-static void FillBox(int x, int y, int w, int h, int colour)
+static void DrawScreen(void)
{
int f;
- uint16 *base;
+ int r;
+ int ink;
+ int paper;
+ Z80Byte *scr;
+ Z80Byte *old_scr;
+ int scr_data;
+ int inv_scr_data;
+ int att;
+ uint16 *vr;
- colour|=0x8000;
+ old_scr = last_screen;
- base=vram+x+y*256;
+ swiWaitForVBlank();
- while(h--)
+ for(f=0;f<TXT_W*TXT_H;f++)
{
- for(f=0;f<w;f++)
+ /* Get attribute
+ */
+ att = Z80_MEMORY[ATTR+f];
+
+ if ((att&0x80)&&(flash))
{
- *(base+f)=colour;
+ paper = (att&0x07);
+ ink = (att&0x38)>>3;
+ }
+ else
+ {
+ ink = (att&0x07);
+ paper = (att&0x38)>>3;
}
- base+=256;
- }
-}
-
+ if (att&0x40)
+ {
+ ink += 8;
+ paper += 8;
+ }
+ /* Get screen address for this attribute and VRAM base
+ */
+ scr = scr_accel[f];
+ vr = vram_accel[f];
-static void DrawScreen(void)
-{
- int f,r;
- int ink,paper,t;
- int y;
- Z80Byte *scr;
- Z80Byte b;
- Z80Byte att;
- uint16 *vr;
+ /* If attribute has changed, redraw 8x8 block
+ */
+ if (last_attr[f].ink != ink || last_attr[f].paper != paper)
+ {
+ for(r=0;r<8;r++)
+ {
+ scr_data = *scr;
+ inv_scr_data = scr_data^0xff;
- vr=vram;
+ *vr = (bitmap_to_screen[scr_data][0] & ink) |
+ (bitmap_to_screen[inv_scr_data][0] & paper);
- /* swiWaitForVBlank(); */
+ *(vr+1) = (bitmap_to_screen[scr_data][1] & ink) |
+ (bitmap_to_screen[inv_scr_data][1] & paper);
- for(y=0;y<SCR_H;y++)
- {
- scr=line[y];
+ *(vr+2) = (bitmap_to_screen[scr_data][2] & ink) |
+ (bitmap_to_screen[inv_scr_data][2] & paper);
- for(f=0;f<TXT_W;f++)
- {
- att=ATTR_AT(f,y);
+ *(vr+3) = (bitmap_to_screen[scr_data][3] & ink) |
+ (bitmap_to_screen[inv_scr_data][3] & paper);
- ink=(att&0x07);
- paper=(att&0x38)>>3;
+ vr += 128;
- if (att&0x40)
- {
- ink+=8;
- paper+=8;
- }
+ *old_scr++ = scr_data;
- if ((att&0x80)&&(flash))
- {
- t=ink;
- ink=paper;
- paper=t;
+ scr += 32;
}
- b=*scr++;
-
+ last_attr[f].ink = ink;
+ last_attr[f].paper = paper;
+ }
+ else
+ {
+ /* Attribute not changed, so see if screen data has changed
+ */
for(r=0;r<8;r++)
{
- if (b&(1<<(7-r)))
- {
- *vr++=coltable[ink].col;
- }
- else
+ scr_data = *scr;
+
+ if (scr_data != *old_scr)
{
- *vr++=coltable[paper].col;
- }
- }
- }
- }
+ inv_scr_data = scr_data^0xff;
- if (debug_matrix)
- {
- int m;
- int b;
+ *vr = (bitmap_to_screen[scr_data][0] & ink) |
+ (bitmap_to_screen[inv_scr_data][0] & paper);
- for(m=0;m<8;m++)
- {
- for(b=0;b<8;b++)
- {
- uint16 col;
+ *(vr+1) = (bitmap_to_screen[scr_data][1] & ink) |
+ (bitmap_to_screen[inv_scr_data][1] & paper);
- if (matrix[m]&(1<<b))
- {
- col=RGB15(0,31,0);
+ *(vr+2) = (bitmap_to_screen[scr_data][2] & ink) |
+ (bitmap_to_screen[inv_scr_data][2] & paper);
+
+ *(vr+3) = (bitmap_to_screen[scr_data][3] & ink) |
+ (bitmap_to_screen[inv_scr_data][3] & paper);
+
+ *old_scr++ = scr_data;
}
else
{
- col=RGB15(31,0,0);
+ old_scr++;
}
- FillBox((7-b)*5,150+m*5,4,4,col);
+ vr += 128;
+ scr += 32;
}
}
}
@@ -328,8 +355,6 @@ static int CheckTimers(Z80 *z80, Z80Val val)
DrawScreen();
- /* TODO: Process sound emulation */
-
return FALSE;
}
else
@@ -341,8 +366,13 @@ static int CheckTimers(Z80 *z80, Z80Val val)
/* ---------------------------------------- EXPORTED INTERFACES
*/
-void SPECInit(uint16 *v, Z80 *z80)
+void SPECInit(uint16 *p, uint16 *v, Z80 *z80)
{
+ int c;
+ int r;
+ int f;
+
+ pal=p;
vram=v;
memcpy(Z80_MEMORY,spec48_bin,ROMLEN);
@@ -353,6 +383,61 @@ void SPECInit(uint16 *v, Z80 *z80)
Z80LodgeCallback(z80,eZ80_EDHook,EDCallback);
Z80LodgeCallback(z80,eZ80_Instruction,CheckTimers);
+ /* Define the palette
+ */
+ for(f=0;f<16;f++)
+ {
+ pal[f] = RGB15(coltable[f].r,coltable[f].g,coltable[f].b);
+ }
+
+ for(f=0;f<SCR_H*SCR_W/2;f++)
+ {
+ int pix;
+
+ pix = ((f/8)%16);
+ *(vram+f) = pix | (pix<<8);
+ }
+
+ /* Set up screen accelerators
+ */
+ for(r=0;r<TXT_H;r++)
+ {
+ for(c=0;c<TXT_W;c++)
+ {
+ f = (r/8) * 2048;
+
+ scr_accel[c+r*TXT_W] = Z80_MEMORY + SCRDATA + f + c + (r%8)*32;
+
+ vram_accel[c+r*TXT_W] = vram + (c*4) + (r*4*SCR_W);
+ }
+ }
+
+ for(f=0;f<256;f++)
+ {
+ r=f;
+
+ for(c=0;c<4;c++)
+ {
+ switch(r&0xc0)
+ {
+ case 0x00:
+ bitmap_to_screen[f][c]=0x0000;
+ break;
+ case 0x80:
+ bitmap_to_screen[f][c]=0xff00;
+ break;
+ case 0x40:
+ bitmap_to_screen[f][c]=0x00ff;
+ break;
+ case 0xc0:
+ bitmap_to_screen[f][c]=0xffff;
+ break;
+ }
+
+ r=r<<2;
+ }
+ }
+
SPECReset(z80);
}
@@ -373,11 +458,6 @@ void SPECHandleKey(SoftKey key, int is_pressed)
else
{
/* TODO: Joysticks! */
-
- if (is_pressed && key==SK_PAD_SELECT)
- {
- debug_matrix = !debug_matrix;
- }
}
}
@@ -455,8 +535,6 @@ void SPECWritePort(Z80 *z80, Z80Word port, Z80Byte val)
void SPECReset(Z80 *z80)
{
int f;
- int c;
- int r;
/* Set up the keyboard
*/
@@ -465,35 +543,17 @@ void SPECReset(Z80 *z80)
matrix[f]=0x1f;
}
- /* Set up the colours
+ /* Force full-screen redraw
*/
- for(f=0;f<16;f++)
+ for(f=0; f<TXT_W*TXT_H; f++)
{
- coltable[f].col=0x8000|RGB15(coltable[f].r,coltable[f].g,coltable[f].b);
+ last_attr[f].ink = -1;
+ last_attr[f].paper = -1;
}
flash=0;
flashctr=0;
- /* Set up screen
- */
- c=0;
- r=0;
- for(f=0;f<SCR_H;f++)
- {
- line[f]=Z80_MEMORY+SCRDATA+(c*8*TXT_W)+(r*TXT_W);
-
- c++;
-
- if ((c%8)==0)
- {
- if (++r==8)
- r=0;
- else
- c-=8;
- }
- }
-
Z80ResetCycles(z80,0);
Z80Reset(z80);
}