1
/* Xep128: Minimalistic Enterprise-128 emulator with focus on "exotic" hardware
2
Copyright (C)2015,2016 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
5
Partial Wiznet W5300 emulation, using the host OS (which runs the emulator)
6
TCP/IP API. Thus, many of the W5300 features won't work, or limited, like:
7
RAW mode, ICMP sockets, listening mode (it would be possible but eg in case
8
of UNIX there would be a need for privilege, which is not so nice to
9
run an emulator as "root" user), no IP/MAC setting (always uses the OS IP
10
and MAC). DHCP and DNS is planned to "faked" so w5300 softwares trying to
11
get IP address via DHCP or wanting resolve a DNS name would get an answer
12
from this w5300 emulator instead of from the "real" network.
14
Note: I've just discovered that FUSE Spectrum emulator does have some kind
15
of w5100 emulation. Though w5100 and w5300 are not the very same, some things
16
are similar, so their sources may help me in the future, thanks for their
17
work (also a GNU/GPL software, so there is no license problem here).
19
This program is free software; you can redistribute it and/or modify
20
it under the terms of the GNU General Public License as published by
21
the Free Software Foundation; either version 2 of the License, or
22
(at your option) any later version.
24
This program is distributed in the hope that it will be useful,
25
but WITHOUT ANY WARRANTY; without even the implied warranty of
26
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
GNU General Public License for more details.
29
You should have received a copy of the GNU General Public License
30
along with this program; if not, write to the Free Software
31
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
38
#ifdef CONFIG_W5300_SUPPORT
42
//static Uint8 wmem[0x20000]; // 128K of internal RAM of w5300
43
static Uint8 wregs[0x400]; // W5300 registers
44
static Uint8 idm_ar0, idm_ar1, idm_ar;
45
static Uint8 mr0, mr1;
46
static void (*interrupt_cb)(int);
49
static void update_interrupts ( void )
51
int v = ((wregs[2] & wregs[4] & 0xF0) | (wregs[3] & wregs[5])) > 0;
60
static Uint8 read_reg ( int addr )
65
static void write_reg ( int addr, Uint8 data )
70
wregs[addr] &= 255 - data;
85
static void default_interrupt_callback ( int level ) {
89
/* ---Interface functions --- */
92
void w5300_reset ( void )
94
memset(wregs, 0, sizeof wregs);
95
mr0 = 0x38; mr1 = 0x00;
96
idm_ar0 = 0; idm_ar1 = 0; idm_ar = 0;
98
wregs[0x1C] = 0x07; wregs[0x1D] = 0xD0; // RTR retransmission timeout-period register
99
wregs[0x1F] = 8; // RCR retransmission retry-count register
100
memset(wregs + 0x20, 8, 16); // TX and RX mem size conf
101
wregs[0x31] = 0xFF; // MTYPER1
102
DEBUG("W5300: reset" NL);
105
void w5300_init ( void (*cb)(int) )
107
interrupt_cb = cb ? cb : default_interrupt_callback;
108
DEBUG("W5300: init" NL);
111
void w5300_shutdown ( void )
113
DEBUG("W5300: shutdown pending connections (if any)" NL);
116
void w5300_write_mr0 ( Uint8 data ) { // high byte of MR
117
if (data & 1) ERROR_WINDOW("W5300: FIFO byte-order swap feature is not emulated");
118
mr0 = data & 0x3F; // DBW and MPF bits cannot be overwritten by user
120
void w5300_write_mr1 ( Uint8 data ) { // low byte of MR
121
if (data & 128) { // software reset?
123
w5300_shutdown(); // shuts down host OS connections, etc, emulator is being done
125
if (data & 8) ERROR_WINDOW("W5300: PPPoE mode is not emulated");
126
if (data & 4) ERROR_WINDOW("W5300: data bus byte-order swap feature is not emulated");
127
if ((data & 1) == 0) ERROR_WINDOW("W5300: direct mode is NOT emulated, only indirect");
131
void w5300_write_idm_ar0 ( Uint8 data ) { // high byte of address
133
idm_ar = (idm_ar & 0xFF) | ((data & 0x3F) << 8);
135
void w5300_write_idm_ar1 ( Uint8 data ) { // low byte of address
137
idm_ar = (idm_ar & 0xFF00) | (data & 0xFE);
139
void w5300_write_idm_dr0 ( Uint8 data ) { // high byte of adta
140
write_reg(idm_ar, data);
142
void w5300_write_idm_dr1 ( Uint8 data ) { // low byte of data
143
write_reg(idm_ar | 1, data);
145
Uint8 w5300_read_mr0 ( void ) {
148
Uint8 w5300_read_mr1 ( void ) {
151
Uint8 w5300_read_idm_ar0 ( void ) {
154
Uint8 w5300_read_idm_ar1 ( void ) {
157
Uint8 w5300_read_idm_dr0 ( void ) {
158
return read_reg(idm_ar);
160
Uint8 w5300_read_idm_dr1 ( void ) {
161
return read_reg(idm_ar | 1);