made word_mode into an enum
This commit is contained in:
parent
ff2d0eadb7
commit
b2f3fdb0e9
5 changed files with 145 additions and 143 deletions
18
bus.cpp
18
bus.cpp
|
@ -82,7 +82,7 @@ void bus::init()
|
||||||
MMR3 = 0;
|
MMR3 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bus::read_pdr(const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only)
|
uint16_t bus::read_pdr(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only)
|
||||||
{
|
{
|
||||||
int page = (a >> 1) & 7;
|
int page = (a >> 1) & 7;
|
||||||
bool is_d = a & 16;
|
bool is_d = a & 16;
|
||||||
|
@ -94,7 +94,7 @@ uint16_t bus::read_pdr(const uint32_t a, const int run_mode, const bool word_mod
|
||||||
return word_mode ? (a & 1 ? t >> 8 : t & 255) : t;
|
return word_mode ? (a & 1 ? t >> 8 : t & 255) : t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bus::read_par(const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only)
|
uint16_t bus::read_par(const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only)
|
||||||
{
|
{
|
||||||
int page = (a >> 1) & 7;
|
int page = (a >> 1) & 7;
|
||||||
bool is_d = a & 16;
|
bool is_d = a & 16;
|
||||||
|
@ -114,7 +114,7 @@ void bus::trap_odd(const uint16_t a)
|
||||||
c->trap(004); // invalid access
|
c->trap(004); // invalid access
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bus::read(const uint16_t a, const bool word_mode, const bool use_prev, const bool peek_only, const d_i_space_t space)
|
uint16_t bus::read(const uint16_t a, const word_mode_t word_mode, const bool use_prev, const bool peek_only, const d_i_space_t space)
|
||||||
{
|
{
|
||||||
uint16_t temp = 0;
|
uint16_t temp = 0;
|
||||||
|
|
||||||
|
@ -637,7 +637,7 @@ void bus::addToMMR1(const int8_t delta, const uint8_t reg)
|
||||||
MMR1 |= reg;
|
MMR1 |= reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus::write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode)
|
void bus::write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode)
|
||||||
{
|
{
|
||||||
bool is_d = a & 16;
|
bool is_d = a & 16;
|
||||||
int page = (a >> 1) & 7;
|
int page = (a >> 1) & 7;
|
||||||
|
@ -665,7 +665,7 @@ void bus::write_pdr(const uint32_t a, const int run_mode, const uint16_t value,
|
||||||
DOLOG(debug, true, "WRITE-I/O PDR run-mode %d: %c for %d: %o [%d]", run_mode, is_d ? 'D' : 'I', page, value, word_mode);
|
DOLOG(debug, true, "WRITE-I/O PDR run-mode %d: %c for %d: %o [%d]", run_mode, is_d ? 'D' : 'I', page, value, word_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus::write_par(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode)
|
void bus::write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode)
|
||||||
{
|
{
|
||||||
bool is_d = a & 16;
|
bool is_d = a & 16;
|
||||||
int page = (a >> 1) & 7;
|
int page = (a >> 1) & 7;
|
||||||
|
@ -683,7 +683,7 @@ void bus::write_par(const uint32_t a, const int run_mode, const uint16_t value,
|
||||||
DOLOG(debug, true, "WRITE-I/O PAR run-mode %d: %c for %d: %o (%07o)", run_mode, is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[run_mode][is_d][page].par * 64);
|
DOLOG(debug, true, "WRITE-I/O PAR run-mode %d: %c for %d: %o (%07o)", run_mode, is_d ? 'D' : 'I', page, word_mode ? value & 0xff : value, pages[run_mode][is_d][page].par * 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus::write(const uint16_t a, const bool word_mode, uint16_t value, const bool use_prev, const d_i_space_t space)
|
void bus::write(const uint16_t a, const word_mode_t word_mode, uint16_t value, const bool use_prev, const d_i_space_t space)
|
||||||
{
|
{
|
||||||
int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3;
|
int run_mode = (c->getPSW() >> (use_prev ? 12 : 14)) & 3;
|
||||||
|
|
||||||
|
@ -993,17 +993,17 @@ uint16_t bus::readPhysical(const uint32_t a)
|
||||||
|
|
||||||
uint16_t bus::readWord(const uint16_t a, const d_i_space_t s)
|
uint16_t bus::readWord(const uint16_t a, const d_i_space_t s)
|
||||||
{
|
{
|
||||||
return read(a, false, false, false, s);
|
return read(a, wm_word, false, false, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bus::peekWord(const uint16_t a)
|
uint16_t bus::peekWord(const uint16_t a)
|
||||||
{
|
{
|
||||||
return read(a, false, false, true);
|
return read(a, wm_word, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus::writeWord(const uint16_t a, const uint16_t value, const d_i_space_t s)
|
void bus::writeWord(const uint16_t a, const uint16_t value, const d_i_space_t s)
|
||||||
{
|
{
|
||||||
write(a, false, value, false, s);
|
write(a, wm_word, value, false, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bus::readUnibusByte(const uint16_t a)
|
uint16_t bus::readUnibusByte(const uint16_t a)
|
||||||
|
|
20
bus.h
20
bus.h
|
@ -60,6 +60,8 @@ class tty;
|
||||||
|
|
||||||
typedef enum { d_space, i_space } d_i_space_t;
|
typedef enum { d_space, i_space } d_i_space_t;
|
||||||
|
|
||||||
|
typedef enum { wm_word = 0, wm_byte = 1 } word_mode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t virtual_address;
|
uint16_t virtual_address;
|
||||||
uint8_t apf; // active page field
|
uint8_t apf; // active page field
|
||||||
|
@ -94,10 +96,10 @@ private:
|
||||||
uint16_t console_switches { 0 };
|
uint16_t console_switches { 0 };
|
||||||
uint16_t console_leds { 0 };
|
uint16_t console_leds { 0 };
|
||||||
|
|
||||||
uint16_t read_pdr (const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only);
|
uint16_t read_pdr (const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only);
|
||||||
uint16_t read_par (const uint32_t a, const int run_mode, const bool word_mode, const bool peek_only);
|
uint16_t read_par (const uint32_t a, const int run_mode, const word_mode_t word_mode, const bool peek_only);
|
||||||
void write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode);
|
void write_pdr(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode);
|
||||||
void write_par(const uint32_t a, const int run_mode, const uint16_t value, const bool word_mode);
|
void write_par(const uint32_t a, const int run_mode, const uint16_t value, const word_mode_t word_mode);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bus();
|
bus();
|
||||||
|
@ -127,15 +129,15 @@ public:
|
||||||
void set_lf_crs_b7();
|
void set_lf_crs_b7();
|
||||||
uint8_t get_lf_crs();
|
uint8_t get_lf_crs();
|
||||||
|
|
||||||
uint16_t read(const uint16_t a, const bool word_mode, const bool use_prev, const bool peek_only=false, const d_i_space_t s = i_space);
|
uint16_t read(const uint16_t a, const word_mode_t word_mode, const bool use_prev, const bool peek_only=false, const d_i_space_t s = i_space);
|
||||||
uint16_t readByte(const uint16_t a) { return read(a, true, false); }
|
uint16_t readByte(const uint16_t a) { return read(a, wm_byte, false); }
|
||||||
uint16_t readWord(const uint16_t a, const d_i_space_t s = i_space);
|
uint16_t readWord(const uint16_t a, const d_i_space_t s = i_space);
|
||||||
uint16_t peekWord(const uint16_t a);
|
uint16_t peekWord(const uint16_t a);
|
||||||
|
|
||||||
uint16_t readUnibusByte(const uint16_t a);
|
uint16_t readUnibusByte(const uint16_t a);
|
||||||
|
|
||||||
void write(const uint16_t a, const bool word_mode, uint16_t value, const bool use_prev, const d_i_space_t s = i_space);
|
void write(const uint16_t a, const word_mode_t word_mode, uint16_t value, const bool use_prev, const d_i_space_t s = i_space);
|
||||||
void writeByte(const uint16_t a, const uint8_t value) { return write(a, true, value, false); }
|
void writeByte(const uint16_t a, const uint8_t value) { return write(a, wm_byte, value, false); }
|
||||||
void writeWord(const uint16_t a, const uint16_t value, const d_i_space_t s = i_space);
|
void writeWord(const uint16_t a, const uint16_t value, const d_i_space_t s = i_space);
|
||||||
|
|
||||||
uint16_t readPhysical(const uint32_t a);
|
uint16_t readPhysical(const uint32_t a);
|
||||||
|
@ -161,5 +163,5 @@ public:
|
||||||
|
|
||||||
bool get_use_data_space(const int run_mode);
|
bool get_use_data_space(const int run_mode);
|
||||||
memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a);
|
memory_addresses_t calculate_physical_address(const int run_mode, const uint16_t a);
|
||||||
void check_address(const bool trap_on_failure, const bool is_write, const memory_addresses_t & addr, const bool word_mode, const bool is_data, const int run_mode);
|
void check_address(const bool trap_on_failure, const bool is_write, const memory_addresses_t & addr, const word_mode_t word_mode, const bool is_data, const int run_mode);
|
||||||
};
|
};
|
||||||
|
|
226
cpu.cpp
226
cpu.cpp
|
@ -1,4 +1,4 @@
|
||||||
// (C) 2018-2022 by Folkert van Heusden
|
// (C) 2018-2023 by Folkert van Heusden
|
||||||
// Released under Apache License v2.0
|
// Released under Apache License v2.0
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -10,9 +10,9 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#define SIGN(x, wm) ((wm) ? (x) & 0x80 : (x) & 0x8000)
|
#define SIGN(x, wm) ((wm) == wm_byte ? (x) & 0x80 : (x) & 0x8000)
|
||||||
|
|
||||||
#define IS_0(x, wm) ((wm) ? ((x) & 0xff) == 0 : (x) == 0)
|
#define IS_0(x, wm) ((wm) == wm_byte ? ((x) & 0xff) == 0 : (x) == 0)
|
||||||
|
|
||||||
cpu::cpu(bus *const b, std::atomic_uint32_t *const event) : b(b), event(event)
|
cpu::cpu(bus *const b, std::atomic_uint32_t *const event) : b(b), event(event)
|
||||||
{
|
{
|
||||||
|
@ -129,9 +129,9 @@ void cpu::setRegister(const int nr, const uint16_t value, const bool prev_mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu::setRegisterLowByte(const int nr, const bool word_mode, const uint16_t value) // prev_mode == false
|
void cpu::setRegisterLowByte(const int nr, const word_mode_t word_mode, const uint16_t value) // prev_mode == false
|
||||||
{
|
{
|
||||||
if (word_mode) {
|
if (word_mode == wm_byte) {
|
||||||
uint16_t v = getRegister(nr);
|
uint16_t v = getRegister(nr);
|
||||||
|
|
||||||
v &= 0xff00;
|
v &= 0xff00;
|
||||||
|
@ -249,7 +249,7 @@ void cpu::setPSW(const uint16_t v, const bool limited)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu::setPSW_flags_nzv(const uint16_t value, const bool word_mode)
|
void cpu::setPSW_flags_nzv(const uint16_t value, const word_mode_t word_mode)
|
||||||
{
|
{
|
||||||
setPSW_n(SIGN(value, word_mode));
|
setPSW_n(SIGN(value, word_mode));
|
||||||
setPSW_z(IS_0(value, word_mode));
|
setPSW_z(IS_0(value, word_mode));
|
||||||
|
@ -297,23 +297,23 @@ void cpu::queue_interrupt(const uint8_t level, const uint8_t vector)
|
||||||
DOLOG(debug, true, "Queueing interrupt vector %o (IPL %d, current: %d), n: %zu", vector, level, getPSW_spl(), it->second.size());
|
DOLOG(debug, true, "Queueing interrupt vector %o (IPL %d, current: %d), n: %zu", vector, level, getPSW_spl(), it->second.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu::addToMMR1(const uint8_t mode, const uint8_t reg, const bool word_mode)
|
void cpu::addToMMR1(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode)
|
||||||
{
|
{
|
||||||
if (b->getMMR0() & 0160000 /* bits frozen? */)
|
if (b->getMMR0() & 0160000 /* bits frozen? */)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool neg = mode == 4 || mode == 5;
|
bool neg = mode == 4 || mode == 5;
|
||||||
|
|
||||||
if (!word_mode || reg >= 6 || mode == 6 || mode == 7)
|
if (word_mode == wm_word || reg >= 6 || mode == 6 || mode == 7)
|
||||||
b->addToMMR1(neg ? -2 : 2, reg);
|
b->addToMMR1(neg ? -2 : 2, reg);
|
||||||
else
|
else
|
||||||
b->addToMMR1(neg ? -1 : 1, reg);
|
b->addToMMR1(neg ? -1 : 1, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GAM = general addressing modes
|
// GAM = general addressing modes
|
||||||
gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode, const bool prev_mode, const bool read_value)
|
gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode, const bool prev_mode, const bool read_value)
|
||||||
{
|
{
|
||||||
gam_rc_t g { false, false, i_space, { }, 0 };
|
gam_rc_t g { wm_word, false, i_space, { }, 0, 0 };
|
||||||
g.word_mode = word_mode; // word/byte
|
g.word_mode = word_mode; // word/byte
|
||||||
g.prev_mode = prev_mode; // run mode
|
g.prev_mode = prev_mode; // run mode
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case 0: // Rn
|
case 0: // Rn
|
||||||
g.reg = reg;
|
g.reg = reg;
|
||||||
g.value = getRegister(reg, prev_mode) & (word_mode ? 0xff : 0xffff);
|
g.value = getRegister(reg, prev_mode) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
break;
|
break;
|
||||||
case 1: // (Rn)
|
case 1: // (Rn)
|
||||||
g.addr = getRegister(reg, prev_mode);
|
g.addr = getRegister(reg, prev_mode);
|
||||||
|
@ -338,11 +338,11 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode
|
||||||
g.addr = getRegister(reg, prev_mode);
|
g.addr = getRegister(reg, prev_mode);
|
||||||
if (read_value)
|
if (read_value)
|
||||||
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, isR7_space);
|
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, isR7_space);
|
||||||
addRegister(reg, prev_mode, !word_mode || reg == 7 || reg == 6 ? 2 : 1);
|
addRegister(reg, prev_mode, word_mode == wm_word || reg == 7 || reg == 6 ? 2 : 1);
|
||||||
addToMMR1(mode, reg, word_mode);
|
addToMMR1(mode, reg, word_mode);
|
||||||
break;
|
break;
|
||||||
case 3: // @(Rn)+ / @#a
|
case 3: // @(Rn)+ / @#a
|
||||||
g.addr = b->read(getRegister(reg, prev_mode), false, prev_mode, false, isR7_space);
|
g.addr = b->read(getRegister(reg, prev_mode), wm_word, prev_mode, false, isR7_space);
|
||||||
addRegister(reg, prev_mode, 2);
|
addRegister(reg, prev_mode, 2);
|
||||||
if (read_value) {
|
if (read_value) {
|
||||||
g.space = d_space;
|
g.space = d_space;
|
||||||
|
@ -351,7 +351,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode
|
||||||
addToMMR1(mode, reg, word_mode);
|
addToMMR1(mode, reg, word_mode);
|
||||||
break;
|
break;
|
||||||
case 4: // -(Rn)
|
case 4: // -(Rn)
|
||||||
addRegister(reg, prev_mode, !word_mode || reg == 7 || reg == 6 ? -2 : -1);
|
addRegister(reg, prev_mode, word_mode == wm_word || reg == 7 || reg == 6 ? -2 : -1);
|
||||||
g.addr = getRegister(reg, prev_mode);
|
g.addr = getRegister(reg, prev_mode);
|
||||||
if (read_value)
|
if (read_value)
|
||||||
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, isR7_space);
|
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, isR7_space);
|
||||||
|
@ -359,7 +359,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode
|
||||||
break;
|
break;
|
||||||
case 5: // @-(Rn)
|
case 5: // @-(Rn)
|
||||||
addRegister(reg, prev_mode, -2);
|
addRegister(reg, prev_mode, -2);
|
||||||
g.addr = b->read(getRegister(reg, prev_mode), false, prev_mode, false, isR7_space);
|
g.addr = b->read(getRegister(reg, prev_mode), wm_word, prev_mode, false, isR7_space);
|
||||||
if (read_value) {
|
if (read_value) {
|
||||||
g.space = d_space;
|
g.space = d_space;
|
||||||
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, g.space);
|
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, g.space);
|
||||||
|
@ -367,7 +367,7 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode
|
||||||
addToMMR1(mode, reg, word_mode);
|
addToMMR1(mode, reg, word_mode);
|
||||||
break;
|
break;
|
||||||
case 6: // x(Rn) / a
|
case 6: // x(Rn) / a
|
||||||
next_word = b->read(getPC(), false, prev_mode, false, i_space);
|
next_word = b->read(getPC(), wm_word, prev_mode, false, i_space);
|
||||||
addRegister(7, prev_mode, + 2);
|
addRegister(7, prev_mode, + 2);
|
||||||
g.addr = getRegister(reg, prev_mode) + next_word;
|
g.addr = getRegister(reg, prev_mode) + next_word;
|
||||||
if (read_value) {
|
if (read_value) {
|
||||||
|
@ -376,9 +376,9 @@ gam_rc_t cpu::getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: // @x(Rn) / @a
|
case 7: // @x(Rn) / @a
|
||||||
next_word = b->read(getPC(), false, prev_mode, false, i_space);
|
next_word = b->read(getPC(), wm_word, prev_mode, false, i_space);
|
||||||
addRegister(7, prev_mode, + 2);
|
addRegister(7, prev_mode, + 2);
|
||||||
g.addr = b->read(getRegister(reg, prev_mode) + next_word, false, prev_mode, false, d_space);
|
g.addr = b->read(getRegister(reg, prev_mode) + next_word, wm_word, prev_mode, false, d_space);
|
||||||
if (read_value) {
|
if (read_value) {
|
||||||
g.space = d_space;
|
g.space = d_space;
|
||||||
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, g.space);
|
g.value = b->read(g.addr.value(), word_mode, prev_mode, false, g.space);
|
||||||
|
@ -402,14 +402,14 @@ bool cpu::putGAM(const gam_rc_t & g, const uint16_t value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gam_rc_t cpu::getGAMAddress(const uint8_t mode, const int reg, const bool word_mode)
|
gam_rc_t cpu::getGAMAddress(const uint8_t mode, const int reg, const word_mode_t word_mode)
|
||||||
{
|
{
|
||||||
return getGAM(mode, reg, word_mode, false, false);
|
return getGAM(mode, reg, word_mode, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cpu::double_operand_instructions(const uint16_t instr)
|
bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
{
|
{
|
||||||
const bool word_mode = !!(instr & 0x8000);
|
const word_mode_t word_mode = instr & 0x8000 ? wm_byte : wm_word;
|
||||||
|
|
||||||
const uint8_t operation = (instr >> 12) & 7;
|
const uint8_t operation = (instr >> 12) & 7;
|
||||||
|
|
||||||
|
@ -417,7 +417,7 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
return single_operand_instructions(instr);
|
return single_operand_instructions(instr);
|
||||||
|
|
||||||
if (operation == 0b111) {
|
if (operation == 0b111) {
|
||||||
if (word_mode)
|
if (word_mode == wm_byte)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return additional_double_operand_instructions(instr);
|
return additional_double_operand_instructions(instr);
|
||||||
|
@ -427,7 +427,7 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
const uint8_t src_mode = (src >> 3) & 7;
|
const uint8_t src_mode = (src >> 3) & 7;
|
||||||
const uint8_t src_reg = src & 7;
|
const uint8_t src_reg = src & 7;
|
||||||
|
|
||||||
gam_rc_t g_src { false, false, i_space, { }, 0 };
|
gam_rc_t g_src { wm_word, false, i_space, { }, 0, 0 };
|
||||||
|
|
||||||
if (operation != 0b110)
|
if (operation != 0b110)
|
||||||
g_src = getGAM(src_mode, src_reg, word_mode, false);
|
g_src = getGAM(src_mode, src_reg, word_mode, false);
|
||||||
|
@ -440,7 +440,7 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
|
|
||||||
switch(operation) {
|
switch(operation) {
|
||||||
case 0b001: { // MOV/MOVB Move Word/Byte
|
case 0b001: { // MOV/MOVB Move Word/Byte
|
||||||
if (word_mode && dst_mode == 0)
|
if (word_mode == wm_byte && dst_mode == 0)
|
||||||
setRegister(dst_reg, int8_t(g_src.value.value())); // int8_t: sign extension
|
setRegister(dst_reg, int8_t(g_src.value.value())); // int8_t: sign extension
|
||||||
else {
|
else {
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false, false);
|
||||||
|
@ -457,7 +457,7 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
case 0b010: { // CMP/CMPB Compare Word/Byte
|
case 0b010: { // CMP/CMPB Compare Word/Byte
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
|
|
||||||
uint16_t temp = (g_src.value.value() - g_dst.value.value()) & (word_mode ? 0xff : 0xffff);
|
uint16_t temp = (g_src.value.value() - g_dst.value.value()) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
|
|
||||||
setPSW_n(SIGN(temp, word_mode));
|
setPSW_n(SIGN(temp, word_mode));
|
||||||
setPSW_z(IS_0(temp, word_mode));
|
setPSW_z(IS_0(temp, word_mode));
|
||||||
|
@ -469,7 +469,7 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
|
|
||||||
case 0b011: { // BIT/BITB Bit Test Word/Byte
|
case 0b011: { // BIT/BITB Bit Test Word/Byte
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
uint16_t result = (g_dst.value.value() & g_src.value.value()) & (word_mode ? 0xff : 0xffff);
|
uint16_t result = (g_dst.value.value() & g_src.value.value()) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
|
|
||||||
setPSW_flags_nzv(result, word_mode);
|
setPSW_flags_nzv(result, word_mode);
|
||||||
|
|
||||||
|
@ -502,9 +502,9 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0b110: { // ADD/SUB Add/Subtract Word
|
case 0b110: { // ADD/SUB Add/Subtract Word
|
||||||
auto g_ssrc = getGAM(src_mode, src_reg, false, false);
|
auto g_ssrc = getGAM(src_mode, src_reg, wm_word, false);
|
||||||
|
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, false, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, wm_word, false);
|
||||||
|
|
||||||
int16_t result = 0;
|
int16_t result = 0;
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
result = (g_dst.value.value() - g_ssrc.value.value()) & 0xffff;
|
result = (g_dst.value.value() - g_ssrc.value.value()) & 0xffff;
|
||||||
|
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_v(SIGN((g_dst.value.value() ^ g_ssrc.value.value()) & (~g_ssrc.value.value() ^ result), false));
|
setPSW_v(SIGN((g_dst.value.value() ^ g_ssrc.value.value()) & (~g_ssrc.value.value() ^ result), wm_word));
|
||||||
setPSW_c(uint16_t(g_dst.value.value()) < uint16_t(g_ssrc.value.value()));
|
setPSW_c(uint16_t(g_dst.value.value()) < uint16_t(g_ssrc.value.value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,7 +524,7 @@ bool cpu::double_operand_instructions(const uint16_t instr)
|
||||||
result = temp;
|
result = temp;
|
||||||
|
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_v(SIGN((~g_ssrc.value.value() ^ g_dst.value.value()) & (g_ssrc.value.value() ^ (temp & 0xffff)), false));
|
setPSW_v(SIGN((~g_ssrc.value.value() ^ g_dst.value.value()) & (g_ssrc.value.value() ^ (temp & 0xffff)), wm_word));
|
||||||
setPSW_c(uint16_t(result) < uint16_t(g_ssrc.value.value()));
|
setPSW_c(uint16_t(result) < uint16_t(g_ssrc.value.value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,7 +557,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
case 0: { // MUL
|
case 0: { // MUL
|
||||||
int16_t R1 = getRegister(reg);
|
int16_t R1 = getRegister(reg);
|
||||||
|
|
||||||
auto R2g = getGAM(dst_mode, dst_reg, false, false);
|
auto R2g = getGAM(dst_mode, dst_reg, wm_word, false);
|
||||||
int16_t R2 = R2g.value.value();
|
int16_t R2 = R2g.value.value();
|
||||||
|
|
||||||
int32_t result = R1 * R2;
|
int32_t result = R1 * R2;
|
||||||
|
@ -573,7 +573,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1: { // DIV
|
case 1: { // DIV
|
||||||
auto R2g = getGAM(dst_mode, dst_reg, false, false);
|
auto R2g = getGAM(dst_mode, dst_reg, wm_word, false);
|
||||||
int16_t divider = R2g.value.value();
|
int16_t divider = R2g.value.value();
|
||||||
|
|
||||||
if (divider == 0) { // divide by zero
|
if (divider == 0) { // divide by zero
|
||||||
|
@ -613,10 +613,10 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
case 2: { // ASH
|
case 2: { // ASH
|
||||||
uint32_t R = getRegister(reg), oldR = R;
|
uint32_t R = getRegister(reg), oldR = R;
|
||||||
|
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, false, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, wm_word, false);
|
||||||
uint16_t shift = g_dst.value.value() & 077;
|
uint16_t shift = g_dst.value.value() & 077;
|
||||||
|
|
||||||
bool sign = SIGN(R, false);
|
bool sign = SIGN(R, wm_word);
|
||||||
|
|
||||||
// extend sign-bit
|
// extend sign-bit
|
||||||
if (sign)
|
if (sign)
|
||||||
|
@ -629,7 +629,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
else if (shift <= 15) {
|
else if (shift <= 15) {
|
||||||
R <<= shift;
|
R <<= shift;
|
||||||
setPSW_c(R & 0x10000);
|
setPSW_c(R & 0x10000);
|
||||||
setPSW_v(SIGN(oldR, false) != SIGN(R, false));
|
setPSW_v(SIGN(oldR, wm_word) != SIGN(R, wm_word));
|
||||||
}
|
}
|
||||||
else if (shift < 32) {
|
else if (shift < 32) {
|
||||||
setPSW_c((R << (shift - 16)) & 1);
|
setPSW_c((R << (shift - 16)) & 1);
|
||||||
|
@ -640,7 +640,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
R = -sign;
|
R = -sign;
|
||||||
|
|
||||||
setPSW_c(sign);
|
setPSW_c(sign);
|
||||||
setPSW_v(SIGN(R, false) != SIGN(oldR, false));
|
setPSW_v(SIGN(R, wm_word) != SIGN(oldR, wm_word));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int shift_n = (64 - shift) - 1;
|
int shift_n = (64 - shift) - 1;
|
||||||
|
@ -648,14 +648,14 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
R >>= shift_n;
|
R >>= shift_n;
|
||||||
|
|
||||||
setPSW_c(R & 1);
|
setPSW_c(R & 1);
|
||||||
setPSW_v(SIGN(R, false) != SIGN(oldR, false));
|
setPSW_v(SIGN(R, wm_word) != SIGN(oldR, wm_word));
|
||||||
|
|
||||||
R >>= 1;
|
R >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
R &= 0xffff;
|
R &= 0xffff;
|
||||||
|
|
||||||
setPSW_n(SIGN(R, false));
|
setPSW_n(SIGN(R, wm_word));
|
||||||
setPSW_z(R == 0);
|
setPSW_z(R == 0);
|
||||||
|
|
||||||
setRegister(reg, R);
|
setRegister(reg, R);
|
||||||
|
@ -666,7 +666,7 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
case 3: { // ASHC
|
case 3: { // ASHC
|
||||||
uint32_t R0R1 = (getRegister(reg) << 16) | getRegister(reg | 1);
|
uint32_t R0R1 = (getRegister(reg) << 16) | getRegister(reg | 1);
|
||||||
|
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, false, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, wm_word, false);
|
||||||
uint16_t shift = g_dst.value.value() & 077;
|
uint16_t shift = g_dst.value.value() & 077;
|
||||||
|
|
||||||
bool sign = R0R1 & 0x80000000;
|
bool sign = R0R1 & 0x80000000;
|
||||||
|
@ -722,13 +722,13 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
|
||||||
|
|
||||||
case 4: { // XOR (word only)
|
case 4: { // XOR (word only)
|
||||||
uint16_t reg_v = getRegister(reg); // in case it is R7
|
uint16_t reg_v = getRegister(reg); // in case it is R7
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, false, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, wm_word, false);
|
||||||
uint16_t vl = g_dst.value.value() ^ reg_v;
|
uint16_t vl = g_dst.value.value() ^ reg_v;
|
||||||
|
|
||||||
bool set_flags = putGAM(g_dst, vl);
|
bool set_flags = putGAM(g_dst, vl);
|
||||||
|
|
||||||
if (set_flags)
|
if (set_flags)
|
||||||
setPSW_flags_nzv(vl, false);
|
setPSW_flags_nzv(vl, wm_word);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -755,12 +755,12 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
const uint8_t dst = instr & 63;
|
const uint8_t dst = instr & 63;
|
||||||
const uint8_t dst_mode = (dst >> 3) & 7;
|
const uint8_t dst_mode = (dst >> 3) & 7;
|
||||||
const uint8_t dst_reg = dst & 7;
|
const uint8_t dst_reg = dst & 7;
|
||||||
const bool word_mode = !!(instr & 0x8000);
|
const word_mode_t word_mode = instr & 0x8000 ? wm_byte : wm_word;
|
||||||
bool set_flags = true;
|
bool set_flags = true;
|
||||||
|
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case 0b00000011: { // SWAB
|
case 0b00000011: { // SWAB
|
||||||
if (word_mode) // handled elsewhere
|
if (word_mode == wm_byte) // handled elsewhere
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
|
@ -772,7 +772,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
set_flags = putGAM(g_dst, v);
|
set_flags = putGAM(g_dst, v);
|
||||||
|
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_flags_nzv(v, true);
|
setPSW_flags_nzv(v, wm_byte);
|
||||||
setPSW_c(false);
|
setPSW_c(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,8 +782,8 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
case 0b000101000: { // CLR/CLRB
|
case 0b000101000: { // CLR/CLRB
|
||||||
bool set_flags = false;
|
bool set_flags = false;
|
||||||
|
|
||||||
if (word_mode && dst_mode == 0) {
|
if (word_mode == wm_byte && dst_mode == 0) {
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, true, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, wm_byte, false);
|
||||||
|
|
||||||
uint16_t r = g_dst.value.value() & 0xff00;
|
uint16_t r = g_dst.value.value() & 0xff00;
|
||||||
|
|
||||||
|
@ -809,7 +809,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
uint16_t v = a.value.value();
|
uint16_t v = a.value.value();
|
||||||
|
|
||||||
if (word_mode)
|
if (word_mode == wm_byte)
|
||||||
v ^= 0xff;
|
v ^= 0xff;
|
||||||
else
|
else
|
||||||
v ^= 0xffff;
|
v ^= 0xffff;
|
||||||
|
@ -829,26 +829,26 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
|
|
||||||
if (dst_mode == 0) {
|
if (dst_mode == 0) {
|
||||||
uint16_t v = a.value.value();
|
uint16_t v = a.value.value();
|
||||||
uint16_t add = word_mode ? v & 0xff00 : 0;
|
uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0;
|
||||||
|
|
||||||
v = (v + 1) & (word_mode ? 0xff : 0xffff);
|
v = (v + 1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
v |= add;
|
v |= add;
|
||||||
|
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v(word_mode ? (v & 0xff) == 0x80 : v == 0x8000);
|
setPSW_v(word_mode == wm_byte ? (v & 0xff) == 0x80 : v == 0x8000);
|
||||||
|
|
||||||
setRegister(dst_reg, v);
|
setRegister(dst_reg, v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int32_t vl = (a.value.value() + 1) & (word_mode ? 0xff : 0xffff);
|
int32_t vl = (a.value.value() + 1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
|
|
||||||
bool set_flags = a.addr.value() != ADDR_PSW;
|
bool set_flags = a.addr.value() != ADDR_PSW;
|
||||||
|
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_n(SIGN(vl, word_mode));
|
setPSW_n(SIGN(vl, word_mode));
|
||||||
setPSW_z(IS_0(vl, word_mode));
|
setPSW_z(IS_0(vl, word_mode));
|
||||||
setPSW_v(word_mode ? vl == 0x80 : vl == 0x8000);
|
setPSW_v(word_mode == wm_byte ? vl == 0x80 : vl == 0x8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->write(a.addr.value(), word_mode, vl, false);
|
b->write(a.addr.value(), word_mode, vl, false);
|
||||||
|
@ -861,28 +861,28 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
// TODO unify
|
// TODO unify
|
||||||
if (dst_mode == 0) {
|
if (dst_mode == 0) {
|
||||||
uint16_t v = getRegister(dst_reg);
|
uint16_t v = getRegister(dst_reg);
|
||||||
uint16_t add = word_mode ? v & 0xff00 : 0;
|
uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0;
|
||||||
|
|
||||||
v = (v - 1) & (word_mode ? 0xff : 0xffff);
|
v = (v - 1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
v |= add;
|
v |= add;
|
||||||
|
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v(word_mode ? (v & 0xff) == 0x7f : v == 0x7fff);
|
setPSW_v(word_mode == wm_byte ? (v & 0xff) == 0x7f : v == 0x7fff);
|
||||||
|
|
||||||
setRegister(dst_reg, v);
|
setRegister(dst_reg, v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
uint16_t v = a.value.value();
|
uint16_t v = a.value.value();
|
||||||
int32_t vl = (v - 1) & (word_mode ? 0xff : 0xffff);
|
int32_t vl = (v - 1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
|
|
||||||
bool set_flags = a.addr.value() != ADDR_PSW;
|
bool set_flags = a.addr.value() != ADDR_PSW;
|
||||||
|
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_n(SIGN(vl, word_mode));
|
setPSW_n(SIGN(vl, word_mode));
|
||||||
setPSW_z(IS_0(vl, word_mode));
|
setPSW_z(IS_0(vl, word_mode));
|
||||||
setPSW_v(word_mode ? vl == 0x7f : vl == 0x7fff);
|
setPSW_v(word_mode == wm_byte ? vl == 0x7f : vl == 0x7fff);
|
||||||
}
|
}
|
||||||
|
|
||||||
b->write(a.addr.value(), word_mode, vl, false);
|
b->write(a.addr.value(), word_mode, vl, false);
|
||||||
|
@ -894,14 +894,14 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
case 0b000101100: { // NEG/NEGB
|
case 0b000101100: { // NEG/NEGB
|
||||||
if (dst_mode == 0) {
|
if (dst_mode == 0) {
|
||||||
uint16_t v = getRegister(dst_reg);
|
uint16_t v = getRegister(dst_reg);
|
||||||
uint16_t add = word_mode ? v & 0xff00 : 0;
|
uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0;
|
||||||
|
|
||||||
v = (-v) & (word_mode ? 0xff : 0xffff);
|
v = (-v) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
v |= add;
|
v |= add;
|
||||||
|
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v(word_mode ? (v & 0xff) == 0x80 : v == 0x8000);
|
setPSW_v(word_mode == wm_byte ? (v & 0xff) == 0x80 : v == 0x8000);
|
||||||
setPSW_c(v);
|
setPSW_c(v);
|
||||||
|
|
||||||
setRegister(dst_reg, v);
|
setRegister(dst_reg, v);
|
||||||
|
@ -917,7 +917,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v(word_mode ? (v & 0xff) == 0x80 : v == 0x8000);
|
setPSW_v(word_mode == wm_byte ? (v & 0xff) == 0x80 : v == 0x8000);
|
||||||
setPSW_c(v);
|
setPSW_c(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -929,16 +929,16 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
if (dst_mode == 0) {
|
if (dst_mode == 0) {
|
||||||
const uint16_t vo = getRegister(dst_reg);
|
const uint16_t vo = getRegister(dst_reg);
|
||||||
uint16_t v = vo;
|
uint16_t v = vo;
|
||||||
uint16_t add = word_mode ? v & 0xff00 : 0;
|
uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0;
|
||||||
bool org_c = getPSW_c();
|
bool org_c = getPSW_c();
|
||||||
|
|
||||||
v = (v + org_c) & (word_mode ? 0xff : 0xffff);
|
v = (v + org_c) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
v |= add;
|
v |= add;
|
||||||
|
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v((word_mode ? (vo & 0xff) == 0x7f : vo == 0x7fff) && org_c);
|
setPSW_v((word_mode == wm_byte ? (vo & 0xff) == 0x7f : vo == 0x7fff) && org_c);
|
||||||
setPSW_c((word_mode ? (vo & 0xff) == 0xff : vo == 0xffff) && org_c);
|
setPSW_c((word_mode == wm_byte ? (vo & 0xff) == 0xff : vo == 0xffff) && org_c);
|
||||||
|
|
||||||
setRegister(dst_reg, v);
|
setRegister(dst_reg, v);
|
||||||
}
|
}
|
||||||
|
@ -946,7 +946,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
const uint16_t vo = a.value.value();
|
const uint16_t vo = a.value.value();
|
||||||
bool org_c = getPSW_c();
|
bool org_c = getPSW_c();
|
||||||
uint16_t v = (vo + org_c) & (word_mode ? 0x00ff : 0xffff);
|
uint16_t v = (vo + org_c) & (word_mode == wm_byte ? 0x00ff : 0xffff);
|
||||||
|
|
||||||
b->write(a.addr.value(), word_mode, v, false);
|
b->write(a.addr.value(), word_mode, v, false);
|
||||||
|
|
||||||
|
@ -955,8 +955,8 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v((word_mode ? (vo & 0xff) == 0x7f : vo == 0x7fff) && org_c);
|
setPSW_v((word_mode == wm_byte ? (vo & 0xff) == 0x7f : vo == 0x7fff) && org_c);
|
||||||
setPSW_c((word_mode ? (vo & 0xff) == 0xff : vo == 0xffff) && org_c);
|
setPSW_c((word_mode == wm_byte ? (vo & 0xff) == 0xff : vo == 0xffff) && org_c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,15 +967,15 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
if (dst_mode == 0) {
|
if (dst_mode == 0) {
|
||||||
uint16_t v = getRegister(dst_reg);
|
uint16_t v = getRegister(dst_reg);
|
||||||
const uint16_t vo = v;
|
const uint16_t vo = v;
|
||||||
uint16_t add = word_mode ? v & 0xff00 : 0;
|
uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0;
|
||||||
bool org_c = getPSW_c();
|
bool org_c = getPSW_c();
|
||||||
|
|
||||||
v = (v - org_c) & (word_mode ? 0xff : 0xffff);
|
v = (v - org_c) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
v |= add;
|
v |= add;
|
||||||
|
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v(word_mode ? (vo & 0xff) == 0x80 : vo == 0x8000);
|
setPSW_v(word_mode == wm_byte ? (vo & 0xff) == 0x80 : vo == 0x8000);
|
||||||
|
|
||||||
if (IS_0(vo, word_mode) && org_c)
|
if (IS_0(vo, word_mode) && org_c)
|
||||||
setPSW_c(true);
|
setPSW_c(true);
|
||||||
|
@ -988,7 +988,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
const uint16_t vo = a.value.value();
|
const uint16_t vo = a.value.value();
|
||||||
bool org_c = getPSW_c();
|
bool org_c = getPSW_c();
|
||||||
uint16_t v = (vo - org_c) & (word_mode ? 0xff : 0xffff);
|
uint16_t v = (vo - org_c) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
|
|
||||||
b->write(a.addr.value(), word_mode, v, false);
|
b->write(a.addr.value(), word_mode, v, false);
|
||||||
|
|
||||||
|
@ -997,7 +997,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, word_mode));
|
setPSW_z(IS_0(v, word_mode));
|
||||||
setPSW_v(word_mode? (vo & 0xff) == 0x80 : vo == 0x8000);
|
setPSW_v(word_mode == wm_byte ? (vo & 0xff) == 0x80 : vo == 0x8000);
|
||||||
|
|
||||||
if (IS_0(vo, word_mode) && org_c)
|
if (IS_0(vo, word_mode) && org_c)
|
||||||
setPSW_c(true);
|
setPSW_c(true);
|
||||||
|
@ -1023,7 +1023,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
bool new_carry = v & 1;
|
bool new_carry = v & 1;
|
||||||
|
|
||||||
uint16_t temp = 0;
|
uint16_t temp = 0;
|
||||||
if (word_mode) {
|
if (word_mode == wm_byte) {
|
||||||
uint16_t add = v & 0xff00;
|
uint16_t add = v & 0xff00;
|
||||||
|
|
||||||
temp = (v >> 1) | (getPSW_c() << 7) | add;
|
temp = (v >> 1) | (getPSW_c() << 7) | add;
|
||||||
|
@ -1045,7 +1045,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
bool new_carry = t & 1;
|
bool new_carry = t & 1;
|
||||||
|
|
||||||
uint16_t temp = 0;
|
uint16_t temp = 0;
|
||||||
if (word_mode)
|
if (word_mode == wm_byte)
|
||||||
temp = (t >> 1) | (getPSW_c() << 7);
|
temp = (t >> 1) | (getPSW_c() << 7);
|
||||||
else
|
else
|
||||||
temp = (t >> 1) | (getPSW_c() << 15);
|
temp = (t >> 1) | (getPSW_c() << 15);
|
||||||
|
@ -1070,7 +1070,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
bool new_carry = false;
|
bool new_carry = false;
|
||||||
|
|
||||||
uint16_t temp = 0;
|
uint16_t temp = 0;
|
||||||
if (word_mode) {
|
if (word_mode == wm_byte) {
|
||||||
new_carry = v & 0x80;
|
new_carry = v & 0x80;
|
||||||
temp = (((v << 1) | getPSW_c()) & 0xff) | (v & 0xff00);
|
temp = (((v << 1) | getPSW_c()) & 0xff) | (v & 0xff00);
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1092,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
bool new_carry = false;
|
bool new_carry = false;
|
||||||
|
|
||||||
uint16_t temp = 0;
|
uint16_t temp = 0;
|
||||||
if (word_mode) {
|
if (word_mode == wm_byte) {
|
||||||
new_carry = t & 0x80;
|
new_carry = t & 0x80;
|
||||||
temp = ((t << 1) | getPSW_c()) & 0xff;
|
temp = ((t << 1) | getPSW_c()) & 0xff;
|
||||||
}
|
}
|
||||||
|
@ -1119,11 +1119,11 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
if (dst_mode == 0) {
|
if (dst_mode == 0) {
|
||||||
uint16_t v = getRegister(dst_reg);
|
uint16_t v = getRegister(dst_reg);
|
||||||
|
|
||||||
bool hb = word_mode ? v & 128 : v & 32768;
|
bool hb = word_mode == wm_byte ? v & 128 : v & 32768;
|
||||||
|
|
||||||
setPSW_c(v & 1);
|
setPSW_c(v & 1);
|
||||||
|
|
||||||
if (word_mode) {
|
if (word_mode == wm_byte) {
|
||||||
uint16_t add = v & 0xff00;
|
uint16_t add = v & 0xff00;
|
||||||
|
|
||||||
v = (v & 255) >> 1;
|
v = (v & 255) >> 1;
|
||||||
|
@ -1144,13 +1144,13 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
else {
|
else {
|
||||||
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
uint16_t v = a.value.value();
|
uint16_t v = a.value.value();
|
||||||
uint16_t add = word_mode ? v & 0xff00 : 0;
|
uint16_t add = word_mode == wm_byte ? v & 0xff00 : 0; // TODO is this right?
|
||||||
|
|
||||||
bool hb = word_mode ? v & 128 : v & 32768;
|
bool hb = word_mode == wm_byte ? v & 128 : v & 32768;
|
||||||
|
|
||||||
setPSW_c(v & 1);
|
setPSW_c(v & 1);
|
||||||
|
|
||||||
if (word_mode) {
|
if (word_mode == wm_byte) {
|
||||||
v = (v & 255) >> 1;
|
v = (v & 255) >> 1;
|
||||||
v |= hb << 7;
|
v |= hb << 7;
|
||||||
v |= add;
|
v |= add;
|
||||||
|
@ -1176,13 +1176,13 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
case 0b00110011: { // ASL/ASLB
|
case 0b00110011: { // ASL/ASLB
|
||||||
if (dst_mode == 0) {
|
if (dst_mode == 0) {
|
||||||
uint16_t vl = getRegister(dst_reg);
|
uint16_t vl = getRegister(dst_reg);
|
||||||
uint16_t add = word_mode ? vl & 0xff00 : 0;
|
uint16_t add = word_mode == wm_byte ? vl & 0xff00 : 0;
|
||||||
|
|
||||||
uint16_t v = (vl << 1) & (word_mode ? 0xff : 0xffff);
|
uint16_t v = (vl << 1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
v |= add;
|
v |= add;
|
||||||
|
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, false));
|
setPSW_z(IS_0(v, wm_word));
|
||||||
setPSW_c(SIGN(vl, word_mode));
|
setPSW_c(SIGN(vl, word_mode));
|
||||||
setPSW_v(getPSW_n() ^ getPSW_c());
|
setPSW_v(getPSW_n() ^ getPSW_c());
|
||||||
|
|
||||||
|
@ -1192,13 +1192,13 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
else {
|
else {
|
||||||
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto a = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
uint16_t vl = a.value.value();
|
uint16_t vl = a.value.value();
|
||||||
uint16_t v = (vl << 1) & (word_mode ? 0xff : 0xffff);
|
uint16_t v = (vl << 1) & (word_mode == wm_byte ? 0xff : 0xffff);
|
||||||
|
|
||||||
bool set_flags = a.addr.value() != ADDR_PSW;
|
bool set_flags = a.addr.value() != ADDR_PSW;
|
||||||
|
|
||||||
if (set_flags) {
|
if (set_flags) {
|
||||||
setPSW_n(SIGN(v, word_mode));
|
setPSW_n(SIGN(v, word_mode));
|
||||||
setPSW_z(IS_0(v, false));
|
setPSW_z(IS_0(v, wm_word));
|
||||||
setPSW_c(SIGN(vl, word_mode));
|
setPSW_c(SIGN(vl, word_mode));
|
||||||
setPSW_v(getPSW_n() ^ getPSW_c());
|
setPSW_v(getPSW_n() ^ getPSW_c());
|
||||||
}
|
}
|
||||||
|
@ -1218,28 +1218,28 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
v = getRegister(dst_reg, true);
|
v = getRegister(dst_reg, true);
|
||||||
else {
|
else {
|
||||||
// calculate address in current address space
|
// calculate address in current address space
|
||||||
auto a = getGAMAddress(dst_mode, dst_reg, false);
|
auto a = getGAMAddress(dst_mode, dst_reg, wm_word);
|
||||||
|
|
||||||
set_flags = a.addr.value() != ADDR_PSW;
|
set_flags = a.addr.value() != ADDR_PSW;
|
||||||
|
|
||||||
if (a.addr.value() >= 0160000) {
|
if (a.addr.value() >= 0160000) {
|
||||||
// read from previous space
|
// read from previous space
|
||||||
v = b->read(a.addr.value(), false, true);
|
v = b->read(a.addr.value(), wm_word, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int run_mode = (getPSW() >> 12) & 3;
|
int run_mode = (getPSW() >> 12) & 3;
|
||||||
auto phys = b->calculate_physical_address(run_mode, a.addr.value());
|
auto phys = b->calculate_physical_address(run_mode, a.addr.value());
|
||||||
|
|
||||||
uint32_t a = word_mode ? phys.physical_data : phys.physical_instruction;
|
uint32_t a = word_mode == wm_byte ? phys.physical_data : phys.physical_instruction;
|
||||||
|
|
||||||
b->check_odd_addressing(a, run_mode, word_mode ? d_space : i_space, false);
|
b->check_odd_addressing(a, run_mode, word_mode ? d_space : i_space, false);
|
||||||
|
|
||||||
v = b->readPhysical(word_mode ? phys.physical_data : phys.physical_instruction);
|
v = b->readPhysical(word_mode == wm_byte ? phys.physical_data : phys.physical_instruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_flags)
|
if (set_flags)
|
||||||
setPSW_flags_nzv(v, false);
|
setPSW_flags_nzv(v, wm_word);
|
||||||
|
|
||||||
// put on current stack
|
// put on current stack
|
||||||
pushStack(v);
|
pushStack(v);
|
||||||
|
@ -1260,29 +1260,29 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
if (dst_mode == 0)
|
if (dst_mode == 0)
|
||||||
setRegister(dst_reg, v, true);
|
setRegister(dst_reg, v, true);
|
||||||
else {
|
else {
|
||||||
auto a = getGAMAddress(dst_mode, dst_reg, false);
|
auto a = getGAMAddress(dst_mode, dst_reg, wm_word);
|
||||||
|
|
||||||
set_flags = a.addr.value() != ADDR_PSW;
|
set_flags = a.addr.value() != ADDR_PSW;
|
||||||
|
|
||||||
if (a.addr.value() >= 0160000)
|
if (a.addr.value() >= 0160000)
|
||||||
b->write(a.addr.value(), false, v, true); // put in '13/12' address space
|
b->write(a.addr.value(), wm_word, v, true); // put in '13/12' address space
|
||||||
else {
|
else {
|
||||||
int run_mode = (getPSW() >> 12) & 3;
|
int run_mode = (getPSW() >> 12) & 3;
|
||||||
auto phys = b->calculate_physical_address(run_mode, a.addr.value());
|
auto phys = b->calculate_physical_address(run_mode, a.addr.value());
|
||||||
|
|
||||||
DOLOG(debug, true, "%lu %06o MTP%c %06o: %06o", mtpi_count, pc-2, word_mode ? 'D' : 'I', a.addr.value(), v);
|
DOLOG(debug, true, "%lu %06o MTP%c %06o: %06o", mtpi_count, pc-2, word_mode == wm_byte ? 'D' : 'I', a.addr.value(), v);
|
||||||
mtpi_count++;
|
mtpi_count++;
|
||||||
|
|
||||||
uint32_t a = word_mode ? phys.physical_data : phys.physical_instruction;
|
uint32_t a = word_mode == wm_byte ? phys.physical_data : phys.physical_instruction;
|
||||||
|
|
||||||
b->check_odd_addressing(a, run_mode, word_mode ? d_space : i_space, true);
|
b->check_odd_addressing(a, run_mode, word_mode == wm_byte ? d_space : i_space, true);
|
||||||
|
|
||||||
b->writePhysical(a, v);
|
b->writePhysical(a, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_flags)
|
if (set_flags)
|
||||||
setPSW_flags_nzv(v, false);
|
setPSW_flags_nzv(v, wm_word);
|
||||||
|
|
||||||
b->addToMMR1(2, 6);
|
b->addToMMR1(2, 6);
|
||||||
|
|
||||||
|
@ -1290,7 +1290,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0b000110100: // MARK/MTPS (put something in PSW)
|
case 0b000110100: // MARK/MTPS (put something in PSW)
|
||||||
if (word_mode) { // MTPS
|
if (word_mode == wm_byte) { // MTPS
|
||||||
#if 0 // not in the PDP-11/70
|
#if 0 // not in the PDP-11/70
|
||||||
psw &= 0xff00; // only alter lower 8 bits
|
psw &= 0xff00; // only alter lower 8 bits
|
||||||
psw |= getGAM(dst_mode, dst_reg, word_mode, false).value.value() & 0xef; // can't change bit 4
|
psw |= getGAM(dst_mode, dst_reg, word_mode, false).value.value() & 0xef; // can't change bit 4
|
||||||
|
@ -1308,7 +1308,7 @@ bool cpu::single_operand_instructions(const uint16_t instr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0b000110111: { // MFPS (get PSW to something) / SXT
|
case 0b000110111: { // MFPS (get PSW to something) / SXT
|
||||||
if (word_mode) { // MFPS
|
if (word_mode == wm_byte) { // MFPS
|
||||||
#if 0 // not in the PDP-11/70
|
#if 0 // not in the PDP-11/70
|
||||||
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
auto g_dst = getGAM(dst_mode, dst_reg, word_mode, false);
|
||||||
|
|
||||||
|
@ -1544,7 +1544,7 @@ bool cpu::misc_operations(const uint16_t instr)
|
||||||
|
|
||||||
int dst_reg = instr & 7;
|
int dst_reg = instr & 7;
|
||||||
|
|
||||||
bool word_mode = false;
|
word_mode_t word_mode = wm_word;
|
||||||
setPC(getGAMAddress(dst_mode, dst_reg, word_mode).addr.value());
|
setPC(getGAMAddress(dst_mode, dst_reg, word_mode).addr.value());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1557,7 +1557,7 @@ bool cpu::misc_operations(const uint16_t instr)
|
||||||
|
|
||||||
int dst_reg = instr & 7;
|
int dst_reg = instr & 7;
|
||||||
|
|
||||||
auto dst_value = getGAMAddress(dst_mode, dst_reg, false).addr.value();
|
auto dst_value = getGAMAddress(dst_mode, dst_reg, wm_word).addr.value();
|
||||||
|
|
||||||
int link_reg = (instr >> 6) & 7;
|
int link_reg = (instr >> 6) & 7;
|
||||||
|
|
||||||
|
@ -1659,7 +1659,7 @@ void cpu::trap(uint16_t vector, const int new_ipl, const bool is_interrupt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const bool word_mode) const
|
cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const
|
||||||
{
|
{
|
||||||
assert(mode_register < 64);
|
assert(mode_register < 64);
|
||||||
|
|
||||||
|
@ -1667,7 +1667,7 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c
|
||||||
|
|
||||||
int reg = mode_register & 7;
|
int reg = mode_register & 7;
|
||||||
|
|
||||||
uint16_t mask = word_mode ? 0xff : 0xffff;
|
uint16_t mask = word_mode == wm_byte ? 0xff : 0xffff;
|
||||||
|
|
||||||
std::string reg_name;
|
std::string reg_name;
|
||||||
if (reg == 6)
|
if (reg == 6)
|
||||||
|
@ -1697,7 +1697,7 @@ cpu::operand_parameters cpu::addressing_to_string(const uint8_t mode_register, c
|
||||||
return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peekWord(b->peekWord(getRegister(reg))) & mask) };
|
return { format("@(%s)+", reg_name.c_str()), 2, -1, uint16_t(b->peekWord(b->peekWord(getRegister(reg))) & mask) };
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peekWord(getRegister(reg) - (word_mode == false || reg >= 6 ? 2 : 1)) & mask) };
|
return { format("-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peekWord(getRegister(reg) - (word_mode == wm_word || reg >= 6 ? 2 : 1)) & mask) };
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peekWord(b->peekWord(getRegister(reg) - 2)) & mask) };
|
return { format("@-(%s)", reg_name.c_str()), 2, -1, uint16_t(b->peekWord(b->peekWord(getRegister(reg) - 2)) & mask) };
|
||||||
|
@ -1722,8 +1722,8 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
||||||
{
|
{
|
||||||
uint16_t instruction = b->peekWord(addr);
|
uint16_t instruction = b->peekWord(addr);
|
||||||
|
|
||||||
bool word_mode = !!(instruction & 0x8000);
|
word_mode_t word_mode = instruction & 0x8000 ? wm_byte : wm_word;
|
||||||
std::string word_mode_str = word_mode ? "B" : "";
|
std::string word_mode_str = word_mode == wm_byte ? "B" : "";
|
||||||
uint8_t ado_opcode = (instruction >> 9) & 7; // additional double operand
|
uint8_t ado_opcode = (instruction >> 9) & 7; // additional double operand
|
||||||
uint8_t do_opcode = (instruction >> 12) & 7; // double operand
|
uint8_t do_opcode = (instruction >> 12) & 7; // double operand
|
||||||
uint8_t so_opcode = (instruction >> 6) & 63; // single operand
|
uint8_t so_opcode = (instruction >> 6) & 63; // single operand
|
||||||
|
@ -1752,7 +1752,7 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
||||||
// single_operand_instructions
|
// single_operand_instructions
|
||||||
switch(so_opcode) {
|
switch(so_opcode) {
|
||||||
case 0b00000011:
|
case 0b00000011:
|
||||||
if (!word_mode)
|
if (word_mode == wm_word)
|
||||||
text = "SWAB " + dst_text.operand;
|
text = "SWAB " + dst_text.operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1805,20 +1805,20 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0b00110101:
|
case 0b00110101:
|
||||||
name = word_mode ? "MFPD" : "MFPI";
|
name = word_mode == wm_byte ? "MFPD" : "MFPI";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0b00110110:
|
case 0b00110110:
|
||||||
name = word_mode ? "MTPD" : "MTPI";
|
name = word_mode == wm_byte ? "MTPD" : "MTPI";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0b000110100:
|
case 0b000110100:
|
||||||
if (word_mode == true)
|
if (word_mode == wm_byte)
|
||||||
name = "MTPS";
|
name = "MTPS";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0b000110111:
|
case 0b000110111:
|
||||||
if (word_mode == true)
|
if (word_mode == wm_byte)
|
||||||
name = "MFPS";
|
name = "MFPS";
|
||||||
else
|
else
|
||||||
name = "SXT";
|
name = "SXT";
|
||||||
|
@ -1832,7 +1832,7 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
||||||
instruction_words.push_back(next_word);
|
instruction_words.push_back(next_word);
|
||||||
}
|
}
|
||||||
else if (do_opcode == 0b111) {
|
else if (do_opcode == 0b111) {
|
||||||
if (word_mode)
|
if (word_mode == wm_byte)
|
||||||
name = "?";
|
name = "?";
|
||||||
else {
|
else {
|
||||||
std::string src_text = format("R%d", (instruction >> 6) & 7);
|
std::string src_text = format("R%d", (instruction >> 6) & 7);
|
||||||
|
@ -1898,7 +1898,7 @@ std::map<std::string, std::vector<std::string> > cpu::disassemble(const uint16_t
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0b110:
|
case 0b110:
|
||||||
if (word_mode)
|
if (word_mode == wm_byte)
|
||||||
name = "SUB";
|
name = "SUB";
|
||||||
else
|
else
|
||||||
name = "ADD";
|
name = "ADD";
|
||||||
|
|
14
cpu.h
14
cpu.h
|
@ -13,7 +13,7 @@
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool word_mode;
|
word_mode_t word_mode;
|
||||||
bool prev_mode;
|
bool prev_mode;
|
||||||
d_i_space_t space;
|
d_i_space_t space;
|
||||||
|
|
||||||
|
@ -51,11 +51,11 @@ private:
|
||||||
|
|
||||||
uint16_t addRegister(const int nr, const bool prev_mode, const uint16_t value);
|
uint16_t addRegister(const int nr, const bool prev_mode, const uint16_t value);
|
||||||
|
|
||||||
void addToMMR1(const uint8_t mode, const uint8_t reg, const bool word_mode);
|
void addToMMR1(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode);
|
||||||
|
|
||||||
|
|
||||||
gam_rc_t getGAM(const uint8_t mode, const uint8_t reg, const bool word_mode, const bool prev_mode, const bool read_value = true);
|
gam_rc_t getGAM(const uint8_t mode, const uint8_t reg, const word_mode_t word_mode, const bool prev_mode, const bool read_value = true);
|
||||||
gam_rc_t getGAMAddress(const uint8_t mode, const int reg, const bool word_mode);
|
gam_rc_t getGAMAddress(const uint8_t mode, const int reg, const word_mode_t word_mode);
|
||||||
bool putGAM(const gam_rc_t & g, const uint16_t value); // returns false when flag registers should not be updated
|
bool putGAM(const gam_rc_t & g, const uint16_t value); // returns false when flag registers should not be updated
|
||||||
|
|
||||||
bool double_operand_instructions(const uint16_t instr);
|
bool double_operand_instructions(const uint16_t instr);
|
||||||
|
@ -72,7 +72,7 @@ private:
|
||||||
uint16_t work_value;
|
uint16_t work_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
operand_parameters addressing_to_string(const uint8_t mode_register, const uint16_t pc, const bool word_mode) const;
|
operand_parameters addressing_to_string(const uint8_t mode_register, const uint16_t pc, const word_mode_t word_mode) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit cpu(bus *const b, std::atomic_uint32_t *const event);
|
explicit cpu(bus *const b, std::atomic_uint32_t *const event);
|
||||||
|
@ -118,7 +118,7 @@ public:
|
||||||
void setPSW_n(const bool v);
|
void setPSW_n(const bool v);
|
||||||
void setPSW_spl(const int v);
|
void setPSW_spl(const int v);
|
||||||
void setBitPSW(const int bit, const bool v);
|
void setBitPSW(const int bit, const bool v);
|
||||||
void setPSW_flags_nzv(const uint16_t value, const bool word_mode);
|
void setPSW_flags_nzv(const uint16_t value, const word_mode_t word_mode);
|
||||||
|
|
||||||
uint16_t getPSW() const { return psw; }
|
uint16_t getPSW() const { return psw; }
|
||||||
void setPSW(const uint16_t v, const bool limited);
|
void setPSW(const uint16_t v, const bool limited);
|
||||||
|
@ -131,7 +131,7 @@ public:
|
||||||
|
|
||||||
void setRegister(const int nr, const uint16_t value, const bool prev_mode = false);
|
void setRegister(const int nr, const uint16_t value, const bool prev_mode = false);
|
||||||
|
|
||||||
void setRegisterLowByte(const int nr, const bool prev_mode, const uint16_t value);
|
void setRegisterLowByte(const int nr, const word_mode_t word_mode, const uint16_t value);
|
||||||
|
|
||||||
void setStackPointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; }
|
void setStackPointer(const int which, const uint16_t value) { assert(which >= 0 && which < 4); sp[which] = value; }
|
||||||
void setPC(const uint16_t value) { pc = value; }
|
void setPC(const uint16_t value) { pc = value; }
|
||||||
|
|
|
@ -111,8 +111,8 @@ void dump_par_pdr(console *const cnsl, bus *const b, const uint16_t pdrs, const
|
||||||
cnsl->put_string_lf(" PAR PDR");
|
cnsl->put_string_lf(" PAR PDR");
|
||||||
|
|
||||||
for(int i=0; i<8; i++) {
|
for(int i=0; i<8; i++) {
|
||||||
uint16_t par_value = b->read(pars + i * 2, false, false, true);
|
uint16_t par_value = b->read(pars + i * 2, wm_word, false, true);
|
||||||
uint16_t pdr_value = b->read(pdrs + i * 2, false, false, true);
|
uint16_t pdr_value = b->read(pdrs + i * 2, wm_word, false, true);
|
||||||
|
|
||||||
uint16_t pdr_len = (((pdr_value >> 8) & 127) + 1) * 64;
|
uint16_t pdr_len = (((pdr_value >> 8) & 127) + 1) * 64;
|
||||||
|
|
||||||
|
@ -317,9 +317,9 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
|
||||||
|
|
||||||
for(int i=0; i<n; i++) {
|
for(int i=0; i<n; i++) {
|
||||||
if (!word)
|
if (!word)
|
||||||
val = b->read(addr + i, true, false, true);
|
val = b->read(addr + i, wm_byte, false, true);
|
||||||
else if (word)
|
else if (word)
|
||||||
val = b->read(addr + i, false, false, true);
|
val = b->read(addr + i, wm_word, false, true);
|
||||||
|
|
||||||
if (val == -1) {
|
if (val == -1) {
|
||||||
cnsl->put_string_lf(format("Can't read from %06o\n", addr + i));
|
cnsl->put_string_lf(format("Can't read from %06o\n", addr + i));
|
||||||
|
|
Loading…
Add table
Reference in a new issue