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;} }
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); }
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); }
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) }
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; }
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); }
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); } } }
//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); }