From 2f725fe3e4c25bb085e8888fc35ffafaef7705ae Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Thu, 14 Oct 2021 00:01:30 +0200 Subject: [PATCH] viacuda: fix PRAM reading and writing. --- devices/viacuda.cpp | 45 ++++++++++++++++++++++++++++++++------------- devices/viacuda.h | 9 ++++++--- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/devices/viacuda.cpp b/devices/viacuda.cpp index bfc651e..f4df27d 100644 --- a/devices/viacuda.cpp +++ b/devices/viacuda.cpp @@ -24,10 +24,12 @@ along with this program. If not, see . Author: Max Poliakovski 2019 */ -#include "viacuda.h" #include "adb.h" +#include "memaccess.h" +#include "viacuda.h" #include #include +#include using namespace std; @@ -43,19 +45,14 @@ ViaCuda::ViaCuda() { this->via_regs[VIA_T1LH] = 0xFF; this->via_regs[VIA_IER] = 0x7F; - // PRAM Pre-Initialization - this->pram_obj = new NVram("pram.bin", 256); + // PRAM is part of Cuda + this->pram_obj = std::unique_ptr (new NVram("pram.bin", 256)); this->adb_obj = new ADB_Bus(); this->init(); } -ViaCuda::~ViaCuda() { - if (this->pram_obj) - delete (this->pram_obj); -} - void ViaCuda::init() { this->old_tip = 0; this->old_byteack = 0; @@ -197,11 +194,17 @@ void ViaCuda::write(uint8_t new_state) { } } -/* sends zeros to host at infinitum */ +/* sends zeros to host ad infinitum */ void ViaCuda::null_out_handler() { this->via_regs[VIA_SR] = 0; } +/* sends PRAM content to host ad infinitum */ +void ViaCuda::pram_out_handler() +{ + this->via_regs[VIA_SR] = this->pram_obj->read_byte(this->cur_pram_addr++); +} + /* sends data from out_buf until exhausted, then switches to next_out_handler */ void ViaCuda::out_buf_handler() { if (this->out_pos < this->out_count) { @@ -307,6 +310,8 @@ void ViaCuda::process_adb_command(uint8_t cmd_byte, int data_count) { } void ViaCuda::pseudo_command(int cmd, int data_count) { + uint16_t addr; + switch (cmd) { case CUDA_START_STOP_AUTOPOLL: if (this->in_buf[2]) { @@ -317,12 +322,26 @@ void ViaCuda::pseudo_command(int cmd, int data_count) { response_header(CUDA_PKT_PSEUDO, 0); break; case CUDA_READ_PRAM: - response_header(CUDA_PKT_PSEUDO, 0); - this->pram_obj->read_byte(this->in_buf[2]); + addr = READ_WORD_BE_A(&this->in_buf[2]); + if (addr <= 0xFF) { + response_header(CUDA_PKT_PSEUDO, 0); + // this command is open-ended so set up the corresponding context + this->cur_pram_addr = addr; + this->next_out_handler = &ViaCuda::pram_out_handler; + this->is_open_ended = true; + } else { + error_response(CUDA_ERR_BAD_PAR); + } break; case CUDA_WRITE_PRAM: - response_header(CUDA_PKT_PSEUDO, 0); - this->pram_obj->write_byte(this->in_buf[2], this->in_buf[3]); + addr = READ_WORD_BE_A(&this->in_buf[2]); + if (addr <= 0xFF) { + // TODO: implement open-ended write transaction properly + response_header(CUDA_PKT_PSEUDO, 0); + this->pram_obj->write_byte(addr, this->in_buf[4]); + } else { + error_response(CUDA_ERR_BAD_PAR); + } break; case CUDA_SET_AUTOPOLL_RATE: this->poll_rate = this->in_buf[2]; diff --git a/devices/viacuda.h b/devices/viacuda.h index 0b7194c..00a0aea 100644 --- a/devices/viacuda.h +++ b/devices/viacuda.h @@ -49,6 +49,7 @@ along with this program. If not, see . #include "hwcomponent.h" #include "i2c.h" #include "nvram.h" +#include /** VIA register offsets. */ enum { @@ -103,6 +104,7 @@ enum { CUDA_ERR_BAD_PKT = 1, /* invalid packet type */ CUDA_ERR_BAD_CMD = 2, /* invalid pseudo command */ CUDA_ERR_BAD_SIZE = 3, /* invalid packet size */ + CUDA_ERR_BAD_PAR = 4, /* invalid parameter */ CUDA_ERR_I2C = 5 /* invalid I2C data or no acknowledge */ }; @@ -110,7 +112,7 @@ enum { class ViaCuda : public HWComponent, public I2CBus { public: ViaCuda(); - ~ViaCuda(); + ~ViaCuda() = default; bool supports_type(HWCompType type) { return (type == HWCompType::ADB_HOST || type == HWCompType::I2C_HOST); @@ -135,11 +137,12 @@ private: bool is_open_ended; uint8_t curr_i2c_addr; + uint8_t cur_pram_addr; void (ViaCuda::*out_handler)(void); void (ViaCuda::*next_out_handler)(void); - NVram* pram_obj; + std::unique_ptr pram_obj; ADB_Bus* adb_obj; void print_enabled_ints(); /* print enabled VIA interrupts and their sources */ @@ -149,13 +152,13 @@ private: void assert_sr_int(); void write(uint8_t new_state); void response_header(uint32_t pkt_type, uint32_t pkt_flag); - // void cuda_response_packet(); void error_response(uint32_t error); void process_packet(); void process_adb_command(uint8_t cmd_byte, int data_count); void pseudo_command(int cmd, int data_count); void null_out_handler(void); + void pram_out_handler(void); void out_buf_handler(void); void i2c_handler(void);