Skip to content

Commit 42973e8

Browse files
committed
iris: Implement MAC EEPROM
1 parent 4f2439c commit 42973e8

File tree

10 files changed

+257
-5
lines changed

10 files changed

+257
-5
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ target_sources(iris PRIVATE
194194
src/shared/sif.c
195195
src/shared/speed.c
196196
src/shared/speed/ata.c
197+
src/shared/speed/eeprom.c
197198
src/shared/speed/flash.c
198199
deps/imgui/imgui.cpp
199200
deps/imgui/imgui_demo.cpp

frontend/iris.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ struct instance {
303303
std::string flash_path = "";
304304
std::string ini_path = "";
305305

306+
uint8_t mac_address[6] = { 0 };
307+
306308
bool core0_mute[24] = { false };
307309
bool core1_mute[24] = { false };
308310
int core0_solo = -1;

frontend/settings.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,22 @@ bool parse_toml_settings(iris::instance* iris) {
122122
auto system = tbl["system"];
123123
iris->system = system["model"].value_or(PS2_SYSTEM_AUTO);
124124

125+
toml::array* mac_array = system["mac_address"].as_array();
126+
127+
if (mac_array && mac_array->size() == 6) {
128+
for (int i = 0; i < 6; i++) {
129+
iris->mac_address[i] = static_cast<uint8_t>(mac_array->at(i).as_integer()->get());
130+
}
131+
} else {
132+
// Default MAC address
133+
iris->mac_address[0] = 0x00;
134+
iris->mac_address[1] = 0x1A;
135+
iris->mac_address[2] = 0x2B;
136+
iris->mac_address[3] = 0x3C;
137+
iris->mac_address[4] = 0x4D;
138+
iris->mac_address[5] = 0x5E;
139+
}
140+
125141
auto screenshots = tbl["screenshots"];
126142
iris->screenshot_format = screenshots["format"].value_or(IRIS_SCREENSHOT_FORMAT_PNG);
127143
iris->screenshot_jpg_quality_mode = screenshots["jpg_quality_mode"].value_or(IRIS_SCREENSHOT_JPG_QUALITY_MAXIMUM);
@@ -145,7 +161,7 @@ bool parse_toml_settings(iris::instance* iris) {
145161

146162
auto ui = tbl["ui"];
147163
iris->theme = ui["theme"].value_or(IRIS_THEME_GRANITE);
148-
iris->codeview_font_scale = ui["codeview_font_scale"].value_or(0.0f);
164+
iris->codeview_font_scale = ui["codeview_font_scale"].value_or(1.0f);
149165
iris->codeview_color_scheme = ui["codeview_color_scheme"].value_or(IRIS_CODEVIEW_COLOR_SCHEME_SOLARIZED_DARK);
150166
iris->codeview_use_theme_background = ui["codeview_use_theme_background"].value_or(true);
151167
iris->ui_scale = ui["scale"].value_or(1.0f);
@@ -340,6 +356,7 @@ bool init(iris::instance* iris, int argc, const char* argv[]) {
340356

341357
ps2_set_system(iris->ps2, iris->system);
342358
ps2_speed_load_flash(iris->ps2->speed, iris->flash_path.c_str());
359+
ps2_speed_set_mac_address(iris->ps2->speed, iris->mac_address);
343360

344361
return true;
345362
}
@@ -354,7 +371,15 @@ void close(iris::instance* iris) {
354371

355372
auto tbl = toml::table {
356373
{ "system", toml::table {
357-
{ "model", iris->system }
374+
{ "model", iris->system },
375+
{ "mac_address", toml::array {
376+
iris->mac_address[0],
377+
iris->mac_address[1],
378+
iris->mac_address[2],
379+
iris->mac_address[3],
380+
iris->mac_address[4],
381+
iris->mac_address[5]
382+
} }
358383
} },
359384
{ "screenshots", toml::table {
360385
{ "format", iris->screenshot_format },

frontend/ui/settings.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,29 @@ void show_system_settings(iris::instance* iris) {
148148

149149
EndTable();
150150
}
151+
152+
SeparatorText("Network");
153+
154+
// To-do: Improve MAC address input by using a single text input
155+
// that fills in the colons automatically
156+
157+
Text("MAC Address");
158+
159+
PushFont(iris->font_code);
160+
161+
float w = CalcTextSize("FFFFFFFFFFFF").x;
162+
163+
SetNextItemWidth(w * 2.0);
164+
165+
if (InputScalarN("##macaddress", ImGuiDataType_U8, iris->mac_address, 6, nullptr, nullptr, "%02X", ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_EnterReturnsTrue)) {
166+
ps2_set_mac_address(iris->ps2, iris->mac_address);
167+
} SameLine();
168+
169+
PopFont();
170+
171+
if (Button(ICON_MS_REFRESH "##macaddress")) {
172+
ps2_set_mac_address(iris->ps2, iris->mac_address);
173+
}
151174
}
152175

153176
const char* ssaa_names[] = {

src/ps2.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,4 +517,8 @@ void ps2_set_system(struct ps2_state* ps2, int system) {
517517

518518
ee_bus_init_fastmem(ps2->ee_bus, ps2->ee_ram->size, ps2->iop_ram->size);
519519
iop_bus_init_fastmem(ps2->iop_bus, ps2->iop_ram->size);
520+
}
521+
522+
void ps2_set_mac_address(struct ps2_state* ps2, const uint8_t* mac) {
523+
ps2_speed_set_mac_address(ps2->speed, mac);
520524
}

src/ps2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ void ps2_set_timescale(struct ps2_state* ps2, int timescale);
137137
void ps2_iop_cycle(struct ps2_state* ps2);
138138
void ps2_destroy(struct ps2_state* ps2);
139139
void ps2_set_system(struct ps2_state* ps2, int system);
140+
void ps2_set_mac_address(struct ps2_state* ps2, const uint8_t* mac);
140141

141142
#ifdef __cplusplus
142143
}

src/shared/speed.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@ void ps2_speed_init(struct ps2_speed* speed, struct ps2_iop_intc* iop_intc) {
1414
speed->iop_intc = iop_intc;
1515
speed->flash = ps2_flash_create();
1616
speed->ata = ps2_ata_create();
17+
speed->eeprom = ps2_eeprom_create();
1718

1819
ps2_flash_init(speed->flash);
1920
ps2_ata_init(speed->ata, speed);
21+
ps2_eeprom_init(speed->eeprom);
2022

2123
speed->rev8 |= 2;
2224
}
2325

2426
void ps2_speed_destroy(struct ps2_speed* speed) {
2527
ps2_flash_destroy(speed->flash);
2628
ps2_ata_destroy(speed->ata);
29+
ps2_eeprom_destroy(speed->eeprom);
2730

2831
free(speed);
2932
}
@@ -34,7 +37,7 @@ uint64_t ps2_speed_read8(struct ps2_speed* speed, uint32_t addr) {
3437
printf("speed: read8 %08x %08x\n", addr);
3538

3639
switch (addr) {
37-
case 0x002e: return 0;
40+
case 0x002e: return ps2_eeprom_read(speed->eeprom);
3841
}
3942

4043
return 0;
@@ -87,7 +90,7 @@ void ps2_speed_write8(struct ps2_speed* speed, uint32_t addr, uint64_t data) {
8790

8891
switch (addr) {
8992
case 0x002c: speed->pio_dir = data; return;
90-
case 0x002e: speed->pio_data = data; return;
93+
case 0x002e: ps2_eeprom_write(speed->eeprom, data); return;
9194
}
9295

9396
// exit(1);
@@ -148,4 +151,24 @@ int ps2_speed_load_flash(struct ps2_speed* speed, const char* path) {
148151
}
149152

150153
return ret;
154+
}
155+
156+
void ps2_speed_set_mac_address(struct ps2_speed* speed, const uint8_t* mac) {
157+
uint16_t data[32] = {
158+
0x0000, 0x0000, 0x0000, 0x0000,
159+
0x0000, 0x0000, 0x0000, 0x0000,
160+
0x0000, 0x1000, 0x0000, 0x0000,
161+
0x0000, 0x0000, 0x0000, 0x0000,
162+
0x0010, 0x0000, 0x0000, 0x0000,
163+
0x0000, 0x0000, 0x0000, 0x0000,
164+
0x1000, 0x0000, 0x0000, 0x0000,
165+
0x0000, 0x0000, 0x0000, 0x0000
166+
};
167+
168+
data[0] = (mac[1] << 8) | mac[0];
169+
data[1] = (mac[3] << 8) | mac[2];
170+
data[2] = (mac[5] << 8) | mac[4];
171+
data[3] = data[0] + data[1] + data[2];
172+
173+
ps2_eeprom_load(speed->eeprom, data);
151174
}

src/shared/speed.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern "C" {
1010
#include "iop/intc.h"
1111
#include "speed/ata.h"
1212
#include "speed/flash.h"
13+
#include "speed/eeprom.h"
1314

1415
// SPEED is a chip presented as a register interface to speed devices.
1516
// This includes:
@@ -60,9 +61,9 @@ struct ps2_speed {
6061
uint32_t mwdma_mode; // 10000072
6162
uint32_t udma_mode; // 10000074
6263

63-
// FLASH (XFROM) registers
6464
struct ps2_ata* ata;
6565
struct ps2_flash* flash;
66+
struct ps2_eeprom* eeprom;
6667

6768
struct ps2_iop_intc* iop_intc;
6869
};
@@ -78,6 +79,7 @@ void ps2_speed_write16(struct ps2_speed* speed, uint32_t addr, uint64_t data);
7879
void ps2_speed_write32(struct ps2_speed* speed, uint32_t addr, uint64_t data);
7980
void ps2_speed_send_irq(struct ps2_speed* speed, uint16_t irq);
8081
int ps2_speed_load_flash(struct ps2_speed* speed, const char* path);
82+
void ps2_speed_set_mac_address(struct ps2_speed* speed, const uint8_t* mac);
8183

8284
#ifdef __cplusplus
8385
}

src/shared/speed/eeprom.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include <string.h>
2+
#include <stdio.h>
3+
4+
#include "eeprom.h"
5+
6+
uint16_t default_data[32] = {
7+
0x6D76, 0x6361, 0x3130, 0x0207,
8+
0x0000, 0x0000, 0x0000, 0x0000,
9+
0x0000, 0x1000, 0x0000, 0x0000,
10+
0x0000, 0x0000, 0x0000, 0x0000,
11+
0x0010, 0x0000, 0x0000, 0x0000,
12+
0x0000, 0x0000, 0x0000, 0x0000,
13+
0x1000, 0x0000, 0x0000, 0x0000,
14+
0x0000, 0x0000, 0x0000, 0x0000
15+
};
16+
17+
struct ps2_eeprom* ps2_eeprom_create(void) {
18+
return malloc(sizeof(struct ps2_eeprom));
19+
}
20+
21+
void ps2_eeprom_init(struct ps2_eeprom* eeprom) {
22+
memset(eeprom, 0, sizeof(struct ps2_eeprom));
23+
24+
memcpy(eeprom->buf, default_data, 32 * sizeof(uint16_t));
25+
}
26+
27+
void ps2_eeprom_load(struct ps2_eeprom* eeprom, const uint16_t* data) {
28+
memcpy(eeprom->buf, data, 32 * sizeof(uint16_t));
29+
}
30+
31+
void ps2_eeprom_destroy(struct ps2_eeprom* eeprom) {
32+
free(eeprom);
33+
}
34+
35+
uint64_t ps2_eeprom_read(struct ps2_eeprom* eeprom) {
36+
return eeprom->dout << PP_DOUT;
37+
}
38+
39+
void eeprom_step(struct ps2_eeprom* eeprom) {
40+
switch (eeprom->state) {
41+
case EEPROM_S_CMD_START: {
42+
eeprom->sequence = 0;
43+
44+
if (eeprom->din) {
45+
eeprom->state = EEPROM_S_CMD_READ;
46+
}
47+
} break;
48+
49+
case EEPROM_S_CMD_READ: {
50+
eeprom->cmd |= eeprom->din << (1 - eeprom->sequence);
51+
eeprom->sequence++;
52+
53+
if (eeprom->sequence == 2) {
54+
eeprom->sequence = 0;
55+
eeprom->state = EEPROM_S_ADDR_READ;
56+
}
57+
} break;
58+
59+
case EEPROM_S_ADDR_READ: {
60+
// Address read in from highest bit to lowest bit
61+
eeprom->addr |= eeprom->din << (5 - eeprom->sequence);
62+
63+
// Don't know what the behaviour would be but lets prevent oob.
64+
eeprom->addr = eeprom->addr & 31;
65+
66+
eeprom->sequence++;
67+
if (eeprom->sequence == 6)
68+
{
69+
eeprom->state = EEPROM_S_TRANSMIT;
70+
eeprom->sequence = 0;
71+
}
72+
} break;
73+
74+
// fire away, bit position increments every pulse
75+
case EEPROM_S_TRANSMIT: {
76+
if (eeprom->cmd == PP_OP_READ) {
77+
eeprom->dout = (eeprom->buf[eeprom->addr] >> (15 - eeprom->sequence)) & 1;
78+
}
79+
80+
if (eeprom->cmd == PP_OP_WRITE) {
81+
eeprom->buf[eeprom->addr] = eeprom->buf[eeprom->addr] | (eeprom->din << (15 - eeprom->sequence));
82+
}
83+
84+
eeprom->sequence++;
85+
86+
if (eeprom->sequence == 16) {
87+
eeprom->sequence = 0;
88+
89+
// Let's prevent oob here too
90+
eeprom->addr = (eeprom->addr + 1) & 31;
91+
}
92+
} break;
93+
}
94+
return;
95+
}
96+
97+
void ps2_eeprom_write(struct ps2_eeprom* eeprom, uint64_t data) {
98+
uint8_t csel = (data >> PP_CSEL) & 1;
99+
uint8_t sclk = (data >> PP_SCLK) & 1;
100+
uint8_t din = (data >> PP_DIN) & 1;
101+
102+
if (!csel) {
103+
eeprom->sequence = 0;
104+
eeprom->addr = 0;
105+
eeprom->state = EEPROM_S_CMD_START;
106+
eeprom->clk = 0;
107+
108+
return;
109+
}
110+
111+
eeprom->din = din;
112+
113+
if (sclk && !eeprom->clk) {
114+
eeprom_step(eeprom);
115+
}
116+
117+
eeprom->clk = sclk;
118+
}

src/shared/speed/eeprom.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#ifndef EEPROM_H
2+
#define EEPROM_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
#include <stdint.h>
9+
#include <stdlib.h>
10+
11+
#define PP_DOUT 4
12+
#define PP_DIN 5
13+
#define PP_SCLK 6
14+
#define PP_CSEL 7
15+
#define PP_OP_READ 2
16+
#define PP_OP_WRITE 1
17+
#define PP_OP_EWEN 0
18+
#define PP_OP_EWDS 0
19+
20+
enum {
21+
EEPROM_S_CMD_START,
22+
EEPROM_S_CMD_READ,
23+
EEPROM_S_ADDR_READ,
24+
EEPROM_S_TRANSMIT
25+
};
26+
27+
struct ps2_eeprom {
28+
int state;
29+
30+
// Pins
31+
uint8_t clk;
32+
uint8_t din;
33+
uint8_t dout;
34+
35+
uint8_t cmd;
36+
uint8_t sequence;
37+
uint8_t addr;
38+
39+
uint16_t buf[32];
40+
};
41+
42+
struct ps2_eeprom* ps2_eeprom_create(void);
43+
void ps2_eeprom_init(struct ps2_eeprom* eeprom);
44+
void ps2_eeprom_load(struct ps2_eeprom* eeprom, const uint16_t* data);
45+
void ps2_eeprom_destroy(struct ps2_eeprom* eeprom);
46+
uint64_t ps2_eeprom_read(struct ps2_eeprom* eeprom);
47+
void ps2_eeprom_write(struct ps2_eeprom* eeprom, uint64_t data);
48+
49+
#ifdef __cplusplus
50+
}
51+
#endif
52+
53+
#endif

0 commit comments

Comments
 (0)