VOGONS


Reply 20 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmmm.... Looking at what's sending/receiving the modem's data and initializing it, I don't see any call from BIOS interrupt 14h(the serial communication interrupt), except when booting the system(initializing the serial port).

I also only see non-BIOS I/O to/from the data ports, so that means that the application has taken matters into it's own hand, manually driving the COM2 port.

I also see only two kinds of instructions accessing the UART data ports: 0xEE and another one of the same class(can't remember which one). Hmmm...
Edit: It's opcode 0xEC. EE for sending, EC for receiving.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 21 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just found out something interesting: When sending AT commands, the 688 attack sub program sends "AT<command here>\r\n". All the way up to the carriage return was echoed back to the program(The E1 option), but when the command includes an E0 instruction(disable local echo), the \r would execute the command, while \n would be sent, but not echoed back to the program at all.

That's another small bug out of the window! 😁

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 22 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just changed it up a bit: when receiving the <CR> for command completion, a timeout is started. When within that timeout a <LF> is received(and no other character), the timeout is stopped and the command is executed. When the timeout expires and no <LF> is received, the command is executed anyways(and no <LF> is sent back to the UART). That should fix the <LF> being sent after <CR> in a command byte, but not send it back when the UART doesn't send one within a timeout as well.
Edit: Hmmm... The timeout of 10 UART bytes isn't enough(at a speed of 57600 bytes/second). Now trying with 5760 bytes command linefeed timeout instead.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 23 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... It looks (looking at Dosbox's softmodem.cpp) like Dosbox has an issue with the linefeed after carriage return in a modem command as well(when echo is disabled): when carriage return is sent(0xD), the modem starts executing the command and clearing the buffer(including disabling local echo if E0 is given). Then, if a 0xA(line feed) follows said command, it isn't echoed back to the user(and if it were, it's echoed after the result that the command execution performs, instead of before it).

UniPCemu now handles a small(10 commands/second) delay, which allows the application or OS to send the additional 0xA linefeed(and sending it back when echo is enabled) before executing the command(and of course, when within said delay the 0xA byte is sent after the 0xD anyways, it's executed at said time instead(when the linefeed is sent (and echoed back is echo is enabled))).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 24 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... Now it cheats the Hayes compatiblity: after sending the init string, then during "ATS0=1\r" it doesn't send the line feed(which UniPCemu assumes to have been sent after 0.1 second now.

Although the init string did have the \n added after the \r. Weird?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 25 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... What is the default echo mode when the modem is powered on and/or reset? E1 or E0? I've talked about it with someone I know irl(from messing around with an Arduino) and he says that it defaults to E0, while all I can find(tcpser, Dosbox) says it's E1?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 26 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... Interesting. The server keeps sending 16h a bunch of times, then 0x01, 0x52, 0xAD, 0x00, 0x16 (, 0x16 a bunch of times again)... But it receives only 0xAA bytes?

Edit: Let's see what the client side does...

Edit: The client side receives 0x55 a bunch of times.
Edit: After receiving a bunch of 0x55 bytes(huh?), it sends 0xAA to the server.
It does send that a bunch of times.
Edit: It then sends 0x01, 0x52, 0xAD, 0x00, 0x16, 0x16, ... 0x16 a bunch of times?

So both the server and the client are trying to send the same sequence of bytes to the other side, but the other side never properly receives said data somehow(through the SDL2_net TCP connection)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 27 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... Interesting. When trying a TCP connection locally(through the Windows loopback device) the received(or sent?) data somehow gets messed up, but when using an ethernet loopback(dialing from the UniPCemu client to the external IP address of the host, so through the modem, to the ISP, back to the same modem, back to the PC that's running the other UniPCemu server), the data seems to arrive without issues?

Although the software still doesn't seem to connect properly?

The host seems to receive all kinds of different data, with 0x16 parts in between?
The server is now receivng all kinds of stuff.
The same seems to happen on the sending side of the server.

So there's at least some kind of connection now. It just doesn't seem to work with 688 attack sub on the Windows local loopback adapter? Although no issues with Rise of The Triad(which works without issues).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 28 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. It works while communicating over the ethernet, but not over the Microsoft Loopback adapter? Strange(even though it's just a plain local TCP connection instead of a TCP connection routed through a router to an ISP and back to the very same computer? Perhaps a latency issue?).

Although it eventually times out after connection is made.
Edit: This seems to be mainly the issue of not receiving input from the players it seems. After reconnecting it, it ran without visible problems.

So there is indeed some kind of weird issue with the Microsoft TCP Loopback when using 127.0.0.1?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 29 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Trying the ISP route with ROTT works as well:

2020-01-02 (2).png
Filename
2020-01-02 (2).png
File size
160.03 KiB
Views
1139 views
File comment
Chatting over ROTT's connection with the other UniPCemu client.
File license
Fair use/fair dealing exception

Also, 688 attack sub over the same connection:

2020-01-02.png
Filename
2020-01-02.png
File size
163.99 KiB
Views
1140 views
File comment
Playing 688 attack sub over the ethernet.
File license
Fair use/fair dealing exception

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 30 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmm... Software doesn't seem to see when the connection is dropped(hanged up) from the other side, besides not receiving/sending anything anymore?

Afaik in that case, the carrier signal is dropped, so the software should see that, but doesn't respond to it nor the NO CARRIER message?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 31 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just found a little bug in the UART: when in loopback mode, it was setting CTS to OUT1 and DSR to RTS instead of CTS to RTS and DSR to DTR. Whoops!

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 32 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... Windows 95 seems to do it's stuff with CTS/RTS and Loopback, but doesn't seem to recognise the modem or send/receive anything other than sending and receiving a byte through the loopback function of the UART?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 33 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

So now, while testing using Windows 95(including the WinCheckIt! 4.0 software, Hayes modem with Hyperterminal and normal dial-up for internet(using the dial-up prompt from This PC's dial-up connection folder) all have the same issue: they somehow try to eventually switch the UART to loopback mode(bit 4 of the MCR register)? Although WinCheckIt executes a modem Init command(which responds with "OK\r\n") and complains about the IRQ not working properly scanning for it(while the UART isn't raising any)?
Although I did turn off the bus detection/test of the CheckIt data collection due to system hanging issues(it locks up the entire Windows session).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 34 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've just implemented the various &Q0-&Q6 handling into the modem's reporting of the status bits(it defaults at "&Q5&R1&S0" for this):

byte modem_getstatus()
{
byte result = 0;
result = 0;
//0: Clear to Send(Can we buffer data to be sent), 1: Data Set Ready(Not hang up, are we ready for use), 2: Ring Indicator, 3: Carrrier detect
if (modem.communicationsmode && (modem.communicationsmode < 4)) //Synchronous mode? CTS is affected!
{
switch (modem.CTSAlwaysActive)
{
case 0: //Track RTS?
result |= ((modem.effectiveline >> 1) & 1); //Track RTS!
break;
case 1: //Depends on the buffers!
result |= ((modem.datamode == 1) ? ((modem.connectionid >= 0) ? (fifobuffer_freesize(modem.outputbuffer[modem.connectionid]) ? 1 : 0) : 1) : 1); //Can we send to the modem?
break;
case 2: //Always on?
result |= 1; //Always on!
break;
}
}
else
{
//Hayes documentation says it doesn't control CTS and RTS functions!
result |= ((modem.effectiveline >> 1) & 1); //Always on! &Rn has no effect according to Hayes docs! But do this anyways!
}
//DSRisConnectionEstablished: 0:1, 1:DTR
if ((modem.communicationsmode) && (modem.communicationsmode < 5)) //Special actions taken?
{
//((modem.outputline & 1) << 1)
switch (modem.DSRisConnectionEstablished) //What state?
{
default:
case 0: //S0?
case 1: //S1?
//0 at command state and idle, handshake(connected) turns on, lowered when hanged up.
if ((modem.connected == 1) && (modem.datamode != 2)) //Handshaked?
{
result |= 2; //Raise the line!
}
//Otherwise, lower the line!
break;
case 2: //S2?
//0 at command state and idle, prior to handshake turns on, lowered when hanged up.
if ((modem.connected == 1) && (modem.datamode)) //Handshaked or pending handshake?
{
result |= 2; //Raise the line!
}
//Otherwise, lower the line!
break;
}
}
else //Q0/5/6?
{
switch (modem.DSRisConnectionEstablished) //What state?
{
default:
case 0: //S0?
result |= 2; //Always raised!
break;
case 1: //S1?
Show last 11 lines
			result |= ((modem.outputline & 1) << 1); //Follow handshake!
break;
case 2: //S2?
result |= ((modem.outputline & 1) << 1); //Follow handshake!
break;
}
}
result |= (((modem.ringing&1)&((modem.ringing)>>1))?4:0)| //Currently Ringing?
(((modem.connected==1)||(modem.DCDisCarrier==0))?8:0); //Connected or forced on?
return result; //Give the resulting line status!
}

Would that be correct behaviour?

I've based this on the descriptions of &Sn, &Cn and &Qn as best as I could imagine with full compatibility. Of course the else case of the CTS line I added myself, to which the Hayes documentation says it's not driven at all(which it can't be, it's either zero or one, not neither for such a modem status line)?

It literally says:

In Other Modes (&QO, &Q4, &Q5, and &Q6), the &R option in effect does not control the RTS and CTS functions.

So what would be correct CTS line behaviour in that case? Just follow RTS?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 35 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... The improvements (at least with the default settings, except &S1 instead of &S0 as I'm testing it) makes Windows send an empty "AT\r" command to the modem. And WinCheckIt! Pro 4.0 seems to like the emulation as a whole a lot better(making it find the IRQ properly)?

What is the actual (factory(&F) or reset state(pulling DTR low)) default setting of the &S parameter? &S0 or &S1?

Edit: OK. WinCheckIt Pro 4.0 still works correctly(and detects the IRQ properly) when using &S0(which is supposed to be the factory/reset default according to most documentation I can find).

So the proper emulation added for "&Q" and "&Q0" through "&Q6" with regards to the CTS and DSR lines seems what makes it succeed now instead of failing detecting the IRQ(Defaulting on &S0&R1&Q5) with WinCheckIt Pro 4.0? Although Windows 95 still fails greatly(sending an empty line at most).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 36 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Found some missing break; statements within the command parsing code(ATE and AT\N commands). Also, phonebook errors(invalid commands for those) were aborting with OK instead of a proper ERROR. Those missing breaks caused errors when they shouldn't(Whoops!).

What should the correct response be for invalid/malformed AT&Zn instructions(too early End-Of-Command-Line or invalid characters?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 37 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've just modified the phonebook and quick dial functionality(quick dial is simply a number between 0 and 9 as the phone number) to:
- Save and load phonebook entries in the original case(as in the settings file or as sent to the modem) instead of converted to upper case(when saving a phonebook entry using the AT&Zn=... command). It will also take case into account when parsing the dial string after "ATD", so ATDS will use the phonebook, but ATDs won't(will try to dial "s" instead).
- The ATD<address here>, ATDT<address here>, ATDP<address here> will all work in the same way. ATD[T, P or none][0-9] will redirect to ATS[0-9] instead.
- All those phonebook entries are now protected against infinitely looping between entries. So when phonebook entry #0 is set to "S0", then it will simply abort the call instead of infinitely looping(when it detects the loop being triggered by processing the same entry for a second time during the loop). This will result in a ATD-compatible error message in that case(NO CARRIER) instead of the error code it gives when the number is out-of-range(past 9). When the code is past 9(during ATS[10 and up]), it will give an ERROR message instead(which is the only exception to the NO CARRIER rule when dialing).

So that makes the phonebook entries fully compatible with the Hayes standard, as well as still allowing 'normal' web addresses to be used. E.g. "sourceforge.net" will use normal dialing, but "Sourceforge.net" will try to execute a phonebook dial on the letter 'o', which will throw an ERROR message.
Of course that's the case for both quick dial methods(both through dialing a simple 0-10 number using ATD/ATDT/ATDP and ATDS).

I've also implemented the ATI commands in a Dosbox-compatible way. ATI3 and ATI4 will give a firmware version and hardware version respectively. All others (ATI[0 through 2] and ATI[4 through 8]) will simply give a OK result code/message(depending on verbose mode).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 38 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... It seems (while testing) that ROTT doesn't notice(when selecting COMM game) that the other side has hanged up? The DCD signal is properly lowered(and perhaps an interrupt, if enabled by the software through modem status register interrupts), but the software seems to still be waiting for the other side to perhaps communicate? It still says "Please wait for players to choose their characters.", even though the other player has already hung up?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 39 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmm... Windows 95 is behaving weirdly with the COM port: the log of Portmon seems to say it's trying to send AT\r to the COM2 port, but debugging the port from visual studio(port 2f8) shows that nothing is even being written to it?

So there's a driver at fault right there?

Edit: I've logged the portmon output to a text file:

Filename
unipcemu.LOG
File size
11.53 KiB
Downloads
69 downloads
File comment
Portmon log
File license
Fair use/fair dealing exception

Anyone can see something from it?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io