mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-03 15:29:45 +00:00
Merge pull request #570 from TomHarte/TecToyEtc
Separates request for an SMS2 VDP from current graphics mode.
This commit is contained in:
commit
6cb956d1d6
@ -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]
|
!data[0x7fea] && !data[0x7feb] && !data[0x7fec] && !data[0x7fed] && !data[0x7fee] && !data[0x7fef]
|
||||||
) {
|
) {
|
||||||
target->paging_scheme = Target::PagingScheme::Codemasters;
|
target->paging_scheme = Target::PagingScheme::Codemasters;
|
||||||
|
target->model = Target::Model::MasterSystem2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,16 @@ namespace Sega {
|
|||||||
|
|
||||||
struct Target: public ::Analyser::Static::Target {
|
struct Target: public ::Analyser::Static::Target {
|
||||||
enum class Model {
|
enum class Model {
|
||||||
|
SG1000,
|
||||||
MasterSystem,
|
MasterSystem,
|
||||||
SG1000
|
MasterSystem2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Region {
|
enum class Region {
|
||||||
Japan,
|
Japan,
|
||||||
USA,
|
USA,
|
||||||
Europe
|
Europe,
|
||||||
|
Brazil
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PagingScheme {
|
enum class PagingScheme {
|
||||||
@ -35,6 +37,8 @@ struct Target: public ::Analyser::Static::Target {
|
|||||||
PagingScheme paging_scheme = PagingScheme::Sega;
|
PagingScheme paging_scheme = PagingScheme::Sega;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define is_master_system(v) v >= Analyser::Static::Sega::Target::Model::MasterSystem
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ Base::Base(Personality p) :
|
|||||||
switch(p) {
|
switch(p) {
|
||||||
case TI::TMS::TMS9918A:
|
case TI::TMS::TMS9918A:
|
||||||
case TI::TMS::SMSVDP:
|
case TI::TMS::SMSVDP:
|
||||||
|
case TI::TMS::SMS2VDP:
|
||||||
case TI::TMS::GGVDP:
|
case TI::TMS::GGVDP:
|
||||||
ram_.resize(16 * 1024);
|
ram_.resize(16 * 1024);
|
||||||
break;
|
break;
|
||||||
@ -481,17 +482,14 @@ void TMS9918::set_register(int address, uint8_t value) {
|
|||||||
|
|
||||||
write_phase_ = false;
|
write_phase_ = false;
|
||||||
if(value & 0x80) {
|
if(value & 0x80) {
|
||||||
switch(personality_) {
|
if(is_sega_vdp(personality_)) {
|
||||||
default:
|
|
||||||
value &= 0x7;
|
|
||||||
break;
|
|
||||||
case TI::TMS::SMSVDP:
|
|
||||||
if(value & 0x40) {
|
if(value & 0x40) {
|
||||||
master_system_.cram_is_selected = true;
|
master_system_.cram_is_selected = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value &= 0xf;
|
value &= 0xf;
|
||||||
break;
|
} else {
|
||||||
|
value &= 0x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a write to a register.
|
// This is a write to a register.
|
||||||
@ -523,6 +521,7 @@ void TMS9918::set_register(int address, uint8_t value) {
|
|||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
pattern_name_address_ = size_t((low_write_ & 0xf) << 10) | 0x3ff;
|
pattern_name_address_ = size_t((low_write_ & 0xf) << 10) | 0x3ff;
|
||||||
|
master_system_.pattern_name_address = pattern_name_address_ | ((personality_ == TMS::SMSVDP) ? 0x000 : 0x400);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
@ -535,10 +534,12 @@ void TMS9918::set_register(int address, uint8_t value) {
|
|||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
sprite_attribute_table_address_ = size_t((low_write_ & 0x7f) << 7) | 0x7f;
|
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;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
sprite_generator_table_address_ = size_t((low_write_ & 0x07) << 11) | 0x7ff;
|
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;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
|
@ -24,6 +24,7 @@ enum Personality {
|
|||||||
V9938,
|
V9938,
|
||||||
V9958,
|
V9958,
|
||||||
SMSVDP,
|
SMSVDP,
|
||||||
|
SMS2VDP,
|
||||||
GGVDP,
|
GGVDP,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -270,6 +271,10 @@ class Base {
|
|||||||
// Holds the vertical scroll position for this frame; this is latched
|
// Holds the vertical scroll position for this frame; this is latched
|
||||||
// once and cannot dynamically be changed until the next frame.
|
// once and cannot dynamically be changed until the next frame.
|
||||||
uint8_t latched_vertical_scroll = 0;
|
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_;
|
} master_system_;
|
||||||
|
|
||||||
void set_current_screen_mode() {
|
void set_current_screen_mode() {
|
||||||
@ -644,12 +649,12 @@ class Base {
|
|||||||
#define sprite_fetch(sprite) {\
|
#define sprite_fetch(sprite) {\
|
||||||
line_buffer.active_sprites[sprite].x = \
|
line_buffer.active_sprites[sprite].x = \
|
||||||
ram_[\
|
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); \
|
] - (master_system_.shift_sprites_8px_left ? 8 : 0); \
|
||||||
const uint8_t name = ram_[\
|
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);\
|
] & (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[0] = ram_[graphic_location]; \
|
||||||
line_buffer.active_sprites[sprite].image[1] = ram_[graphic_location+1]; \
|
line_buffer.active_sprites[sprite].image[1] = ram_[graphic_location+1]; \
|
||||||
line_buffer.active_sprites[sprite].image[2] = ram_[graphic_location+2]; \
|
line_buffer.active_sprites[sprite].image[2] = ram_[graphic_location+2]; \
|
||||||
@ -668,8 +673,8 @@ class Base {
|
|||||||
|
|
||||||
#define sprite_y_read(location, sprite) \
|
#define sprite_y_read(location, sprite) \
|
||||||
slot(location): \
|
slot(location): \
|
||||||
posit_sprite(sprite_selection_buffer, sprite, ram_[sprite_attribute_table_address & ((sprite) | 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_[sprite_attribute_table_address & ((sprite + 1) | 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) {\
|
#define fetch_tile_name(column, row_info) {\
|
||||||
const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\
|
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.
|
// Limit address bits in use if this is a SMS2 mode.
|
||||||
const bool is_tall_mode = mode_timing_.pixel_lines != 192;
|
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 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.
|
// 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.
|
// The programmer can opt out of applying vertical scrolling to the right-hand portion of the display.
|
||||||
|
@ -129,7 +129,7 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Map RAM.
|
// Map RAM.
|
||||||
if(model_ == Target::Model::MasterSystem) {
|
if(is_master_system(model_)) {
|
||||||
map(read_pointers_, ram_, 8*1024, 0xc000, 0x10000);
|
map(read_pointers_, ram_, 8*1024, 0xc000, 0x10000);
|
||||||
map(write_pointers_, ram_, 8*1024, 0xc000, 0x10000);
|
map(write_pointers_, ram_, 8*1024, 0xc000, 0x10000);
|
||||||
} else {
|
} else {
|
||||||
@ -146,7 +146,13 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setup_output(float aspect_ratio) override {
|
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(
|
vdp_->set_tv_standard(
|
||||||
(region_ == Target::Region::Europe) ?
|
(region_ == Target::Region::Europe) ?
|
||||||
TI::TMS::TVStandard::PAL : TI::TMS::TVStandard::NTSC);
|
TI::TMS::TVStandard::PAL : TI::TMS::TVStandard::NTSC);
|
||||||
@ -249,7 +255,7 @@ class ConcreteMachine:
|
|||||||
case CPU::Z80::PartialMachineCycle::Output:
|
case CPU::Z80::PartialMachineCycle::Output:
|
||||||
switch(address & 0xc1) {
|
switch(address & 0xc1) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
if(model_ == Target::Model::MasterSystem) {
|
if(is_master_system(model_)) {
|
||||||
// TODO: Obey the RAM enable.
|
// TODO: Obey the RAM enable.
|
||||||
memory_control_ = *cycle.value;
|
memory_control_ = *cycle.value;
|
||||||
page_cartridge();
|
page_cartridge();
|
||||||
@ -401,7 +407,7 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool has_bios() {
|
bool has_bios() {
|
||||||
return model_ == Target::Model::MasterSystem && region_ != Target::Region::Japan;
|
return is_master_system(model_) && region_ != Target::Region::Japan;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user