/************************************************************************\
 * File Version Information
 * $Header: /Altair32v2/console.c 8     11/08/06 9:21p Racini $
 ************************************************************************/
/************************************************************************\
  MITS Altair Emulator
  MITS 88-2SIO device driver

  Copyright (c) 2000-2006 Richard A. Cini

  This module emulates the RS232 serial interface card used in the
  Altair. Choices were the SIO or 2SIO (dual port) interface cards.
  The original card, the SIO, was based on the COM2502 UAR/T (equivalent
  to the GI AY-3-1013 or AY-3-1015 chips). The 2SIO dual-port card had
  two RS-232 ports based on the 6850 ACIA chip from Motorola. MITS
  assigned standard port addresses of 20Q-21Q	(10h-11h) for the first
  port of the 2SIO and 22Q-23Q (12h-13h) for the second port. Port
  assignments were modifyable based on a limited selection. Baud rates
  ranged from 110 to 9600 although most hardware ran only at 300 baud.

  A typical later-period configuration would include a "glass TTY" terminal
  (commonly known as a VDT) connected to the first port. 

  Here's the layout of the port configuration. Only the first port is shown
  here; port 2 of the 2SIO card is handled in taperdr.c.

	   Port 	Dir		Function
	   ----		---		--------
	   10/11 2SIO-1 -- Console port
	   10		W		Configuration register (not meaningful here)
	   10		R		Status register
       11		W		Write console data
       11		R		Read console data


  Tape BASIC programs are saved by using the logging capabilities of the
  telnet client or the Windows Console. Alternatively, a program can be
  loaded into BASIC by cutting and pasting into the terminal client.
  This is a crude but effective emulation of the way programs were
  loaded and saved when using an ASR33 -- set the mode to "punch" and
  LIST the program. LOADing was done by setting the mode to "reader"
  and running the tape -- the characters were jammed into the BASIC input
  buffer as if the user typed them.

  To handle true paper tape images (i.e., programs like BASIC 3.2 itself)
  there is programmatic access through ports 24h-25h by connecting a tape
  image file through the punch control dialog. CP/M supports a paper
  tape punch which uses the second port of the 2SIO card.

Change Log: 
  2000/12/06  RAC -- Began coding.
  2000/12/20  RAC -- Decided to use file capture route. Implemented.
  2001/01/03  RAC -- Added power control flag for conditionals.
  2001/02/20  RAC -- "Module global" fix; return parens; string term.
  2001/07/16  RAC -- Began integration and testing of TCP connection.
  2001/07/31  TMP -- Telnet code passes loopback verification test.
  2001/08/08  TMP -- Changes to telnet code for better error flag handling.
  2001/08/19  RAC -- RELEASE MARKER -- v2.0
  2001/08/29  RAC -- Comments updated.
  2001/09/17  RAC -- Added PTP mode code.
  2001/10/15  RAC -- Changed prototypes to Hex
  2001/11/16  RAC -- Made temporary changes to prove CP/M operation.
  2001/11/25  RAC -- Added "CPM" conditional
  2001/11/26  RAC -- Separated tape console from disk console; removed
  						CPM conditional.
  2001/12/03  RAC -- Separated LPR code into separate source file. Added
  						control code trap in console code for BELL (^G)
  						which doesn't seem to work yet.
  2001/12/14  RAC -- RELEASE MARKER -- v2.1
  2001/12/20  RAC -- Changes to comments.
  2002/01/02  RAC -- Moved routines to new master include file and merged
  						all serial devices into one export header (sio.h
  						is new serial device header)
  2002/01/31  RAC -- Fixed (hopefully) minor problem in sio01h to get BASIC
  						3.2 working.
  2002/01/31  RAC -- RELEASE MARKER -- v2.2
  2002/07/07  RAC -- RELEASE MARKER -- v2.3
  2002/08/23  RAC -- RELEASE MARKER -- v2.30.10
  2002/10/04  RAC -- Made changes to support calling through simstate.con_func
  						in support of swappable console modes (telnet/WinCon)
  2002/11/15  RAC -- RELEASE MARKER -- v2.40.2100
  2003/04/26  RAC -- RELEASE MARKER -- v2.50.2045
  2003/06/30  RAC -- Comments updated
  2003/10/16  RAC -- Began changes to move PUN/RDR to 2SIO/2, LIST to 88LPC.
  2004/07/30  RAC -- RELEASE MARKER -- v3.00.0135
  2006/05/12  RAC -- RELEASE MARKER -- v3.10.0200
  2006/11/15  RAC -- RELEASE MARKER -- v3.20.0400
\************************************************************************/
#include <windows.h>
#include <commdlg.h>
#include <stdio.h>		// C-lib
#include <mmsystem.h>
#include "altair32.h"	// includes "resource.h"


// Port status defines
#define RxStat_BIT	0x01	// bit0=RxReady (1=DAV)
#define TxStat_BIT 	0x02	// bit1=TxReady (1=OK to write)

	
/**************************************************************\
*   I/O Instruction Handlers  *********************************|
***************************************************************|
*
*	I/O instruction handlers are called from the CPU module
*  	when an IN or OUT instruction is issued.
*
*  	Each function is passed an 'io' flag, where 0 means a read
*  	from the port, and 1 means a write to the port.  On input,
*	the actual input is passed as the return value. On output,
*	'data' is written to the device.
\**************************************************************/

/*--  SIO10h  -------------------------------------------------
	Status/configuration register for CP/M console device.
	Status information is passed on simply as go/no-go.

	Ports 10h-11h are used to support CP/M disks which assume
	that a console device lives on the first serial port of a
	2SIO card.	
-------------------------------------------------------------*/
int sio10h(int io, int data)
{
	int nSioStatus = 0;

	if (io == 0) {							// READ
		if (simstate.constato_func() == 0){	// Can't write means we're not connected
			nSioStatus = 0;					// No input data ready and can't output			
		}
		else {								// We have a connection, so...
			if (simstate.constati_func() == 0){	// get in_stat...0=no data 1=DAV
				nSioStatus = TxStat_BIT;		// No input, but we can write
			}
			else {							// Have input ready AND can write
				nSioStatus = ( TxStat_BIT | RxStat_BIT );
			}
		}
		return nSioStatus;
	}
	else return 0;						// We don't support a write to SIO status reg
}


/*--  SIO11h  -------------------------------------------------
	Data register for console device. ConStatO returns 1 if data
	can be written,	0 if data can't be written (i.e., buffer
	full). On read, ConRead returns character or 0 if no data
	is available. ConWrite presently ignores errors.
-------------------------------------------------------------*/
int sio11h(int io, int data)
{
	int nData = 0xff;

	switch (io){
		case 0:									// READ
			nData = simstate.conread_func();	// get char from console
			if (nData == 0x07){					// do BELL from user
				PlaySound("BELL", winstate.hInst, SND_RESOURCE | SND_ASYNC | SND_NOWAIT);
			}
			return nData;						// return character

		case 1:									// WRITE
			if (simstate.constato_func()){		// 1=OK to write to TCP, send char
				if (data == 0x07){				// do BELL coming from the Altair
					PlaySound("BELL", winstate.hInst, SND_RESOURCE | SND_ASYNC | SND_NOWAIT);
				}
				simstate.conwrite_func((byte) data);
			}
			return 0;

		default:
			return 0;
	}
}

/*  end of file: console.c  */
