Commit 59ebad75 authored by Andre Leiradella's avatar Andre Leiradella
Browse files

integrated chorma 81 emulation code from erik

parent 7d4a9661
......@@ -55,6 +55,7 @@ extern int scanline_len;
extern int SelectAYReg;
int border=7, ink=0, paper=7;
int pink=0, ppaper=7;
int NMI_generator=0;
int HSYNC_generator=0;
......@@ -121,6 +122,7 @@ void zx81_initialise(void)
if (zx81.truehires==HIRESG007) memory_load("g007hrg.rom",10240,2048);
if (zx81.machine==MACHINELAMBDA) { ink=7; paper=border=0; }
else if (zx81.Chroma81) { ink=0; ppaper=paper=border=15; }
else { ink=0; paper=border=7; }
NMI_generator=0;
......@@ -152,6 +154,12 @@ void zx81_writebyte(int Address, int Data)
return;
}
if (zx81.Chroma81 && Address>=49152)
{
memory[Address]=Data;
return;
}
if (zx81.machine==MACHINEZX97LE)
{
if (zx97.protect08 && Address<0x2000) return;
......@@ -205,6 +213,12 @@ BYTE zx81_readbyte(int Address)
return(data);
}
if (zx81.Chroma81 && Address>=49152)
{
data=memory[Address];
return(data);
}
if (zx81.machine==MACHINEZX97LE)
{
if (zx97.bankswitch && Address<8192) Address+=0x8000;
......@@ -335,11 +349,30 @@ BYTE zx81_opcode_fetch(int Address)
// character sets are only 64 characters in size.
if ((zx81.chrgen==CHRGENCHR16 && (z80.i&1))
|| (zx81.chrgen==CHRGENQS && zx81.enableqschrgen))
|| (zx81.chrgen==CHRGENQS && zx81.enableqschrgen)
|| (zx81.chromamode==0x20))
data = ((data&128)>>1)|(data&63);
else data = data&63;
if (zx81.colour==COLOURCHROMA)
{
int c;
// If the Chroma 81 interface is enabled, we had better fetch
// the ink and paper colour from memory too.
if (zx81.chromamode&0x10) // Attribute file
c=memory[Address];
else // Character code
c=memory[0xc000 + (data<<3) | rowcounter];
ink = pink;
paper = ppaper;
pink = c&15;
ppaper = (c>>4) & 15;
}
// If I points to ROM, OR I points to the 8-16k region for
// CHR$x16, we'll fetch the bitmap from there.
// Lambda and the QS Character board have external memory
......@@ -384,6 +417,14 @@ BYTE zx81_opcode_fetch(int Address)
setborder=0;
}
}
else if (zx81.colour==COLOURCHROMA)
{
if (setborder)
{
border=zx81.chromamode & 15;
setborder=0;
}
}
// Finally load the bitmap we retrieved into the video shift
// register, remembering to make some video noise too.
......@@ -400,6 +441,8 @@ BYTE zx81_opcode_fetch(int Address)
// bit 6 set in the display file. We actually execute these
// opcodes, and generate the noise.
ppaper = zx81.chromamode & 15;
noise |= data;
return(opcode);
}
......@@ -407,6 +450,12 @@ BYTE zx81_opcode_fetch(int Address)
void zx81_writeport(int Address, int Data, int *tstates)
{
if (Address==0x7fef && zx81.Chroma81) {
zx81.colour = Data&0x20 ? COLOURCHROMA : COLOURDISABLED;
zx81.chromamode = Data;
return;
}
switch(Address&255)
{
case 0x01:
......@@ -509,6 +558,9 @@ BYTE zx81_readport(int Address, int *tstates)
return(~data);
}
else if (Address==0x7fef) {
return zx81.Chroma81 ? 0 : 255;
}
else
switch(Address&255)
{
......
......@@ -73,6 +73,8 @@ void load_config(void)
zx81.zxprinter=1;
machine.clockspeed=3250000;
zx81.speedup=0;
zx81.chromamode=255;
zx81.chromamode=0;
machine.tperscanline=207;
machine.tperframe=312*207;
machine.intposition=0;
......
......@@ -79,6 +79,7 @@
#define COLOURDDC 3
#define COLOURHAVEN 4
#define COLOURACE 5
#define COLOURCHROMA 6
#define CRCACE 0x0a09
#define CRCASZMIC 0xcac9
......@@ -159,6 +160,8 @@ typedef struct
int romcrc;
int frameskip;
int speedup;
int Chroma81;
int chromamode;
char ROM80[256];
char ROM81[256];
......
......@@ -47,7 +47,7 @@ Save states are supported.
## Thanks
* Erik Olofsen, for the correct values to set the Z80 registers and some memory variables to successfully load .P files
* Erik Olofsen, for the correct values to set the Z80 registers and some memory variables to successfully load .P files, and for the Chroma 81 emulation
## Versions
......
......@@ -324,7 +324,8 @@ static void compute_palette( CONFIG* cfg )
BrightnessLevel -= ContrastLevel;
int HiBrightLevel = BrightnessLevel + ( ContrastLevel / 2 ) + 2 * ContrastLevel;
ContrastLevel = BrightnessLevel + ContrastLevel + ContrastLevel;
int r, g, b;
int i;
for( i = 0; i < 16; i++ )
......@@ -336,37 +337,46 @@ static void compute_palette( CONFIG* cfg )
colour = ( i & 8 ) + ( 7 - ( colour & 7 ) );
}
int difference = ( 1000 * ( ( ( colour > 7 ) ? HiBrightLevel : ContrastLevel ) - BrightnessLevel ) ) / 16;
int basecolour = ( difference * ( ( colour & 7 ) + 9 ) ) / 1000;
if ( colour == 0 || colour == 8)
if ( !zx81.Chroma81 )
{
basecolour = BrightnessLevel;
}
int difference = ( 1000 * ( ( ( colour > 7 ) ? HiBrightLevel : ContrastLevel ) - BrightnessLevel ) ) / 16;
int basecolour = ( difference * ( ( colour & 7 ) + 9 ) ) / 1000;
if ( colour == 0 || colour == 8)
{
basecolour = BrightnessLevel;
}
int colr, colg, colb;
if ( cfg->Vibrant )
{
colb = ( colour & 1 ) ? ( ( i > 7 ) ? HiBrightLevel : ContrastLevel ) : BrightnessLevel;
colg = ( colour & 4 ) ? ( ( i > 7 ) ? HiBrightLevel : ContrastLevel ) : BrightnessLevel;
colr = ( colour & 2 ) ? ( ( i > 7 ) ? HiBrightLevel : ContrastLevel ) : BrightnessLevel;
int colr, colg, colb;
if ( cfg->Vibrant )
{
colb = ( colour & 1 ) ? ( ( i > 7 ) ? HiBrightLevel : ContrastLevel ) : BrightnessLevel;
colg = ( colour & 4 ) ? ( ( i > 7 ) ? HiBrightLevel : ContrastLevel ) : BrightnessLevel;
colr = ( colour & 2 ) ? ( ( i > 7 ) ? HiBrightLevel : ContrastLevel ) : BrightnessLevel;
}
else
{
colb = BrightnessLevel + ( ( colour & 1 ) ? basecolour :0 );
colg = BrightnessLevel + ( ( colour & 4 ) ? basecolour :0 );
colr = BrightnessLevel + ( ( colour & 2 ) ? basecolour :0 );
}
int bwb = BrightnessLevel + basecolour;
int bwg = BrightnessLevel + basecolour;
int bwr = BrightnessLevel + basecolour;
r = ( ( ( colr - bwr ) * ColourLevel ) / 255 ) + bwr;
g = ( ( ( colg - bwg ) * ColourLevel ) / 255 ) + bwg;
b = ( ( ( colb - bwb ) * ColourLevel ) / 255 ) + bwb;
}
else
else // Chroma
{
colb = BrightnessLevel + ( ( colour & 1 ) ? basecolour :0 );
colg = BrightnessLevel + ( ( colour & 4 ) ? basecolour :0 );
colr = BrightnessLevel + ( ( colour & 2 ) ? basecolour :0 );
r = (colour & 2) ? ((colour & 8) ? 255 : 128) : 0;
g = (colour & 4) ? ((colour & 8) ? 255 : 128) : 0;
b = (colour & 1) ? ((colour & 8) ? 255 : 128) : 0;
}
int bwb = BrightnessLevel + basecolour;
int bwg = BrightnessLevel + basecolour;
int bwr = BrightnessLevel + basecolour;
int r = ( ( ( colr - bwr ) * ColourLevel ) / 255 ) + bwr;
int g = ( ( ( colg - bwg ) * ColourLevel ) / 255 ) + bwg;
int b = ( ( ( colb - bwb ) * ColourLevel ) / 255 ) + bwb;
Palette[ i * 16 ] = DoPal( r, g, b );
Palette[ 4 + i * 16 ] = DoPal( r + GhostLevel2, g + GhostLevel2, b + GhostLevel2 );
......
......@@ -150,6 +150,7 @@ static int internal_init( CONFIG* cfg )
zx81.aytype = cfg->SoundCard;
zx81.aysound = cfg->SoundCard != AY_TYPE_DISABLED;
zx81.m1not = cfg->M1Not ? 49152 : 32768;
zx81.Chroma81 = cfg->Chroma81;
if ( zx81.machine == MACHINEZX97LE )
{
......@@ -261,7 +262,7 @@ int eo_init( CONFIG* cfg )
void eo_settv( CONFIG* cfg )
{
zx81.dirtydisplay= cfg->Artifacts;
zx81.dirtydisplay = cfg->Artifacts;
zx81.simpleghost = cfg->SimpleGhosting;
tv.AdvancedEffects = cfg->AdvancedEffects;
tv.DotCrawl = cfg->DotCrawl;
......
......@@ -37,6 +37,7 @@ typedef struct
int RamPack;
int HiRes;
int SoundCard;
bool Chroma81;
int Brightness; /* 0 -> 255 */
int Contrast; /* 0 -> 255 */
......
......@@ -3,8 +3,6 @@
#include <keybovl.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <eo.h>
#include <types.h>
......@@ -26,28 +24,29 @@
typedef struct
{
bool joystate[ 16 ]; // there should be a #define for that
bool keystate[ RETROK_LAST ];
CONFIG cfg;
void* data;
size_t size;
int scaled;
int transp;
int ms;
unsigned devices[ 2 ];
}
state_t;
// #include <stdio.h>
// #include <stdarg.h>
static void dummy_log( enum retro_log_level level, const char* fmt, ... )
{
va_list args;
(void)level;
(void)fmt;
va_start( args, fmt );
vfprintf( stderr, fmt, args );
va_end( args );
fflush( stderr );
// va_list args;
// va_start( args, fmt );
// vfprintf( stderr, fmt, args );
// va_end( args );
// fflush( stderr );
}
static retro_video_refresh_t video_cb;
......@@ -66,14 +65,17 @@ static state_t state;
static const struct retro_variable core_vars[] =
{
{ "81_video_presets", "Video Presets; clean|tv|noisy" },
{ "81_chroma_81", "Emulate Chroma 81; disabled|enabled" },
{ "81_video_presets", "Video Presets; clean|tv|noisy" },
{ "81_keybovl_transp", "Transparent Keyboard Overlay; enabled|disabled" },
{ "81_key_hold_time", "Time to Release Key in ms; 500|1000|100|300" },
{ "81_key_hold_time", "Time to Release Key in ms; 500|1000|100|300" },
{ NULL, NULL },
};
static void update_variables( void )
static int update_variables( void )
{
int old_scaled = state.scaled;
{
int option = coreopt( env_cb, core_vars, "81_video_presets", NULL );
option += option < 0;
......@@ -84,16 +86,16 @@ static void update_variables( void )
state.cfg.Brightness = 128;
state.cfg.Contrast = 0;
state.cfg.Colour = 0;
state.cfg.Vibrant = 1;
state.cfg.AdvancedEffects = 1;
state.cfg.DotCrawl = 1;
state.cfg.Vibrant = 0;
state.cfg.AdvancedEffects = 0;
state.cfg.DotCrawl = 0;
state.cfg.Interlaced = 0;
state.cfg.Artifacts = 0;
state.cfg.Noise = -6;
state.cfg.Ghosting = 40;
state.cfg.ScanLines = 40;
state.cfg.SimpleGhosting = 1;
state.cfg.Noise = 0;
state.cfg.Ghosting = 0;
state.cfg.ScanLines = 0;
state.cfg.SimpleGhosting = 0;
break;
......@@ -135,6 +137,41 @@ static void update_variables( void )
eo_settv( &state.cfg );
}
{
int option = coreopt( env_cb, core_vars, "81_chroma_81", NULL );
option += option < 0;
if ( option )
{
state.cfg.Brightness = 128;
state.cfg.Contrast = 0;
state.cfg.Colour = 0;
state.cfg.Vibrant = 0;
state.cfg.AdvancedEffects = 0;
state.cfg.DotCrawl = 0;
state.cfg.Interlaced = 0;
state.cfg.Artifacts = 0;
state.cfg.Noise = 0;
state.cfg.Ghosting = 0;
state.cfg.ScanLines = 0;
state.cfg.SimpleGhosting = 0;
eo_settv( &state.cfg );
}
if ( state.cfg.Chroma81 != option )
{
state.cfg.Chroma81 = option;
eo_init( &state.cfg );
if ( state.size != 0 )
{
eo_loadp( state.data, state.size );
}
}
}
state.transp = coreopt( env_cb, core_vars, "81_keybovl_transp", NULL ) != 1;
{
......@@ -142,6 +179,9 @@ static void update_variables( void )
int option = coreopt( env_cb, core_vars, "81_key_hold_time", &value );
state.ms = option >= 0 ? strtoll( value, NULL, 10 ) : 500LL;
}
state.scaled = ( WinR - WinL ) == 640;
return old_scaled != state.scaled;
}
void retro_get_system_info( struct retro_system_info* info )
......@@ -214,6 +254,7 @@ bool retro_load_game( const struct retro_game_info* info )
return false;
}
memset( (void*)&state, 0, sizeof( state ) );
state.size = info->size;
state.data = malloc( state.size );
......@@ -225,9 +266,6 @@ bool retro_load_game( const struct retro_game_info* info )
memcpy( state.data, info->data, state.size );
memset( state.keystate, 0, sizeof( state.keystate ) );
memset( state.joystate, 0, sizeof( state.joystate ) );
state.devices[ 0 ] = RETRO_DEVICE_CURSOR_JOYSTICK;
state.devices[ 1 ] = RETRO_DEVICE_CURSOR_JOYSTICK;
......@@ -243,6 +281,9 @@ bool retro_load_game( const struct retro_game_info* info )
state.cfg.RamPack = RAMPACK16;
state.cfg.HiRes = HIRESDISABLED;
state.cfg.SoundCard = AY_TYPE_DISABLED;
state.cfg.Chroma81 = 0;
state.scaled = -1;
update_variables();
......@@ -313,7 +354,12 @@ void retro_run( void )
if ( env_cb( RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated ) && updated )
{
update_variables();
if ( update_variables() )
{
struct retro_system_av_info info;
retro_get_system_av_info( &info );
env_cb( RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info );
}
}
input_poll_cb();
......@@ -321,7 +367,7 @@ void retro_run( void )
uint16_t* fb = TVFB + WinL + WinT * TVP / 2;
eo_tick();
keybovl_update( input_state_cb, state.devices, fb, TVP / 2, state.transp, ( WinR - WinL ) == 640, state.ms, 20 );
keybovl_update( input_state_cb, state.devices, fb, TVP / 2, state.transp, state.scaled, state.ms, 20 );
video_cb( (void*)fb, WinR - WinL, WinB - WinT, TVP );
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment