Beispiel #1
0
static void load_sample_info(int size, SFInfo *sf, FILE *fd)
{
	int i;
	int in_rom;

	/* the record size depends on the soundfont version */
	if (sf->version > 1) {
		/* SF2 includes sample name and other infos */
		sf->nsamples = size / 46;
		sf->sample = NEW(SFSampleInfo, sf->nsamples);
	} else  {
		/* SBK; sample name may be read already */
		int nsamples = size / 16;
		if (sf->sample == NULL) {
			sf->nsamples = nsamples;
			sf->sample = NEW(SFSampleInfo, sf->nsamples);
		} else if (sf->nsamples != nsamples) {
#if 0
			fprintf(stderr, "*** different # of infos ?? (%d : %d)\n",
			       sf->nsamples, nsamples);
			FSKIP(size, fd);
			return;
#endif
			/* overwrite it */
			sf->nsamples = nsamples;
		}
	}

	in_rom = 1;  /* data may start from ROM samples */
	for (i = 0; i < sf->nsamples; i++) {
		if (sf->version > 1) /* SF2 only */
			READSTR(sf->sample[i].name, fd);
		READDW(sf->sample[i].startsample, fd);
		READDW(sf->sample[i].endsample, fd);
		READDW(sf->sample[i].startloop, fd);
		READDW(sf->sample[i].endloop, fd);
		if (sf->version > 1) { /* SF2 only */
			READDW(sf->sample[i].samplerate, fd);
			READB(sf->sample[i].originalPitch, fd);
			READB(sf->sample[i].pitchCorrection, fd);
			READW(sf->sample[i].samplelink, fd);
			READW(sf->sample[i].sampletype, fd);
		} else { /* for SBK; set missing infos */
			sf->sample[i].samplerate = 44100;
			sf->sample[i].originalPitch = 60;
			sf->sample[i].pitchCorrection = 0;
			sf->sample[i].samplelink = 0;
			/* the first RAM data starts from address 0 */
			if (sf->sample[i].startsample == 0)
				in_rom = 0;
			if (in_rom)
				sf->sample[i].sampletype = 0x8001;
			else
				sf->sample[i].sampletype = 1;
		}
	}
}
Beispiel #2
0
void Instruments::load_sample_info(int size, SFInfo *sf, struct timidity_file *fd)
{
	int i;
	int in_rom;

	/* the record size depends on the soundfont version */
	if (sf->version > 1) {
		/* SF2 includes sample name and other infos */
		sf->nsamples = size / 46;
		sf->sample = NEW(SFSampleInfo, sf->nsamples);
	}
	else {
		/* SBK; sample name may be read already */
		int nsamples = size / 16;
		if (sf->sample == NULL) {
			sf->nsamples = nsamples;
			sf->sample = NEW(SFSampleInfo, sf->nsamples);
		}
		else if (sf->nsamples != nsamples) {
			/* overwrite it */
			sf->nsamples = nsamples;
		}
	}

	in_rom = 1;  /* data may start from ROM samples */
	for (i = 0; i < sf->nsamples; i++) {
		if (sf->version > 1) /* SF2 only */
			READSTR(sf->sample[i].name, fd);
		READDW((uint32_t *)&sf->sample[i].startsample, fd);
		READDW((uint32_t *)&sf->sample[i].endsample, fd);
		READDW((uint32_t *)&sf->sample[i].startloop, fd);
		READDW((uint32_t *)&sf->sample[i].endloop, fd);
		if (sf->version > 1) { /* SF2 only */
			READDW((uint32_t *)&sf->sample[i].samplerate, fd);
			READB(sf->sample[i].originalPitch, fd);
			READB(sf->sample[i].pitchCorrection, fd);
			READW(&sf->sample[i].samplelink, fd);
			READW(&sf->sample[i].sampletype, fd);
		}
		else { /* for SBK; set missing infos */
			sf->sample[i].samplerate = 44100;
			sf->sample[i].originalPitch = 60;
			sf->sample[i].pitchCorrection = 0;
			sf->sample[i].samplelink = 0;
			/* the first RAM data starts from address 0 */
			if (sf->sample[i].startsample == 0)
				in_rom = 0;
			if (in_rom)
				sf->sample[i].sampletype = 0x8001;
			else
				sf->sample[i].sampletype = 1;
		}
	}
}
Beispiel #3
0
/* new version of lookahead:
*
*	gets PC of the instruction that wants to know wich flags it should deliver
*	still doesn work
*/
byte cmpl_alive(int pc, byte unknown, int n, int include)
{
	int op, pc_a, pc_b, self_read, self_write, new_unknown;
	byte successor_flags;

	if(pc == 0) {	 //special case for instructions with just one successor (dummy)
		return 0x00; //no flags alive
	}

	if(n <= 0) {
		return unknown; // time is up, everything unknown might be alive
	}

	switch(branchtype[(op =readb(pc))]) {
		case BR_STRAIGHT:
				pc_a = pc + imm_ops[op]+1;
				pc_b = 0;
			break;
		break;

		case BR_A_UNCOND:
				pc_a = readw(pc+1);
				pc_b = 0;
		break;

		case BR_R_UNCOND:
				pc_a = pc + ((int)(signed char)READB(pc+1)) + 2;
				pc_b = 0;
		break;

		case BR_A_COND:
				pc_a = pc + imm_ops[op]+1;
				pc_b = readw(pc+1);
		break;

		case BR_R_COND:
				pc_a = pc + imm_ops[op]+1;
				pc_b = pc + ((int)(signed char)READB(pc+1)) + 2;
		break;

		default:
				return unknown; //fallback everything unknown is alive
		break;
	}

	//checking the range:
	if(pc < 0x4000) { // Rombank 0: only lookahead in rombank 0
		if(pc_a >= 0x4000)
			pc_a = 0;
		if(pc_b >= 0x4000)
			pc_b = 0;
	}
	else if(pc < 0x8000) {	// Rombank n: lookahead to all 0 and n
		if(pc_a >= 0x8000)
			pc_a = 0;
		if(pc_b >= 0x8000)
			pc_b = 0;

	}else if(pc >= 0x8000) { // outside main rom: no lookahead
		pc_a = pc_b = 0;
	}


	if(op == 0xcb) {
		self_read = cbrmask[readb(pc+1)];
		self_write = cbwmask[readb(pc+1)];
	}else{
		self_read = rmask[op];
		self_write = wmask[op];
	}

	if(include) {	//use flags from current opcode or just successors?
		new_unknown = unknown & ~(self_read | ~self_write);
	}else{
		new_unknown = unknown;
	}

	if(new_unknown){
		successor_flags = cmpl_alive(pc_a,new_unknown,n-1,1) | cmpl_alive(pc_b,new_unknown,n-1,1);
	}else{
		successor_flags = 0;
	}

	if(include) {
		return (unknown & self_read) | successor_flags;
	} else {
		return successor_flags;
	}
}
Beispiel #4
0
void sab8253x_init_lineS(struct sab_port *port)
{
	unsigned char stat;
	
	if(port->chip->c_cim)
	{
		if(port->chip->c_cim->ci_type == CIM_SP502)
		{
			aura_sp502_program(port, SP502_OFF_MODE);
		}
	}

	/*
	 * Wait for any commands or immediate characters
	 */
	sab8253x_cec_wait(port);
#if 0
	sab8253x_tec_wait(port);	/* I have to think about this one
					 * should I assume the line was
					 * previously in async mode*/
#endif
	
	/*
	 * Clear the FIFO buffers.
	 */
	
	WRITEB(port, cmdr, SAB82532_CMDR_RHR);
	sab8253x_cec_wait(port);
	WRITEB(port,cmdr,SAB82532_CMDR_XRES);
	
	
	/*
	 * Clear the interrupt registers.
	 */
	stat = READB(port, isr0);	/* acks ints */
	stat = READB(port, isr1);
	
	/*
	 * Now, initialize the UART 
	 */
	WRITEB(port, ccr0, 0);	  /* power-down */
	WRITEB(port, ccr0, getccr0configS(port));
	WRITEB(port, ccr1, getccr1configS(port));
	WRITEB(port, ccr2, getccr2configS(port));
	WRITEB(port, ccr3, getccr3configS(port));
	WRITEB(port, ccr4, getccr4configS(port));	/* 32 byte receive fifo */
	WRITEB(port, mode, getmodeS(port));
	WRITEB(port, tic /* really rlcr */, getrlcrconfigS(port));
	/* power-up */
	
	switch(port->ccontrol.ccr4 & SAB82532_CCR4_RF02)
	{
	case SAB82532_CCR4_RF32:
		port->recv_fifo_size = 32;
		break;
	case SAB82532_CCR4_RF16:
		port->recv_fifo_size = 16;
		break;
	case SAB82532_CCR4_RF04:
		port->recv_fifo_size = 4;
		break;
	case SAB82532_CCR4_RF02:
		port->recv_fifo_size = 2;
		break;
	default:
		port->recv_fifo_size = 32;
		port->ccontrol.ccr4 &= ~SAB82532_CCR4_RF02;
		break;
	}
	
	if(port->ccontrol.ccr2 & SAB82532_CCR2_TOE)
	{
		RAISE(port, txclkdir);
	}
	else
	{
		LOWER(port, txclkdir);
	}
	
	SET_REG_BIT(port,ccr0,SAB82532_CCR0_PU);

	if(port->chip->c_cim)
	{
		if(port->chip->c_cim->ci_type == CIM_SP502)
		{
			aura_sp502_program(port, port->sigmode);
		}
	}
}
Beispiel #5
0
void CReplay :: ParseReplay( bool parseBlocks )
{
	m_HostPID = 0;
	m_HostName.clear( );
	m_GameName.clear( );
	m_StatString.clear( );
	m_PlayerCount = 0;
	m_MapGameType = 0;
	m_Players.clear( );
	m_Slots.clear( );
	m_RandomSeed = 0;
	m_SelectMode = 0;
	m_StartSpotCount = 0;
	m_LoadingBlocks = queue<BYTEARRAY>( );
	m_Blocks = queue<BYTEARRAY>( );
	m_CheckSums = queue<uint32_t>( );

	if( m_Flags != 32768 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (flags mismatch)" );
		m_Valid = false;
		return;
	}

	istringstream ISS( m_Decompressed );

	unsigned char Garbage1;
	uint32_t Garbage4;
	string GarbageString;
	unsigned char GarbageData[65535];

	READB( ISS, &Garbage4, 4 );				// Unknown (4.0)

	if( Garbage4 != 272 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.0 Unknown mismatch)" );
		m_Valid = false;
		return;
	}

	READB( ISS, &Garbage1, 1 );				// Host RecordID (4.1)

	if( Garbage1 != 0 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host RecordID mismatch)" );
		m_Valid = false;
		return;
	}

	READB( ISS, &m_HostPID, 1 );

	if( m_HostPID > 15 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host PlayerID is invalid)" );
		m_Valid = false;
		return;
	}

	READSTR( ISS, m_HostName );				// Host PlayerName (4.1)
	READB( ISS, &Garbage1, 1 );				// Host AdditionalSize (4.1)

	if( Garbage1 != 1 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host AdditionalSize mismatch)" );
		m_Valid = false;
		return;
	}

	READB( ISS, &Garbage1, 1 );				// Host AdditionalData (4.1)

	if( Garbage1 != 0 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host AdditionalData mismatch)" );
		m_Valid = false;
		return;
	}

	AddPlayer( m_HostPID, m_HostName );
	READSTR( ISS, m_GameName );				// GameName (4.2)
	READSTR( ISS, GarbageString );			// Null (4.0)
	READSTR( ISS, m_StatString );			// StatString (4.3)
	READB( ISS, &m_PlayerCount, 4 );		// PlayerCount (4.6)

	if( m_PlayerCount > 12 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.6 PlayerCount is invalid)" );
		m_Valid = false;
		return;
	}

	READB( ISS, &m_MapGameType, 4 );		// GameType (4.7)
	READB( ISS, &Garbage4, 4 );				// LanguageID (4.8)

	while( 1 )
	{
		READB( ISS, &Garbage1, 1 );			// Player RecordID (4.1)

		if( Garbage1 == 22 )
		{
			unsigned char PlayerID;
			string PlayerName;
			READB( ISS, &PlayerID, 1 );		// Player PlayerID (4.1)

			if( PlayerID > 15 )
			{
				CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player PlayerID is invalid)" );
				m_Valid = false;
				return;
			}

			READSTR( ISS, PlayerName );		// Player PlayerName (4.1)
			READB( ISS, &Garbage1, 1 );		// Player AdditionalSize (4.1)

			if( Garbage1 != 1 )
			{
				CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player AdditionalSize mismatch)" );
				m_Valid = false;
				return;
			}

			READB( ISS, &Garbage1, 1 );		// Player AdditionalData (4.1)

			if( Garbage1 != 0 )
			{
				CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player AdditionalData mismatch)" );
				m_Valid = false;
				return;
			}

			READB( ISS, &Garbage4, 4 );		// Unknown

			if( Garbage4 != 0 )
			{
				CONSOLE_Print( "[REPLAY] invalid replay (4.9 Unknown mismatch)" );
				m_Valid = false;
				return;
			}

			AddPlayer( PlayerID, PlayerName );
		}
		else if( Garbage1 == 25 )
			break;
		else
		{
			CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player RecordID mismatch)" );
			m_Valid = false;
			return;
		}
	}

	uint16_t Size;
	unsigned char NumSlots;
	READB( ISS, &Size, 2 );					// Size (4.10)
	READB( ISS, &NumSlots, 1 );				// NumSlots (4.10)

	if( Size != 7 + NumSlots * 9 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.10 Size is invalid)" );
		m_Valid = false;
		return;
	}

	if( NumSlots == 0 || NumSlots > 12 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (4.10 NumSlots is invalid)" );
		m_Valid = false;
		return;
	}

        for( int i = 0; i < NumSlots; ++i )
	{
		unsigned char SlotData[9];
		READB( ISS, SlotData, 9 );
		BYTEARRAY SlotDataBA = UTIL_CreateByteArray( SlotData, 9 );
		m_Slots.push_back( CGameSlot( SlotDataBA ) );
	}

	READB( ISS, &m_RandomSeed, 4 );			// RandomSeed (4.10)
	READB( ISS, &m_SelectMode, 1 );			// SelectMode (4.10)
	READB( ISS, &m_StartSpotCount, 1 );		// StartSpotCount (4.10)

	if( ISS.eof( ) || ISS.fail( ) )
	{
		CONSOLE_Print( "[SAVEGAME] failed to parse replay header" );
		m_Valid = false;
		return;
	}

	if( !parseBlocks )
		return;

	READB( ISS, &Garbage1, 1 );				// first start block ID (5.0)

	if( Garbage1 != CReplay :: REPLAY_FIRSTSTARTBLOCK )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (5.0 first start block ID mismatch)" );
		m_Valid = false;
		return;
	}

	READB( ISS, &Garbage4, 4 );				// first start block data (5.0)

	if( Garbage4 != 1 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (5.0 first start block data mismatch)" );
		m_Valid = false;
		return;
	}

	READB( ISS, &Garbage1, 1 );				// second start block ID (5.0)

	if( Garbage1 != CReplay :: REPLAY_SECONDSTARTBLOCK )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (5.0 second start block ID mismatch)" );
		m_Valid = false;
		return;
	}

	READB( ISS, &Garbage4, 4 );				// second start block data (5.0)

	if( Garbage4 != 1 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (5.0 second start block data mismatch)" );
		m_Valid = false;
		return;
	}

	while( 1 )
	{
		READB( ISS, &Garbage1, 1 );			// third start block ID *or* loading block ID (5.0)

		if( ISS.eof( ) || ISS.fail( ) )
		{
			CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block unexpected end of file found)" );
			m_Valid = false;
			return;
		}
		if( Garbage1 == CReplay :: REPLAY_LEAVEGAME )
		{
			READB( ISS, GarbageData, 13 );
			BYTEARRAY LoadingBlock;
			LoadingBlock.push_back( Garbage1 );
			UTIL_AppendByteArray( LoadingBlock, GarbageData, 13 );
			m_LoadingBlocks.push( LoadingBlock );
		}
		else if( Garbage1 == CReplay :: REPLAY_THIRDSTARTBLOCK )
			break;
		else
		{
			CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block ID mismatch)" );
			m_Valid = false;
			return;
		}
	}

	READB( ISS, &Garbage4, 4 );				// third start block data (5.0)

	if( Garbage4 != 1 )
	{
		CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block data mismatch)" );
		m_Valid = false;
		return;
	}

	if( ISS.eof( ) || ISS.fail( ) )
	{
		CONSOLE_Print( "[SAVEGAME] failed to parse replay start blocks" );
		m_Valid = false;
		return;
	}

	uint32_t ActualReplayLength = 0;

	while( 1 )
	{
		READB( ISS, &Garbage1, 1 );			// block ID (5.0)

		if( ISS.eof( ) || ISS.fail( ) )
			break;
		else if( Garbage1 == CReplay :: REPLAY_LEAVEGAME )
		{
			READB( ISS, GarbageData, 13 );

			// reconstruct the block

			BYTEARRAY Block;
			Block.push_back( CReplay :: REPLAY_LEAVEGAME );
			UTIL_AppendByteArray( Block, GarbageData, 13 );
			m_Blocks.push( Block );
		}
		else if( Garbage1 == CReplay :: REPLAY_TIMESLOT )
		{
			uint16_t BlockSize;
			READB( ISS, &BlockSize, 2 );
			READB( ISS, GarbageData, BlockSize );

			if( BlockSize >= 2 )
				ActualReplayLength += GarbageData[0] | GarbageData[1] << 8;

			// reconstruct the block

			BYTEARRAY Block;
			Block.push_back( CReplay :: REPLAY_TIMESLOT );
			UTIL_AppendByteArray( Block, BlockSize, false );
			UTIL_AppendByteArray( Block, GarbageData, BlockSize );
			m_Blocks.push( Block );
		}
		else if( Garbage1 == CReplay :: REPLAY_CHATMESSAGE )
		{
			unsigned char PID;
			uint16_t BlockSize;
			READB( ISS, &PID, 1 );

			if( PID > 15 )
			{
				CONSOLE_Print( "[REPLAY] invalid replay (5.0 chatmessage pid is invalid)" );
				m_Valid = false;
				return;
			}

			READB( ISS, &BlockSize, 2 );
			READB( ISS, GarbageData, BlockSize );

			// reconstruct the block

			BYTEARRAY Block;
			Block.push_back( CReplay :: REPLAY_CHATMESSAGE );
			Block.push_back( PID );
			UTIL_AppendByteArray( Block, BlockSize, false );
			UTIL_AppendByteArray( Block, GarbageData, BlockSize );
			m_Blocks.push( Block );
		}
		else if( Garbage1 == CReplay :: REPLAY_CHECKSUM )
		{
			READB( ISS, &Garbage1, 1 );

			if( Garbage1 != 4 )
			{
				CONSOLE_Print( "[REPLAY] invalid replay (5.0 checksum unknown mismatch)" );
				m_Valid = false;
				return;
			}

			uint32_t CheckSum;
			READB( ISS, &CheckSum, 4 );
			m_CheckSums.push( CheckSum );
		}
		else
		{
			// it's not necessarily an error if we encounter an unknown block ID since replays can contain extra data

			break;
		}
	}

	if( m_ReplayLength != ActualReplayLength )
		CONSOLE_Print( "[REPLAY] warning - replay length mismatch (" + UTIL_ToString( m_ReplayLength ) + "ms/" + UTIL_ToString( ActualReplayLength ) + "ms)" );

	m_Valid = true;
}
Beispiel #6
0
void sab8253x_start_txS(struct sab_port *port)
{
	unsigned long flags;
	register int count;
	register int total;
	register int offset;
	char temporary[32];
	register unsigned int slopspace;
	register int sendsize;
	unsigned int totaltransmit;
	unsigned fifospace;
	unsigned loadedcount;
	struct tty_struct *tty = port->tty; /* a little gross tty flags whether
					       invoked from a tty or the network */
	
	fifospace = port->xmit_fifo_size; /* This code can handle fragmented frames
					     although currently none are generated*/
	loadedcount = 0;
	
	if(port->sabnext2.transmit == NULL)
	{
		return;
	}
	
	save_flags(flags); 
	cli();			
	
	
	if(count = port->sabnext2.transmit->Count, (count & OWNER) == OWN_SAB)
	{
		count &= ~OWN_SAB; /* OWN_SAB is really 0 but cannot guarantee in the future */
		
		if(port->sabnext2.transmit->HostVaddr)
		{
			total = (port->sabnext2.transmit->HostVaddr->tail - 
				 port->sabnext2.transmit->HostVaddr->data); /* packet size */
		}
		else
		{
			total = 0;		/* the data is only the crc/trailer */
		}
		
		if(tty && (tty->stopped || tty->hw_stopped) && (count == total))
		{			/* works for frame that only has a trailer (crc) */
			port->interrupt_mask1 |= SAB82532_IMR1_XPR;
			WRITEB(port, imr1, port->interrupt_mask1);
			restore_flags(flags);	/* can't send */
			return;
		}
		
		offset = (total - count);	/* offset to data still to send */
		
		port->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
		WRITEB(port, imr1, port->interrupt_mask1);
		port->all_sent = 0;
		
		if(READB(port,star) & SAB82532_STAR_XFW)
		{
			if(count <= fifospace)
			{
				port->xmit_cnt = count;
				slopspace = 0;
				sendsize = 0;
				if(port->sabnext2.transmit->sendcrc) 
				/* obviously should not happen for async but might use for
				   priority transmission */
				{
					slopspace = fifospace - count;
				}
				if(slopspace)
				{
					if(count)
					{
						memcpy(temporary, &port->sabnext2.transmit->HostVaddr->data[offset], 
						       count);
					}
					sendsize = MIN(slopspace, (4 - port->sabnext2.transmit->crcindex)); 
				/* how many bytes to send */
					memcpy(&temporary[count], 
					       &((unsigned char*)(&port->sabnext2.transmit->crc))
					       [port->sabnext2.transmit->crcindex], 
					       sendsize);
					port->sabnext2.transmit->crcindex += sendsize;
					if(port->sabnext2.transmit->crcindex >= 4)
					{
						port->sabnext2.transmit->sendcrc = 0;
					}
					port->xmit_buf = temporary;
				}
				else
				{
					port->xmit_buf =	/* set up wrifefifo variables */
						&port->sabnext2.transmit->HostVaddr->data[offset];
				}
				port->xmit_cnt += sendsize;
				count = 0;
			}
			else
			{
				count -= fifospace;
				port->xmit_cnt = fifospace;
				port->xmit_buf =	/* set up wrifefifo variables */
					&port->sabnext2.transmit->HostVaddr->data[offset];
				
			}
			port->xmit_tail= 0;
			loadedcount = port->xmit_cnt;
			(*port->writefifo)(port);
			totaltransmit = Sab8253xCountTransmitDescriptors(port);
			if(tty && (totaltransmit < (sab8253xs_listsize/2))) /* only makes sense on a TTY */
			{
				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
			}
			
			if((sab8253xt_listsize - totaltransmit) > (sab8253xt_listsize/2))
			{
				port->buffergreedy = 0;
			}
			else
			{
				port->buffergreedy = 1;
			}
			
			port->xmit_buf = NULL; /* this var is used to indicate whether to call kfree */
			
			/* fifospace -= loadedcount;*/
			/* Here to make mods to handle arbitrarily fragmented frames look to 8253xtty.c for help */
			
			if ((count <= 0) && (port->sabnext2.transmit->sendcrc == 0))
			{
				port->sabnext2.transmit->Count = OWN_DRIVER;
				if(!tty)
				{		/* called by network driver */
					++(port->Counters.transmitpacket);
				}
#ifdef FREEININTERRUPT		/* treat this routine as if taking place in interrupt */
				if(port->sabnext2.transmit->HostVaddr)
				{
					skb_unlink(port->sabnext2.transmit->HostVaddr);
					dev_kfree_skb_any(port->sabnext2.transmit->HostVaddr);
					port->sabnext2.transmit->HostVaddr = 0; /* no skb */
				}
				port->sabnext2.transmit->crcindex = 0; /* no single byte */
#endif
				sab8253x_cec_wait(port);
				WRITEB(port, cmdr, SAB82532_CMDR_XME|SAB82532_CMDR_XTF); /* Terminate the frame */
				
				port->sabnext2.transmit = port->sabnext2.transmit->VNext;
				
				if(!tty && port->tx_full)	/* invoked from the network driver */
				{
					port->tx_full = 0; /* there is a free slot */
					switch(port->open_type)
					{
					case OPEN_SYNC_NET:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
						port->dev->start = 1;
						port->dev->tbusy = 0;	/* maybe need mark_bh here */
#else
						netif_start_queue(port->dev);
#endif
						break;
						
					case OPEN_SYNC_CHAR:
						wake_up_interruptible(&port->write_wait);
						break;
						
					default:
						break;
					}
				}
				
				if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB)
				{		/* new frame to send */
					port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
					WRITEB(port, imr1, port->interrupt_mask1);
				}
				else
				{
					port->interrupt_mask1 |= SAB82532_IMR1_XPR;
					WRITEB(port, imr1, port->interrupt_mask1);
					if((port->open_type == OPEN_SYNC_CHAR) && port->async_queue)
					{		/* if indication of transmission is needed by the */
						/* application on a per-frame basis kill_fasync */
						/* can provide it */
						kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
					}
				}
				restore_flags(flags);
				return;
			}
			/* Issue a Transmit FIFO command. */
			sab8253x_cec_wait(port);
			WRITEB(port, cmdr, SAB82532_CMDR_XTF);	
			port->sabnext2.transmit->Count = (count|OWN_SAB);
		}
		port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR); /* more to send */
		WRITEB(port, imr1, port->interrupt_mask1);
	}
	else
	{				/* nothing to send */
		port->interrupt_mask1 |= SAB82532_IMR1_XPR;
		WRITEB(port, imr1, port->interrupt_mask1);
	}
	restore_flags(flags);
	return;
}
/*
 * This routine is called to set the UART divisor registers to match
 * the specified baud rate for a serial port.
 */
static void sab8253x_change_speedS(struct sab_port *port)
{
	unsigned long	flags,baud;
	tcflag_t	cflag;
	u8	        ccr2=0,ccr4=0,ebrg=0;
	int		i, bits;
#ifdef DEBUGGING
	printk("Change speed!  ");
#endif
	if (!port->tty || !port->tty->termios) 
	{
#ifdef DEBUGGING
		printk("NOT!\n");
#endif
		return;
	}
	
#ifdef DEBUGGING
	printk(" for real.\n");
#endif
	
	cflag = port->tty->termios->c_cflag;
	
	/* Byte size and parity */
	switch (cflag & CSIZE) 
	{
	case CS5: 
		bits = 7; 
		break;
	case CS6: 
		bits = 8; 
		break;
	case CS7: 
		bits = 9; 
		break;
	default:
	case CS8: 
		bits = 10; 
		break;
	}
	
	if (cflag & CSTOPB) 
	{
		bits++;
	}
	
	if (cflag & PARENB) 
	{
		bits++;
	}
	
	/* Determine EBRG values based on the "encoded"baud rate */
	i = cflag & CBAUD;
	switch(i)
	{
	case B0:
		baud=0;
		break;
	case  B50:
		baud=100;
		break;
	case  B75:
		baud=150;
		break;
	case  B110:
		baud=220;
		break;
	case  B134:
		baud=269;
		break;
	case  B150:
		baud=300;
		break;
	case  B200:
		baud=400;
		break;
	case B300:
		baud=600;
		break;
	case B600:
		baud=1200;
		break;
	case B1200:
		baud=2400;
		break;
	case B1800:
		baud=3600;
		break;
	case B2400:
		baud=4800;
		break;
	case B4800:
		baud=9600;
		break;
	case B9600:
		baud=19200;
		break;
	case B19200:
		baud=38400;
		break;
	case  B38400:
		if(port->custspeed)
		{
			baud=port->custspeed<<1;
		}
		else
		{
			baud=76800;
		}
		break;
	case B57600:
		baud=115200;
		break;
#ifdef SKIPTHIS
	case B76800:
		baud=153600;
		break;
	case B153600:
		baud=307200;
		break;
#endif
	case B230400:
		baud=460800;
		break;
	case  B460800:
		baud=921600;
		break;
	case B115200:
	default:
		baud=230400;
		break;
	}
	
	if(!sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud))) 
	{
		printk("Aurora Warning. baudrate %ld could not be set! Using 115200",baud);
		baud=230400;
		sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud));
	}
	
	if (port->baud)
		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;
	else
		port->timeout = 0;
	port->timeout += HZ / 50;		/* Add .02 seconds of slop */
	
	/* CTS flow control flags */
	if (cflag & CRTSCTS)
		port->flags |= FLAG8253X_CTS_FLOW;
	else
		port->flags &= ~(FLAG8253X_CTS_FLOW);
	
	if (cflag & CLOCAL)
		port->flags &= ~(FLAG8253X_CHECK_CD);
	else
		port->flags |= FLAG8253X_CHECK_CD;
	if (port->tty)
		port->tty->hw_stopped = 0;
	
	/*
	 * Set up parity check flag
	 * XXX: not implemented, yet.
	 */
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
	
	/*
	 * Characters to ignore
	 * XXX: not implemented, yet.
	 */
	
	/*
	 * !!! ignore all characters if CREAD is not set
	 * XXX: not implemented, yet.
	 */
	if ((cflag & CREAD) == 0)
		port->ignore_status_mask |= SAB82532_ISR0_RPF;
	
	save_flags(flags); 
	cli();
	sab8253x_cec_wait(port);
	
	WRITEB(port, bgr, ebrg);
	WRITEB(port, ccr2, READB(port, ccr2) & ~(0xc0)); /* clear out current baud rage */
	WRITEB(port, ccr2, READB(port, ccr2) | ccr2);
	WRITEB(port, ccr4, (READB(port,ccr4) & ~SAB82532_CCR4_EBRG) | ccr4);
	
	if (port->flags & FLAG8253X_CTS_FLOW) 
	{
		WRITEB(port, mode, READB(port,mode) & ~(SAB82532_MODE_RTS));
		port->interrupt_mask1 &= ~(SAB82532_IMR1_CSC);
		WRITEB(port, imr1, port->interrupt_mask1);
	} 
	else 
	{
		WRITEB(port, mode, READB(port,mode) | SAB82532_MODE_RTS);
		port->interrupt_mask1 |= SAB82532_IMR1_CSC;
		WRITEB(port, imr1, port->interrupt_mask1);
	}
	WRITEB(port, mode, READB(port, mode) | SAB82532_MODE_RAC);
	restore_flags(flags);
}
static void sab8253x_receive_charsS(struct sab_port *port,
			     union sab8253x_irq_status *stat)
{
	struct tty_struct *tty = port->tty;
	unsigned char buf[32];
	int free_fifo = 0;
	int reset_fifo = 0;
	int msg_done = 0;
	int msg_bad = 0;
	int count = 0;
	int total_size = 0;
	int rstatus = 0;
	struct sk_buff *skb;
	
	/* Read number of BYTES (Character + Status) available. */
	
	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
	{
		++msg_bad;
		++free_fifo;
		++reset_fifo;
	}
	else
	{
		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
		{
			count = port->recv_fifo_size;
			++free_fifo;
		}
		
		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
		{
			count = READB(port, rbcl);
			count &= (port->recv_fifo_size - 1);
			++msg_done;
			++free_fifo;
			
			total_size = READB(port, rbch);
			if(total_size & SAB82532_RBCH_OV) /* need to revisit for 4096 byte frames */
			{
				msg_bad++;
			}
			
			rstatus = READB(port, rsta);
			if((rstatus & SAB82532_RSTA_VFR) == 0)
			{
				msg_bad++;
			}
			if(rstatus & SAB82532_RSTA_RDO)
			{
				msg_bad++;
			}
			if((rstatus & SAB82532_RSTA_CRC) == 0)
			{
				msg_bad++;
			}
			if(rstatus & SAB82532_RSTA_RAB)
			{
				msg_bad++;
			}
		}
	}
	
	/* Read the FIFO. */
	
	(*port->readfifo)(port, buf, count);
	
	
	/* Issue Receive Message Complete command. */
	
	if (free_fifo) 
	{
		sab8253x_cec_wait(port);
		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
	}
	
	if(reset_fifo)
	{
		sab8253x_cec_wait(port);
		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
	}
	
	if(msg_bad)
	{
		port->msgbufindex = 0;
		return;
	}
	
	memcpy(&port->msgbuf[port->msgbufindex], buf, count);
	port->msgbufindex += count;
	
#ifdef CONSOLE_SUPPORT
	if (port->is_console)
	{
		wake_up(&keypress_wait);
	}
#endif
	
	if(msg_done)
	{
		
		if(port->msgbufindex <= 3) /* min is 1 char + 2 CRC + status byte */
		{
			port->msgbufindex = 0;
			return;
		}
		
		total_size = port->msgbufindex - 3; /* strip off the crc16 and the status byte */
		port->msgbufindex = 0;
		
		/* ignore the receive buffer waiting -- we know the correct size here */
		
		if (!tty)
		{
			return;
		}
		if(skb = dev_alloc_skb(total_size), skb)
		{
			memcpy(skb->data, &port->msgbuf[0], total_size);
			skb->tail = (skb->data + total_size);
			skb->data_len = total_size;
			skb->len = total_size;
			skb_queue_tail(port->sab8253xc_rcvbuflist, skb);
		}
		queue_task(&tty->flip.tqueue, &tq_timer); /* clear out flip buffer as fast as possible
							   * maybe should not be done unconditionally hear
							   * but should be within the above consequence
							   * clause */
	}
}
void CSaveGame :: ParseSaveGame( )
{
    m_MapPath.clear( );
    m_GameName.clear( );
    m_NumSlots = 0;
    m_Slots.clear( );
    m_RandomSeed = 0;
    m_MagicNumber.clear( );

    if( m_Flags != 0 )
    {
        CONSOLE_Print( "[SAVEGAME] invalid replay (flags mismatch)" );
        m_Valid = false;
        return;
    }

    istringstream ISS( m_Decompressed );

    // savegame format figured out by Varlock:
    // string		-> map path
    // 0 (string?)	-> ??? (no idea what this is)
    // string		-> game name
    // 0 (string?)	-> ??? (maybe original game password)
    // string		-> stat string
    // 4 bytes		-> ??? (seems to be # of slots)
    // 4 bytes		-> ??? (seems to be 0x01 0x28 0x49 0x00 on both of the savegames examined)
    // 2 bytes		-> ??? (no idea what this is)
    // slot structure
    // 4 bytes		-> magic number

    unsigned char Garbage1;
    uint16_t Garbage2;
    uint32_t Garbage4;
    string GarbageString;
    uint32_t MagicNumber;

    READSTR( ISS, m_MapPath );				// map path
    READSTR( ISS, GarbageString );			// ???
    READSTR( ISS, m_GameName );				// game name
    READSTR( ISS, GarbageString );			// ???
    READSTR( ISS, GarbageString );			// stat string
    READB( ISS, &Garbage4, 4 );				// ???
    READB( ISS, &Garbage4, 4 );				// ???
    READB( ISS, &Garbage2, 2 );				// ???
    READB( ISS, &m_NumSlots, 1 );			// number of slots

    if( m_NumSlots > 12 )
    {
        CONSOLE_Print( "[SAVEGAME] invalid savegame (too many slots)" );
        m_Valid = false;
        return;
    }

    for( unsigned char i = 0; i < m_NumSlots; i++ )
    {
        unsigned char SlotData[9];
        READB( ISS, SlotData, 9 );			// slot data
        m_Slots.push_back( CGameSlot( SlotData[0], SlotData[1], SlotData[2], SlotData[3], SlotData[4], SlotData[5], SlotData[6], SlotData[7], SlotData[8] ) );
    }

    READB( ISS, &m_RandomSeed, 4 );			// random seed
    READB( ISS, &Garbage1, 1 );				// GameType
    READB( ISS, &Garbage1, 1 );				// number of player slots (non observer)
    READB( ISS, &MagicNumber, 4 );			// magic number

    if( ISS.eof( ) || ISS.fail( ) )
    {
        CONSOLE_Print( "[SAVEGAME] failed to parse savegame header" );
        m_Valid = false;
        return;
    }

    m_MagicNumber = UTIL_CreateByteArray( MagicNumber, false );
    m_Valid = true;
}
	/* stream */
static void sab8253x_receive_charsN(struct sab_port *port,
				    union sab8253x_irq_status *stat)
{
	unsigned char buf[32];
	int free_fifo = 0;
	int reset_fifo = 0;
	int msg_done = 0;
	int msg_bad = 0;
	int count = 0;
	int total_size = 0;
	int rstatus = 0;
	struct sk_buff *skb;
	
	/* Read number of BYTES (Character + Status) available. */
	
	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
	{
		++msg_bad;
		++free_fifo;
		++reset_fifo;
	}
	else
	{
		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
		{
			count = port->recv_fifo_size;
			++free_fifo;
		}
		
		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
		{
			count = READB(port,rbcl);
			count &= (port->recv_fifo_size - 1);
			++msg_done;
			++free_fifo;
			
			total_size = READB(port, rbch);
			if(total_size & SAB82532_RBCH_OV)
			{
				msg_bad++;
			}
			
			rstatus = READB(port, rsta);
			if((rstatus & SAB82532_RSTA_VFR) == 0)
			{
				msg_bad++;
			}
			if(rstatus & SAB82532_RSTA_RDO)
			{
				msg_bad++;
			}
			if((rstatus & SAB82532_RSTA_CRC) == 0)
			{
				msg_bad++;
			}
			if(rstatus & SAB82532_RSTA_RAB)
			{
				msg_bad++;
			}
		}
	}
	
	/* Read the FIFO. */
	(*port->readfifo)(port, buf, count);
	
	/* Issue Receive Message Complete command. */
	
	if (free_fifo) 
	{
		sab8253x_cec_wait(port);
		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
	}
	
	if(reset_fifo)
	{
		sab8253x_cec_wait(port);
		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
	}
	
	if(port->active2.receive == NULL)
	{
		return;
	}
	
	if(msg_bad)
	{
		++(port->Counters.rx_drops);
		port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; /* clear the buffer */
		port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
		return;
	}
	
	memcpy(port->active2.receive->HostVaddr->tail, buf, count);
	port->active2.receive->HostVaddr->tail += count;
	
	if(msg_done)
	{
		port->active2.receive->Count = 
			(port->active2.receive->HostVaddr->tail - port->active2.receive->HostVaddr->data);
		if((port->active2.receive->Count < (ETH_ZLEN+4+3)) || /* 4 is the CRC32 size 3 bytes from the SAB part */
		   (skb = dev_alloc_skb(sab8253xn_rbufsize), skb == NULL))
		{
			++(port->Counters.rx_drops);
			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 
				/* clear the buffer */
			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
		}
		else
		{
			port->active2.receive->Count -= 3;
			port->active2.receive->HostVaddr->len = port->active2.receive->Count;
			port->active2.receive->HostVaddr->pkt_type = PACKET_HOST;
			port->active2.receive->HostVaddr->dev = port->dev;
			port->active2.receive->HostVaddr->protocol = 
				eth_type_trans(port->active2.receive->HostVaddr, port->dev);
			port->active2.receive->HostVaddr->tail -= 3;
			++(port->Counters.receivepacket);
			port->Counters.receivebytes += port->active2.receive->Count;
			skb_unlink(port->active2.receive->HostVaddr);
			
			netif_rx(port->active2.receive->HostVaddr);
			
			skb_queue_head(port->sab8253xbuflist, skb);
			port->active2.receive->HostVaddr = skb;
			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
		}
	}
}