1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-06 15:00:05 +00:00

Merge pull request #570 from TomHarte/TecToyEtc

Separates request for an SMS2 VDP from current graphics mode.
This commit is contained in:
Thomas Harte 2018-10-23 22:20:11 -04:00 committed by GitHub
commit 6cb956d1d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 20 deletions

View File

@ -71,6 +71,7 @@ Analyser::Static::TargetList Analyser::Static::Sega::GetTargets(const Media &med
!data[0x7fea] && !data[0x7feb] && !data[0x7fec] && !data[0x7fed] && !data[0x7fee] && !data[0x7fef]
) {
target->paging_scheme = Target::PagingScheme::Codemasters;
target->model = Target::Model::MasterSystem2;
}
}
}

View File

@ -15,14 +15,16 @@ namespace Sega {
struct Target: public ::Analyser::Static::Target {
enum class Model {
SG1000,
MasterSystem,
SG1000
MasterSystem2,
};
enum class Region {
Japan,
USA,
Europe
Europe,
Brazil
};
enum class PagingScheme {
@ -35,6 +37,8 @@ struct Target: public ::Analyser::Static::Target {
PagingScheme paging_scheme = PagingScheme::Sega;
};
#define is_master_system(v) v >= Analyser::Static::Sega::Target::Model::MasterSystem
}
}
}

View File

@ -54,6 +54,7 @@ Base::Base(Personality p) :
switch(p) {
case TI::TMS::TMS9918A:
case TI::TMS::SMSVDP:
case TI::TMS::SMS2VDP:
case TI::TMS::GGVDP:
ram_.resize(16 * 1024);
break;
@ -481,17 +482,14 @@ void TMS9918::set_register(int address, uint8_t value) {
write_phase_ = false;
if(value & 0x80) {
switch(personality_) {
default:
value &= 0x7;
break;
case TI::TMS::SMSVDP:
if(is_sega_vdp(personality_)) {
if(value & 0x40) {
master_system_.cram_is_selected = true;
return;
}
value &= 0xf;
break;
} else {
value &= 0x7;
}
// This is a write to a register.
@ -523,6 +521,7 @@ void TMS9918::set_register(int address, uint8_t value) {
case 2:
pattern_name_address_ = size_t((low_write_ & 0xf) << 10) | 0x3ff;
master_system_.pattern_name_address = pattern_name_address_ | ((personality_ == TMS::SMSVDP) ? 0x000 : 0x400);
break;
case 3:
@ -535,10 +534,12 @@ void TMS9918::set_register(int address, uint8_t value) {
case 5:
sprite_attribute_table_address_ = size_t((low_write_ & 0x7f) << 7) | 0x7f;
master_system_.sprite_attribute_table_address = sprite_attribute_table_address_ | ((personality_ == TMS::SMSVDP) ? 0x00 : 0x80);
break;
case 6:
sprite_generator_table_address_ = size_t((low_write_ & 0x07) << 11) | 0x7ff;
master_system_.sprite_generator_table_address = sprite_generator_table_address_ | ((personality_ == TMS::SMSVDP) ? 0x0000 : 0x1800);
break;
case 7:

View File

@ -24,6 +24,7 @@ enum Personality {
V9938,
V9958,
SMSVDP,
SMS2VDP,
GGVDP,
};
@ -270,6 +271,10 @@ class Base {
// Holds the vertical scroll position for this frame; this is latched
// once and cannot dynamically be changed until the next frame.
uint8_t latched_vertical_scroll = 0;
size_t pattern_name_address;
size_t sprite_attribute_table_address;
size_t sprite_generator_table_address;
} master_system_;
void set_current_screen_mode() {
@ -644,12 +649,12 @@ class Base {
#define sprite_fetch(sprite) {\
line_buffer.active_sprites[sprite].x = \
ram_[\
sprite_attribute_table_address & size_t(0x3f80 | (line_buffer.active_sprites[sprite].index << 1))\
master_system_.sprite_attribute_table_address & size_t(0x3f80 | (line_buffer.active_sprites[sprite].index << 1))\
] - (master_system_.shift_sprites_8px_left ? 8 : 0); \
const uint8_t name = ram_[\
sprite_attribute_table_address & size_t(0x3f81 | (line_buffer.active_sprites[sprite].index << 1))\
master_system_.sprite_attribute_table_address & size_t(0x3f81 | (line_buffer.active_sprites[sprite].index << 1))\
] & (sprites_16x16_ ? ~1 : ~0);\
const size_t graphic_location = sprite_generator_table_address & size_t(0x2000 | (name << 5) | (line_buffer.active_sprites[sprite].row << 2)); \
const size_t graphic_location = master_system_.sprite_generator_table_address & size_t(0x2000 | (name << 5) | (line_buffer.active_sprites[sprite].row << 2)); \
line_buffer.active_sprites[sprite].image[0] = ram_[graphic_location]; \
line_buffer.active_sprites[sprite].image[1] = ram_[graphic_location+1]; \
line_buffer.active_sprites[sprite].image[2] = ram_[graphic_location+2]; \
@ -668,8 +673,8 @@ class Base {
#define sprite_y_read(location, sprite) \
slot(location): \
posit_sprite(sprite_selection_buffer, sprite, ram_[sprite_attribute_table_address & ((sprite) | 0x3f00)], write_pointer_.row); \
posit_sprite(sprite_selection_buffer, sprite+1, ram_[sprite_attribute_table_address & ((sprite + 1) | 0x3f00)], write_pointer_.row); \
posit_sprite(sprite_selection_buffer, sprite, ram_[master_system_.sprite_attribute_table_address & ((sprite) | 0x3f00)], write_pointer_.row); \
posit_sprite(sprite_selection_buffer, sprite+1, ram_[master_system_.sprite_attribute_table_address & ((sprite + 1) | 0x3f00)], write_pointer_.row); \
#define fetch_tile_name(column, row_info) {\
const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\
@ -717,10 +722,8 @@ class Base {
// Limit address bits in use if this is a SMS2 mode.
const bool is_tall_mode = mode_timing_.pixel_lines != 192;
const size_t pattern_name_address = pattern_name_address_ | (is_tall_mode ? 0xc00 : 0);
const size_t pattern_name_address = master_system_.pattern_name_address | (is_tall_mode ? 0x800 : 0);
const size_t pattern_name_offset = is_tall_mode ? 0x100 : 0;
const size_t sprite_attribute_table_address = sprite_attribute_table_address_ | (is_tall_mode ? 0x80 : 0);
const size_t sprite_generator_table_address = sprite_generator_table_address_ | (is_tall_mode ? 0x1800 : 0);
// Determine row info for the screen both (i) if vertical scrolling is applied; and (ii) if it isn't.
// The programmer can opt out of applying vertical scrolling to the right-hand portion of the display.

View File

@ -129,7 +129,7 @@ class ConcreteMachine:
}
// Map RAM.
if(model_ == Target::Model::MasterSystem) {
if(is_master_system(model_)) {
map(read_pointers_, ram_, 8*1024, 0xc000, 0x10000);
map(write_pointers_, ram_, 8*1024, 0xc000, 0x10000);
} else {
@ -146,7 +146,13 @@ class ConcreteMachine:
}
void setup_output(float aspect_ratio) override {
vdp_.reset(new TI::TMS::TMS9918(model_ == Target::Model::SG1000 ? TI::TMS::TMS9918A : TI::TMS::SMSVDP));
TI::TMS::Personality personality = TI::TMS::TMS9918A;
switch(model_) {
case Target::Model::SG1000: personality = TI::TMS::TMS9918A; break;
case Target::Model::MasterSystem: personality = TI::TMS::SMSVDP; break;
case Target::Model::MasterSystem2: personality = TI::TMS::SMS2VDP; break;
}
vdp_.reset(new TI::TMS::TMS9918(personality));
vdp_->set_tv_standard(
(region_ == Target::Region::Europe) ?
TI::TMS::TVStandard::PAL : TI::TMS::TVStandard::NTSC);
@ -249,7 +255,7 @@ class ConcreteMachine:
case CPU::Z80::PartialMachineCycle::Output:
switch(address & 0xc1) {
case 0x00:
if(model_ == Target::Model::MasterSystem) {
if(is_master_system(model_)) {
// TODO: Obey the RAM enable.
memory_control_ = *cycle.value;
page_cartridge();
@ -401,7 +407,7 @@ class ConcreteMachine:
}
}
bool has_bios() {
return model_ == Target::Model::MasterSystem && region_ != Target::Region::Japan;
return is_master_system(model_) && region_ != Target::Region::Japan;
}
};