Exemple #1
0
static void MPU401_Reset(void) {
	Bit8u i; /* SOFTMPU */

	mpu.mode=(mpu.intelligent ? M_INTELLIGENT : M_UART);
	PIC_RemoveEvents(EOI_HANDLER);
	mpu.state.eoi_scheduled=false;
	mpu.state.wsd=false;
	mpu.state.wsm=false;
	mpu.state.conductor=false;
	mpu.state.cond_req=false;
	mpu.state.cond_set=false;
	mpu.state.playing=false;
	mpu.state.run_irq=false;
	mpu.state.irq_pending=false;
	mpu.state.cmask=0xff;
	mpu.state.amask=mpu.state.tmask=0;
	mpu.state.midi_mask=0xffff;
	mpu.state.data_onoff=0;
	mpu.state.command_byte=0;
	mpu.state.block_ack=false;
	mpu.clock.tempo=mpu.clock.old_tempo=100;
        mpu.clock.timebase=mpu.clock.old_timebase=120/(RTCFREQ/1000);
	mpu.clock.tempo_rel=mpu.clock.old_tempo_rel=40;
	mpu.clock.tempo_grad=0;
	mpu.clock.clock_to_host=false;
	mpu.clock.cth_rate=60;
	mpu.clock.cth_counter=0;
	ClrQueue();
	mpu.state.req_mask=0;
	mpu.condbuf.counter=0;
	mpu.condbuf.type=T_OVERFLOW;
	for (i=0;i<8;i++) {mpu.playbuf[i].type=T_OVERFLOW;mpu.playbuf[i].counter=0;}
}
Exemple #2
0
void MPU401_Event(void) {
	/* SOFTMPU */
	Bit8u i;
	Bitu new_time;
	if (mpu.mode==M_UART) return;
	if (mpu.state.irq_pending) goto next_event;
	for (i=0;i<8;i++) { /* Decrease counters */
		if (mpu.state.amask&(1<<i)) {
			mpu.playbuf[i].counter--;
			if (mpu.playbuf[i].counter<=0) UpdateTrack(i);
		}
	}               
	if (mpu.state.conductor) {
		mpu.condbuf.counter--;
		if (mpu.condbuf.counter<=0) UpdateConductor();
	}
	if (mpu.clock.clock_to_host) {
		mpu.clock.cth_counter++;
		if (mpu.clock.cth_counter >= mpu.clock.cth_rate) {
			mpu.clock.cth_counter=0;
			mpu.state.req_mask|=(1<<13);
		}
	}
	if (!mpu.state.irq_pending && mpu.state.req_mask) MPU401_EOIHandler();
next_event:
	PIC_RemoveEvents(MPU_EVENT);
	if ((new_time=mpu.clock.tempo*mpu.clock.timebase)==0) return;
        PIC_AddEvent(MPU_EVENT,(Bitu)MPU401_TIMECONSTANT/new_time);
}
Exemple #3
0
void KEYBOARD_ClrBuffer(void) {
	keyb.buf8042_len=0;
	keyb.buf8042_pos=0;
	keyb.used=0;
	keyb.pos=0;
	PIC_RemoveEvents(KEYBOARD_TransferBuffer);
	keyb.scheduled=false;
}
static void cmos_checktimer(void) {
	PIC_RemoveEvents(cmos_timerevent);	
	if (cmos.timer.div<=2) cmos.timer.div+=7;
	cmos.timer.delay=(1000.0f/(32768.0f / (1 << (cmos.timer.div - 1))));
	if (!cmos.timer.div || !cmos.timer.enabled) return;
	LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay);
	PIC_AddEvent(cmos_timerevent,cmos.timer.delay);
}
Exemple #5
0
static void cmos_checktimer(void) {
	PIC_RemoveEvents(cmos_timerevent);	
	if (cmos.timer.div<=2) cmos.timer.div+=7;
	cmos.timer.delay=(1000.0f/(32768.0f / (1 << (cmos.timer.div - 1))));
	if (!cmos.timer.div || !cmos.timer.enabled) return;
	LOG(LOG_PIT,LOG_NORMAL)("RTC Timer at %.2f hz",1000.0/cmos.timer.delay);
//	PIC_AddEvent(cmos_timerevent,cmos.timer.delay);
	/* A rtc is always running */
	double remd=fmod(PIC_FullIndex(),(double)cmos.timer.delay);
	PIC_AddEvent(cmos_timerevent,(float)((double)cmos.timer.delay-remd)); //Should be more like a real pc. Check
//	status reg A reading with this (and with other delays actually)
}
Exemple #6
0
void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) {
//	if((crtc(index)!=0xe)&&(crtc(index)!=0xf)) 
//		LOG_MSG("CRTC w #%2x val %2x",crtc(index),val);
	switch(crtc(index)) {
	case 0x00:	/* Horizontal Total Register */
		if (crtc(read_only)) break;
		crtc(horizontal_total)=val;
		/* 	0-7  Horizontal Total Character Clocks-5 */
		break;
	case 0x01:	/* Horizontal Display End Register */
		if (crtc(read_only)) break;
		if (val != crtc(horizontal_display_end)) {
			crtc(horizontal_display_end)=val;
			VGA_StartResize();
		}
		/* 	0-7  Number of Character Clocks Displayed -1 */
		break;
	case 0x02:	/* Start Horizontal Blanking Register */
		if (crtc(read_only)) break;
		crtc(start_horizontal_blanking)=val;
		/*	0-7  The count at which Horizontal Blanking starts */
		break;
	case 0x03:	/* End Horizontal Blanking Register */
		if (crtc(read_only)) break;
		crtc(end_horizontal_blanking)=val;
		/*
			0-4	Horizontal Blanking ends when the last 6 bits of the character
				counter equals this field. Bit 5 is at 3d4h index 5 bit 7.
			5-6	Number of character clocks to delay start of display after Horizontal
				Total has been reached.
			7	Access to Vertical Retrace registers if set. If clear reads to 3d4h
				index 10h and 11h access the Lightpen read back registers ??
		*/
		break;
	case 0x04:	/* Start Horizontal Retrace Register */
		if (crtc(read_only)) break;
		crtc(start_horizontal_retrace)=val;
		/*	0-7  Horizontal Retrace starts when the Character Counter reaches this value. */
		break;
	case 0x05:	/* End Horizontal Retrace Register */
		if (crtc(read_only)) break;
		crtc(end_horizontal_retrace)=val;
		/*
			0-4	Horizontal Retrace ends when the last 5 bits of the character counter
				equals this value.
			5-6	Number of character clocks to delay start of display after Horizontal
				Retrace.
			7	bit 5 of the End Horizontal Blanking count (See 3d4h index 3 bit 0-4)
		*/	
		break;
	case 0x06: /* Vertical Total Register */
		if (crtc(read_only)) break;
		if (val != crtc(vertical_total)) {
			crtc(vertical_total)=val;	
			VGA_StartResize();
		}
		/*	0-7	Lower 8 bits of the Vertical Total. Bit 8 is found in 3d4h index 7
				bit 0. Bit 9 is found in 3d4h index 7 bit 5.
			Note: For the VGA this value is the number of scan lines in the display -2.
		*/
		break;
	case 0x07:	/* Overflow Register */
		//Line compare bit ignores read only */
		vga.config.line_compare=(vga.config.line_compare & 0x6ff) | (val & 0x10) << 4;
		if (crtc(read_only)) break;
		if ((vga.crtc.overflow ^ val) & 0xd6) {
			crtc(overflow)=val;
			VGA_StartResize();
		} else crtc(overflow)=val;
		/*
			0  Bit 8 of Vertical Total (3d4h index 6)
			1  Bit 8 of Vertical Display End (3d4h index 12h)
			2  Bit 8 of Vertical Retrace Start (3d4h index 10h)
			3  Bit 8 of Start Vertical Blanking (3d4h index 15h)
			4  Bit 8 of Line Compare Register (3d4h index 18h)
			5  Bit 9 of Vertical Total (3d4h index 6)
			6  Bit 9 of Vertical Display End (3d4h index 12h)
			7  Bit 9 of Vertical Retrace Start (3d4h index 10h)
		*/
		break;
	case 0x08:	/* Preset Row Scan Register */
		crtc(preset_row_scan)=val;
		vga.config.hlines_skip=val&31;
		if (IS_VGA_ARCH) vga.config.bytes_skip=(val>>5)&3;
		else vga.config.bytes_skip=0;
//		LOG_DEBUG("Skip lines %d bytes %d",vga.config.hlines_skip,vga.config.bytes_skip);
		/*
			0-4	Number of lines we have scrolled down in the first character row.
				Provides Smooth Vertical Scrolling.b
			5-6	Number of bytes to skip at the start of scanline. Provides Smooth
				Horizontal Scrolling together with the Horizontal Panning Register
				(3C0h index 13h).
		*/
		break;
	case 0x09: /* Maximum Scan Line Register */
	{
		if (IS_VGA_ARCH) {
			vga.config.line_compare &= 0x5ff;
			vga.config.line_compare |= (val&0x40)<<3;
		} else if(machine==MCH_EGA) {
			val &= 0x7f; // EGA ignores the doublescan bit
			}
		Bit8u old = crtc(maximum_scan_line);
		crtc(maximum_scan_line) = val;

		if(!vga.draw.doublescan_merging) {
			if ((old ^ val) & 0x20) VGA_StartResize();
			vga.draw.address_line_total = (val &0x1F) + 1;
			if (val&0x80) vga.draw.address_line_total*=2;
		} else if ((old ^ val) & 0xbf)
				VGA_StartResize();
		/*
			0-4	Number of scan lines in a character row -1. In graphics modes this is
				the number of times (-1) the line is displayed before passing on to
				the next line (0: normal, 1: double, 2: triple...).
				This is independent of bit 7, except in CGA modes which seems to
				require this field to be 1 and bit 7 to be set to work.
			5	Bit 9 of Start Vertical Blanking
			6	Bit 9 of Line Compare Register
			7	Doubles each scan line if set. I.e. displays 200 lines on a 400 display.
		*/
		break;
	}
	case 0x0A:	/* Cursor Start Register */
		crtc(cursor_start)=val;
		vga.draw.cursor.sline=val&0x1f;
		if (IS_VGA_ARCH) vga.draw.cursor.enabled=!(val&0x20);
		else vga.draw.cursor.enabled=true;
		/*
			0-4	First scanline of cursor within character.
			5	Turns Cursor off if set
		*/
		break;
	case 0x0B:	/* Cursor End Register */
		crtc(cursor_end)=val;
		vga.draw.cursor.eline=val&0x1f;
		vga.draw.cursor.delay=(val>>5)&0x3;

		/* 
			0-4	Last scanline of cursor within character
			5-6	Delay of cursor data in character clocks.
		*/
		break;
	case 0x0C:	/* Start Address High Register */
		crtc(start_address_high)=val;
		vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8);
		/* 0-7  Upper 8 bits of the start address of the display buffer */
		page_flip_debug_notify();
		break;
	case 0x0D:	/* Start Address Low Register */
		crtc(start_address_low)=val;
		vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val;
		/*	0-7	Lower 8 bits of the start address of the display buffer */
		page_flip_debug_notify();
		break;
	case 0x0E:	/*Cursor Location High Register */
		crtc(cursor_location_high)=val;
		vga.config.cursor_start&=0xff00ff;
		vga.config.cursor_start|=val << 8;
		/*	0-7  Upper 8 bits of the address of the cursor */
		break;
	case 0x0F:	/* Cursor Location Low Register */
//TODO update cursor on screen
		crtc(cursor_location_low)=val;
		vga.config.cursor_start&=0xffff00;
		vga.config.cursor_start|=val;
		/*	0-7  Lower 8 bits of the address of the cursor */
		break;
	case 0x10:	/* Vertical Retrace Start Register */
		crtc(vertical_retrace_start)=val;
		/*	
			0-7	Lower 8 bits of Vertical Retrace Start. Vertical Retrace starts when
			the line counter reaches this value. Bit 8 is found in 3d4h index 7
			bit 2. Bit 9 is found in 3d4h index 7 bit 7.
		*/
		break;
	case 0x11:	/* Vertical Retrace End Register */
		crtc(vertical_retrace_end)=val;
		
		if (IS_EGAVGA_ARCH && !(val & 0x10)) {
			vga.draw.vret_triggered=false;
			if (GCC_UNLIKELY(machine==MCH_EGA)) PIC_DeActivateIRQ(9);
		}
		if (IS_VGA_ARCH) crtc(read_only)=(val & 128)>0;
		else crtc(read_only)=false;
		/*
			0-3	Vertical Retrace ends when the last 4 bits of the line counter equals
				this value.
			4	if clear Clears pending Vertical Interrupts.
			5	Vertical Interrupts (IRQ 2) disabled if set. Can usually be left
				disabled, but some systems (including PS/2) require it to be enabled.
			6	If set selects 5 refresh cycles per scanline rather than 3.
			7	Disables writing to registers 0-7 if set 3d4h index 7 bit 4 is not
				affected by this bit.
		*/
		break;
	case 0x12:	/* Vertical Display End Register */
		if (val!=crtc(vertical_display_end)) {
			if (abs((Bits)val-(Bits)crtc(vertical_display_end))<3) {
				// delay small vde changes a bit to avoid screen resizing
				// if they are reverted in a short timeframe
				PIC_RemoveEvents(VGA_SetupDrawing);
				vga.draw.resizing=false;
				crtc(vertical_display_end)=val;
				VGA_StartResize(150);
			} else {
				crtc(vertical_display_end)=val;
				VGA_StartResize();
			}
		}
		/*
			0-7	Lower 8 bits of Vertical Display End. The display ends when the line
				counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1.
			Bit 9 is found in 3d4h index 7 bit 6.
		*/
		break;
	case 0x13:	/* Offset register */
		crtc(offset)=val;
		vga.config.scan_len&=0x300;
		vga.config.scan_len|=val;
		VGA_CheckScanLength();
		/*
			0-7	Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for
				word mode and 8 for Double Word mode.
		*/
		break;
	case 0x14:	/* Underline Location Register */
		crtc(underline_location)=val;
		if (IS_VGA_ARCH) {
			//Byte,word,dword mode
			if ( crtc(underline_location) & 0x40 )
				vga.config.addr_shift = 2;
			else if ( crtc( mode_control) & 0x40 )
				vga.config.addr_shift = 0;
			else
				vga.config.addr_shift = 1;
		} else {
			vga.config.addr_shift = 1;
		}

		VGA_CheckScanLength();
		/*
			0-4	Position of underline within Character cell.
			5	If set memory address is only changed every fourth character clock.
			6	Double Word mode addressing if set
		*/
		break;
	case 0x15:	/* Start Vertical Blank Register */
		if (val!=crtc(start_vertical_blanking)) {
			crtc(start_vertical_blanking)=val;
			VGA_StartResize();
		}
		/* 
			0-7	Lower 8 bits of Vertical Blank Start. Vertical blanking starts when
				the line counter reaches this value. Bit 8 is found in 3d4h index 7
				bit 3.
		*/
		break;
	case 0x16:	/*  End Vertical Blank Register */
		if (val!=crtc(end_vertical_blanking)) {
			crtc(end_vertical_blanking)=val;
			VGA_StartResize();
		}
		/*
			0-6	Vertical blanking stops when the lower 7 bits of the line counter
				equals this field. Some SVGA chips uses all 8 bits!
				IBM actually says bits 0-7.
		*/
		break;
	case 0x17:	/* Mode Control Register */
		crtc(mode_control)=val;
		vga.tandy.line_mask = (~val) & 3;
		//Byte,word,dword mode
		if ( crtc(underline_location) & 0x40 )
			vga.config.addr_shift = 2;
		else if ( crtc( mode_control) & 0x40 )
			vga.config.addr_shift = 0;
		else
			vga.config.addr_shift = 1;

		if ( vga.tandy.line_mask ) {
			vga.tandy.line_shift = 13;
			vga.tandy.addr_mask = (1 << 13) - 1;
		} else {
			vga.tandy.addr_mask = ~0;
			vga.tandy.line_shift = 0;
		}
		VGA_CheckScanLength();

		//Should we really need to do a determinemode here?
//		VGA_DetermineMode();
		/*
			0	If clear use CGA compatible memory addressing system
				by substituting character row scan counter bit 0 for address bit 13,
				thus creating 2 banks for even and odd scan lines.
			1	If clear use Hercules compatible memory addressing system by
				substituting character row scan counter bit 1 for address bit 14,
				thus creating 4 banks.
			2	If set increase scan line counter only every second line.
			3	If set increase memory address counter only every other character clock.
			5	When in Word Mode bit 15 is rotated to bit 0 if this bit is set else
				bit 13 is rotated into bit 0.
			6	If clear system is in word mode. Addresses are rotated 1 position up
				bringing either bit 13 or 15 into bit 0.
			7	Clearing this bit will reset the display system until the bit is set again.
		*/
		break;
	case 0x18:	/* Line Compare Register */
		crtc(line_compare)=val;
		vga.config.line_compare=(vga.config.line_compare & 0x700) | val;
		/*
			0-7	Lower 8 bits of the Line Compare. When the Line counter reaches this
				value, the display address wraps to 0. Provides Split Screen
				facilities. Bit 8 is found in 3d4h index 7 bit 4.
				Bit 9 is found in 3d4h index 9 bit 6.
		*/
		break;
	default:
		if (svga.write_p3d5) {
			svga.write_p3d5(crtc(index), val, iolen);
		} else {
			LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write to unknown index %X",crtc(index));
		}
		break;
	}
Exemple #7
0
void MPU401_WriteCommand(Bit8u val) { /* SOFTMPU */
	Bit8u i; /* SOFTMPU */
	if (mpu.state.reset) {
		if (mpu.state.cmd_pending || (val!=0x3f && val!=0xff)) {
			mpu.state.cmd_pending=val+1;
			return;
		}
		PIC_RemoveEvents(RESET_DONE);
		mpu.state.reset=false;
	}
	if (val<=0x2f) {
		switch (val&3) { /* MIDI stop, start, continue */
			case 1: {MIDI_RawOutByte(0xfc);break;}
			case 2: {MIDI_RawOutByte(0xfa);break;}
			case 3: {MIDI_RawOutByte(0xfb);break;}
		}
		/*if (val&0x20) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Unhandled Recording Command %x",val);*/ /* SOFTMPU */
		switch (val&0xc) {
			case  0x4:      /* Stop */
				PIC_RemoveEvents(MPU_EVENT);
				mpu.state.playing=false;
				for (i=0xb0;i<0xbf;i++) {  /* All notes off */
					MIDI_RawOutByte(i);
					MIDI_RawOutByte(0x7b);
					MIDI_RawOutByte(0);
				}
				break;
			case 0x8:       /* Play */
				/*LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started");*/ /* SOFTMPU */
				mpu.state.playing=true;
				PIC_RemoveEvents(MPU_EVENT);
                PIC_AddEvent(MPU_EVENT,(Bitu)MPU401_TIMECONSTANT/(mpu.clock.tempo*mpu.clock.timebase));
				ClrQueue();
				break;
		}
	}
	else if (val>=0xa0 && val<=0xa7) {      /* Request play counter */
		if (mpu.state.cmask&(1<<(val&7))) QueueByte((Bit8u)mpu.playbuf[val&7].counter);
	}
	else if (val>=0xd0 && val<=0xd7) {      /* Send data */
		mpu.state.old_chan=mpu.state.channel;
		mpu.state.channel=val&7;
		mpu.state.wsd=true;
		mpu.state.wsm=false;
		mpu.state.wsd_start=true;
	}
	else
	switch (val) {
		case 0xdf:      /* Send system message */
			mpu.state.wsd=false;
			mpu.state.wsm=true;
			mpu.state.wsd_start=true;
			break;
		case 0x8e:      /* Conductor */
			mpu.state.cond_set=false;
			break;
		case 0x8f:
			mpu.state.cond_set=true;
			break;
		case 0x94: /* Clock to host */
			mpu.clock.clock_to_host=false;
			break;
		case 0x95:
			mpu.clock.clock_to_host=true;
			break;
		case 0xc2: /* Internal timebase */
                        mpu.clock.timebase=48/(RTCFREQ/1000); /* SOFTMPU */
			break;
		case 0xc3:
                        mpu.clock.timebase=72/(RTCFREQ/1000); /* SOFTMPU */
			break;
		case 0xc4:
                        mpu.clock.timebase=96/(RTCFREQ/1000); /* SOFTMPU */
			break;
		case 0xc5:
                        mpu.clock.timebase=120/(RTCFREQ/1000); /* SOFTMPU */
			break;
		case 0xc6:
                        mpu.clock.timebase=144/(RTCFREQ/1000); /* SOFTMPU */
			break;
		case 0xc7:
                        mpu.clock.timebase=168/(RTCFREQ/1000); /* SOFTMPU */
			break;
		case 0xc8:
                        mpu.clock.timebase=192/(RTCFREQ/1000); /* SOFTMPU */
			break;
		/* Commands with data byte */
		case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: 
		case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef:
			mpu.state.command_byte=val;
			break;
		/* Commands 0xa# returning data */
		case 0xab:      /* Request and clear recording counter */
			QueueByte(MSG_MPU_ACK);
			QueueByte(0);
			return;
		case 0xac:      /* Request version */
                        if (CONFIG_VERSIONFIX)
                        {
                                /* SOFTMPU: Fix missing music in Gateway by reversing version and ACK */
                                QueueByte(MPU401_VERSION);
                                QueueByte(MSG_MPU_ACK);
                        }
                        else
                        {
                                QueueByte(MSG_MPU_ACK);
                                QueueByte(MPU401_VERSION);
                        }
			return;
		case 0xad:      /* Request revision */
			QueueByte(MSG_MPU_ACK);
			QueueByte(MPU401_REVISION);
			return;
		case 0xae:		/* HardMPU: Request config */
			QueueByte(MSG_MPU_ACK);
			QueueByte(mpu.config);
			return;
		case 0xaf:      /* Request tempo */
			QueueByte(MSG_MPU_ACK);
			QueueByte(mpu.clock.tempo);
			return;
		case 0xb1:      /* Reset relative tempo */
			mpu.clock.tempo_rel=40;
			break;
		case 0xb9:      /* Clear play map */
		case 0xb8:      /* Clear play counters */
			for (i=0xb0;i<0xbf;i++) {  /* All notes off */
				MIDI_RawOutByte((Bit8u)i);
				MIDI_RawOutByte(0x7b);
				MIDI_RawOutByte(0);
			}
			for (i=0;i<8;i++) {
				mpu.playbuf[i].counter=0;
				mpu.playbuf[i].type=T_OVERFLOW;
			}
			mpu.condbuf.counter=0;
			mpu.condbuf.type=T_OVERFLOW;
			if (!(mpu.state.conductor=mpu.state.cond_set)) mpu.state.cond_req=0;
			mpu.state.amask=mpu.state.tmask;
			mpu.state.req_mask=0;
			mpu.state.irq_pending=true;
			break;
		case 0xfe:		/* HardMPU: Reset with config byte */
			mpu.state.command_byte=val;
			break;
		case 0xff:      /* Reset MPU-401 */
			/*LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Reset %X",val);*/ /* SOFTMPU */
            PIC_AddEvent(RESET_DONE,MPU401_RESETBUSY);
			mpu.state.reset=true;
			MPU401_Reset();
			if (mpu.mode==M_UART) return;//do not send ack in UART mode
			break;
		case 0x3f:      /* UART mode */
			/*LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Set UART mode %X",val);*/ /* SOFTMPU */
			mpu.mode=M_UART;
			break;
		default:
			/*LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val);*/
			break;
	}
	QueueByte(MSG_MPU_ACK);
}
Exemple #8
0
void
bx_ne2k_c::write_cr(Bit32u value)
{
  BX_DEBUG ("wrote 0x%02x to CR", value);

  // Validate remote-DMA
  if ((value & 0x38) == 0x00) {
    BX_DEBUG("CR write - invalid rDMA value 0");
    value |= 0x20; /* dma_cmd == 4 is a safe default */
	//value = 0x22; /* dma_cmd == 4 is a safe default */
  }

  // Check for s/w reset
  if (value & 0x01) {
    BX_NE2K_THIS s.ISR.reset = 1;
    BX_NE2K_THIS s.CR.stop   = 1;
  } else {
    BX_NE2K_THIS s.CR.stop = 0;
  }

  BX_NE2K_THIS s.CR.rdma_cmd = (value & 0x38) >> 3;
  
  // If start command issued, the RST bit in the ISR
  // must be cleared
  if ((value & 0x02) && !BX_NE2K_THIS s.CR.start) {
    BX_NE2K_THIS s.ISR.reset = 0;
  }

  BX_NE2K_THIS s.CR.start = ((value & 0x02) == 0x02);
  BX_NE2K_THIS s.CR.pgsel = (value & 0xc0) >> 6;

    // Check for send-packet command
    if (BX_NE2K_THIS s.CR.rdma_cmd == 3) {
	// Set up DMA read from receive ring
		BX_NE2K_THIS s.remote_start = BX_NE2K_THIS s.remote_dma =
			BX_NE2K_THIS s.bound_ptr * 256;
		BX_NE2K_THIS s.remote_bytes = *((Bit16u*) &
			BX_NE2K_THIS s.mem[BX_NE2K_THIS s.bound_ptr * 256 + 2 - BX_NE2K_MEMSTART]);
		BX_INFO("Sending buffer #x%x length %d",
			BX_NE2K_THIS s.remote_start,
			BX_NE2K_THIS s.remote_bytes);
    }

  // Check for start-tx
    if ((value & 0x04) && BX_NE2K_THIS s.TCR.loop_cntl) {
		// loopback mode
		if (BX_NE2K_THIS s.TCR.loop_cntl != 1) {
			BX_INFO("Loop mode %d not supported.", BX_NE2K_THIS s.TCR.loop_cntl);
		} else {
			rx_frame (& BX_NE2K_THIS s.mem[BX_NE2K_THIS s.tx_page_start*256 -
				BX_NE2K_MEMSTART],
				BX_NE2K_THIS s.tx_bytes);

			// do a TX interrupt
			// Generate an interrupt if not masked and not one in progress
			if (BX_NE2K_THIS s.IMR.tx_inte && !BX_NE2K_THIS s.ISR.pkt_tx) {
				//LOG_MSG("tx complete interrupt");
				PIC_ActivateIRQ(s.base_irq);
			}
			BX_NE2K_THIS s.ISR.pkt_tx = 1;
		}
    } else if (value & 0x04) {
		// start-tx and no loopback
		if (BX_NE2K_THIS s.CR.stop || !BX_NE2K_THIS s.CR.start)
			BX_PANIC(("CR write - tx start, dev in reset"));
	    
		if (BX_NE2K_THIS s.tx_bytes == 0)
			BX_PANIC(("CR write - tx start, tx bytes == 0"));

#ifdef notdef    
    // XXX debug stuff
    printf("packet tx (%d bytes):\t", BX_NE2K_THIS s.tx_bytes);
    for (int i = 0; i < BX_NE2K_THIS s.tx_bytes; i++) {
      printf("%02x ", BX_NE2K_THIS s.mem[BX_NE2K_THIS s.tx_page_start*256 - 
				BX_NE2K_MEMSTART + i]);
      if (i && (((i+1) % 16) == 0)) 
	printf("\t");
    }
    printf("");
#endif    

    // Send the packet to the system driver
	/* TODO: Transmit packet */
    //BX_NE2K_THIS ethdev->sendpkt(& BX_NE2K_THIS s.mem[BX_NE2K_THIS s.tx_page_start*256 - BX_NE2K_MEMSTART], BX_NE2K_THIS s.tx_bytes);
        NE2000_PrivelegeEscalate();
	pcap_sendpacket(adhandle,&s.mem[s.tx_page_start*256 - BX_NE2K_MEMSTART], s.tx_bytes);
        NE2000_PrivelegeDrop();

	// some more debug
	if (BX_NE2K_THIS s.tx_timer_active) {
      BX_PANIC(("CR write, tx timer still active"));
	  PIC_RemoveEvents(NE2000_TX_Event);
	}
	//LOG_MSG("send packet command");
	//s.tx_timer_index = (64 + 96 + 4*8 + BX_NE2K_THIS s.tx_bytes*8)/10;
	s.tx_timer_active = 1;
	PIC_AddEvent(NE2000_TX_Event,(float)((64 + 96 + 4*8 + BX_NE2K_THIS s.tx_bytes*8)/10000.0),0);
    // Schedule a timer to trigger a tx-complete interrupt
    // The number of microseconds is the bit-time / 10.
    // The bit-time is the preamble+sfd (64 bits), the
    // inter-frame gap (96 bits), the CRC (4 bytes), and the
    // the number of bits in the frame (s.tx_bytes * 8).
    //

	/* TODO: Code transmit timer */
	/*
    bx_pc_system.activate_timer(BX_NE2K_THIS s.tx_timer_index,
				(64 + 96 + 4*8 + BX_NE2K_THIS s.tx_bytes*8)/10,
				0); // not continuous
	*/
  } // end transmit-start branch

  // Linux probes for an interrupt by setting up a remote-DMA read
  // of 0 bytes with remote-DMA completion interrupts enabled.
  // Detect this here
  if (BX_NE2K_THIS s.CR.rdma_cmd == 0x01 &&
      BX_NE2K_THIS s.CR.start &&
      BX_NE2K_THIS s.remote_bytes == 0) {
    BX_NE2K_THIS s.ISR.rdma_done = 1;
    if (BX_NE2K_THIS s.IMR.rdma_inte) {
		PIC_ActivateIRQ(s.base_irq);
      //DEV_pic_raise_irq(BX_NE2K_THIS s.base_irq);
    }
  }
}
Exemple #9
0
//Does way to much. Many things should be moved to mouse reset one day
void Mouse_NewVideoMode(void) {
	mouse.inhibit_draw=false;
	/* Get the correct resolution from the current video mode */
	Bit8u mode=mem_readb(BIOS_VIDEO_MODE);
	if(mode == mouse.mode) {LOG(LOG_MOUSE,LOG_NORMAL)("New video is the same as the old"); /*return;*/}
	switch (mode) {
	case 0x00:
	case 0x01:
	case 0x02:
	case 0x03: {
		Bitu rows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
		if ((rows==0) || (rows>250)) rows=25-1;
		mouse.max_y=8*(rows+1)-1;
		break;
	}
	case 0x04:
	case 0x05:
	case 0x06:
	case 0x07:
	case 0x08:
	case 0x09:
	case 0x0a:
	case 0x0d:
	case 0x0e:
	case 0x13:
		mouse.max_y=199;
		break;
	case 0x0f:
	case 0x10:
		mouse.max_y=349;
		break;
	case 0x11:
	case 0x12:
		mouse.max_y=479;
		break;
	default:
		LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode);
		mouse.inhibit_draw=true;
		return;
	}
	mouse.mode = mode;
	mouse.hidden = 1;
	mouse.max_x = 639;
	mouse.min_x = 0;
	mouse.min_y = 0;
	mouse.granMask = (mode == 0x0d || mode == 0x13) ? 0xfffe : 0xffff;

	mouse.events = 0;
	mouse.timer_in_progress = false;
	PIC_RemoveEvents(MOUSE_Limit_Events);

	mouse.hotx		 = 0;
	mouse.hoty		 = 0;
	mouse.background = false;
	mouse.screenMask = defaultScreenMask;
	mouse.cursorMask = defaultCursorMask;
	mouse.textAndMask= defaultTextAndMask;
	mouse.textXorMask= defaultTextXorMask;
	mouse.language   = 0;
	mouse.page               = 0;
	mouse.doubleSpeedThreshold = 64;
	mouse.updateRegion_x[0] = 1;
	mouse.updateRegion_y[0] = 1;
	mouse.updateRegion_x[1] = 1;
	mouse.updateRegion_y[1] = 1;
	mouse.cursorType = 0;
	mouse.enabled=true;
	mouse.oldhidden=1;

	oldmouseX = static_cast<Bit16s>(mouse.x);
	oldmouseY = static_cast<Bit16s>(mouse.y);


}