Add server functionality to the emulated modem

This commit is contained in:
CrazyEttin 2022-10-01 19:54:30 +03:00
parent 7c2905b558
commit f8b27b8465
3 changed files with 110 additions and 51 deletions

View File

@ -26,9 +26,9 @@ type
//Modem connection state //Modem connection state
Connection = record Connection = record
Call: boolean; Call: boolean;
Answer: boolean;
Addr: longword; Addr: longword;
Port: word; Port: word;
Answer: boolean;
Hang: boolean; Hang: boolean;
end; end;
{$endif} {$endif}
@ -50,7 +50,7 @@ const
{$endif} {$endif}
var var
Hlt, Echo{$ifdef floppy}, DiscRead, DiscWrite, DiscTrackSet, DiscSectSet{$endif}{$ifdef modem}, Calling{$endif}: boolean; //Halt and echo flags, disc system flags, and modem connection flag Hlt, Echo{$ifdef floppy}, DiscRead, DiscWrite, DiscTrackSet, DiscSectSet{$endif}{$ifdef modem}, Calling, Answering{$endif}: boolean; //Halt and echo flags, disc system flags, and modem connection flags
Op, Regs: 0 .. $f; //Opcode Op, Regs: 0 .. $f; //Opcode
X, Y: 0 .. 3; //Register arguments X, Y: 0 .. 3; //Register arguments
Addr, IP, RP: word; //Immediate or address argument and instruction and return pointers Addr, IP, RP: word; //Immediate or address argument and instruction and return pointers
@ -78,8 +78,8 @@ var
{$ifdef modem} {$ifdef modem}
ModemConn: Connection; //State of the modem ModemConn: Connection; //State of the modem
ModemState: file of Connection; //File storing the state of the modem ModemState: file of Connection; //File storing the state of the modem
ServerSocket: longint; //Server socket ServerSocket, ListenSocket, ClientSocket, ClientAddrSize: longint; //Server socket
ServerAddr: TInetSockAddr; //Server address ServerAddr, ClientAddr: TInetSockAddr; //Server address
{$endif} {$endif}
{$ifdef status} {$ifdef status}
FileDescs: TFDset; //File descriptor set FileDescs: TFDset; //File descriptor set
@ -133,14 +133,40 @@ begin
end; end;
end; end;
//Hang //Hang
if ModemConn.Hang then if Calling then begin if ModemConn.Hang then begin
CloseSocket (ServerSocket); if Calling then begin
ModemConn.Hang := false; CloseSocket (ServerSocket);
Calling := false; ModemConn.Hang := false;
Calling := false;
end
else if Answering then begin
CloseSocket (ClientSocket);
CloseSocket (ListenSocket);
ModemConn.Hang := false;
Answering := false;
end;
end end
else if ModemConn.Call then if Calling then begin else if ModemConn.Call then begin
CloseSocket (ServerSocket); if Calling then begin
Calling := false; CloseSocket (ServerSocket);
Calling := false;
end
else if Answering then begin
CloseSocket (ClientSocket);
CloseSocket (ListenSocket);
Answering := false;
end;
end
else if ModemConn.Answer then begin
if Calling then begin
CloseSocket (ServerSocket);
Calling := false;
end
else if Answering then begin
CloseSocket (ClientSocket);
CloseSocket (ListenSocket);
Answering := false;
end;
end; end;
//Call //Call
if ModemConn.Call then if Calling = false then begin if ModemConn.Call then if Calling = false then begin
@ -149,14 +175,36 @@ begin
if ServerSocket <> -1 then begin if ServerSocket <> -1 then begin
//Connect //Connect
ServerAddr.sin_family := AF_INET; ServerAddr.sin_family := AF_INET;
ServerAddr.sin_port := htons (ModemConn.Port);
ServerAddr.sin_addr.s_addr := htonl (ModemConn.Addr); ServerAddr.sin_addr.s_addr := htonl (ModemConn.Addr);
if fpconnect (ServerSocket, @ServerAddr, Sizeof (ServerAddr)) <> -1 then begin ServerAddr.sin_port := htons (ModemConn.Port);
if fpConnect (ServerSocket, @ServerAddr, Sizeof (ServerAddr)) <> -1 then begin
ModemConn.Call := false; ModemConn.Call := false;
Calling := true; Calling := true;
end; end;
end; end;
end; end;
//Answer
if ModemConn.Answer then if Answering = false then begin
//Create a socket
ListenSocket := fpSocket (AF_INET, SOCK_STREAM, 0);
if ListenSocket <> -1 then begin
//Listen
ServerAddr.sin_family := AF_INET;
ServerAddr.sin_addr.s_addr := htonl (ModemConn.Addr);
ServerAddr.sin_port := htons (ModemConn.Port);
if fpBind (ListenSocket, @ServerAddr, Sizeof (ServerAddr)) <> -1 then begin
if fpListen (ListenSocket, 1) <> -1 then begin
//Accept
ClientAddrSize := sizeof (ClientAddr);
ClientSocket := fpAccept (ListenSocket, @ClientAddr, @ClientAddrSize) ;
if ClientSocket <> -1 then begin
ModemConn.Answer := false;
Answering := true;
end;
end;
end;
end;
end;
//Save the modem state //Save the modem state
if FileExists (ExpandFileName ('~/.thingamajig/connection')) then begin if FileExists (ExpandFileName ('~/.thingamajig/connection')) then begin
try try
@ -261,12 +309,13 @@ begin
//Modem //Modem
else if W = $fffa then begin else if W = $fffa then begin
{$ifndef fast} {$ifndef fast}
wait (26); wait (33);
{$endif} {$endif}
//Connect //Connect
CallServer; CallServer;
//Recieve //Recieve
if Calling then fpRecv (ServerSocket, @B, 1, 0) if Calling then fpRecv (ServerSocket, @B, 1, 0)
else if Answering then fpRecv (ClientSocket, @B, 1, 0)
else B := 0; else B := 0;
end end
{$endif} {$endif}
@ -299,6 +348,11 @@ begin
fpfd_zero (FileDescs); fpfd_zero (FileDescs);
fpfd_set (ServerSocket, FileDescs); fpfd_set (ServerSocket, FileDescs);
if fpSelect (ServerSocket + 1, @FileDescs, nil, nil, 0) > 0 then B := B or $20; if fpSelect (ServerSocket + 1, @FileDescs, nil, nil, 0) > 0 then B := B or $20;
end
else if Answering then begin
fpfd_zero (FileDescs);
fpfd_set (ClientSocket, FileDescs);
if fpSelect (ClientSocket + 1, @FileDescs, nil, nil, 0) > 0 then B := B or $20;
end; end;
{$endif} {$endif}
{$ifndef modem} {$ifndef modem}
@ -651,12 +705,13 @@ begin
//Modem //Modem
else if W = $fffa then begin else if W = $fffa then begin
{$ifndef fast} {$ifndef fast}
wait (26); wait (33);
{$endif} {$endif}
//Connect //Connect
CallServer; CallServer;
//Send //Send
if Calling then fpSend (ServerSocket, @B, 1, 0); if Calling then fpSend (ServerSocket, @B, 1, 0)
else if Answering then fpSend (ClientSocket, @B, 1, 0);
end end
{$endif} {$endif}
//Regular store //Regular store
@ -877,7 +932,11 @@ begin
{$ifdef modem} {$ifdef modem}
//Disconnect the modem //Disconnect the modem
if Calling then CloseSocket (ServerSocket); if Calling then CloseSocket (ServerSocket)
else if Answering then begin
CloseSocket (ClientSocket);
CloseSocket (ListenSocket);
end;
{$endif} {$endif}
{$ifndef fast} {$ifndef fast}

View File

@ -8,9 +8,9 @@ type
//Connection state //Connection state
Connection = record Connection = record
Call: boolean; Call: boolean;
Answer: boolean;
Addr: longword; Addr: longword;
Port: word; Port: word;
Answer: boolean;
Hang: boolean; Hang: boolean;
end; end;
@ -23,14 +23,20 @@ begin
//Check the arguments //Check the arguments
if ParamStr (1) = '-c' then begin if ParamStr (1) = '-c' then begin
if ParamCount > 2 then begin if ParamCount <> 2 then begin
writeln ('Usage: modemctl [-c address:port]/-a/-h'); writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1);
end;
end
else if ParamStr (1) = '-a' then begin
if ParamCount <> 2 then begin
writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1); halt (1);
end; end;
end end
else begin else begin
if ParamCount > 1 then begin if ParamCount > 1 then begin
writeln ('Usage: modemctl [-c address:port]/-a/-h'); writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1); halt (1);
end; end;
end; end;
@ -38,59 +44,53 @@ begin
//Assign the state file //Assign the state file
assign (State, ExpandFileName ('~/.thingamajig/connection')); assign (State, ExpandFileName ('~/.thingamajig/connection'));
//Read existing state if any
if FileExists (ExpandFileName ('~/.thingamajig/connection')) then begin
try
reset (State);
read (State, ModemConn);
close (State);
except
end;
end
//Or else assign a default state
else begin
ModemConn.Call := false;
ModemConn.Addr := 0;
ModemConn.Port := 0;
ModemConn.Answer := false;
ModemConn.Hang := false;
end;
//Set the connection //Set the connection
if ParamStr (1) = '-c' then begin if ParamStr (1) = '-c' then begin
ModemConn.Call := true; ModemConn.Call := true;
ModemConn.Answer := false;
try try
Addr := StrToHostAddr (ExtractDelimited (1, ParamStr (2), [':'])); Addr := StrToHostAddr (ExtractDelimited (1, ParamStr (2), [':']));
ModemConn.Addr := Addr.s_addr; ModemConn.Addr := Addr.s_addr;
except except
writeln ('Usage: modemctl [-c address:port]/-a/-h'); writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1); halt (1);
end; end;
try try
ModemConn.Port := StrToInt (ExtractDelimited (2, ParamStr (2), [':'])); ModemConn.Port := StrToInt (ExtractDelimited (2, ParamStr (2), [':']));
except except
writeln ('Usage: modemctl [-c address:port]/-a/-h'); writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1); halt (1);
end; end;
ModemConn.Answer := false;
ModemConn.Hang := false; ModemConn.Hang := false;
end end
else if ParamStr (1) = '-a' then begin else if ParamStr (1) = '-a' then begin
ModemConn.Call := false; ModemConn.Call := false;
ModemConn.Addr := 0;
ModemConn.Port := 0;
ModemConn.Answer := true; ModemConn.Answer := true;
try
Addr := StrToHostAddr (ExtractDelimited (1, ParamStr (2), [':']));
ModemConn.Addr := Addr.s_addr;
except
writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1);
end;
try
ModemConn.Port := StrToInt (ExtractDelimited (2, ParamStr (2), [':']));
except
writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1);
end;
ModemConn.Hang := false;
ModemConn.Hang := false; ModemConn.Hang := false;
end end
else if ParamStr (1) = '-h' then begin else if ParamStr (1) = '-h' then begin
ModemConn.Call := false; ModemConn.Call := false;
ModemConn.Answer := false;
ModemConn.Addr := 0; ModemConn.Addr := 0;
ModemConn.Port := 0; ModemConn.Port := 0;
ModemConn.Answer := false;
ModemConn.Hang := true; ModemConn.Hang := true;
end end
else begin else begin
writeln ('Usage: modemctl [-c address:port]/-a/-h'); writeln ('Usage: modemctl [-c address:port]/[-a address:port]/-h');
halt (1); halt (1);
end; end;

View File

@ -98,7 +98,7 @@ Usage:
* emulator (-v) program (2> verbose_output) * emulator (-v) program (2> verbose_output)
* tapectl (-r tape) (-p tape) * tapectl (-r tape) (-p tape)
* floppyctl (-0 disc) (-1 disc) * floppyctl (-0 disc) (-1 disc)
* modemctl [-c address:port]/-a/-h * modemctl [-c address:port]/[-a address:port]/-h
By default the emulator runs at roughly 500 KIPS and has 2 KiB of RAM. By default the emulator runs at roughly 500 KIPS and has 2 KiB of RAM.
The arguments -dRAM4, -dRAM8, -dRAM16, -dRAM32, and -dRAM64 can be used The arguments -dRAM4, -dRAM8, -dRAM16, -dRAM32, and -dRAM64 can be used
@ -133,10 +133,10 @@ arguments -0 and -1 respectively. The disc system uses hard sectored
single-sided discs with 77 tracks of 32 sectors of 137 bytes, or 337568 single-sided discs with 77 tracks of 32 sectors of 137 bytes, or 337568
bytes in total: the disc files must be of this size. The modem is bytes in total: the disc files must be of this size. The modem is
controlled by the program modemctl: the option -c is used to call an IP controlled by the program modemctl: the option -c is used to call an IP
address and port, -a to set the modem ready for answering calls to port address and port, -a to set the modem ready for answering calls to a
1337, and -h to hang. Hanging manually is not necessary when making a loopback or local IP address and port, and -h to hang. Hanging manually
new call or switching between calling and answering. Note: Answering is is not necessary when making or answering a new call or switching
not implemented yet. between calling and answering.
The floppy disc system uses two ports: command at FFFB and data at FFFC. The floppy disc system uses two ports: command at FFFB and data at FFFC.
Only the low nibble of the command port is used, consisting of a Only the low nibble of the command port is used, consisting of a