Skip to content

Instantly share code, notes, and snippets.

@realmonster
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save realmonster/aab6e632b06321a16995 to your computer and use it in GitHub Desktop.
Save realmonster/aab6e632b06321a16995 to your computer and use it in GitHub Desktop.
GEMS parallel lua connection
/*
* Copyright (C) 2002-2013 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// include guard
#ifndef DOSBOX_GEMSLPT_H
#define DOSBOX_GEMSLPT_H
#include "dosbox.h"
#include "parport.h"
#include <winsock2.h>
class CGemsLPT : public CParallel {
public:
CGemsLPT (Bitu nr, Bit8u initIrq, CommandLine* cmd);
~CGemsLPT();
bool InstallationSuccessful; // check after constructing. If
// something was wrong, delete it right away.
bool socketOpen;
SOCKET socket;
std::string name; // name of the thing to open
bool OpenFile();
Bitu Read_PR();
Bitu Read_COM();
Bitu Read_SR();
Bit8u datareg;
Bit8u controlreg;
void Write_PR(Bitu);
void Write_CON(Bitu);
void Write_IOSEL(Bitu);
bool Putchar(Bit8u);
virtual void handleUpperEvent(Bit16u type);
};
#endif // include guard
/*
* Copyright (C) 2002-2013 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "dosbox.h"
#include "parport.h"
#include "gemslpt.h"
#include "callback.h"
#include "pic.h"
#include "hardware.h" //OpenCaptureFile
#include <stdio.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
SOCKET OpenSocket()
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
LOG_MSG("GEMS parallel: WSAStartup failed with error: %d", iResult);
return INVALID_SOCKET;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("127.0.0.1", "5000", &hints, &result);
if ( iResult != 0 ) {
LOG_MSG("GEMS parallel: getaddrinfo failed with error: %d", iResult);
WSACleanup();
return INVALID_SOCKET;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
LOG_MSG("GEMS parallel: socket failed with error: %ld", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return INVALID_SOCKET;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
LOG_MSG("GEMS parallel: Unable to connect to server!");
WSACleanup();
return INVALID_SOCKET;
}
return ConnectSocket;
}
CGemsLPT::CGemsLPT (Bitu nr, Bit8u initIrq, CommandLine* cmd)
:CParallel (cmd, nr,initIrq) {
socketOpen = false;
InstallationSuccessful = true;
controlreg=0;
LOG_MSG("GEMS Parallel port started %08X",nr);
}
CGemsLPT::~CGemsLPT ()
{
// close socket
if(socketOpen)
{
closesocket(socket);
WSACleanup();
}
// remove tick handler
removeEvent(0);
}
bool CGemsLPT::Putchar(Bit8u val)
{
// write to file (or not)
if(!socketOpen)
{
socket = OpenSocket();
if (socket != INVALID_SOCKET)
socketOpen = true;
}
if (!socketOpen)
return false;
int iResult = send( socket, (const char*)&val, 1, 0 );
if (iResult == SOCKET_ERROR)
{
LOG_MSG("GEMS parallel: send failed with error: %d", WSAGetLastError());
closesocket(socket);
WSACleanup();
socketOpen = false;
return 0;
}
return 1;
}
Bitu CGemsLPT::Read_PR()
{
return datareg;
}
Bitu CGemsLPT::Read_COM()
{
return 0;
}
Bitu CGemsLPT::Read_SR()
{
return 0;
}
void CGemsLPT::Write_PR(Bitu val)
{
datareg = (Bit8u)val;
}
void CGemsLPT::Write_CON(Bitu val)
{
controlreg=val;
}
void CGemsLPT::Write_IOSEL(Bitu val)
{
}
void CGemsLPT::handleUpperEvent(Bit16u type)
{
}
local socket = require("socket");
local s = socket.bind("*",5000);
--local rep = io.open("gems_connection.log","wb");
s:settimeout(0);
local clients = {};
local byte = 0;
local readed = 0;
gens.speedmode("normal");
gens.registerbefore(function()
s:settimeout(0);
local o = s:accept();
if (o ~= nil )then
oc = {};
oc.socket = o;
o:settimeout(0);
oc.status = 0;
local i,p = o:getpeername();
print("Connected: "..i..":"..p);
table.insert(clients,oc);
end
local was = true;
while was do
was = false;
n = table.getn(clients);
for i=1,n do
if (clients[i].status == 2) then
local ip, p = clients[i].socket:getpeername();
table.remove(clients,i);
print ("Disconected: "..ip..":"..p);
was = true;
break;
end
end
end
end)
memory.registerexec(0x2F26,1, function(address,size)
local n = table.getn(clients);
local i;
if (readed == 0) then
for i=1,n do
clients[i].socket:settimeout(0);
byte = clients[i].socket:receive(1);
if (byte ~= nil) then
--rep:write(string.format("%02X",string.byte(byte)).."\n");
--rep:flush();
readed = 1;
break;
end
end
end
local v = memory.getregister('d0');
if (readed == 0) then
memory.setregister('d0',AND(v,0xFFFFFF00)+0x10);
else
memory.setregister('d0',AND(v,0xFFFFFF00));
end
end)
memory.registerexec(0x1192,1, function(address,size)
local v = memory.getregister('d0');
memory.setregister('d0',AND(v,0xFFFFFF00)+string.byte(byte));
readed = 0;
end)
--[[memory.registerexec(0x1248,1, function(address,size)
rep:write(string.format("Result: %02X",memory.getregister('d0')).."\n");
end)
memory.registerwrite(0,0x200000, function(address,size)
rep:write(string.format("Write at: %06X PC: %06X",address,memory.getregister('pc')).."\n");
rep:flush();
end)
local cmds = {
[0] = 'cmdnoteon',
[1] = 'cmdnoteoff',
[2] = 'cmdpchange',
[3] = 'cmdpupdate',
[4] = 'cmdpbend',
[5] = 'cmdtempo',
[6] = 'cmdenv',
[7] = 'cmdretrig',
[8] = '?',
[9] = '?',
[10] = '?',
[11] = '?',
[12] = 'cmdpause',
[13] = 'cmdresume',
[14] = 'cmdsussw',
[15] = '?',
[16] = 'cmdstartseq',
[17] = '?',
[18] = 'cmdstopseq',
[19] = 'cmdreload',
[20] = 'cmdsetprio',
[21] = '?',
[22] = 'cmdstopall',
[23] = '?',
[24] = '?',
[25] = '?',
[26] = 'cmdsamprate',
[27] = 'cmdstore',
[28] = 'cmdlockch',
[29] = 'cmdunlockch',
[30] = '?',
[31] = 'cmdvolume',
[254] = 'drawalltext'
};
memory.registerexec(0x1AEE,1,function(address,size)
local d1 = memory.getregister('d1');
rep:write(string.format("CMD: %d ",d1)..cmds[d1].."\n");
end)
]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment