mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +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:
parent
ebbf6e6133
commit
cc4cb45e9d
@ -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);
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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"; }
|
||||||
|
Loading…
Reference in New Issue
Block a user