mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-22 14:30:31 +00:00
viacuda: fix PRAM reading and writing.
This commit is contained in:
parent
e53296f7a9
commit
2f725fe3e4
@ -24,10 +24,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
Author: Max Poliakovski 2019
|
||||
*/
|
||||
|
||||
#include "viacuda.h"
|
||||
#include "adb.h"
|
||||
#include "memaccess.h"
|
||||
#include "viacuda.h"
|
||||
#include <cinttypes>
|
||||
#include <loguru.hpp>
|
||||
#include <memory>
|
||||
|
||||
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<NVram> (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];
|
||||
|
@ -49,6 +49,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include "hwcomponent.h"
|
||||
#include "i2c.h"
|
||||
#include "nvram.h"
|
||||
#include <memory>
|
||||
|
||||
/** 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<NVram> 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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user