1
0
Fork 0
mirror of https://github.com/melonDS-emu/melonDS.git synced 2025-03-06 21:00:31 +01:00
This commit is contained in:
barret 2025-01-22 17:01:33 -07:00
parent c4f682d106
commit ec123fffde
3 changed files with 316 additions and 45 deletions

View file

@ -6,14 +6,21 @@
#include "H8300.h"
#include <string.h>
#include "types.h"
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
H8300::H8300(){
printf("H8/300 has been created");
//debugSerialPort();
}
H8300::~H8300(){
printf("H8/300 has been killed");
}
void H8300::speak(){
@ -21,10 +28,259 @@ void H8300::speak(){
}
//This should be called dynamically??
int H8300::configureSerialPort(){
memset(buf, 0, sizeof(buf));
//This should be configures in options
const char *portname = "/dev/ttyUSB0";
//sudo chmod 666 /dev/ttyUSB0
fd = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1){
printf("H8/300 failed to open the serial port\n");
return 1;
}
struct termios options;
tcgetattr(fd, &options);
//Set walker params. We can potentially make this different if we want to talk to walker EMUS
//baud rate
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
//no parity, 1 stop bit, clear char size mask, 8 data bits, no hardware flow ctrl,
// enable reciever, ignore modem control lines
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CRTSCTS;
options.c_cflag |= CREAD | CLOCAL;
// options.c_cc[VTIME] = 1;
// options.c_cc[VMIN] = 0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &options);
if (tcgetattr(fd, &options) == -1){
printf("H8/300 failed to configure the serial port\n");
close(fd);
return 1;
}
return 0;
}
int H8300::readSerialPort(){
//needs to be done this way so we dont have spliced packets. 4ms of no comms indicates eof. Try to ignore and just wait till there are no packets
/* WORKING BETTER*/
char tempBuf[0xB8];
int len = 1; //read(fd, tempBuf, sizeof(tempBuf));
u8 pointer = 0;
while (len > 0){
usleep(4000);
len = read(fd, tempBuf, sizeof(tempBuf));
if (len < 0) break;
for(int i = 0; i < len; i++){
buf[pointer + i] = tempBuf[i];
}
pointer = pointer + len;
}
recvLen = pointer;
if (recvLen == 0) return 0;
printf("\nrecieved a packet of len: %d\n", recvLen);
for (int i = 0; i < recvLen; i++){
printf("0x%02x ", (u8)buf[i] ^ 0xaa);
}
printf("\n");
return recvLen;
/*
printf("trying to recieve\n");
struct timeval tv;
gettimeofday(&tv, NULL);
long lastRxTime = tv.tv_usec;
char tempBuf[0xB8];
int len = read(fd, tempBuf, sizeof(tempBuf));
u8 pointer = 0;
if (len > 0){
printf("we are rxing a packer");
//We are now recieving a packet
long cond = tv.tv_usec - lastRxTime;
while(cond < 3500){
cond = tv.tv_usec - lastRxTime;
gettimeofday(&tv, NULL);
len = read(fd, tempBuf, sizeof(tempBuf));
if (len < 0) continue;
else{
lastRxTime = tv.tv_usec;
for(int i = 0; i < len; i++){
buf[pointer + i] = tempBuf[i];
}
pointer = pointer + len;
}
}
}
recvLen = pointer;
if (recvLen == 0) return 0;
printf("\nrecieved a packet of len: %d\n", recvLen);
for (int i = 0; i < recvLen; i++){
printf("0x%02x ", (u8)buf[i] ^ 0xaa);
}
printf("\n");
return recvLen;
*/
}
int H8300::sendSerialPort(){
tcflush(fd, TCIFLUSH);
//printf("Send packet requested\n");
printf("\n Sending %d Bytes: %d", sendLen);
/*
for (int i = 0; i < sendLen; i++){
printf("0x%02x ", (u8)sendBuf[i] ^ 0xaa);
}
printf("\n");*/
u8 written = write(fd, sendBuf, sendLen);
//printf("wrote %d bytes\n", written);
// getchar();
return 0;
}
int H8300::debugSerialPort(){
int option = 0;
while(option != 9){
printf("\n\nWelcome to the mini H8/300 Debugger. Please select an option.\n");
printf("1. Read\n");
printf("2. Write\n");
printf("3. FD status\n");
printf("4. Configure Serial Port\n");
printf("5. Close serial port\n");
printf("8. Exit without closing port\n");
printf("9. Exit and close serial port\n");
scanf("%d", &option);
if (option ==1){
//printf("You have 5 seconds to send me some data!!!\n");
//sleep(5);
memset(buf, 0, sizeof(buf));
int len = -1;
while (len < 0){
len = read(fd, buf, sizeof(buf));
}
printf("Rxed %d bytes\n", len);
for (int i = 0; i < len; i++){
printf("0x%02x ", (unsigned char)buf[i]);
}
printf("\n");
}
else if (option == 2){
printf("writing not implemented\n");
}
else if (option == 3){
printf("FD status: %d\n", fd);
}
else if (option == 4){
configureSerialPort();
}
else if (option == 5){
close(fd);
printf("hopefully closed fd\n");
}
else if (option == 8){
break;
}
else if (option == 9){
close(fd);
printf("Exiting.\n");
break;
}
}
return 0;
}
//A botched implementation
u8 H8300::handleSPI(u8& IRCmd, u8& val, u32&pos, bool& last){
printf("IRCmd: %d val:%d pos: %ld last: %d\n", IRCmd, val, pos, last);
// readSerialPort();
// printf("IRCmd: %d val:%02x pos: %ld last: %d\n", IRCmd, val, pos, last);
switch (IRCmd)
{
case 0x00: // pass-through
@ -33,21 +289,51 @@ u8 H8300::handleSPI(u8& IRCmd, u8& val, u32&pos, bool& last){
case 0x01:
u8 rtnval;
if (pos == 0){
return 0x00;
}
if (pos == 1){
rtnval = 0x01;
}
if (pos == 2){
rtnval = 0x56;
}
printf(" returning: 0x%02x val: %d pos: %ld last: %d\n", rtnval, val, pos, last);
return rtnval;
recvLen = readSerialPort();
// printf(" pos 1: found %d bytes\n", recvLen);
return recvLen;
}
else{
u8 data = (unsigned char)buf[pos-2];
// printf(" pos: %02x, last: %d, dgettimeofday(&tv, NULL);ata: 0x%02x \n", pos, last, data);
return data;
}
return 0x00;
case 0x02:
//printf(" press any key to continue.");
//getchar();
if (pos == 0){
// memset(buf, 0, sizeof(buf)); //we can clear our read buffer because we are sending now. (make easier)
// recvLen = 0;
}
else{
sendBuf[pos-1] = val; //Load the spi packet into the buffer;
}
if (last == 1){
sendLen = pos;
sendSerialPort();
}
return 0x00;
case 0x08: // ID
if (fd <0){
printf("Configuring port during IR init sequence\n");
configureSerialPort();
}
return 0xAA;
}
printf("Unhandled: %d val:%d pos: %ld last: %d\n", IRCmd, val, pos, last);
// printf("Unhandled: %d val:%d pos: %ld last: %d\n", IRCmd, val, pos, last);
return 0x00;
}

View file

@ -23,8 +23,24 @@ public:
u8 handleSPI(u8& IRCmd, u8& val, u32&pos, bool& last);
//TODO add options later
int configureSerialPort();
int debugSerialPort();
int readSerialPort();
int sendSerialPort();
private:
int exampleInt;
int sessionStatus = 0;
//file where the TTY will be stores
int fd = -1;
u8 recvLen = 0;
char buf[0xB8];
char sendBuf[0xB8];
u8 sendLen;
};
#endif

View file

@ -1129,48 +1129,17 @@ u8 CartRetailIR::SPIWrite(u8 val, u32 pos, bool last)
//Kind of like an init sequence, we only really care about commands after this first one
if (pos == 0)
{
// printf("IRCmd: %d val:%d pos: %ld last: %d\n", val, val, pos, last);
IRCmd = val;
return 0;
}
// TODO: emulate actual IR comm
if (IRCmd == 0){
return CartRetail::SPIWrite(val, pos-1, last);
}
//Yay I am doing the TODO :) Thanks to the giants that came before me!
else{
return IRChip.handleSPI(IRCmd, val, pos, last);
}
/*
switch (IRCmd)
{
case 0x00: // pass-through
return CartRetail::SPIWrite(val, pos-1, last);
case 0xaa:
u8 rtnval;
if (pos == 1){
rtnval = 0x01;
}
if (pos == 2){
rtnval = 0x56;
}
printf(" returning: 0x%02x val: %d pos: %ld last: %d\n", rtnval, val, pos, last);
return rtnval;
case 0x08: // ID
return 0xAA;
}
return IRChip.handleSPI(val, pos,last);
//printf(" Unhandled Case: val: 0x%02x\n", val);
//return 0;*/
}
//BARRET END CHANGES
CartRetailBT::CartRetailBT(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::unique_ptr<u8[]>&& sram, u32 sramlen, void* userdata) :