1
0
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:
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),
hsync_(false),
ram_(1024),
line_data_(nullptr) {
line_data_(nullptr),
key_states_{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} {
// run at 3.25 Mhz
set_clock_rate(3250000);
Memory::Fuzz(ram_);
@ -34,13 +35,20 @@ int Machine::perform_machine_cycle(const CPU::Z80::MachineCycle &cycle) {
}
break;
case CPU::Z80::BusOperation::Input:
case CPU::Z80::BusOperation::Input: {
uint8_t value = 0xff;
if((address&7) == 6) {
set_vsync(true);
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;
break;
}
*cycle.value = value;
} break;
case CPU::Z80::BusOperation::Interrupt:
set_hsync(true);
@ -189,9 +197,22 @@ void Machine::output_byte(uint8_t byte) {
void Machine::setup_output(float aspect_ratio) {
crt_.reset(new Outputs::CRT::CRT(210 * 2, 1, Outputs::CRT::DisplayType::PAL50, 1));
crt_->set_rgb_sampling_function(
"vec3 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)"
crt_->set_composite_sampling_function(
"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
};
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:
public CPU::Z80::Processor<Machine>,
public CRTMachine::Machine,
@ -44,6 +55,8 @@ class Machine:
void configure_as_target(const StaticAnalyser::Target &target);
void set_rom(ROMType type, std::vector<uint8_t> data);
void set_key_state(uint16_t key, bool isPressed);
void clear_all_keys();
private:
std::shared_ptr<Outputs::CRT::CRT> crt_;
@ -55,6 +68,8 @@ class Machine:
uint8_t *line_data_, *line_data_pointer_;
int line_counter_;
uint8_t key_states_[8];
unsigned int cycles_since_display_update_;
void update_display();
void set_vsync(bool sync);

View File

@ -15,18 +15,18 @@
#import "NSBundle+DataResource.h"
@implementation CSZX8081 {
ZX8081::Machine zx8081;
ZX8081::Machine _zx8081;
}
- (CRTMachine::Machine * const)machine {
return &zx8081;
return &_zx8081;
}
- (instancetype)init {
self = [super init];
if(self) {
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::ZX80, [self rom:@"zx80"].stdVector8);
_zx8081.set_rom(ZX8081::ROMType::ZX81, [self rom:@"zx81"].stdVector8);
}
return self;
}
@ -38,9 +38,65 @@
#pragma mark - Keyboard Mapping
- (void)clearAllKeys {
@synchronized(self) {
_zx8081.clear_all_keys();
}
}
- (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"; }