145 lines
5.3 KiB
C
145 lines
5.3 KiB
C
/* sage_stddev.c: Standard devices for sage-II system
|
|
|
|
Copyright (c) 2009-2010 Holger Veit
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the "Software"),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
Holger Veit BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
Except as contained in this notice, the name of Holger Veit et al shall not be
|
|
used in advertising or otherwise to promote the sale, use or other dealings
|
|
in this Software without prior written authorization from Holger Veit et al.
|
|
|
|
22-Jan-10 HV Initial version
|
|
*/
|
|
|
|
#include "sim_defs.h"
|
|
#include "m68k_cpu.h"
|
|
#include "chip_defs.h"
|
|
|
|
static int i8251_bitmask[] = { 0x1f, 0x3f, 0x7f, 0xff };
|
|
|
|
/* Debug Flags */
|
|
DEBTAB i8251_dt[] = {
|
|
{ "READ", DBG_UART_RD },
|
|
{ "WRITE", DBG_UART_WR },
|
|
{ "IRQ", DBG_UART_IRQ },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
t_stat i8251_io(IOHANDLER* ioh,uint32* value,uint32 rw,uint32 mask)
|
|
{
|
|
int port = ioh->offset;
|
|
I8251* chip = (I8251*)ioh->ctxt;
|
|
if (rw==MEM_WRITE) {
|
|
return chip->write ? chip->write(chip,port,*value) : i8251_write(chip,port,*value);
|
|
} else {
|
|
return chip->read ? chip->read(chip,port,value) : i8251_read(chip,port,value);
|
|
}
|
|
}
|
|
|
|
t_stat i8251_write(I8251* chip,int port,uint32 value)
|
|
{
|
|
int bits;
|
|
|
|
if (port==0) { /* data port */
|
|
chip->obuf = value & chip->bitmask;
|
|
TRACE_PRINT1(DBG_UART_WR,"WR DATA = 0x%02x",chip->obuf);
|
|
if (chip->init==3) { /* is fully initialized */
|
|
if ((chip->mode & I8251_MODE_BAUD)==I8251_MODE_SYNC) {
|
|
sim_printf("i8251: sync mode not implemented\n");
|
|
return STOP_IMPL;
|
|
}
|
|
if (chip->cmd & I8251_CMD_TXEN) {
|
|
/* transmit data */
|
|
chip->status &= ~(I8251_ST_TXEMPTY|I8251_ST_TXRDY);
|
|
sim_activate(chip->out,chip->out->wait);
|
|
}
|
|
}
|
|
return SCPE_OK;
|
|
} else { /* control port */
|
|
switch (chip->init) {
|
|
case 0: /* expect mode word */
|
|
chip->mode = value;
|
|
TRACE_PRINT1(DBG_UART_WR,"WR MODE = 0x%02x",value);
|
|
chip->init = (value & I8251_MODE_BAUD)==I8251_MODE_SYNC ? 1 : 3;
|
|
bits = (chip->mode & I8251_AMODE_BITS) >> 2;
|
|
chip->bitmask = i8251_bitmask[bits];
|
|
break;
|
|
case 1: /* expect sync1 */
|
|
chip->sync1 = value;
|
|
TRACE_PRINT1(DBG_UART_WR,"WR SYNC1 = 0x%02x",value);
|
|
chip->init = 2;
|
|
break;
|
|
case 2: /* expect sync2 */
|
|
chip->sync2 = value;
|
|
TRACE_PRINT1(DBG_UART_WR,"WR SYNC2 = 0x%02x",value);
|
|
chip->init = 3;
|
|
break;
|
|
case 3: /* expect cmd word */
|
|
chip->cmd = value;
|
|
TRACE_PRINT1(DBG_UART_WR,"WR CMD = 0x%02x",value);
|
|
if (value & I8251_CMD_EH) {
|
|
sim_printf("i8251: hunt mode not implemented\n");
|
|
return STOP_IMPL;
|
|
}
|
|
if (value & I8251_CMD_IR)
|
|
chip->init = 0;
|
|
if (value & I8251_CMD_ER)
|
|
chip->status &= ~(I8251_ST_FE|I8251_ST_OE|I8251_ST_PE);
|
|
if (value & I8251_CMD_SBRK)
|
|
sim_printf("i8251: BREAK sent\n");
|
|
if (value & I8251_CMD_RXE) {
|
|
sim_activate(chip->in,chip->in->wait);
|
|
} else {
|
|
if (!chip->oob) sim_cancel(chip->in);
|
|
}
|
|
if (value & I8251_CMD_TXEN) {
|
|
if (!(chip->status & I8251_ST_TXEMPTY))
|
|
sim_activate(chip->out,chip->out->wait);
|
|
else {
|
|
chip->status |= I8251_ST_TXRDY;
|
|
if (chip->txint) chip->txint(chip);
|
|
}
|
|
} else {
|
|
chip->status &= ~I8251_ST_TXRDY;
|
|
sim_cancel(chip->out);
|
|
}
|
|
}
|
|
return SCPE_OK;
|
|
}
|
|
}
|
|
|
|
t_stat i8251_read(I8251* chip,int port,uint32* value)
|
|
{
|
|
if (port==0) { /* data read */
|
|
*value = chip->ibuf;
|
|
chip->status &= ~I8251_ST_RXRDY; /* mark read buffer as empty */
|
|
TRACE_PRINT1(DBG_UART_RD,"RD DATA = 0x%02x",*value);
|
|
} else { /* status read */
|
|
*value = chip->status & 0xff;
|
|
TRACE_PRINT1(DBG_UART_RD,"RD STATUS = 0x%02x",*value);
|
|
}
|
|
return SCPE_OK;
|
|
}
|
|
|
|
t_stat i8251_reset(I8251* chip)
|
|
{
|
|
chip->init = 0;
|
|
chip->oob = FALSE;
|
|
chip->crlf = 0;
|
|
return SCPE_OK;
|
|
}
|