/*
Copyright 2019 Wolfgang Thaller.
This file is part of Retro68.
Retro68 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 3 of the License, or
(at your option) any later version.
Retro68 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 Retro68. If not, see .
*/
#include "MacSerialStream.h"
#include
#include
#include
MacSerialStream::MacSerialStream(int port, int baud)
: port(port), curBaud(baud)
{
open();
}
void MacSerialStream::close()
{
if(inRefNum == 0)
return;
SerSetBuf(inRefNum, NULL, 0);
CloseDriver(inRefNum);
CloseDriver(outRefNum);
inRefNum = outRefNum = 0;
}
void MacSerialStream::open()
{
OpenDriver(port ? "\p.BOut" : "\p.AOut", &outRefNum);
OpenDriver(port ? "\p.BIn" : "\p.AIn", &inRefNum);
SerSetBuf(inRefNum, inputBuffer, kInputBufferSize);
SerShk shk;
memset(&shk, 0, sizeof(shk));
shk.fCTS = true;
Control(outRefNum, kSERDHandshake, &shk);
setBaud(curBaud);
}
MacSerialStream::~MacSerialStream()
{
close();
}
void MacSerialStream::write(const void* p, size_t n)
{
ParamBlockRec pb;
memset(&pb, 0, sizeof(pb));
pb.ioParam.ioRefNum = outRefNum;
pb.ioParam.ioBuffer = (Ptr)p;
pb.ioParam.ioReqCount = n;
/*OSErr err =*/ PBWriteSync(&pb);
}
void MacSerialStream::idle()
{
long count = 0;
SerGetBuf(inRefNum, &count);
while(count > 0)
{
long count1 = count > kReadBufferSize ? kReadBufferSize : count;
ParamBlockRec pb;
memset(&pb, 0, sizeof(pb));
pb.ioParam.ioRefNum = inRefNum;
pb.ioParam.ioBuffer = (Ptr)&readBuffer;
pb.ioParam.ioReqCount = count1;
OSErr err = PBReadSync(&pb);
if(err)
return;
count -= count1;
notifyReceive((uint8_t*)readBuffer, count1);
}
}
void MacSerialStream::setBaud(int baud)
{
curBaud = baud;
short baudval = 0;
switch(baud)
{
case 9600: baudval = baud9600; break;
case 14400: baudval = baud14400; break;
case 19200: baudval = baud19200; break;
case 28800: baudval = baud28800; break;
case 38400: baudval = baud38400; break;
case 57600: baudval = baud57600; break;
case 115200: baudval = 0; break;
case 230400: baudval = 0; break;
}
SerReset(outRefNum, baudval | data8 | noParity | stop10);
if(baud == 115200)
Control(outRefNum, kSERD115KBaud, nullptr);
else if(baud == 230400)
Control(outRefNum, kSERD230KBaud, nullptr);
}