ENTERPRISE KLUB
2019. szeptember 7., 1055 Budapest, Nyugati tér 9. 14-19 óráig
Részletek
Welcome, Guest. Please login or register.


Author Topic: Wiznet 5100/5300 /etc and Enterprise (Read 11538 times)

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #45 on: 2015.July.04. 17:35:58 »
Dear All EPNET Fans! :)

I've exchanged some mails with Bruce meanwhile about the plans on project EPNET. I've already started to write a small "test program" which can be run (in theory ... without any hardware yet, I can't be sure, as I already write it by reading the specification from Wiznet) with the real EPNET and with my emulator Xep128 too (which will support _some_ features of the real hardware, the keyword here is "will", so it's in future tense).

The first problem of mine: where are the six I/O ports from viewpoint of EP. As Bruce told me, it's not a fixed I/O address, also Xep128 likely will use another - fixed - port. I proposed some kind of complicated way to find the I/O port (ie, scan segments to find EPNET ROM and then call a routine there which can tell). It's clear that Bruce has more experience with the Enterprise in general than me (hehe, no wonder ...) because he suggested to use an EXDOS-like method instead. That is: use an EXOS command with a probably impossible to type character in the command itself (like EXDOS\0xFD).

The idea basically: issue the EXOS command EPNET\0xFF (EXOS 26 call with DE set with that string, length of 6) and if command is returned with OK status (as far as I remember, A = 0), maybe register B contains the I/O port. Of course further functionalities can be provided by the EPNET ROM, ie, low level socket manipulation routines etc, and also EXOS integration, but the I/O port is the very basic thing to write the first apps which want to do all the I/O at their own and they only need the I/O address for this. I guess even SymbOS would use that, since - as far as I know - SymbOS loader uses some EXOS commands anyway, but does directly everything after that point by its own, when SymbOS is already running. Of course this "I/O port detection method" via EXOS will be supported by Xep128 too.

Any feedback, opinion, new ideas are welcome. Of course with proper EXOS integration (ie, devices like HTTP: etc) can make it possible later to even write network/internet capable software in IS-BASIC, now the I/O-port related problem is mainly about for the EP apps doing direct I/O anyway (probably including SymbOS!), because as far as I can see it can take more time to develop proper EP OS (EXOS) software support, but I can be wrong ...

Offline Prodatron

  • EP fan
  • *
  • Posts: 249
  • Country: de
  • Back on the Z80
  • OS:
  • Windows 7/Server 2008 R2 Windows 7/Server 2008 R2
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://www.symbos.de
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #46 on: 2015.July.04. 17:59:15 »
Isn't there a map of all known I/O ports for the EP? Or are I/O ports handled in a dynamic way all the time for additional hardware expansions?
On the CPC and even the MSX (but they usually use their memory mapped based slot system) I/O addresses of hardware expansions are always fixed, and we have this table to prevent conflicts between existing and new hardware.
But it's not a problem to detect the I/O port while booting SymbOS or to add them to the Network Daemon setup tab.

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #47 on: 2015.July.04. 18:03:17 »
Honestly, I don't know. You should ask Bruce, or Zozo. What I know that maybe with the bus bridge there was a nice idea to have some kind of "auto config" ability for cards, ie inserting even same type of cards but getting "private" resources (as for memory segments and I/O port ranges) based on (maybe) the card slot position. Or something like this ... The idea is quite "plug and play" like stuff, but ... I think it's not so well known method in Hungary for example and nobody cared on this later. Really, these are my best guesses, I am lame with this topic, just I tried to answer ...

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #48 on: 2015.July.04. 18:08:10 »
Additionally: I think this not fixed I/O address idea has one big disadvantage: the code will be slower maybe. My idea would be to do some kind of self modification on start-up for the I/O ports used inside the code (after the detection when you know what they would be modified to ...). Well, at least at places where it is critical for the performance, eg in the loop of reading/writing TX/RX buffers of w5300, thus the real packet data exchange between the wiz chip and the EP. Most other parts are not so critical for performance, like set up a new connection etc. Just my ideas, of course. The best solution would be :) some kind of odd executable format which not only aware of memory address relocation but I/O port address relocation too. :-) Ok, maybe it's a too big idea without too much sense :)
« Last Edit: 2015.July.04. 18:14:23 by lgb »

Offline Prodatron

  • EP fan
  • *
  • Posts: 249
  • Country: de
  • Back on the Z80
  • OS:
  • Windows 7/Server 2008 R2 Windows 7/Server 2008 R2
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://www.symbos.de
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #49 on: 2015.July.04. 18:42:11 »
My idea would be to do some kind of self modification on start-up for the I/O ports used inside the code (after the detection when you know what they would be modified to ...).
This is what I would do in any case. At least my W5100 driver for the Amstrad CPC (which would use indirect I/O as well) only has two routines, which really have to deal with the base I/O port: setup the address and return the data port; one for register memory access, one for RX/TX buffer access. The W5300 shouldn't be much more complex. So such an I/O port "relocator" is not a problem at all.

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #50 on: 2015.July.04. 19:37:22 »
This is what I would do in any case. At least my W5100 driver for the Amstrad CPC (which would use indirect I/O as well) only has two routines, which really have to deal with the base I/O port: setup the address and return the data port; one for register memory access, one for RX/TX buffer access. The W5300 shouldn't be much more complex. So such an I/O port "relocator" is not a problem at all.

On w5300, indirect 8 bit mode (what we use) they are the same, RX/TX memories can be read/written through a FIFO register which maintains their (internal, cannot be accessed by the programmer) counters to be able to do that. FIFO register is just like another indirect access mode register for each of the 8 sockets. Only one interesting behaviour can be noticed with FIFO registers: according the specification there is need for very strict order to access IDM_DR0 and IDM_DR1, both of them, exactly in this order (probably because not to confuse the internal counters/pointers for RX/TX buffers). So - as far as I can understand - there are the following primitives (not mentioning accessing MR, which is "direct" even in indirect mode, but that is the only register that kind!):

Code: ZiLOG Z80 Assembler
  1. ; Input: DE = w5300 register number to select
  2. ; Output: C = points to IDM_DR0
  3. select_indirect_register:
  4.   LD C, IOB+2  ; C points to IOB+2 now, which is IDM_AR0, this is the only IOB dependent (IOB+2 ...) place we should modify
  5.   OUT (C), D    ; high byte of DE first!
  6.   INC C           ; C points to IOB+3 now, which is IDM_AR1
  7.   OUT (C), E    ; low byte next!
  8.   INC C           ; just let C points to IOB+4 (IDM_DR0) for the use by write_* and read_* routines
  9.   RET
  10.  
  11. ; Input: C = must point to IDM_DR0 (eg set by select routine)
  12. ;          HL = value to set
  13. write_selected_register:
  14.   OUT (C), H    ; high byte of HL first! output data to IDM_DR0
  15.   INC  C           ; C points to IDM_DR1 now
  16.   OUT  (C), L     ; outputs low byte of data into IDM_DR1
  17.   RET
  18.  
  19. ; Input: C = must point to IDM_DR0 (eg set by select routine)
  20. ; Output: HL = read data
  21. read_selected_register:
  22.   IN   H, (C)  ; high byte first!
  23.   INC  C
  24.   IN   L, (C)   ; low byte next
  25.   RET
  26.  

Sorry, this code above just written by me now for this post (so it can contain mistakes ...), this is not how I do for various reasons. Maybe not even this way it should be written, just the proof of the concept. Here, only one byte needed to be modified for IOB-related. The example not shows operations on MR, but it should be only init-time stuff probably!

Now, with the code above, you can read/write any indirect mode registers with select the register first, then read/write it:

Code: ZiLOG Z80 Assembler
  1. LD DE, 0x202 ; register number in w5300
  2. CALL select_indirect_register
  3. LD HL, 0x1234 ; the data ...
  4. CALL write_selected_register
  5. INC DE
  6. INC DE ; we want register now at 0x204 (do not forget that register address MUST BE even number!), so the next 16 bit register. two INCs!
  7. CALL select_indirect_register
  8. CALL read_selected_register
  9. ; now we have data from register 0x204 in HL
  10.  

Note, that it seems (there are some examples in the specification for that) there is way to read/write only ONE "half" of a 16 bit wide register, ie. setting address 0x202 in IDM_AR and then reading/writing IDM_DR0 will access the high byte of register at 0x202, while accessing IDM_DR1 will do with the low byte, so basically it would be 0x203, but IDM_AR ignores the lowest bit set, as the basic 16 bit construction of w5300. Hopefully you see. However FIFO registers MUST be accessed for IDM_DR0 and IDM_DR1 and exactly at this order. Specification even forbids accessing other register after IDM_DR0 than IDM_DR1 if IDM_AR specifies a FIFO register.

As for FIFO registers then, it can be used this way to, just it will be a bit slow. I think since IDM_AR is enough to set up once, and for eg reading RX buffer (received data), this can be something like this:

Code: ZiLOG Z80 Assembler
  1. LD DE, RX_fifo_register_number_for_the_given_socket_i_dont_know_by_heart_now ... ; :-)
  2. CALL select_indirect_register ; now C points to I/O port on EP for IDM_DR0
  3. IN A, (C) ; read IDM_DR0
  4. INC C
  5. IN A, (C) ; read IDM_DR1
  6. DEC C
  7. IN A, (C) ; read IDM_DR0
  8. INC C
  9. IN A, (C) ; read IDM_DR1
  10. DEC C
  11. ; etc etc etc, but you can only read (or write, if TX FIFO register) EVEN number of bytes!
  12.  

Surely, I was lazy, and I forgot to store the data which was read, after each IN opcodes, so it does not make too much sense if done exactly in this way, again, just for demonstration.

Note, that these are my best guesses now on w5300 in indirect+8 bit mode, I can't be sure if it really works this way.

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #51 on: 2015.July.04. 19:46:31 »
Of course in the case of RX/TX data transfer it's maybe slower to use OUT (0x??), A and similar constructs and self-modify code at init to set them at an altering reg, reg+1 numbers for ports, where reg = IOB + 4 is of course. And I meant about the unrolled loop to do data transfer for bigger data chunks, of course. Because IN/OUT with constant (rather than using register C) is faster (if I remember correctly) and then you can save the INC/DEC C opcodes as well.

Online BruceTanner

  • EP user
  • *
  • Posts: 485
  • Country: gb
  • OS:
  • Windows NT 6.3 Windows NT 6.3
  • Browser:
  • Chrome 43.0.2357.130 Chrome 43.0.2357.130
    • View Profile
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #52 on: 2015.July.04. 21:29:46 »
lgb your description of the data transfer, and your code snippets,  agrees with my current understanding (perhaps not surprising as we have read the same datasheet!!) but I hope to be able to confirm for real very soon.

It's a bit disappointing: at first glance of the datasheet with its auto-incrementing register I thought we'd be able to use INIR etc but on closer inspection it seems not. :(

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #53 on: 2015.July.04. 21:52:49 »
lgb your description of the data transfer, and your code snippets,  agrees with my current understanding (perhaps not surprising as we have read the same datasheet!!) but I hope to be able to confirm for real very soon.

Well, with my misunderstanding ability, it would be no wonder to think about a completely different thing even by reading the same spec as you :)

Quote
It's a bit disappointing: at first glance of the datasheet with its auto-incrementing register I thought we'd be able to use INIR etc but on closer inspection it seems not. :(

Hmm, maybe I missed something, but I have no knowledge about any auto-incrementing stuff, or do you mean about the internal counter of FIFO registers maybe? I wouldn't say that not having INIR is a so big problem. INIR is kinda slow, something like 21 cycles (well, about cycles I can be wrong!). At the other hand, a plain IN A,(nn) - let's say we use constant ports, and unrolled loops for big chunks - is 11. So it's faster this way, but for sure, you need _store_ data too then, so maybe not :) If we optimize this to have EP-memory buffer at fixed 256 byte boundary, it can be eg an LD (BC), A - 7 cycles? - and  a plain INC C (if no 256 byte boundary crossed) - 4 cycles, thus we have 11+7+4 ... well, one cycle slower than INIR and having just too much "good" conditions for being fast. Well, better than nothing ... The other possibility would be using memory mapped I/O, thus not real Z80-like I/O, but using a memory area for that, as SD card does it too. In that case, a bigger area (even 16K, etc, but for real it's even OK to decode a smaller part of the EPNET ROM area for that, of course) can be used to address basically IMD_DR0 or IMD_DR1 based on the lowest bit of the address. The other stuffs can be on I/O port. This sounds insane, but consider this: w5300 seems to be indirect for FIFO TX/RX transfer even in direct mode. Register addressing still indirect and needs IDM_AR on I/O ports (and MR too, of course). But when it is set up, IDM_DR0 and DR1 can be accessed via "normal RAM" thus you can use LDIR (as it increases the source address the toogling A0 line in our "DR segment" would read IDM_DR0, IDM_DR1 sequence as we should!), etc for the actual transfer than! Only some extra decoding should be used. I am not sure if it worth anyway :-| Sounds strange, but I've already started to like it :-P What I see here, that from view point of w5300 even in indirect mode, those are just signals, nothing says we can't map w5300 address pins in an "insane" way :)

One other thing I felt the void before, but I haven't realized: there is no way on the w5300 to detect the link status, speed, etc :( If EPNET ROM would support something like doing DHCP it would only wait for timing out when even no cable plugged in. I don't like this. But what I have is an idea: w5300 has outputs to drive LEDs about some attributes we are interested in. What would happen if we also interpret those as logic levels, routing them onto a buffer IC which is enabled in case of reading of an I/O port after the w5300 IDM's ones? Then we would be able to "read the status of LEDs" basically, or so :) But we can see the link status, speed, etc, from software too!

Offline Prodatron

  • EP fan
  • *
  • Posts: 249
  • Country: de
  • Back on the Z80
  • OS:
  • Windows 7/Server 2008 R2 Windows 7/Server 2008 R2
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://www.symbos.de
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #54 on: 2015.July.04. 22:26:29 »
I am a little bit confused as well. Currently I can't find any information about address-auto-incrementation. Wouldn't that mean, that even when reading/writing from/to the RX/TX buffer you have to update the address after each word? That would slow it down indeed. It's not a tragedy, but I wonder, why they should have leave this feature. The W5100 supports it, so I can't believe that they forgot it for the W5300.

Regarding fast data transfer:
That was my first thought if auto-incrementation would work:

LD C,dataport
LD HL,destination (256 byte aligned)
repeat {
INC L:INI:DEC L:DEC L:INC C:INI:INC L:DEC C  ;16microseconds/word = 8microseconds/byte (CPC; no idea about the exact EP timing)
}

Usually you only have 5 microseconds/byte (CPC way), but I think it would be still ok. Without auto-incrementation it would be indeed slower by a factor of maybe 4 or so?
« Last Edit: 2015.July.04. 22:30:15 by Prodatron »

Online BruceTanner

  • EP user
  • *
  • Posts: 485
  • Country: gb
  • OS:
  • Windows NT 6.3 Windows NT 6.3
  • Browser:
  • Chrome 43.0.2357.130 Chrome 43.0.2357.130
    • View Profile
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #55 on: 2015.July.04. 22:54:20 »
All the code examples in the datasheet just have a loop which reads/writes the bytes from/to the data register.

Online BruceTanner

  • EP user
  • *
  • Posts: 485
  • Country: gb
  • OS:
  • Windows NT 6.3 Windows NT 6.3
  • Browser:
  • Chrome 43.0.2357.130 Chrome 43.0.2357.130
    • View Profile
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #56 on: 2015.July.04. 23:01:26 »
prodatron there is a bit [8] in the Mode Register that byte swaps. So your loops would reduce to INI, INC C, INI, DEC C unless I have misunderstood it :) (very possible :oops: )

Edited to adjust punctuation to avoid accidental smiley face
« Last Edit: 2015.July.04. 23:20:52 by BruceTanner »

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #57 on: 2015.July.04. 23:08:24 »
All the code examples in the datasheet just have a loop which reads/writes the bytes from/to the data register.

Ah yes, those are the FIFO registers. Indeed they have auto-incremented (or decremented) _internal_ pointers pointing in the w5300's RAM, but only a "single" (*later on this) port from the viewpoint of the host. So that you need only read a single port to read RX buffer, and only write a single port to fill the TX buffer. Our problem is, that "the single port" is 16 bit wide, so for real (for a 8 bit system), it's reading/writing port, than port +1, then port, port +1, etc (if IDM_AR is set to the fifo register, it's IDM_DR0 and IDM_DR1 altering access then). Exactly that's why it came into my mind, to map _memory_ accesses for the w5300 as within a memory range any EP memory r/w op interpreted to access IDM_DR0 or IDM_DR1, based on the value of address bus bit0. Thus eg a simple LDIR would be able usable to read/write RX/TX memory, if IDM_AR is set up before, and you are very careful to start on even memory address (A0=0 -> accessing IDM_DR0 first) and doing even number of bytes strictly. You can question if it's sane then to use indirect mode, as we can use the direct one too with memory mapped I/O still using 8 bit. But as far as I can remember, the spec says that FIFO registers are some kind of similar and indirect stuff even in direct mode of w5300, so maybe it does not worth to do.

Unfortunately my proposal means some kind of tricky EP signal decoding can be "expensive" using discrete logic (eg with 74xx series of logic ICs) and would need some kind of GAL, PLD, and such. Then we can say that a given I/O port range for I/O request is forwarded towards the w5300, and a given _memory_ range op is forwarded as IDM bus address 4 or 5 based on the value of A0 from the EP. Then we would be able to use memory based ops to do the data transfer :)

Offline lgb

  • EP addict
  • *
  • Posts: 3496
  • Country: hu
  • æðsta yfirmaður
  • OS:
  • Linux (Ubuntu) Linux (Ubuntu)
  • Browser:
  • Firefox 38.0 Firefox 38.0
    • View Profile
    • http://lgb.hu/
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #58 on: 2015.July.04. 23:19:29 »
prodatron there is a bit (8) in the Mode Register that byte swaps. So your loops would reduce to INI, INC C, INI, DEC C unless I have misunderstood it :) (very possible :oops: )

Please don't do that. :) It's kinda useless, unless someone can test it on the real hardware, as the specification is quite confusing here (maybe at least for me, only!). The spec says that accessing of FIFO registers are _always_ should be done in DR0, DR1 order. So it seems even if you use the FIFO swap feature then? Because in this case, data bytes are swapped, so you will read 'hello!' as 'ehll!o' then. At least, in the 8 bit code example, the normal byte order of w5300 (which is the opposite of Z80 btw) results in the "natural" buffer order still from the view point of a 8 bit system. See the example on page 87. The 8 bit version still sends the text "abcde" in this order as you would read that string. If you swap byte order in MR "FS bit" then it will be quite odd pattern, _unless_ if the rule of "DR0 then DR1 for FIFO access" is not reversed as well, but it's not mentioned it seems. I more and more believe in, that these byte order changing stuffs has not so much sense in 8 bit mode because if the nature, it would be required for a 16 bit I/O capable system (but then you can use the DBS bit in MR which would swap 8 bit halves of the data bus for every registers not just for the FIFO registers). So, in nutshell: I feel a bit lost on this issue, but at this moment I would say, it won't work to well to utilize that feature ...

Online BruceTanner

  • EP user
  • *
  • Posts: 485
  • Country: gb
  • OS:
  • Windows NT 6.3 Windows NT 6.3
  • Browser:
  • Chrome 43.0.2357.130 Chrome 43.0.2357.130
    • View Profile
Re: Wiznet 5100/5300 /etc and Enterprise
« Reply #59 on: 2015.July.04. 23:38:02 »
Please don't do that. :)

ok, I won't, I hadn't read that example! :oops: