1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-28 09:29:07 +00:00

Implemented keyboard input and ensured that the signal generated is marked as composite, putting the colour-suppression ball into the CRT's court.

This commit is contained in:
Thomas Harte 2017-06-06 09:25:18 -04:00
parent ebbf6e6133
commit cc4cb45e9d
3 changed files with 103 additions and 11 deletions

View File

@ -16,7 +16,8 @@ Machine::Machine() :
vsync_(false), vsync_(false),
hsync_(false), hsync_(false),
ram_(1024), ram_(1024),
line_data_(nullptr) { line_data_(nullptr),
key_states_{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} {
// run at 3.25 Mhz // run at 3.25 Mhz
set_clock_rate(3250000); set_clock_rate(3250000);
Memory::Fuzz(ram_); Memory::Fuzz(ram_);
@ -34,13 +35,20 @@ int Machine::perform_machine_cycle(const CPU::Z80::MachineCycle &cycle) {
} }
break; break;
case CPU::Z80::BusOperation::Input: case CPU::Z80::BusOperation::Input: {
uint8_t value = 0xff;
if((address&7) == 6) { if((address&7) == 6) {
set_vsync(true); set_vsync(true);
line_counter_ = 0; line_counter_ = 0;
uint16_t mask = 0x100;
for(int c = 0; c < 8; c++) {
if(!(address & mask)) value &= key_states_[c];
mask <<= 1;
}
} }
*cycle.value = 0xff; *cycle.value = value;
break; } break;
case CPU::Z80::BusOperation::Interrupt: case CPU::Z80::BusOperation::Interrupt:
set_hsync(true); set_hsync(true);
@ -189,9 +197,22 @@ void Machine::output_byte(uint8_t byte) {
void Machine::setup_output(float aspect_ratio) { void Machine::setup_output(float aspect_ratio) {
crt_.reset(new Outputs::CRT::CRT(210 * 2, 1, Outputs::CRT::DisplayType::PAL50, 1)); crt_.reset(new Outputs::CRT::CRT(210 * 2, 1, Outputs::CRT::DisplayType::PAL50, 1));
crt_->set_rgb_sampling_function( crt_->set_composite_sampling_function(
"vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" "float composite_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate, float phase, float amplitude)"
"{" "{"
"return vec3(float(texture(texID, coordinate).r) / 255.0);" "return float(texture(texID, coordinate).r) / 255.0;"
"}"); "}");
} }
#pragma mark - Keyboard
void Machine::set_key_state(uint16_t key, bool isPressed) {
if(isPressed)
key_states_[key >> 8] &= (uint8_t)(~key);
else
key_states_[key >> 8] |= (uint8_t)key;
}
void Machine::clear_all_keys() {
memset(key_states_, 0xff, 8);
}

View File

@ -23,6 +23,17 @@ enum ROMType: uint8_t {
ZX80, ZX81 ZX80, ZX81
}; };
enum Key: uint16_t {
KeyShift = 0x0000 | 0x01, KeyZ = 0x0000 | 0x02, KeyX = 0x0000 | 0x04, KeyC = 0x0000 | 0x08, KeyV = 0x0000 | 0x10,
KeyA = 0x0100 | 0x01, KeyS = 0x0100 | 0x02, KeyD = 0x0100 | 0x04, KeyF = 0x0100 | 0x08, KeyG = 0x0100 | 0x10,
KeyQ = 0x0200 | 0x01, KeyW = 0x0200 | 0x02, KeyE = 0x0200 | 0x04, KeyR = 0x0200 | 0x08, KeyT = 0x0200 | 0x10,
Key1 = 0x0300 | 0x01, Key2 = 0x0300 | 0x02, Key3 = 0x0300 | 0x04, Key4 = 0x0300 | 0x08, Key5 = 0x0300 | 0x10,
Key0 = 0x0400 | 0x01, Key9 = 0x0400 | 0x02, Key8 = 0x0400 | 0x04, Key7 = 0x0400 | 0x08, Key6 = 0x0400 | 0x10,
KeyP = 0x0500 | 0x01, KeyO = 0x0500 | 0x02, KeyI = 0x0500 | 0x04, KeyU = 0x0500 | 0x08, KeyY = 0x0500 | 0x10,
KeyEnter = 0x0600 | 0x01, KeyL = 0x0600 | 0x02, KeyK = 0x0600 | 0x04, KeyJ = 0x0600 | 0x08, KeyH = 0x0600 | 0x10,
KeySpace = 0x0700 | 0x01, KeyDot = 0x0700 | 0x02, KeyM = 0x0700 | 0x04, KeyN = 0x0700 | 0x08, KeyB = 0x0700 | 0x10,
};
class Machine: class Machine:
public CPU::Z80::Processor<Machine>, public CPU::Z80::Processor<Machine>,
public CRTMachine::Machine, public CRTMachine::Machine,
@ -44,6 +55,8 @@ class Machine:
void configure_as_target(const StaticAnalyser::Target &target); void configure_as_target(const StaticAnalyser::Target &target);
void set_rom(ROMType type, std::vector<uint8_t> data); void set_rom(ROMType type, std::vector<uint8_t> data);
void set_key_state(uint16_t key, bool isPressed);
void clear_all_keys();
private: private:
std::shared_ptr<Outputs::CRT::CRT> crt_; std::shared_ptr<Outputs::CRT::CRT> crt_;
@ -55,6 +68,8 @@ class Machine:
uint8_t *line_data_, *line_data_pointer_; uint8_t *line_data_, *line_data_pointer_;
int line_counter_; int line_counter_;
uint8_t key_states_[8];
unsigned int cycles_since_display_update_; unsigned int cycles_since_display_update_;
void update_display(); void update_display();
void set_vsync(bool sync); void set_vsync(bool sync);

View File

@ -15,18 +15,18 @@
#import "NSBundle+DataResource.h" #import "NSBundle+DataResource.h"
@implementation CSZX8081 { @implementation CSZX8081 {
ZX8081::Machine zx8081; ZX8081::Machine _zx8081;
} }
- (CRTMachine::Machine * const)machine { - (CRTMachine::Machine * const)machine {
return &zx8081; return &_zx8081;
} }
- (instancetype)init { - (instancetype)init {
self = [super init]; self = [super init];
if(self) { if(self) {
zx8081.set_rom(ZX8081::ROMType::ZX80, [self rom:@"zx80"].stdVector8); _zx8081.set_rom(ZX8081::ROMType::ZX80, [self rom:@"zx80"].stdVector8);
zx8081.set_rom(ZX8081::ROMType::ZX81, [self rom:@"zx81"].stdVector8); _zx8081.set_rom(ZX8081::ROMType::ZX81, [self rom:@"zx81"].stdVector8);
} }
return self; return self;
} }
@ -38,9 +38,65 @@
#pragma mark - Keyboard Mapping #pragma mark - Keyboard Mapping
- (void)clearAllKeys { - (void)clearAllKeys {
@synchronized(self) {
_zx8081.clear_all_keys();
}
} }
- (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { - (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed {
@synchronized(self) {
switch(key)
{
case VK_ANSI_0: _zx8081.set_key_state(ZX8081::Key::Key0, isPressed); break;
case VK_ANSI_1: _zx8081.set_key_state(ZX8081::Key::Key1, isPressed); break;
case VK_ANSI_2: _zx8081.set_key_state(ZX8081::Key::Key2, isPressed); break;
case VK_ANSI_3: _zx8081.set_key_state(ZX8081::Key::Key3, isPressed); break;
case VK_ANSI_4: _zx8081.set_key_state(ZX8081::Key::Key4, isPressed); break;
case VK_ANSI_5: _zx8081.set_key_state(ZX8081::Key::Key5, isPressed); break;
case VK_ANSI_6: _zx8081.set_key_state(ZX8081::Key::Key6, isPressed); break;
case VK_ANSI_7: _zx8081.set_key_state(ZX8081::Key::Key7, isPressed); break;
case VK_ANSI_8: _zx8081.set_key_state(ZX8081::Key::Key8, isPressed); break;
case VK_ANSI_9: _zx8081.set_key_state(ZX8081::Key::Key9, isPressed); break;
case VK_ANSI_Q: _zx8081.set_key_state(ZX8081::Key::KeyQ, isPressed); break;
case VK_ANSI_W: _zx8081.set_key_state(ZX8081::Key::KeyW, isPressed); break;
case VK_ANSI_E: _zx8081.set_key_state(ZX8081::Key::KeyE, isPressed); break;
case VK_ANSI_R: _zx8081.set_key_state(ZX8081::Key::KeyR, isPressed); break;
case VK_ANSI_T: _zx8081.set_key_state(ZX8081::Key::KeyT, isPressed); break;
case VK_ANSI_Y: _zx8081.set_key_state(ZX8081::Key::KeyY, isPressed); break;
case VK_ANSI_U: _zx8081.set_key_state(ZX8081::Key::KeyU, isPressed); break;
case VK_ANSI_I: _zx8081.set_key_state(ZX8081::Key::KeyI, isPressed); break;
case VK_ANSI_O: _zx8081.set_key_state(ZX8081::Key::KeyO, isPressed); break;
case VK_ANSI_P: _zx8081.set_key_state(ZX8081::Key::KeyP, isPressed); break;
case VK_ANSI_A: _zx8081.set_key_state(ZX8081::Key::KeyA, isPressed); break;
case VK_ANSI_S: _zx8081.set_key_state(ZX8081::Key::KeyS, isPressed); break;
case VK_ANSI_D: _zx8081.set_key_state(ZX8081::Key::KeyD, isPressed); break;
case VK_ANSI_F: _zx8081.set_key_state(ZX8081::Key::KeyF, isPressed); break;
case VK_ANSI_G: _zx8081.set_key_state(ZX8081::Key::KeyG, isPressed); break;
case VK_ANSI_H: _zx8081.set_key_state(ZX8081::Key::KeyH, isPressed); break;
case VK_ANSI_J: _zx8081.set_key_state(ZX8081::Key::KeyJ, isPressed); break;
case VK_ANSI_K: _zx8081.set_key_state(ZX8081::Key::KeyK, isPressed); break;
case VK_ANSI_L: _zx8081.set_key_state(ZX8081::Key::KeyL, isPressed); break;
case VK_ANSI_Z: _zx8081.set_key_state(ZX8081::Key::KeyZ, isPressed); break;
case VK_ANSI_X: _zx8081.set_key_state(ZX8081::Key::KeyX, isPressed); break;
case VK_ANSI_C: _zx8081.set_key_state(ZX8081::Key::KeyC, isPressed); break;
case VK_ANSI_V: _zx8081.set_key_state(ZX8081::Key::KeyV, isPressed); break;
case VK_ANSI_B: _zx8081.set_key_state(ZX8081::Key::KeyB, isPressed); break;
case VK_ANSI_N: _zx8081.set_key_state(ZX8081::Key::KeyN, isPressed); break;
case VK_ANSI_M: _zx8081.set_key_state(ZX8081::Key::KeyM, isPressed); break;
case VK_Shift:
case VK_RightShift:
_zx8081.set_key_state(ZX8081::Key::KeyShift, isPressed); break;
break;
case VK_ANSI_Period:_zx8081.set_key_state(ZX8081::Key::KeyDot, isPressed); break;
case VK_Return: _zx8081.set_key_state(ZX8081::Key::KeyEnter, isPressed); break;
case VK_Space: _zx8081.set_key_state(ZX8081::Key::KeySpace, isPressed); break;
}
}
} }
- (NSString *)userDefaultsPrefix { return @"zx8081"; } - (NSString *)userDefaultsPrefix { return @"zx8081"; }