1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-22 19:31:27 +00:00

Wired up joystick directions, at least, and fire button presses get as far as the C++. But there's some latching to figure out before they'll work.

This commit is contained in:
Thomas Harte 2015-08-18 20:33:24 -04:00
parent 902795d61c
commit bc805a90fe
9 changed files with 143 additions and 11 deletions

View File

@ -26,6 +26,9 @@ Machine::Machine()
_rom = nullptr;
_hMoveWillCount = false;
_piaDataValue[0] = _piaDataValue[1] = 0xff;
_piaInputValue[0] = _piaInputValue[1] = 0xff;
setup6502();
set_reset_line(true);
}
@ -505,18 +508,15 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
// check for a PIA access
if ((address&0x1280) == 0x280) {
if(isReadOperation(operation)) {
const uint8_t decodedAddress = address & 0xf;
switch(address & 0xf) {
case 0x00:
// TODO: port A read
case 0x02:
returnValue &= _piaDataValue[decodedAddress / 2];
break;
case 0x01:
// TODO: port A DDR
break;
case 0x02:
// TODO: port B read
break;
case 0x03:
// TODO: port B DDR
// TODO: port DDR
break;
case 0x04:
returnValue &= _piaTimerValue >> _piaTimerShift;
@ -530,6 +530,11 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
returnValue &= _piaTimerStatus;
_piaTimerStatus &= ~0x40;
break;
case 0x0c:
case 0x0d:
returnValue &= _piaInputValue[decodedAddress - 0x0c];
break;
}
} else {
const uint8_t decodedAddress = address & 0x0f;
@ -562,6 +567,23 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
return cycles_run_for;
}
void Machine::set_digital_input(Atari2600DigitalInput input, bool state)
{
switch (input) {
case Atari2600DigitalInputJoy1Up: if(state) _piaDataValue[0] &= 0x10; else _piaDataValue[0] |= 0x10; break;
case Atari2600DigitalInputJoy1Down: if(state) _piaDataValue[0] &= 0x20; else _piaDataValue[0] |= 0x20; break;
case Atari2600DigitalInputJoy1Left: if(state) _piaDataValue[0] &= 0x40; else _piaDataValue[0] |= 0x40; break;
case Atari2600DigitalInputJoy1Right: if(state) _piaDataValue[0] &= 0x80; else _piaDataValue[0] |= 0x80; break;
case Atari2600DigitalInputJoy2Up: if(state) _piaDataValue[0] &= 0x01; else _piaDataValue[0] |= 0x01; break;
case Atari2600DigitalInputJoy2Down: if(state) _piaDataValue[0] &= 0x02; else _piaDataValue[0] |= 0x02; break;
case Atari2600DigitalInputJoy2Left: if(state) _piaDataValue[0] &= 0x04; else _piaDataValue[0] |= 0x04; break;
case Atari2600DigitalInputJoy2Right: if(state) _piaDataValue[0] &= 0x08; else _piaDataValue[0] |= 0x08; break;
default: break;
}
}
void Machine::set_rom(size_t length, const uint8_t *data)
{
_rom_size = 1024;

View File

@ -12,6 +12,7 @@
#include "../Processors/6502/CPU6502.hpp"
#include "../Outputs/CRT.hpp"
#include <stdint.h>
#include "Atari2600Inputs.h"
namespace Atari2600 {
@ -27,6 +28,8 @@ class Machine: public CPU6502::Processor<Machine> {
void set_rom(size_t length, const uint8_t *data);
void switch_region();
void set_digital_input(Atari2600DigitalInput input, bool state);
Outputs::CRT *get_crt() { return _crt; }
private:
@ -72,6 +75,11 @@ class Machine: public CPU6502::Processor<Machine> {
uint8_t _objectCounter[5], _objectMotion[5];
uint8_t _hMoveFlags;
// joystick state
uint8_t _piaDataDirection[2];
uint8_t _piaDataValue[2];
uint8_t _piaInputValue[2];
// collisions
uint8_t _collisions[8];

View File

@ -0,0 +1,34 @@
//
// Atari2600Inputs.h
// Clock Signal
//
// Created by Thomas Harte on 18/08/2015.
// Copyright © 2015 Thomas Harte. All rights reserved.
//
#ifndef Atari2600Inputs_h
#define Atari2600Inputs_h
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
Atari2600DigitalInputJoy1Up,
Atari2600DigitalInputJoy1Down,
Atari2600DigitalInputJoy1Left,
Atari2600DigitalInputJoy1Right,
Atari2600DigitalInputJoy1Fire,
Atari2600DigitalInputJoy2Up,
Atari2600DigitalInputJoy2Down,
Atari2600DigitalInputJoy2Left,
Atari2600DigitalInputJoy2Right,
Atari2600DigitalInputJoy2Fire,
} Atari2600DigitalInput;
#ifdef __cplusplus
}
#endif
#endif /* Atari2600Inputs_h */

View File

@ -329,6 +329,7 @@
4B6D7F921B58822000787C9A /* Atari2600.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Atari2600.cpp; sourceTree = "<group>"; };
4B6D7F931B58822000787C9A /* Atari2600.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Atari2600.hpp; sourceTree = "<group>"; };
4B92EAC91B7C112B00246143 /* TimingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimingTests.swift; sourceTree = "<group>"; };
4BA3921C1B8402B3007FBF0E /* Atari2600Inputs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = "<group>"; };
4BB297DF1B587D8200A49093 /* Clock SignalTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Clock SignalTests-Bridging-Header.h"; sourceTree = "<group>"; };
4BB297E01B587D8300A49093 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = "<group>"; };
4BB297E11B587D8300A49093 /* AllSuiteA.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = AllSuiteA.bin; sourceTree = "<group>"; };
@ -1015,6 +1016,7 @@
children = (
4B6D7F921B58822000787C9A /* Atari2600.cpp */,
4B6D7F931B58822000787C9A /* Atari2600.hpp */,
4BA3921C1B8402B3007FBF0E /* Atari2600Inputs.h */,
);
name = Machines;
path = ../../Machines;

View File

@ -8,13 +8,14 @@
import Cocoa
class Atari2600Document: NSDocument, CSCathodeRayViewDelegate {
class Atari2600Document: NSDocument, CSCathodeRayViewDelegate, CSCathodeRayViewResponderDelegate {
@IBOutlet weak var openGLView: CSCathodeRayView?
@IBOutlet weak var openGLView: CSCathodeRayView!
override func windowControllerDidLoadNib(aController: NSWindowController) {
super.windowControllerDidLoadNib(aController)
openGLView!.delegate = self
openGLView.delegate = self
openGLView.responderDelegate = self
atari2600!.view = openGLView!
// bind the content aspect ratio to remain 4:3 from now on
@ -45,7 +46,7 @@ class Atari2600Document: NSDocument, CSCathodeRayViewDelegate {
override func close() {
super.close()
openGLView!.invalidate()
openGLView.invalidate()
}
// MARK: CSOpenGLViewDelegate
@ -69,4 +70,32 @@ class Atari2600Document: NSDocument, CSCathodeRayViewDelegate {
}
lastCycleCount = cycleCount
}
// MARK: CSOpenGLViewResponderDelegate
func inputForKey(event: NSEvent) -> Atari2600DigitalInput? {
switch event.keyCode {
case 123: return Atari2600DigitalInputJoy1Left
case 126: return Atari2600DigitalInputJoy1Up
case 124: return Atari2600DigitalInputJoy1Right
case 125: return Atari2600DigitalInputJoy1Down
case 0: return Atari2600DigitalInputJoy1Fire
default: print("\(event.keyCode)"); return nil
}
}
func keyDown(event: NSEvent) {
if let input = inputForKey(event) {
atari2600!.setState(true, forDigitalInput: input)
}
}
func keyUp(event: NSEvent) {
if let input = inputForKey(event) {
atari2600!.setState(false, forDigitalInput: input)
}
}
func flagsChanged(newModifiers: NSEvent) {
}
}

View File

@ -8,6 +8,7 @@
#import <Foundation/Foundation.h>
#import "CSCathodeRayView.h"
#include "Atari2600Inputs.h"
@interface CSAtari2600 : NSObject
@ -15,5 +16,6 @@
- (void)runForNumberOfCycles:(int)cycles;
- (void)setROM:(NSData *)rom;
- (void)setState:(BOOL)state forDigitalInput:(Atari2600DigitalInput)digitalInput;
@end

View File

@ -77,6 +77,12 @@ struct Atari2600CRTDelegate: public Outputs::CRT::CRTDelegate {
});
}
- (void)setState:(BOOL)state forDigitalInput:(Atari2600DigitalInput)digitalInput {
dispatch_async(_serialDispatchQueue, ^{
_atari2600.set_digital_input(digitalInput, state ? true : false);
});
}
- (instancetype)init {
self = [super init];

View File

@ -16,9 +16,16 @@
- (void)openGLView:(CSCathodeRayView * __nonnull)view didUpdateToTime:(CVTimeStamp)time;
@end
@protocol CSCathodeRayViewResponderDelegate <NSObject>
- (void)keyDown:(NSEvent * __nonnull)event;
- (void)keyUp:(NSEvent * __nonnull)event;
- (void)flagsChanged:(NSEvent * __nonnull)newModifiers;
@end
@interface CSCathodeRayView : NSOpenGLView
@property (nonatomic, weak) id <CSCathodeRayViewDelegate> delegate;
@property (nonatomic, weak) id <CSCathodeRayViewResponderDelegate> responderDelegate;
- (void)invalidate;

View File

@ -301,4 +301,26 @@ const char *fragmentShader =
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
#pragma mark - NSResponder
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)keyDown:(NSEvent *)theEvent
{
[self.responderDelegate keyDown:theEvent];
}
- (void)keyUp:(NSEvent *)theEvent
{
[self.responderDelegate keyUp:theEvent];
}
- (void)flagsChanged:(NSEvent *)theEvent
{
[self.responderDelegate flagsChanged:theEvent];
}
@end