nedoPC.org

Community of electronics hobbyists established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 16 Sep 2021 10:36



Reply to topic  [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5
Project SprinterNet 
Author Message
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 19894
Location: Silicon Valley
Reply with quote
Обновил исходники сервера в репозитории на гитлабе:

https://gitlab.com/sprinter-computer/net

А также добавил исходники первой сетевой программы для Спринтера :)

https://gitlab.com/sprinter-computer/net/-/blob/master/apps/tests/inet1.asm

Сейчас она работает только в эмуляторе Zpring (скоро выложу исходники с частичной поддержкой сетевого API):

Attachment:
Screenshot from 2021-07-25 01-27-59.png
Screenshot from 2021-07-25 01-27-59.png [ 13.67 KiB | Viewed 466 times ]


P.S. Вторая сетевая программа для Спринтера:

https://gitlab.com/sprinter-computer/net/-/blob/master/apps/tests/inet2.asm

_________________
:eugeek: https://twitter.com/Shaos1973


25 Jul 2021 16:59
Profile WWW
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 19894
Location: Silicon Valley
Reply with quote
Как оказалось мой SprinterNet API очень похож на низкоуровневый API Spectranet (документация на сайте автора похерена):
https://web.archive.org/web/20120212190609/http://spectrum.alioth.net/doc/index.php/Spectranet:_Tutorial_2
Там даже либа для программировании на Си тоже есть, как и я планировал (правда для Z88DK).
Отсюда возникла идея - а не подружить ли SprinterNet и Spectranet? А именно:
- дать возможность со Спринтера ходить по спректранетовским ресурсам в виде TNFS-серверов;
- дать возможность использовать SprinterNet утилиты на ZX со Spectranet (как минимум утилиты командной строки и текстовые утилиты не использующие расширенную память);
- допустить собираемость спектранетовских программ под Спринтер с платой SprinterNet.
А вот запускаемость уже готовых спектранетовских бинарей на Спринтере вряд ли получится т.к. в Спектранете точки входа в API лежат в нулевом окне процессора и подменяют собой 48к ПЗУ спектрума...

_________________
:eugeek: https://twitter.com/Shaos1973


01 Aug 2021 16:06
Profile WWW
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 19894
Location: Silicon Valley
Reply with quote
Сравнение моего SprinterNet API со Spectranet API (по архиву https://web.archive.org/web/20200618075948/http://spectrum.alioth.net/doc/index.php/Software) - как оказалось они очень похожи:

Shaos wrote:
#D003 - getconf (возврат IP-конфигурации путём копирования 32 байт с адреса HL и 6 байт мака с адреса DE) - возвращает конфигурацию в том виде, как она сохранена в EEPROM (имя пользователя, IP-адрес, маска, гейтвей, 3 экстра байта для DHCP и 1 байт таймзона) + MAC;

https://web.archive.org/web/20120414225619/http://spectrum.alioth.net/doc/index.php/Ifconfig_inet
Code:
; get_ifconfig_inet (HLCALL 0x3E6F) - read the internet protocol address
; get_ifconfig_netmask (HLCALL 0x3E72) - read the netmask
; get_ifconfig_gw (HLCALL 0x3E75) - read the default gateway

    ld de, inet_addr
    ld hl, GET_IFCONFIG_INET
    call HLCALL

    ld de, inet_netmask
    ld hl, GET_IFCONFIG_NETMASK
    call HLCALL

    ld de, inet_gw
    ld hl, GET_IFCONFIG_GW
    call HLCALL

; he get_ifconfig_inet(), get_ifconfig_netmask() and get_ifconfig_gw() functions fill a 4 byte buffer with
; the current IP address, netmask and gateway respectively, in big endian form.

Сишный интерфейс:
Code:
    #include <sys/types.h>
    #include <spectranet.h>

    void get_ifconfig_inet(in_addr_t *inet_addr);
    void get_ifconfig_netmask(in_addr_t *inet_netmask);
    void get_ifconfig_gw(in_addr_t *inet_gw);

У меня все настройки забираются в один присест плюс ещё будет возможность забрать настройки в человеческом формате через псевдопеременные.

Shaos wrote:
#D00C - setip (изменение IP-конфигурации с адреса HL) -> A - запись в EEPROM IP-адреса, маски и гейтвея (если IP-адрес нулевой, то в недалёком будущем оно будет в рамках локальной сети делать DHCP запрос) и возвращает код ошибки (0 если всё Ок)- изменение конфигурации повлечёт за собой ре-инициализацию визнета;

https://web.archive.org/web/20120414225619/http://spectrum.alioth.net/doc/index.php/Ifconfig_inet
Code:
; get_ifconfig_inet (HLCALL 0x3E6F) - read the internet protocol address
; get_ifconfig_netmask (HLCALL 0x3E72) - read the netmask
; get_ifconfig_gw (HLCALL 0x3E75) - read the default gateway
; deconfig (HLCALL 0x3E57) - Deconfigure all internet address settings

    ; all the functions use 4 byte buffers for the
    ; big endian address (inet_addr_t)
    ld hl, inet_addr
    ld ix, IFCONFIG_INET
    call IXCALL

    ld hl, inet_netmask
    ld ix, IFCONFIG_NETMASK
    call IXCALL

    ld hl, inet_gw
    ld ix, IFCONFIG_GW
    call IXCALL

    ld hl, DECONFIG
    call HLCALL

; The ifconfig_inet(), ifconfig_netmask() and ifconfig_gw() functions set the interface configuration for internet addresses.
; The functions take a pointer to a 4 byte big endian internet address, netmask or gateway, defined as in_addr_t.
; The functions make an immediate change to the relevant interface configuration, however, the change is not permanent
; and will be lost when the power is cycled or if the built in DHCP client runs on reset. Permanent changes must be made
; in the configuration stored in flash.

; The deconfig() function resets the IP address, default gateway and netmask with immediate effect. The change is not permament.

Как можно видеть у спектранета эти настройки временные - для постоянных надо перезаписывать флеш. У меня же изменение конфигурации делается одним вызовом и это сразу меняет EEPROM и переинициализирует WizNet.

Сишный интерфейс в Спектранете:
Code:
    #include <sys/types.h>
    #include <spectranet.h>

    void ifconfig_inet(in_addr_t *inet_addr);
    void ifconfig_netmask(in_addr_t *inet_netmask);
    void ifconfig_gw(in_addr_t *inet_gw);

    void deconfig();

Плюс в Спектранете есть функции для чтения и записи MAC-адреса, что в случае SprinterNet ненужно (и даже вредно):
https://web.archive.org/web/20120212192405/http://spectrum.alioth.net/doc/index.php/Sethwaddr
Code:
sethwaddr (IXCALL 0x3E51) - set the MAC address
gethwaddr (HLCALL 0x3E54) - get the MAC address

(в спектранете функция записи мак-адреса также является временной - т.е. лишь меняет мак-адрес в ОЗУ)

Shaos wrote:
#D00F - socket (D=domain, E=type) -> A - возвращает следующий свободный сокет (если тип сокета AF_INET или AF_PACKET, то сокетов может быть максимум 3, а если AF_LOCAL, то скажем 16 с номерами от 0x10 и выше);

https://web.archive.org/web/20200217222129/http://spectrum.alioth.net/doc/index.php/Socket
Code:
ld c, SOCK_STREAM       ; A reliable stream - TCP
ld hl, SOCKET           ; Call table for socket() - 0x3E00
call HLCALL             ; Trigger ROM page in
bit 7, a                ; Check for a negative return code (MSB set)
jr nz, .handle_error    ; failed to allocate a socket if the return code < 0

; at this point, A contains the file descriptor (aka socket handle)

Сишный интерфейс:
Code:
int sock;
sock=socket(AF_INET, SOCK_STREAM, 0);
if(sock > 0)
{
   /* socket opened successfully, do something */
}
else
{
   /* handle the error */
}

// The socket function opens an end point for communication, and returns a file descriptor on success.
// Only AF_INET sockets are supported. In the C interface, the domain and protocol parameters are
// provided for compatibility with the BSD socket library and are ignored. The protocol parameter
// should be set to zero; it is very possible that the protocol parameter will be used in a later release of the library.

У меня ещё предполагалось возможность использования AF_LOCAL (UNIX-сокеты внутри машины) и AF_PACKET (RAW-сокеты):
Code:
int sock_r;
sock_r=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_r<0)
{
 printf("error in socket\n");
 return -1;
}


Shaos wrote:
#D012 - bind (A=sock, HL=my_addr, E=addrlen) -> A - устанавливает порт для сокета (вызывает функцию визнета OPEN для открытия серверного сокета) и вызывает код ошибки (0 если всё Ок);

https://web.archive.org/web/20120212191405/http://spectrum.alioth.net/doc/index.php/Bind
Code:
ld a, (socket_fd)   ; The socket handle, as returned by socket
ld de, 2000         ; Port number
ld hl, BIND         ; Jump table entry point - 0x3E0C
call HLCALL
jr c, .handle_error ; On error, carry flag is set

; bind() gives the socket sockfd the local address my_addr. In this implementation, only the port address is used
; for the local address, and other parameters in the sockaddr structure are currently ignored. Fields are provided for compatibility.
; It is normally necessary to assign a local address before a SOCK_STREAM can accept incoming connections.
; The port number passed to bind is the port that will be listened on when the listen call is made.

; Return value

; On success, the assembly language interface returns with the carry flag cleared.
; On error, the accumulator contains the error number and the carry flag is set.

Сишный интерфейс:
Code:
#include <sys/socket.h>
#include <sys/types.h>

int sockfd;
struct sockaddr_in addr;
sock=socket(AF_INET, SOCK_STREAM, 0);
if(sock > 0)
{
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = htonl(INADDR_ANY); /* provided for compatibility */
   addr.sin_port = htons(2000); /* htons is a no-op, but a macro is provided for compatibility */
   if(bind(sockfd, &addr, sizeof(addr)) < 0)
   {
      handle_error("bind");
   }
}

// On success, the C interface returns zero. On error, -1 is returned, and errno is set to the error number.

// The port number is the only local address that is used, since the hardware only supports a single
// internet protocol address; in the C interface, all other fields in the sockaddr structure are ignored.
// C programmers should still avoid invalid values in case these values are used in the future.
// It is acceptable to zero out unused values.


Shaos wrote:
#D015 - listen (A=sock, E=backlog) -> A - слушает входящие сообщения серверного TCP сокета (backlog в данный момент может принимать значения от 0 до 2 - вызывает функцию визнета LISTEN если сокет один либо OPEN/LISTEN несколько раз, если требуемых сокетов больше чем 1) и возвращает код ошибки (0 если всё Ок);


Shaos wrote:
#D018 - accept (A=sock, HL=in_addr, E=addrlen) - в регистре A возвращает сокет, к которому подцепился TCP клиент (функция не имеет аналога в визнете и будет реализована программно - возвращаемый сокет может совпадать или не совпадать с входящим);


Shaos wrote:
#D01B - shutdown (A=sock, E=param) - закрывает соединение правильным образом с серверной стороны в случае TCP (вызывает функцию визнета DISCON);


Shaos wrote:
#D01E - connect (A=sock, HL=their_addr, E=addrlen) -> A - коннектится к серверу по TCP со стороны клиента, используя параметры адреса (вызывает функции визнета OPEN и CONNECT), возвращает код ошибки (0 если всё Ок);


Shaos wrote:
#D021 - send (A=sock, HL=buf, DE=size, NO flags) -> BC - послать данные по TCP и вернуть количество переданных байт (вызывает функцию визнета SEND);


Shaos wrote:
#D024 - recv (A=sock, HL=buf, DE=size, NO flags) -> BC - получить данные по TCP и вернуть количество принятых байт (вызывает функцию визнета RECV);


Shaos wrote:
#D027 - sendto (A=sock, HL=buf, DE=size, NO flags, IY=out_addr) -> BC - послать данные по UDP и вернуть количество принятых байт (устанавливает адрес и порт удалённого конца и вызывает функцию визнета SEND);


Shaos wrote:
#D02A - recvfrom (A=sock, HL=buf, DE=size, NO flags, IY=in_addr) -> BC - получить данные по UDP и вернуть количество принятых байт (вызывает функцию визнета RECV и копирует адрес и порт с которых пришло сообщение в in_addr);


Shaos wrote:
#D02D - close (A=sock) - закрывает сокет (вызывает функцию визнета CLOSE, однако в случае серверных сокетов логика будет более запутанная, т.к. закрываемый сокет надо будет снова переиспользовать в accept);


Shaos wrote:
#D030 - httpget (IY=url, HL=buf, DE=maxsize) -> BC - прочитать данные из интернета по урлу в буфер ограниченного размера (в BC возвращается количество скопированных байт либо код ответа HTTP если был установлен флаг C - причём 0 будет обозначать ошибку соединения);

В спектранете аналогичной функции (самодостаточный HTTP-клиент для забирания небольших порций данных с произвольного HTTP-сервера) по просту нет.

Shaos wrote:
#D033 - resolv (HL=host) -> BCDE - выдает IP-адрес в регистрах по имени сайта, расположенному по адресу HL и заканчивающемся нулевым байтом (в первой версии IP-адрес будет искаться в записях hosts и если там не найдено или просрочилось - будет производится запрос к шлюзу, а в будущем может быть реализован честный DNS-запрос);

https://web.archive.org/web/20120212111230/http://spectrum.alioth.net/doc/index.php/Gethostbyname
Code:
; gethostbyname (IXCALL 0x3E27) - get network host entry

   ld hl, STR_HOSTNAME
   ld de, BUF_ADDRESS
   ld ix, GETHOSTBYNAME
   call IXCALL

; The gethostbyname() call converts the string passed in name to an address. The parameter name may be
; a null-terminated hostname (such as 'www.worldofspectrum.org' or a null-terminated dotted decimal string
; representation of an IP address. If a dotted decimal address is passed, no lookup is made, and the string
; is converted to a 4 byte big-endian representation of the address. If a hostname is passed, the hostname
; is looked up using the DNS protocol, and the resolved address is returned as a 4 byte big-endian value.
; With the current implementation, only one address is returned on a successful lookup.

; For the assembly language interface, the register pair HL points to a null-terminated string containing the
; hostname or dotted decimal IP address, and the DE register pair points to a location in memory with at least
; 4 bytes free to receive the 4 byte big-endian representation of the address.

; Return values

; The assembly language interface returns with the carry flag set on error, with the A register containing the return code.

Сишный интерфейс:
Code:
   #include <netdb.h>

   struct hostent *gethostbyname(char *name);

/*
For the C function call, the pointer returned is to a statically allocated buffer.
If the value returned needs to be preserved when a subsequent call to
gethostbyname() is made, the value must be copied before the next call is made.
The C interface returns a null pointer if gethostbyname() fails to resolve the address.
*/


Я планирую написать совместимую по заголовочным файлам либу для Спринтера (для z88dk и для SolidC), чтобы одни и те же сишные исходники можно было бы собирать и для ZX+Specranet, и для Sprinter+SprinterNet. В репозитории спектранета есть несколько чисто сишных программ:
- сетевая игра ctfgame
- клиент irc
- tankgame
- twitter (с проксей на перле, которую думаю можно переписать на php и внедрить в наш шлюз)
ну и ещё пара простых примеров клиентов и серверов под спектранет также можно сделать пересобираемыми под SprinterNet.

_________________
:eugeek: https://twitter.com/Shaos1973


02 Aug 2021 04:20
Profile WWW
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 19894
Location: Silicon Valley
Reply with quote
Shaos wrote:
Ещё идея у меня была т.к. WizNet не хранит в себе MAC-адрес (его надо программно прописывать), можно под мою карманную корпорацию официально зарезервировать диапазон MAC-адресов, записав адреса оттуда в EEPROM-ы, которые раздавать вместе с платами. Сейчас блок из 4096 адресов стоит $780 выплаченных однократно - подробнее см.https://standards.ieee.org/products-services/regauth/oui36/index.html) :dj:

Зарезервировал :)


Attachments:
Approval.png
Approval.png [ 109.46 KiB | Viewed 350 times ]

_________________
:eugeek: https://twitter.com/Shaos1973
06 Aug 2021 02:40
Profile WWW
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 19894
Location: Silicon Valley
Reply with quote
Напомню эпопею с прототипами SprinterNet:

Attachment:
SprinterNet-prototype1-small.jpg
SprinterNet-prototype1-small.jpg [ 157.59 KiB | Viewed 112 times ]


Attachment:
SprinterNet-prototype2-small.jpg
SprinterNet-prototype2-small.jpg [ 234.64 KiB | Viewed 112 times ]


Наконец-то дошли руки начать сборку третьего прототипа (через полгода после получения платок):


Attachments:
SprinterNet-proto3-08.jpg
SprinterNet-proto3-08.jpg [ 207.84 KiB | Viewed 44 times ]

_________________
:eugeek: https://twitter.com/Shaos1973
05 Sep 2021 00:26
Profile WWW
Admin
User avatar

Joined: 09 Jan 2003 00:22
Posts: 19894
Location: Silicon Valley
Reply with quote
Обновил фотку третьего прототипа выше после того как воткнул все микросхемы (сам модулёк WizNet располагается с другой стороны)

_________________
:eugeek: https://twitter.com/Shaos1973


11 Sep 2021 22:26
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron

Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.