Skip to content

Commit

Permalink
Message cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkwhoffmann committed Apr 4, 2023
1 parent befdd25 commit 7a63447
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 58 deletions.
64 changes: 51 additions & 13 deletions Emulator/Base/MsgQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,68 @@ MsgQueue::setListener(const void *listener, Callback *callback)
while (!queue.isEmpty()) {

Message &msg = queue.read();
callback(listener,
msg.type, msg.data1, msg.data2, msg.data3, msg.data4);
callback(listener, msg);
}
}
}

void
MsgQueue::put(MsgType type, isize d1, isize d2, isize d3, isize d4)
MsgQueue::put(const Message &msg)
{
{ SYNCHRONIZED

auto i1 = i32(d1);
auto i2 = i32(d2);
auto i3 = i32(d3);
auto i4 = i32(d4);
debug(QUEUE_DEBUG, "%s [%llx]\n", MsgTypeEnum::key(msg.type), msg.value);

debug(QUEUE_DEBUG,
"%s [%d:%d:%d:%d]\n", MsgTypeEnum::key(type), i1, i2, i3, i4);
if (listener) {

// Send the message immediately if a lister has been registered
if (listener) { callback(listener, type, i1, i2, i3, i4); return; }
// Send the message immediately if a lister has been registered
callback(listener, msg); return;

// Otherwise, store it in the ring buffer
Message msg = { type, i1, i2, i3, i4 }; queue.write(msg);
} else {

// Otherwise, store it in the ring buffer
if (!queue.isFull()) {
queue.write(msg);
} else {
warn("Message lost: %s [%llx]\n", MsgTypeEnum::key(msg.type), msg.value);
}
}
}
}

void
MsgQueue::put(MsgType type, i64 payload)
{
put( Message { .type = type, .value = payload } );
}

void
MsgQueue::put(MsgType type, CpuMsg payload)
{
put( Message { .type = type, .cpu = payload } );
}

void
MsgQueue::put(MsgType type, DriveMsg payload)
{
put( Message { .type = type, .drive = payload } );
}

void
MsgQueue::put(MsgType type, ScriptMsg payload)
{
put( Message { .type = type, .script = payload } );
}

bool
MsgQueue::get(Message &msg)
{
{ SYNCHRONIZED

if (queue.isEmpty()) return false;

msg = queue.read();
return true;
}
}

Expand Down
9 changes: 8 additions & 1 deletion Emulator/Base/MsgQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,14 @@ class MsgQueue : public SubComponent {
void setListener(const void *listener, Callback *func);

// Sends a message
void put(MsgType type, isize = 0, isize = 0, isize = 0, isize = 0);
void put(const Message &msg);
void put(MsgType type, i64 payload = 0);
void put(MsgType type, CpuMsg payload);
void put(MsgType type, DriveMsg payload);
void put(MsgType type, ScriptMsg payload);

// Reads a message
bool get(Message &msg);
};

}
24 changes: 13 additions & 11 deletions Emulator/Base/MsgQueueTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ enum_long(MSG_TYPE)
MSG_ROM_MISSING,

// CPU
MSG_CPU_OK,
MSG_CPU_JAMMED,
MSG_BREAKPOINT_REACHED,
MSG_WATCHPOINT_REACHED,
Expand Down Expand Up @@ -158,7 +157,6 @@ struct MsgTypeEnum : util::Reflection<MsgType, MsgType> {
case MSG_DRIVE_ROM_LOADED: return "DRIVE_ROM_LOADED";
case MSG_ROM_MISSING: return "ROM_MISSING";

case MSG_CPU_OK: return "CPU_OK";
case MSG_CPU_JAMMED: return "CPU_JAMMED";
case MSG_BREAKPOINT_REACHED: return "BREAKPOINT_REACHED";
case MSG_WATCHPOINT_REACHED: return "WATCHPOINT_REACHED";
Expand Down Expand Up @@ -224,18 +222,22 @@ struct MsgTypeEnum : util::Reflection<MsgType, MsgType> {
// Structures
//

typedef struct { u16 pc; } CpuMsg;
typedef struct { i16 nr; i16 value; i16 volume; i16 pan; } DriveMsg;
typedef struct { isize line; i16 delay; } ScriptMsg;

typedef struct
{
// Header
MsgType type;

/* The payload of a message consists of up to four (signed) 32-bit values.
* We avoid the usage of 64-bit types inside this structure to make it
* easily processable by JavaScript (web ports).
*/
i32 data1;
i32 data2;
i32 data3;
i32 data4;
// Payload
union {
i64 value;
CpuMsg cpu;
DriveMsg drive;
ScriptMsg script;
};
}
Message;

Expand All @@ -244,4 +246,4 @@ Message;
// Signatures
//

typedef void Callback(const void *, long, i32, i32, i32, i32);
typedef void Callback(const void *, Message);
4 changes: 2 additions & 2 deletions Emulator/Components/C64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1000,14 +1000,14 @@ C64::execute()
// Did we reach a breakpoint?
if (flags & RL::BREAKPOINT) {
clearFlag(RL::BREAKPOINT);
msgQueue.put(MSG_BREAKPOINT_REACHED, cpu.debugger.breakpointPC);
msgQueue.put(MSG_BREAKPOINT_REACHED, CpuMsg {u16(cpu.debugger.breakpointPC)});
newState = EXEC_PAUSED;
}

// Did we reach a watchpoint?
if (flags & RL::WATCHPOINT) {
clearFlag(RL::WATCHPOINT);
msgQueue.put(MSG_WATCHPOINT_REACHED, cpu.debugger.watchpointPC);
msgQueue.put(MSG_WATCHPOINT_REACHED, CpuMsg {u16(cpu.debugger.watchpointPC)});
newState = EXEC_PAUSED;
}

Expand Down
16 changes: 12 additions & 4 deletions Emulator/Peripherals/Drive/Drive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,9 @@ Drive::moveHeadUp()
halftrack, (halftrack + 1) / 2.0, offset);
}

msgQueue.put(MSG_DRIVE_STEP, deviceNr, halftrack, config.stepVolume, config.pan);
msgQueue.put(MSG_DRIVE_STEP, DriveMsg {
i16(deviceNr), i16(halftrack), config.stepVolume, config.pan
});
}

void
Expand All @@ -781,7 +783,9 @@ Drive::moveHeadDown()
halftrack, (halftrack + 1) / 2.0);
}

msgQueue.put(MSG_DRIVE_STEP, deviceNr, halftrack, config.stepVolume, config.pan);
msgQueue.put(MSG_DRIVE_STEP, DriveMsg {
i16(deviceNr), i16(halftrack), config.stepVolume, config.pan
});
}

bool
Expand Down Expand Up @@ -943,7 +947,9 @@ Drive::processDiskChangeEvent(EventID id)
insertionStatus = DISK_FULLY_EJECTED;

// Inform the GUI
msgQueue.put(MSG_DISK_EJECT, deviceNr, halftrack, config.stepVolume, config.pan);
msgQueue.put(MSG_DISK_EJECT, DriveMsg {
i16(deviceNr), i16(halftrack), config.stepVolume, config.pan
});

// Schedule the next transition
reschedule(config.swapDelay);
Expand Down Expand Up @@ -972,7 +978,9 @@ Drive::processDiskChangeEvent(EventID id)
disk = std::move(diskToInsert);

// Inform the GUI
msgQueue.put(MSG_DISK_INSERT, deviceNr, halftrack, config.stepVolume, config.pan);
msgQueue.put(MSG_DISK_INSERT, DriveMsg {
i16(deviceNr), i16(halftrack), config.stepVolume, config.pan
});
break;

default:
Expand Down
44 changes: 17 additions & 27 deletions GUI/MyController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,13 @@ extension MyController {
// Convert 'self' to a void pointer
let myself = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())

c64.setListener(myself) { (ptr, type, d1, d2, d3, d4) in
c64.setListener(myself) { (ptr, msg: Message) in

// Convert void pointer back to 'self'
let myself = Unmanaged<MyController>.fromOpaque(ptr!).takeUnretainedValue()

// Process message in the main thread
DispatchQueue.main.async {
myself.processMessage(Message(type: MsgType(rawValue: type)!,
data1: d1, data2: d2, data3: d3, data4: d4))
}
DispatchQueue.main.async { myself.processMessage(msg) }
}
}

Expand Down Expand Up @@ -279,15 +276,12 @@ extension MyController {

func processMessage(_ msg: Message) {

var data1: Int { return Int(msg.data1) }
var data2: Int { return Int(msg.data2) }
var data3: Int { return Int(msg.data3) }
var data4: Int { return Int(msg.data4) }

var driveNr: Int { return data1 }
var halftrack: Int { return data2; }
var vol: Int { return data3; }
var pan: Int { return data4; }
var value: Int { return Int(msg.value) }
var driveNr: Int { return Int(msg.drive.nr) }
var halftrack: Int { return Int(msg.drive.value) }
var pc: Int { return Int(msg.cpu.pc) }
var vol: Int { return Int(msg.drive.volume) }
var pan: Int { return Int(msg.drive.pan) }

// Only proceed if the proxy object is still alive
if c64 == nil { return }
Expand All @@ -300,7 +294,7 @@ extension MyController {

case .POWER:

if data1 != 0 {
if value != 0 {

renderer.canvas.open(delay: 2)
virtualKeyboard = nil
Expand Down Expand Up @@ -335,15 +329,14 @@ extension MyController {
shutDown()

case .ABORT:
debug(.shutdown, "Aborting with exit code \(msg.data1)")
exit(msg.data1)
debug(.shutdown, "Aborting with exit code \(value)")
exit(Int32(value))

case .WARP,
.TRACK:
case .WARP, .TRACK:
refreshStatusBar()

case .MUTE:
muted = data1 != 0
muted = value != 0
refreshStatusBar()

case .CONSOLE_CLOSE:
Expand Down Expand Up @@ -373,14 +366,11 @@ extension MyController {
case .ROM_MISSING:
break

case .CPU_OK:
break

case .BREAKPOINT_REACHED:
inspector?.signalBreakPoint(pc: Int(msg.data1))
inspector?.signalBreakPoint(pc: pc)

case .WATCHPOINT_REACHED:
inspector?.signalWatchPoint(pc: Int(msg.data1))
inspector?.signalWatchPoint(pc: pc)

case .CPU_JAMMED:
refreshStatusBar()
Expand Down Expand Up @@ -494,10 +484,10 @@ extension MyController {
showAlert(.recorderAborted)

case .DMA_DEBUG:
data1 != 0 ? renderer.zoomTextureOut() : renderer.zoomTextureIn()
value != 0 ? renderer.zoomTextureOut() : renderer.zoomTextureIn()

case .ALARM:
debug(.events, "Received Alarm \(msg.data1)")
debug(.events, "Received Alarm \(msg.value)")

default:
warn("Unknown message: \(msg)")
Expand Down

0 comments on commit 7a63447

Please sign in to comment.