Add server functionality to the emulated modem
This commit is contained in:
parent
7c2905b558
commit
f8b27b8465
93
emulator.pas
93
emulator.pas
|
@ -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}
|
||||||
|
|
58
modemctl.pas
58
modemctl.pas
|
@ -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;
|
||||||
|
|
||||||
|
|
10
readme.md
10
readme.md
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue