mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
402 lines
8.0 KiB
402 lines
8.0 KiB
/* tms9918.c 9/12/2012 dwg - information from TI Docs */
|
|
/* http://www1.cs.columbia.edu/~sedwards/papers/TMS9918.pdf */
|
|
|
|
|
|
/* TMS9918 Modes:
|
|
|
|
Graphics I
|
|
Graphics Mode I provides 256x192 pixel display for generating
|
|
pattern graphics in 15 colors plus transparent.
|
|
|
|
Graphics II
|
|
Graphics mode II is an enhancement of Graphics Mode I, allowing
|
|
it to generate more complex color and pattern displays.
|
|
|
|
Multicolor
|
|
The Muylticolor mode provides an unrestricted 64x48
|
|
color-dot display employing 15 colors plus transparent.
|
|
|
|
Text Mode
|
|
The Text Mode provides twenty-four 40-character in two colors
|
|
and is intended to maximize the capacity of the TV screen to
|
|
display alphanumeric characters. (24 lines of forty blocks (each 8x8).
|
|
|
|
*/
|
|
|
|
#include "applvers.h"
|
|
#include "n8chars.h"
|
|
|
|
/*
|
|
#define DEBUG
|
|
*/
|
|
|
|
#define WIDTH 37
|
|
#define HEIGHT 24
|
|
#define GUTTER 3
|
|
|
|
#define BASE 128
|
|
#define DATAP (BASE+24)
|
|
#define CMDP (BASE+25)
|
|
|
|
#define WO_R0
|
|
#define WOR0B6
|
|
|
|
#define VDP_TRANSPARENT 0
|
|
#define VDP_BLACK 1
|
|
#define VDP_MED_GREEN 2
|
|
#define VDP_LGREEN 3
|
|
#define VDP_DBLUE 4
|
|
#define VDP_LBLUE 5
|
|
#define VDP_DRED 6
|
|
#define VDP_CYAN 7
|
|
#define VDP_MRED 8
|
|
#define VDP_LRED 9
|
|
#define VDP_DYELLOW 10
|
|
#define VDP_LYELLOW 11
|
|
#define VDP_DGREEN 12
|
|
#define VDP_MAGENTA 13
|
|
#define VDP_GRAY 14
|
|
#define VDP_WHITE 15
|
|
|
|
#define SINGLE 11
|
|
#define TRIPLE 0
|
|
char style; /* can be SINGLE or TRIPPLE */
|
|
|
|
unsigned char vdp_regen[24*40];
|
|
|
|
unsigned char buffer(4096);
|
|
|
|
vdp_setvram(o)
|
|
{
|
|
unsigned char byte1;
|
|
unsigned char byte2;
|
|
|
|
byte1 = o & 255;
|
|
byte2 = (o >> 8) | 0x40;
|
|
out(CMDP,byte1);
|
|
out(CMDP,byte2);
|
|
}
|
|
|
|
|
|
vpd_rdblk(ofs,bufptr,buflen)
|
|
unsigned int ofs;
|
|
unsigned char * bufptr;
|
|
int buflen;
|
|
{
|
|
char c,v;
|
|
unsigned char * ptr;
|
|
|
|
printf("DEBUG: vdp_rdblk( 0x%4x(%d), 0x%04x(%d), 0x%04x(%d) );\n",
|
|
ofs,ofs,bufptr,bufptr,buflen,buflen);
|
|
|
|
vdp_setvram(ofs);
|
|
|
|
p = &buffer;
|
|
|
|
for(c=0;c<buflen;c++) {
|
|
*p = in(DATAP);
|
|
}
|
|
|
|
}
|
|
|
|
void vdp_read()
|
|
{
|
|
char c,v;
|
|
|
|
for(c=0;c<17;c++) {
|
|
v = in(DATAP);
|
|
printf("0x2x ",v);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void vdp_display(line,column,string)
|
|
int line;
|
|
int column;
|
|
char * string;
|
|
{
|
|
char index;
|
|
|
|
vdp_wrvram(GUTTER+(line*40)+column);
|
|
for(index=0;index<strlen(string);index++) {
|
|
out(DATAP,string[index]);
|
|
}
|
|
}
|
|
|
|
void vdp_pad(line,column,string)
|
|
int line;
|
|
int column;
|
|
char * string;
|
|
{
|
|
char index;
|
|
|
|
vdp_wrvram(GUTTER+(line*40)+column);
|
|
for(index=0;index<strlen(string);index++) {
|
|
out(DATAP,string[index]);
|
|
}
|
|
if(40>strlen(string)) {
|
|
for(index=strlen(string);index<40;index++) {
|
|
out(DATAP,' ');
|
|
}
|
|
}
|
|
}
|
|
|
|
void vdp_hz_join(line)
|
|
int line;
|
|
{
|
|
char i;
|
|
char szTemp[2];
|
|
|
|
sprintf(szTemp,"%c",0x8a+style);
|
|
for(i=1;i<WIDTH-1;i++) {
|
|
vdp_display(line,i,szTemp);
|
|
}
|
|
|
|
sprintf(szTemp,"%c",0x88+style);
|
|
vdp_display(line,0,szTemp);
|
|
|
|
sprintf(szTemp,"%c",0x89+style);
|
|
vdp_display(line,WIDTH-1,szTemp);
|
|
}
|
|
|
|
|
|
void vdp_main_frame(name)
|
|
char * name;
|
|
{
|
|
char i;
|
|
char szTemp[48];
|
|
|
|
sprintf(szTemp,"%c",0x81+style);
|
|
for(i=1;i<WIDTH-1;i++) {
|
|
vdp_display(0,i,szTemp);
|
|
}
|
|
|
|
sprintf(szTemp,"%c",0x85+style);
|
|
for(i=1;i<WIDTH-1;i++) {
|
|
vdp_display(HEIGHT-1,i,szTemp);
|
|
}
|
|
|
|
sprintf(szTemp,"%c",0x87+style);
|
|
for(i=1;i<HEIGHT-1;i++) {
|
|
vdp_display(i,0,szTemp);
|
|
}
|
|
|
|
sprintf(szTemp,"%c",0x83+style);
|
|
for(i=1;i<HEIGHT-1;i++) {
|
|
vdp_display(i,WIDTH-1,szTemp);
|
|
}
|
|
|
|
sprintf(szTemp,"%c",0x80+style);
|
|
vdp_display(0,0,szTemp);
|
|
|
|
sprintf(szTemp,"%c",0x82+style);
|
|
vdp_display(0,WIDTH-1,szTemp);
|
|
|
|
sprintf(szTemp,"%c",0x84+style);
|
|
vdp_display(HEIGHT-1,WIDTH-1,szTemp);
|
|
|
|
sprintf(szTemp,"%c",0x86+style);
|
|
vdp_display(HEIGHT-1,0,szTemp);
|
|
|
|
sprintf(szTemp,"%s %d/%d/%d Ver %d.%d.%d",
|
|
name,A_MONTH,A_DAY,A_YEAR,A_RMJ,A_RMN,A_RUP);
|
|
vdp_display(1,(WIDTH-strlen(szTemp))/2,szTemp);
|
|
|
|
vdp_hz_join(2);
|
|
vdp_hz_join(HEIGHT-3);
|
|
}
|
|
|
|
|
|
void vdp_clr16k()
|
|
{
|
|
unsigned int a;
|
|
|
|
#ifdef DEBUG
|
|
printf("Let's set VDP write address to #0000 \n");
|
|
#endif
|
|
out(CMDP,0); /* 0x00 - a6 a7 a8 a9 a10 a11 a12 a13 - all zeroes */
|
|
out(CMDP,64); /* 0x40 - 01 a0 a1 a2 a3 a4 a5 - all zeroes */
|
|
#ifdef DEBUG
|
|
printf("Now let's clear first 16Kb of VDP memory\n");
|
|
#endif
|
|
for(a=0;a<16384;a++) {
|
|
out(DATAP,0);
|
|
}
|
|
}
|
|
|
|
void vdp_setregs()
|
|
{
|
|
#ifdef DEBUG
|
|
printf("Now it's time to set up VDP registers\n");
|
|
#endif
|
|
out(CMDP,0); /* 0x00 - 000000 - 0 M3 M3 of 0 required text mode */
|
|
/* 0 EX EX of 0 disables extVDP inp */
|
|
|
|
out(CMDP,128); /* 0x80 - 1 0000 000 - reg 0 */
|
|
}
|
|
|
|
void vdp_modes()
|
|
{
|
|
#ifdef DEBUG
|
|
printf("Select 40 column mode, ");
|
|
printf("enable screen and disable vertical interrupt\n");
|
|
#endif
|
|
out(CMDP,80); /* 0x50 - 0101 0000 - 0 4/16K Select 4027 RAM operation */
|
|
/* 1 BLANK Enables the active display */
|
|
/* 0 IE Disables VDP interrupt */
|
|
/* 1 M1 M1 of 1 is required for text mode */
|
|
/* 0 M2 M2 of zero is required for text mode */
|
|
/* 0 n/a */
|
|
/* 0 SIZE 0 sprites 8x8 */
|
|
/* 0 MAG 0 sprites 2X */
|
|
out(CMDP,129); /* 0x81 - 1 0000 001 - reg 1 */
|
|
}
|
|
|
|
void vdp_pnt()
|
|
{
|
|
#ifdef DEBUG
|
|
printf("Set pattern name table to #0000\n");
|
|
#endif
|
|
out(CMDP,0); /* 0x00 - 0000 0000 - name table base addr 0 */
|
|
out(CMDP,130); /* 0x82 - 1 0000 010 - reg 2 */
|
|
}
|
|
|
|
void vdp_pgt()
|
|
{
|
|
#ifdef DEBUG
|
|
printf("Set pattern generator table to #800\n");
|
|
#endif
|
|
out(CMDP,1); /* 0x01 - 00000 001 - pattern generator base addr 1 */
|
|
out(CMDP,132); /* 0x84 - 1 0000 100 - reg 4 */
|
|
}
|
|
|
|
void vdp_colors()
|
|
{
|
|
#ifdef DEBUG
|
|
printf("Set colors to white on black\n");
|
|
#endif
|
|
out(CMDP,240); /* 0xF0 - 1111 0000 - (text=1111 bkgd=0000 */
|
|
out(CMDP,135); /* 0x87 - 1 0000 111 - reg 7 */
|
|
}
|
|
|
|
void vdp_load_set()
|
|
{
|
|
int c,d,index;
|
|
#ifdef DEBUG
|
|
printf("Let's set VDP write address to #800 so ");
|
|
printf("that we can write character set to memory\n");
|
|
#endif
|
|
out(CMDP,0); /* 0x00 - a6 a7 a8 a9 a10 a11 a12 a13 - all zeroes */
|
|
out(CMDP,72); /* 0x48 - 01 a0=0 a1=0 a2=1 a3=0 a4=0 a5=0 */
|
|
/* a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 */
|
|
/* 0 0 0 1 0 0 0 0 0 0 0 0 0 0 */
|
|
/* 000 1000 0000 0000 */
|
|
|
|
#ifdef DEBUG
|
|
printf("Create a character set\n");
|
|
#endif
|
|
index=0;
|
|
for(c=0;c<256;c++) {
|
|
for(d=0;d<8;d++) {
|
|
out(DATAP,charset[index++]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void vdp_fill()
|
|
{
|
|
int c;
|
|
char d;
|
|
|
|
#ifdef DEBUG
|
|
printf("Let's set write address to start of name table\n");
|
|
#endif
|
|
out(CMDP,0);
|
|
out(CMDP,64); /* 0x40 */
|
|
#ifdef DEBUG
|
|
printf("Let's put characters to screen\n");
|
|
#endif
|
|
d = 0;
|
|
for(c=0;c<(40*24);c++) {
|
|
out(DATAP,d);
|
|
d++;
|
|
if(128 == d) d=0;
|
|
}
|
|
|
|
}
|
|
|
|
void vdp_sync_vdp_regen()
|
|
{
|
|
int c,d;
|
|
|
|
#ifdef DEBUG
|
|
printf("Let's set write address to start of name table\n");
|
|
#endif
|
|
|
|
out(CMDP,0);
|
|
out(CMDP,64); /* 0x40 */
|
|
|
|
#ifdef DEBUG
|
|
printf("Let's put characters to screen\n");
|
|
#endif
|
|
d = 0;
|
|
for(c=0;c<(40*24);c++) {
|
|
out(DATAP,vdp_regen[c]);
|
|
}
|
|
}
|
|
|
|
void func700()
|
|
{
|
|
out(CMDP,0);
|
|
out(CMDP,0);
|
|
}
|
|
|
|
void vdp_clr_vdp_regen()
|
|
{
|
|
unsigned int index;
|
|
|
|
for(index=0;index<(24*40);index++) {
|
|
vdp_regen[index] = ' ';
|
|
}
|
|
}
|
|
|
|
void vdp_set_vdp_regen()
|
|
{
|
|
unsigned int index;
|
|
|
|
for(index=0;index<40*24;index++) {
|
|
vdp_regen[index]=index&0x7f;
|
|
}
|
|
}
|
|
|
|
void vdp_num_vdp_regen()
|
|
{
|
|
unsigned int index;
|
|
|
|
for(index=0;index<40*24;index++) {
|
|
vdp_regen[index]=0x30+(index%10);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
vdp_wrvram(o)
|
|
{
|
|
unsigned char byte1;
|
|
unsigned char byte2;
|
|
|
|
byte1 = o & 255;
|
|
byte2 = (o >> 8) | 0x40;
|
|
out(CMDP,byte1);
|
|
out(CMDP,byte2);
|
|
}
|
|
|
|
/* eof - tms9918.c */
|
|
byte1) |