mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-02-04 21:32:17 +00:00
Merge branch 'master' into cpu-refactor2
This commit is contained in:
commit
3c3d0b46db
File diff suppressed because it is too large
Load Diff
@ -24,12 +24,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef struct PPCDisasmContext {
|
||||
uint32_t instr_addr;
|
||||
uint32_t instr_code;
|
||||
std::string instr_str;
|
||||
bool simplified; /* true if we should output simplified mnemonics */
|
||||
std::vector<std::string> regs_in;
|
||||
std::vector<std::string> regs_out;
|
||||
} PPCDisasmContext;
|
||||
|
||||
std::string disassemble_single(PPCDisasmContext* ctx);
|
||||
|
@ -115,7 +115,7 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
|
||||
ppc_state.spr[SPR::SRR1] = (ppc_state.msr & 0x0000FF73) | srr1_bits;
|
||||
ppc_state.msr &= 0xFFFB1041;
|
||||
/* copy MSR[ILE] to MSR[LE] */
|
||||
ppc_state.msr = (ppc_state.msr & 0xFFFFFFFE) | ((ppc_state.msr >> 16) & 1);
|
||||
ppc_state.msr = (ppc_state.msr & ~MSR::LE) | !!(ppc_state.msr & MSR::ILE);
|
||||
|
||||
if (ppc_state.msr & MSR::IP) {
|
||||
ppc_next_instruction_address |= 0xFFF00000;
|
||||
|
@ -94,7 +94,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
uint32_t ppc_result_b = ppc_state.gpr[reg_b];
|
||||
|
||||
#define ppc_store_iresult_reg(reg, ppc_result)\
|
||||
ppc_state.gpr[(reg)] = ppc_result;
|
||||
ppc_state.gpr[reg] = ppc_result;
|
||||
|
||||
#define ppc_store_sfpresult_int(reg, ppc_result64_d)\
|
||||
ppc_state.fpr[(reg)].int64_r = ppc_result64_d;
|
||||
|
@ -391,7 +391,7 @@ void mmu_change_mode()
|
||||
break;
|
||||
case 1:
|
||||
// user mode can't disable translations
|
||||
LOG_F(ERROR, "instruction mmu mode 1 is invalid!");
|
||||
//LOG_F(ERROR, "instruction mmu mode 1 is invalid!"); // this happens alot. Maybe it's not invalid?
|
||||
mmu_mode = 3;
|
||||
case 3: // user mode with instruction translation enabled
|
||||
pCurITLB1 = &itlb1_mode3[0];
|
||||
|
@ -528,7 +528,7 @@ void dppc_interpreter::ppc_mulli() {
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::ppc_divw() {
|
||||
uint32_t ppc_result_d;
|
||||
uint32_t ppc_result_d = 0;
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
|
||||
if (!ppc_result_b) { /* handle the "anything / 0" case */
|
||||
@ -564,7 +564,7 @@ template void dppc_interpreter::ppc_divw<RC1, OV1>();
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::ppc_divwu() {
|
||||
uint32_t ppc_result_d;
|
||||
uint32_t ppc_result_d = 0;
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
|
||||
if (!ppc_result_b) { /* division by zero */
|
||||
|
@ -96,7 +96,7 @@ uint8_t AdbBus::process_command(const uint8_t* in_data, int data_size) {
|
||||
if (!this->got_answer)
|
||||
return ADB_STAT_TIMEOUT;
|
||||
} else {
|
||||
ABORT_F("%s: unsupported ADB command 0x%X", this->name.c_str(), cmd_byte);
|
||||
LOG_F(ERROR, "%s: unsupported ADB command 0x%X", this->name.c_str(), cmd_byte);
|
||||
}
|
||||
|
||||
return ADB_STAT_OK;
|
||||
|
@ -130,7 +130,7 @@ void DMAChannel::finish_cmd() {
|
||||
this->cur_cmd = cmd_desc[3] >> 4;
|
||||
|
||||
// all commands except STOP update cmd.xferStatus and
|
||||
// perform actions under control of "i", "b" and "w" bits
|
||||
// perform actions under control of "i" interrupt, "b" branch, and "w" wait bits
|
||||
if (this->cur_cmd < DBDMA_Cmd::STOP) {
|
||||
// react to cmd.w (wait) bits
|
||||
if (cmd_desc[2] & 3) {
|
||||
@ -258,7 +258,10 @@ void DMAChannel::update_irq() {
|
||||
}
|
||||
}
|
||||
if (cond) {
|
||||
if (int_ctrl)
|
||||
this->int_ctrl->ack_dma_int(this->irq_id, 1);
|
||||
else
|
||||
LOG_F(ERROR, "%s Interrupt ignored", this->get_name().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -344,8 +347,10 @@ void DMAChannel::reg_write(uint32_t offset, uint32_t value, int size) {
|
||||
break;
|
||||
case DMAReg::CH_STAT:
|
||||
break; // ingore writes to ChannelStatus
|
||||
case DMAReg::CMD_PTR_HI: // Mac OS X writes this optional register with zero
|
||||
LOG_F(9, "CommandPtrHi set to 0x%X", value);
|
||||
case DMAReg::CMD_PTR_HI:
|
||||
if (value != 0) {
|
||||
LOG_F(WARNING, "%s: Unsupported DMA channel register write @%02x.%c = %0*x", this->get_name().c_str(), offset, SIZE_ARG(size), size * 2, value);
|
||||
}
|
||||
break;
|
||||
case DMAReg::CMD_PTR_LO:
|
||||
if (!(this->ch_stat & CH_STAT_RUN) && !(this->ch_stat & CH_STAT_ACTIVE)) {
|
||||
@ -462,11 +467,11 @@ void DMAChannel::start() {
|
||||
|
||||
this->queue_len = 0;
|
||||
|
||||
this->cmd_in_progress = false;
|
||||
|
||||
if (this->start_cb)
|
||||
this->start_cb();
|
||||
|
||||
this->cmd_in_progress = false;
|
||||
|
||||
// some DBDMA programs contain commands that don't transfer data
|
||||
// between a device and memory (LOAD_QUAD, STORE_QUAD, NOP and STOP).
|
||||
// We thus interprete the DBDMA program until a data transfer between
|
||||
|
@ -40,28 +40,48 @@ class InterruptCtrl;
|
||||
enum DMAReg : uint32_t {
|
||||
CH_CTRL = 0,
|
||||
CH_STAT = 4,
|
||||
CMD_PTR_HI = 8,
|
||||
CMD_PTR_HI = 8, // not implemented
|
||||
CMD_PTR_LO = 12,
|
||||
INT_SELECT = 16,
|
||||
BRANCH_SELECT = 20,
|
||||
WAIT_SELECT = 24,
|
||||
// TANSFER_MODES = 28,
|
||||
// DATA_2_PTR_HI = 32, // not implemented
|
||||
// DATA_2_PTR_LO = 36,
|
||||
// RESERVED_1 = 40,
|
||||
// ADDRESS_HI = 44,
|
||||
// RESERVED_2_0 = 48,
|
||||
// RESERVED_2_1 = 52,
|
||||
// RESERVED_2_2 = 56,
|
||||
// RESERVED_2_3 = 60,
|
||||
// UNIMPLEMENTED = 64,
|
||||
// UNDEFINED = 128,
|
||||
};
|
||||
|
||||
/** Channel Status bits (DBDMA spec, 5.5.3) */
|
||||
enum : uint16_t {
|
||||
CH_STAT_ACTIVE = 0x400,
|
||||
CH_STAT_DEAD = 0x800,
|
||||
CH_STAT_WAKE = 0x1000,
|
||||
CH_STAT_FLUSH = 0x2000,
|
||||
CH_STAT_PAUSE = 0x4000,
|
||||
CH_STAT_RUN = 0x8000
|
||||
CH_STAT_S0 = 0x0001, // general purpose status and control
|
||||
CH_STAT_S1 = 0x0002, // general purpose status and control
|
||||
CH_STAT_S2 = 0x0004, // general purpose status and control
|
||||
CH_STAT_S3 = 0x0008, // general purpose status and control
|
||||
CH_STAT_S4 = 0x0010, // general purpose status and control
|
||||
CH_STAT_S5 = 0x0020, // general purpose status and control
|
||||
CH_STAT_S6 = 0x0040, // general purpose status and control
|
||||
CH_STAT_S7 = 0x0080, // general purpose status and control
|
||||
CH_STAT_BT = 0x0100, // hardware status bit
|
||||
CH_STAT_ACTIVE = 0x0400, // hardware status bit
|
||||
CH_STAT_DEAD = 0x0800, // hardware status bit
|
||||
CH_STAT_WAKE = 0x1000, // command bit set by software and cleared by hardware once the action has been performed
|
||||
CH_STAT_FLUSH = 0x2000, // command bit set by software and cleared by hardware once the action has been performed
|
||||
CH_STAT_PAUSE = 0x4000, // control bit set and cleared by software
|
||||
CH_STAT_RUN = 0x8000 // control bit set and cleared by software
|
||||
};
|
||||
|
||||
/** DBDMA command (DBDMA spec, 5.6.1) - all fields are little-endian! */
|
||||
typedef struct DMACmd {
|
||||
uint16_t req_count;
|
||||
uint8_t cmd_bits;
|
||||
uint8_t cmd_key;
|
||||
uint8_t cmd_bits; // wait: & 3, branch: & 0xC, interrupt: & 0x30, reserved: & 0xc0
|
||||
uint8_t cmd_key; // key: & 7, reserved: & 8, cmd: >> 4
|
||||
uint32_t address;
|
||||
uint32_t cmd_arg;
|
||||
uint16_t res_count;
|
||||
|
@ -36,4 +36,7 @@ public:
|
||||
virtual ~MMIODevice() = default;
|
||||
};
|
||||
|
||||
#define SIZE_ARG(size) (size == 4 ? 'l' : size == 2 ? 'w' : \
|
||||
size == 1 ? 'b' : '0' + size)
|
||||
|
||||
#endif /* MMIO_DEVICE_H */
|
||||
|
@ -197,9 +197,6 @@ inline uint32_t pci_cfg_log(uint32_t value, AccessDetails &details) {
|
||||
}
|
||||
}
|
||||
|
||||
#define SIZE_ARG(size) (size == 4 ? 'l' : size == 2 ? 'w' : \
|
||||
size == 1 ? 'b' : '0' + size)
|
||||
|
||||
#define LOG_READ_UNIMPLEMENTED_CONFIG_REGISTER() \
|
||||
do { if ((details.flags & PCI_CONFIG_DIRECTION) == PCI_CONFIG_READ) { \
|
||||
VLOG_F( \
|
||||
|
@ -185,6 +185,10 @@ uint16_t Sc53C94::pseudo_dma_read()
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_F(ERROR, "SC53C94: FIFO underrun %d", data_fifo_pos);
|
||||
data_word = 0;
|
||||
}
|
||||
|
||||
// see if we need to refill FIFO
|
||||
if (!this->data_fifo_pos && !is_done) {
|
||||
|
@ -28,7 +28,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <machines/machineproperties.h>
|
||||
#include <memaccess.h>
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
@ -239,7 +238,7 @@ static char Apple_Copyright_Page_Data[] = "APPLE COMPUTER, INC ";
|
||||
void ScsiCdrom::mode_sense()
|
||||
{
|
||||
uint8_t page_code = this->cmd_buf[2] & 0x3F;
|
||||
uint8_t alloc_len = this->cmd_buf[4];
|
||||
//uint8_t alloc_len = this->cmd_buf[4];
|
||||
|
||||
int num_blocks = this->size_blocks;
|
||||
|
||||
|
@ -82,7 +82,8 @@ void AwacsBase::dma_out_start() {
|
||||
|
||||
if (!this->out_stream_running) {
|
||||
if ((err = snd_server->start_out_stream())) {
|
||||
LOG_F(ERROR, "%s: could not start sound output stream", this->name.c_str());
|
||||
LOG_F(ERROR, "%s: could not start sound output stream: %d",
|
||||
this->name.c_str(), err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,9 @@ uint32_t BurgundyCodec::snd_ctrl_read(uint32_t offset, int size) {
|
||||
}
|
||||
|
||||
void BurgundyCodec::snd_ctrl_write(uint32_t offset, uint32_t value, int size) {
|
||||
uint8_t reg_addr, cur_byte, last_byte;
|
||||
uint8_t reg_addr;
|
||||
uint8_t cur_byte;
|
||||
//uint8_t last_byte;
|
||||
|
||||
value = BYTESWAP_32(value);
|
||||
|
||||
@ -71,7 +73,7 @@ void BurgundyCodec::snd_ctrl_write(uint32_t offset, uint32_t value, int size) {
|
||||
this->last_ctrl_data = value;
|
||||
reg_addr = (value >> 12) & 0xFF;
|
||||
cur_byte = (value >> 8) & 3;
|
||||
last_byte = (value >> 10) & 3;
|
||||
//last_byte = (value >> 10) & 3;
|
||||
if (value & BURGUNDY_REG_WR) {
|
||||
uint32_t mask = 0xFFU << (cur_byte * 8);
|
||||
this->reg_array[reg_addr] = (this->reg_array[reg_addr] & ~mask) |
|
||||
|
@ -686,28 +686,21 @@ void AtiMach64Gx::crtc_update()
|
||||
this->crtc_on = true;
|
||||
}
|
||||
|
||||
void AtiMach64Gx::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
|
||||
uint8_t *src_buf, *src_row, *dst_row, px4;
|
||||
|
||||
void AtiMach64Gx::draw_hw_cursor(uint8_t *dst_row, int dst_pitch) {
|
||||
int vert_offset = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_OFF], ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size);
|
||||
//int horz_offset = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_OFF], ATI_CUR_HORZ_OFF, ATI_CUR_HORZ_OFF_size);
|
||||
|
||||
src_buf = &this->vram_ptr[this->regs[ATI_CUR_OFFSET] * 8];
|
||||
|
||||
int cur_height = 64 - vert_offset;
|
||||
|
||||
uint32_t color0 = this->regs[ATI_CUR_CLR0] | 0x000000FFUL;
|
||||
uint32_t color1 = this->regs[ATI_CUR_CLR1] | 0x000000FFUL;
|
||||
|
||||
for (int h = 0; h < cur_height; h++) {
|
||||
dst_row = &dst_buf[h * dst_pitch];
|
||||
src_row = &src_buf[h * 16];
|
||||
uint64_t *src_row = (uint64_t *)&this->vram_ptr[this->regs[ATI_CUR_OFFSET] * 8];
|
||||
dst_pitch -= 64 * 4;
|
||||
|
||||
for (int x = 0; x < 16; x++) {
|
||||
px4 = src_row[x];
|
||||
|
||||
for (int p = 0; p < 4; p++, px4 >>= 2, dst_row += 4) {
|
||||
switch(px4 & 3) {
|
||||
for (int h = cur_height; h > 0; h--) {
|
||||
for (int x = 2; x > 0; x--) {
|
||||
uint64_t px = *src_row++;
|
||||
for (int p = 32; p > 0; p--, px >>= 2, dst_row += 4) {
|
||||
switch(px & 3) {
|
||||
case 0: // cursor color 0
|
||||
WRITE_DWORD_BE_A(dst_row, color0);
|
||||
break;
|
||||
@ -718,15 +711,18 @@ void AtiMach64Gx::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
|
||||
WRITE_DWORD_BE_A(dst_row, 0);
|
||||
break;
|
||||
case 3: // 1's complement of display pixel
|
||||
WRITE_DWORD_BE_A(dst_row, 0x0000007F);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_row += dst_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void AtiMach64Gx::get_cursor_position(int& x, int& y) {
|
||||
x = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_HORZ_POSN, ATI_CUR_HORZ_POSN_size);
|
||||
x = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_HORZ_POSN, ATI_CUR_HORZ_POSN_size) -
|
||||
extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_OFF ], ATI_CUR_HORZ_OFF , ATI_CUR_HORZ_OFF_size );
|
||||
y = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_VERT_POSN, ATI_CUR_VERT_POSN_size);
|
||||
}
|
||||
|
||||
|
@ -385,6 +385,16 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ATI_CUR_CLR0:
|
||||
case ATI_CUR_CLR1:
|
||||
this->setup_hw_cursor();
|
||||
// fallthrough
|
||||
case ATI_CUR_OFFSET:
|
||||
case ATI_CUR_HORZ_VERT_POSN:
|
||||
case ATI_CUR_HORZ_VERT_OFF:
|
||||
new_value = value;
|
||||
draw_fb = true;
|
||||
break;
|
||||
case ATI_GP_IO:
|
||||
new_value = value;
|
||||
if (offset <= 1 && offset + size > 1) {
|
||||
@ -446,6 +456,7 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
|
||||
this->setup_hw_cursor();
|
||||
else
|
||||
this->cursor_on = false;
|
||||
draw_fb = true;
|
||||
}
|
||||
if (bit_changed(old_value, new_value, ATI_GEN_GUI_RESETB)) {
|
||||
if (!bit_set(new_value, ATI_GEN_GUI_RESETB))
|
||||
@ -549,9 +560,11 @@ void ATIRage::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int siz
|
||||
{
|
||||
if (rgn_start == this->aperture_base[0] && offset < this->aperture_size[0]) {
|
||||
if (offset < this->vram_size) { // little-endian VRAM region
|
||||
draw_fb = true;
|
||||
return write_mem(&this->vram_ptr[offset], value, size);
|
||||
}
|
||||
if (offset >= BE_FB_OFFSET) { // big-endian VRAM region
|
||||
draw_fb = true;
|
||||
return write_mem(&this->vram_ptr[offset & (BE_FB_OFFSET - 1)], value, size);
|
||||
}
|
||||
//if (!bit_set(this->regs[ATI_BUS_CNTL], ATI_BUS_APER_REG_DIS)) {
|
||||
@ -695,38 +708,45 @@ void ATIRage::crtc_update() {
|
||||
switch (this->pixel_format) {
|
||||
case 1:
|
||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
||||
draw_fb = false;
|
||||
this->convert_frame_4bpp_indexed(dst_buf, dst_pitch);
|
||||
};
|
||||
break;
|
||||
case 2:
|
||||
if (bit_set(this->regs[ATI_DAC_CNTL], ATI_DAC_DIRECT)) {
|
||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
||||
draw_fb = false;
|
||||
this->convert_frame_8bpp(dst_buf, dst_pitch);
|
||||
};
|
||||
}
|
||||
else {
|
||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
||||
draw_fb = false;
|
||||
this->convert_frame_8bpp_indexed(dst_buf, dst_pitch);
|
||||
};
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
||||
draw_fb = false;
|
||||
this->convert_frame_15bpp_BE(dst_buf, dst_pitch);
|
||||
};
|
||||
break;
|
||||
case 4:
|
||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
||||
draw_fb = false;
|
||||
this->convert_frame_16bpp(dst_buf, dst_pitch);
|
||||
};
|
||||
break;
|
||||
case 5:
|
||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
||||
draw_fb = false;
|
||||
this->convert_frame_24bpp(dst_buf, dst_pitch);
|
||||
};
|
||||
break;
|
||||
case 6:
|
||||
this->convert_fb_cb = [this](uint8_t *dst_buf, int dst_pitch) {
|
||||
draw_fb = false;
|
||||
this->convert_frame_32bpp_BE(dst_buf, dst_pitch);
|
||||
};
|
||||
break;
|
||||
@ -757,27 +777,22 @@ void ATIRage::crtc_update() {
|
||||
this->crtc_on = true;
|
||||
}
|
||||
|
||||
void ATIRage::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
|
||||
uint8_t *src_buf, *src_row, *dst_row, px4;
|
||||
|
||||
int vert_offset = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_OFF], ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size);
|
||||
|
||||
src_buf = &this->vram_ptr[this->regs[ATI_CUR_OFFSET] * 8];
|
||||
|
||||
void ATIRage::draw_hw_cursor(uint8_t* dst_row, int dst_pitch) {
|
||||
int vert_offset = extract_bits<uint32_t>(
|
||||
this->regs[ATI_CUR_HORZ_VERT_OFF], ATI_CUR_VERT_OFF, ATI_CUR_VERT_OFF_size);
|
||||
int cur_height = 64 - vert_offset;
|
||||
|
||||
uint32_t color0 = this->regs[ATI_CUR_CLR0] | 0x000000FFUL;
|
||||
uint32_t color1 = this->regs[ATI_CUR_CLR1] | 0x000000FFUL;
|
||||
|
||||
for (int h = 0; h < cur_height; h++) {
|
||||
dst_row = &dst_buf[h * dst_pitch];
|
||||
src_row = &src_buf[h * 16];
|
||||
uint64_t* src_row = (uint64_t*)&this->vram_ptr[this->regs[ATI_CUR_OFFSET] * 8];
|
||||
dst_pitch -= 64 * 4;
|
||||
|
||||
for (int x = 0; x < 16; x++) {
|
||||
px4 = src_row[x];
|
||||
|
||||
for (int p = 0; p < 4; p++, px4 >>= 2, dst_row += 4) {
|
||||
switch(px4 & 3) {
|
||||
for (int h = cur_height; h > 0; h--) {
|
||||
for (int x = 2; x > 0; x--) {
|
||||
uint64_t px = *src_row++;
|
||||
for (int p = 32; p > 0; p--, px >>= 2, dst_row += 4) {
|
||||
switch (px & 3) {
|
||||
case 0: // cursor color 0
|
||||
WRITE_DWORD_BE_A(dst_row, color0);
|
||||
break;
|
||||
@ -793,11 +808,13 @@ void ATIRage::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
|
||||
}
|
||||
}
|
||||
}
|
||||
dst_row += dst_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void ATIRage::get_cursor_position(int& x, int& y) {
|
||||
x = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_HORZ_POSN, ATI_CUR_HORZ_POSN_size);
|
||||
x = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_HORZ_POSN, ATI_CUR_HORZ_POSN_size) -
|
||||
extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_OFF ], ATI_CUR_HORZ_OFF , ATI_CUR_HORZ_OFF_size );
|
||||
y = extract_bits<uint32_t>(this->regs[ATI_CUR_HORZ_VERT_POSN], ATI_CUR_VERT_POSN, ATI_CUR_VERT_POSN_size);
|
||||
}
|
||||
|
||||
|
@ -74,9 +74,15 @@ void VideoCtrlBase::update_screen()
|
||||
this->get_cursor_position(cursor_x, cursor_y);
|
||||
}
|
||||
|
||||
if (draw_fb) {
|
||||
if (this->cursor_dirty) {
|
||||
this->setup_hw_cursor();
|
||||
this->cursor_dirty = false;
|
||||
}
|
||||
this->display.update(
|
||||
this->convert_fb_cb, this->cursor_ovl_cb,
|
||||
this->cursor_on, cursor_x, cursor_y);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCtrlBase::start_refresh_task() {
|
||||
|
@ -75,6 +75,7 @@ protected:
|
||||
bool crtc_on = false;
|
||||
bool blank_on = true;
|
||||
bool cursor_on = false;
|
||||
bool cursor_dirty = false;
|
||||
int active_width; // width of the visible display area
|
||||
int active_height; // height of the visible display area
|
||||
int hori_total = 0;
|
||||
@ -85,6 +86,7 @@ protected:
|
||||
int pixel_format;
|
||||
float pixel_clock;
|
||||
float refresh_rate;
|
||||
bool draw_fb = true;
|
||||
|
||||
uint32_t palette[256]; // internal DAC palette in RGBA format
|
||||
|
||||
|
@ -342,7 +342,7 @@ int MachineFactory::load_boot_rom(string& rom_filepath) {
|
||||
size_t file_size;
|
||||
int result = 0;
|
||||
uint32_t rom_load_addr;
|
||||
AddressMapEntry *rom_reg;
|
||||
//AddressMapEntry *rom_reg;
|
||||
|
||||
rom_file.open(rom_filepath, ios::in | ios::binary);
|
||||
if (rom_file.fail()) {
|
||||
@ -373,7 +373,7 @@ int MachineFactory::load_boot_rom(string& rom_filepath) {
|
||||
MemCtrlBase* mem_ctrl = dynamic_cast<MemCtrlBase*>(
|
||||
gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
|
||||
|
||||
if ((rom_reg = mem_ctrl->find_rom_region())) {
|
||||
if ((/*rom_reg = */mem_ctrl->find_rom_region())) {
|
||||
mem_ctrl->set_data(rom_load_addr, sysrom_mem, (uint32_t)file_size);
|
||||
} else {
|
||||
LOG_F(ERROR, "Could not locate physical ROM region!");
|
||||
|
Loading…
x
Reference in New Issue
Block a user