mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-18 23:23:56 +00:00
Merge pull request #520 from TomHarte/EnhancedIIe
Adds Enhanced IIe emulation.
This commit is contained in:
commit
10c930a59d
@ -19,7 +19,8 @@ struct Target: public ::Analyser::Static::Target {
|
|||||||
enum class Model {
|
enum class Model {
|
||||||
II,
|
II,
|
||||||
IIplus,
|
IIplus,
|
||||||
IIe
|
IIe,
|
||||||
|
EnhancedIIe
|
||||||
};
|
};
|
||||||
enum class DiskController {
|
enum class DiskController {
|
||||||
None,
|
None,
|
||||||
|
@ -34,7 +34,9 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <bool is_iie> class ConcreteMachine:
|
#define is_iie() ((model == Analyser::Static::AppleII::Target::Model::IIe) || (model == Analyser::Static::AppleII::Target::Model::EnhancedIIe))
|
||||||
|
|
||||||
|
template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||||
public CRTMachine::Machine,
|
public CRTMachine::Machine,
|
||||||
public MediaTarget::Machine,
|
public MediaTarget::Machine,
|
||||||
public KeyboardMachine::Machine,
|
public KeyboardMachine::Machine,
|
||||||
@ -62,7 +64,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
|
|
||||||
CPU::MOS6502::Processor<ConcreteMachine, false> m6502_;
|
CPU::MOS6502::Processor<ConcreteMachine, false> m6502_;
|
||||||
VideoBusHandler video_bus_handler_;
|
VideoBusHandler video_bus_handler_;
|
||||||
std::unique_ptr<AppleII::Video::Video<VideoBusHandler, is_iie>> video_;
|
std::unique_ptr<AppleII::Video::Video<VideoBusHandler, is_iie()>> video_;
|
||||||
int cycles_into_current_line_ = 0;
|
int cycles_into_current_line_ = 0;
|
||||||
Cycles cycles_since_video_update_;
|
Cycles cycles_since_video_update_;
|
||||||
|
|
||||||
@ -179,7 +181,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
bool has_language_card_ = true;
|
bool has_language_card_ = true;
|
||||||
void set_language_card_paging() {
|
void set_language_card_paging() {
|
||||||
uint8_t *const ram = alternative_zero_page_ ? aux_ram_ : ram_;
|
uint8_t *const ram = alternative_zero_page_ ? aux_ram_ : ram_;
|
||||||
uint8_t *const rom = is_iie ? &rom_[3840] : rom_.data();
|
uint8_t *const rom = is_iie() ? &rom_[3840] : rom_.data();
|
||||||
|
|
||||||
page(0xd0, 0xe0,
|
page(0xd0, 0xe0,
|
||||||
language_card_.read ? &ram[language_card_.bank1 ? 0xd000 : 0xc000] : rom,
|
language_card_.read ? &ram[language_card_.bank1 ? 0xd000 : 0xc000] : rom,
|
||||||
@ -298,7 +300,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ConcreteMachine(const Analyser::Static::AppleII::Target &target, const ROMMachine::ROMFetcher &rom_fetcher):
|
ConcreteMachine(const Analyser::Static::AppleII::Target &target, const ROMMachine::ROMFetcher &rom_fetcher):
|
||||||
m6502_(CPU::MOS6502::Personality::P6502, *this),
|
m6502_((model == Analyser::Static::AppleII::Target::Model::EnhancedIIe) ? CPU::MOS6502::Personality::P65C02 : CPU::MOS6502::Personality::P6502, *this),
|
||||||
video_bus_handler_(ram_, aux_ram_),
|
video_bus_handler_(ram_, aux_ram_),
|
||||||
audio_toggle_(audio_queue_),
|
audio_toggle_(audio_queue_),
|
||||||
speaker_(audio_toggle_) {
|
speaker_(audio_toggle_) {
|
||||||
@ -345,6 +347,11 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
rom_names.push_back("apple2eu-character.rom");
|
rom_names.push_back("apple2eu-character.rom");
|
||||||
rom_names.push_back("apple2eu.rom");
|
rom_names.push_back("apple2eu.rom");
|
||||||
break;
|
break;
|
||||||
|
case Target::Model::EnhancedIIe:
|
||||||
|
rom_size += 3840;
|
||||||
|
rom_names.push_back("apple2e-character.rom");
|
||||||
|
rom_names.push_back("apple2e.rom");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
const auto roms = rom_fetcher("AppleII", rom_names);
|
const auto roms = rom_fetcher("AppleII", rom_names);
|
||||||
|
|
||||||
@ -383,7 +390,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setup_output(float aspect_ratio) override {
|
void setup_output(float aspect_ratio) override {
|
||||||
video_.reset(new AppleII::Video::Video<VideoBusHandler, is_iie>(video_bus_handler_));
|
video_.reset(new AppleII::Video::Video<VideoBusHandler, is_iie()>(video_bus_handler_));
|
||||||
video_->set_character_rom(character_rom_);
|
video_->set_character_rom(character_rom_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +429,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
if(isReadOperation(operation)) *value = read_pages_[address >> 8][address & 0xff];
|
if(isReadOperation(operation)) *value = read_pages_[address >> 8][address & 0xff];
|
||||||
else if(write_pages_[address >> 8]) write_pages_[address >> 8][address & 0xff] = *value;
|
else if(write_pages_[address >> 8]) write_pages_[address >> 8][address & 0xff] = *value;
|
||||||
|
|
||||||
if(is_iie && address >= 0xc300 && address < 0xd000) {
|
if(is_iie() && address >= 0xc300 && address < 0xd000) {
|
||||||
bool internal_c8_rom = internal_c8_rom_;
|
bool internal_c8_rom = internal_c8_rom_;
|
||||||
internal_c8_rom |= ((address >> 8) == 0xc3) && !slot_C3_rom_;
|
internal_c8_rom |= ((address >> 8) == 0xc3) && !slot_C3_rom_;
|
||||||
internal_c8_rom &= (address != 0xcfff);
|
internal_c8_rom &= (address != 0xcfff);
|
||||||
@ -468,7 +475,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
*value &= 0x7f;
|
*value &= 0x7f;
|
||||||
if(
|
if(
|
||||||
static_cast<Joystick *>(joysticks_[0].get())->buttons[0] || static_cast<Joystick *>(joysticks_[1].get())->buttons[2] ||
|
static_cast<Joystick *>(joysticks_[0].get())->buttons[0] || static_cast<Joystick *>(joysticks_[1].get())->buttons[2] ||
|
||||||
(is_iie && open_apple_is_pressed_)
|
(is_iie() && open_apple_is_pressed_)
|
||||||
)
|
)
|
||||||
*value |= 0x80;
|
*value |= 0x80;
|
||||||
break;
|
break;
|
||||||
@ -476,7 +483,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
*value &= 0x7f;
|
*value &= 0x7f;
|
||||||
if(
|
if(
|
||||||
static_cast<Joystick *>(joysticks_[0].get())->buttons[1] || static_cast<Joystick *>(joysticks_[1].get())->buttons[1] ||
|
static_cast<Joystick *>(joysticks_[0].get())->buttons[1] || static_cast<Joystick *>(joysticks_[1].get())->buttons[1] ||
|
||||||
(is_iie && closed_apple_is_pressed_)
|
(is_iie() && closed_apple_is_pressed_)
|
||||||
)
|
)
|
||||||
*value |= 0x80;
|
*value |= 0x80;
|
||||||
break;
|
break;
|
||||||
@ -498,26 +505,26 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
// The IIe-only state reads follow...
|
// The IIe-only state reads follow...
|
||||||
case 0xc011: if(is_iie) *value = (*value & 0x7f) | (language_card_.bank1 ? 0x80 : 0x00); break;
|
case 0xc011: if(is_iie()) *value = (*value & 0x7f) | (language_card_.bank1 ? 0x80 : 0x00); break;
|
||||||
case 0xc012: if(is_iie) *value = (*value & 0x7f) | (language_card_.read ? 0x80 : 0x00); break;
|
case 0xc012: if(is_iie()) *value = (*value & 0x7f) | (language_card_.read ? 0x80 : 0x00); break;
|
||||||
case 0xc013: if(is_iie) *value = (*value & 0x7f) | (read_auxiliary_memory_ ? 0x80 : 0x00); break;
|
case 0xc013: if(is_iie()) *value = (*value & 0x7f) | (read_auxiliary_memory_ ? 0x80 : 0x00); break;
|
||||||
case 0xc014: if(is_iie) *value = (*value & 0x7f) | (write_auxiliary_memory_ ? 0x80 : 0x00); break;
|
case 0xc014: if(is_iie()) *value = (*value & 0x7f) | (write_auxiliary_memory_ ? 0x80 : 0x00); break;
|
||||||
case 0xc015: if(is_iie) *value = (*value & 0x7f) | (internal_CX_rom_ ? 0x80 : 0x00); break;
|
case 0xc015: if(is_iie()) *value = (*value & 0x7f) | (internal_CX_rom_ ? 0x80 : 0x00); break;
|
||||||
case 0xc016: if(is_iie) *value = (*value & 0x7f) | (alternative_zero_page_ ? 0x80 : 0x00); break;
|
case 0xc016: if(is_iie()) *value = (*value & 0x7f) | (alternative_zero_page_ ? 0x80 : 0x00); break;
|
||||||
case 0xc017: if(is_iie) *value = (*value & 0x7f) | (slot_C3_rom_ ? 0x80 : 0x00); break;
|
case 0xc017: if(is_iie()) *value = (*value & 0x7f) | (slot_C3_rom_ ? 0x80 : 0x00); break;
|
||||||
case 0xc018: if(is_iie) *value = (*value & 0x7f) | (video_->get_80_store() ? 0x80 : 0x00); break;
|
case 0xc018: if(is_iie()) *value = (*value & 0x7f) | (video_->get_80_store() ? 0x80 : 0x00); break;
|
||||||
case 0xc019: if(is_iie) *value = (*value & 0x7f) | (video_->get_is_vertical_blank(cycles_since_video_update_) ? 0x00 : 0x80); break;
|
case 0xc019: if(is_iie()) *value = (*value & 0x7f) | (video_->get_is_vertical_blank(cycles_since_video_update_) ? 0x00 : 0x80); break;
|
||||||
case 0xc01a: if(is_iie) *value = (*value & 0x7f) | (video_->get_text() ? 0x80 : 0x00); break;
|
case 0xc01a: if(is_iie()) *value = (*value & 0x7f) | (video_->get_text() ? 0x80 : 0x00); break;
|
||||||
case 0xc01b: if(is_iie) *value = (*value & 0x7f) | (video_->get_mixed() ? 0x80 : 0x00); break;
|
case 0xc01b: if(is_iie()) *value = (*value & 0x7f) | (video_->get_mixed() ? 0x80 : 0x00); break;
|
||||||
case 0xc01c: if(is_iie) *value = (*value & 0x7f) | (video_->get_page2() ? 0x80 : 0x00); break;
|
case 0xc01c: if(is_iie()) *value = (*value & 0x7f) | (video_->get_page2() ? 0x80 : 0x00); break;
|
||||||
case 0xc01d: if(is_iie) *value = (*value & 0x7f) | (video_->get_high_resolution() ? 0x80 : 0x00); break;
|
case 0xc01d: if(is_iie()) *value = (*value & 0x7f) | (video_->get_high_resolution() ? 0x80 : 0x00); break;
|
||||||
case 0xc01e: if(is_iie) *value = (*value & 0x7f) | (video_->get_alternative_character_set() ? 0x80 : 0x00); break;
|
case 0xc01e: if(is_iie()) *value = (*value & 0x7f) | (video_->get_alternative_character_set() ? 0x80 : 0x00); break;
|
||||||
case 0xc01f: if(is_iie) *value = (*value & 0x7f) | (video_->get_80_columns() ? 0x80 : 0x00); break;
|
case 0xc01f: if(is_iie()) *value = (*value & 0x7f) | (video_->get_80_columns() ? 0x80 : 0x00); break;
|
||||||
case 0xc07f: if(is_iie) *value = (*value & 0x7f) | (video_->get_double_high_resolution() ? 0x80 : 0x00); break;
|
case 0xc07f: if(is_iie()) *value = (*value & 0x7f) | (video_->get_double_high_resolution() ? 0x80 : 0x00); break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Write-only switches. All IIe as currently implemented.
|
// Write-only switches. All IIe as currently implemented.
|
||||||
if(is_iie) {
|
if(is_iie()) {
|
||||||
switch(address) {
|
switch(address) {
|
||||||
default: printf("Write %04x?\n", address); break;
|
default: printf("Write %04x?\n", address); break;
|
||||||
|
|
||||||
@ -612,7 +619,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
|
|
||||||
case 0xc05e:
|
case 0xc05e:
|
||||||
case 0xc05f:
|
case 0xc05f:
|
||||||
if(is_iie) {
|
if(is_iie()) {
|
||||||
update_video();
|
update_video();
|
||||||
video_->set_double_high_resolution(!(address&1));
|
video_->set_double_high_resolution(!(address&1));
|
||||||
}
|
}
|
||||||
@ -626,7 +633,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On the IIe, reading C010 returns additional key info.
|
// On the IIe, reading C010 returns additional key info.
|
||||||
if(is_iie && isReadOperation(operation)) {
|
if(is_iie() && isReadOperation(operation)) {
|
||||||
*value = (key_is_down_ ? 0x80 : 0x00) | (keyboard_input_ & 0x7f);
|
*value = (key_is_down_ ? 0x80 : 0x00) | (keyboard_input_ & 0x7f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -769,7 +776,7 @@ template <bool is_iie> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prior to the IIe, the keyboard could produce uppercase only.
|
// Prior to the IIe, the keyboard could produce uppercase only.
|
||||||
if(!is_iie) value = static_cast<char>(toupper(value));
|
if(!is_iie()) value = static_cast<char>(toupper(value));
|
||||||
|
|
||||||
if(is_pressed) {
|
if(is_pressed) {
|
||||||
keyboard_input_ = static_cast<uint8_t>(value | 0x80);
|
keyboard_input_ = static_cast<uint8_t>(value | 0x80);
|
||||||
@ -818,10 +825,12 @@ using namespace AppleII;
|
|||||||
Machine *Machine::AppleII(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
Machine *Machine::AppleII(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
||||||
using Target = Analyser::Static::AppleII::Target;
|
using Target = Analyser::Static::AppleII::Target;
|
||||||
const Target *const appleii_target = dynamic_cast<const Target *>(target);
|
const Target *const appleii_target = dynamic_cast<const Target *>(target);
|
||||||
if(appleii_target->model == Target::Model::IIe) {
|
switch(appleii_target->model) {
|
||||||
return new ConcreteMachine<true>(*appleii_target, rom_fetcher);
|
default: return nullptr;
|
||||||
} else {
|
case Target::Model::II: return new ConcreteMachine<Target::Model::II>(*appleii_target, rom_fetcher);
|
||||||
return new ConcreteMachine<false>(*appleii_target, rom_fetcher);
|
case Target::Model::IIplus: return new ConcreteMachine<Target::Model::IIplus>(*appleii_target, rom_fetcher);
|
||||||
|
case Target::Model::IIe: return new ConcreteMachine<Target::Model::IIe>(*appleii_target, rom_fetcher);
|
||||||
|
case Target::Model::EnhancedIIe: return new ConcreteMachine<Target::Model::EnhancedIIe>(*appleii_target, rom_fetcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,18 +262,20 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
|||||||
case GraphicsMode::Text: {
|
case GraphicsMode::Text: {
|
||||||
const uint8_t inverses[] = {
|
const uint8_t inverses[] = {
|
||||||
0xff,
|
0xff,
|
||||||
alternative_character_set_ ? static_cast<uint8_t>(0xff) : static_cast<uint8_t>((flash_ / flash_length) * 0xff),
|
static_cast<uint8_t>((flash_ / flash_length) * 0xff),
|
||||||
0x00,
|
0x00,
|
||||||
0x00
|
0x00
|
||||||
};
|
};
|
||||||
const uint8_t masks[] = {
|
|
||||||
alternative_character_set_ ? static_cast<uint8_t>(0x7f) : static_cast<uint8_t>(0x3f),
|
|
||||||
is_iie ? 0x7f : 0x3f,
|
|
||||||
};
|
|
||||||
for(int c = column_; c < pixel_end; ++c) {
|
for(int c = column_; c < pixel_end; ++c) {
|
||||||
const uint8_t character = bus_handler_.perform_read(static_cast<uint16_t>(text_address + c));
|
int character = bus_handler_.perform_read(static_cast<uint16_t>(text_address + c));
|
||||||
const uint8_t xor_mask = inverses[character >> 6];
|
if(is_iie) {
|
||||||
const std::size_t character_address = static_cast<std::size_t>(((character & masks[character >> 7]) << 3) + pixel_row);
|
character |= alternative_character_set_ ? 0x100 : 0;
|
||||||
|
} else {
|
||||||
|
character &= 0x3f;
|
||||||
|
|
||||||
|
}
|
||||||
|
const uint8_t xor_mask = is_iie ? 0xff : inverses[character >> 6];
|
||||||
|
const std::size_t character_address = static_cast<std::size_t>((character << 3) + pixel_row);
|
||||||
const uint8_t character_pattern = character_rom_[character_address] ^ xor_mask;
|
const uint8_t character_pattern = character_rom_[character_address] ^ xor_mask;
|
||||||
|
|
||||||
// The character ROM is output MSB to LSB rather than LSB to MSB.
|
// The character ROM is output MSB to LSB rather than LSB to MSB.
|
||||||
@ -290,26 +292,21 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case GraphicsMode::DoubleText: {
|
case GraphicsMode::DoubleText: {
|
||||||
const uint8_t inverses[] = {
|
|
||||||
0xff,
|
|
||||||
alternative_character_set_ ? static_cast<uint8_t>(0xff) : static_cast<uint8_t>((flash_ / flash_length) * 0xff),
|
|
||||||
0x00,
|
|
||||||
0x00
|
|
||||||
};
|
|
||||||
const uint8_t masks[] = {
|
|
||||||
alternative_character_set_ ? static_cast<uint8_t>(0x7f) : static_cast<uint8_t>(0x3f),
|
|
||||||
is_iie ? 0x7f : 0x3f,
|
|
||||||
};
|
|
||||||
for(int c = column_; c < pixel_end; ++c) {
|
for(int c = column_; c < pixel_end; ++c) {
|
||||||
const uint16_t characters = bus_handler_.perform_aux_read(static_cast<uint16_t>(text_address + c));
|
const uint16_t characters = bus_handler_.perform_aux_read(static_cast<uint16_t>(text_address + c));
|
||||||
const std::size_t character_addresses[2] = {
|
const std::size_t character_addresses[2] = {
|
||||||
static_cast<std::size_t>((((characters >> 8) & masks[characters >> 15]) << 3) + pixel_row),
|
static_cast<std::size_t>(
|
||||||
static_cast<std::size_t>(((characters & masks[(characters >> 7)&1]) << 3) + pixel_row),
|
(((characters >> 8)) << 3) + pixel_row
|
||||||
|
),
|
||||||
|
static_cast<std::size_t>(
|
||||||
|
(characters << 3) + pixel_row
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const size_t pattern_offset = alternative_character_set_ ? (256*8) : 0;
|
||||||
const uint8_t character_patterns[2] = {
|
const uint8_t character_patterns[2] = {
|
||||||
static_cast<uint8_t>(character_rom_[character_addresses[0]] ^ inverses[(characters >> 14) & 3]),
|
character_rom_[character_addresses[0] + pattern_offset],
|
||||||
static_cast<uint8_t>(character_rom_[character_addresses[1]] ^ inverses[(characters >> 6) & 3]),
|
character_rom_[character_addresses[1] + pattern_offset],
|
||||||
};
|
};
|
||||||
|
|
||||||
// The character ROM is output MSB to LSB rather than LSB to MSB.
|
// The character ROM is output MSB to LSB rather than LSB to MSB.
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
typedef NS_ENUM(NSInteger, CSMachineAppleIIModel) {
|
typedef NS_ENUM(NSInteger, CSMachineAppleIIModel) {
|
||||||
CSMachineAppleIIModelAppleII,
|
CSMachineAppleIIModelAppleII,
|
||||||
CSMachineAppleIIModelAppleIIPlus,
|
CSMachineAppleIIModelAppleIIPlus,
|
||||||
CSMachineAppleIIModelAppleIIe
|
CSMachineAppleIIModelAppleIIe,
|
||||||
|
CSMachineAppleIIModelAppleEnhancedIIe
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, CSMachineAppleIIDiskController) {
|
typedef NS_ENUM(NSInteger, CSMachineAppleIIDiskController) {
|
||||||
|
@ -172,6 +172,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
|||||||
default: target->model = Target::Model::II; break;
|
default: target->model = Target::Model::II; break;
|
||||||
case CSMachineAppleIIModelAppleIIPlus: target->model = Target::Model::IIplus; break;
|
case CSMachineAppleIIModelAppleIIPlus: target->model = Target::Model::IIplus; break;
|
||||||
case CSMachineAppleIIModelAppleIIe: target->model = Target::Model::IIe; break;
|
case CSMachineAppleIIModelAppleIIe: target->model = Target::Model::IIe; break;
|
||||||
|
case CSMachineAppleIIModelAppleEnhancedIIe: target->model = Target::Model::EnhancedIIe; break;
|
||||||
}
|
}
|
||||||
switch(diskController) {
|
switch(diskController) {
|
||||||
default:
|
default:
|
||||||
|
@ -84,7 +84,7 @@ Gw
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jli-ac-Sij">
|
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jli-ac-Sij">
|
||||||
<rect key="frame" x="65" y="67" width="91" height="26"/>
|
<rect key="frame" x="65" y="67" width="115" height="26"/>
|
||||||
<popUpButtonCell key="cell" type="push" title="Apple II" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="VBQ-JG-AeM" id="U6V-us-O2F">
|
<popUpButtonCell key="cell" type="push" title="Apple II" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="VBQ-JG-AeM" id="U6V-us-O2F">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="menu"/>
|
<font key="font" metaFont="menu"/>
|
||||||
@ -93,6 +93,7 @@ Gw
|
|||||||
<menuItem title="Apple II" state="on" id="VBQ-JG-AeM"/>
|
<menuItem title="Apple II" state="on" id="VBQ-JG-AeM"/>
|
||||||
<menuItem title="Apple II+" tag="1" id="Yme-Wn-Obh"/>
|
<menuItem title="Apple II+" tag="1" id="Yme-Wn-Obh"/>
|
||||||
<menuItem title="Apple IIe" tag="2" id="AMt-WU-a0H"/>
|
<menuItem title="Apple IIe" tag="2" id="AMt-WU-a0H"/>
|
||||||
|
<menuItem title="Enhanced IIe" tag="3" id="kUz-FG-lqW"/>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</popUpButtonCell>
|
</popUpButtonCell>
|
||||||
|
@ -131,6 +131,7 @@ class MachinePicker: NSObject {
|
|||||||
switch appleIIModelButton!.selectedTag() {
|
switch appleIIModelButton!.selectedTag() {
|
||||||
case 1: model = .appleIIPlus
|
case 1: model = .appleIIPlus
|
||||||
case 2: model = .appleIIe
|
case 2: model = .appleIIe
|
||||||
|
case 3: model = .appleEnhancedIIe
|
||||||
case 0: fallthrough
|
case 0: fallthrough
|
||||||
default: model = .appleII
|
default: model = .appleII
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,6 @@ apple2eu.rom — as per apple2e.rom, but for the Unenhanced Apple II.
|
|||||||
|
|
||||||
apple2-character.rom — a 2kb image of the Apple IIe's character ROM.
|
apple2-character.rom — a 2kb image of the Apple IIe's character ROM.
|
||||||
apple2eu-character.rom — a 4kb image of the Unenhanced IIe's character ROM.
|
apple2eu-character.rom — a 4kb image of the Unenhanced IIe's character ROM.
|
||||||
|
apple2e-character.rom — a 4kb image of the Enhanced IIe's character ROM.
|
||||||
|
|
||||||
Apologies for the wackiness around "at least xkb big", it's to allow for use of files such as those on ftp.apple.asimov.net, which tend to be a bunch of other things, then the system ROM.
|
Apologies for the wackiness around "at least xkb big", it's to allow for use of files such as those on ftp.apple.asimov.net, which tend to be a bunch of other things, then the system ROM.
|
Loading…
Reference in New Issue
Block a user