Commit ee9dbb297db6adcac1df966e160e33b166b5a92a
1 parent
c20709aa
NE2000 fixes for windows (Renzo Davoli)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@731 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
61 additions
and
13 deletions
hw/ne2000.c
... | ... | @@ -103,7 +103,10 @@ |
103 | 103 | #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ |
104 | 104 | #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ |
105 | 105 | |
106 | -#define NE2000_MEM_SIZE 32768 | |
106 | +#define NE2000_PMEM_SIZE (32*1024) | |
107 | +#define NE2000_PMEM_START (16*1024) | |
108 | +#define NE2000_PMEM_END (NE2000_PMEM_SIZE+NE2000_PMEM_START) | |
109 | +#define NE2000_MEM_SIZE NE2000_PMEM_END | |
107 | 110 | |
108 | 111 | typedef struct NE2000State { |
109 | 112 | uint8_t cmd; |
... | ... | @@ -244,6 +247,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
244 | 247 | /* control register */ |
245 | 248 | s->cmd = val; |
246 | 249 | if (val & E8390_START) { |
250 | + s->isr &= ~ENISR_RESET; | |
247 | 251 | /* test specific case: zero length transfert */ |
248 | 252 | if ((val & (E8390_RREAD | E8390_RWRITE)) && |
249 | 253 | s->rcnt == 0) { |
... | ... | @@ -251,7 +255,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
251 | 255 | ne2000_update_irq(s); |
252 | 256 | } |
253 | 257 | if (val & E8390_TRANS) { |
254 | - net_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt); | |
258 | + qemu_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt); | |
255 | 259 | /* signal end of transfert */ |
256 | 260 | s->tsr = ENTSR_PTX; |
257 | 261 | s->isr |= ENISR_TX; |
... | ... | @@ -300,7 +304,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
300 | 304 | s->dcfg = val; |
301 | 305 | break; |
302 | 306 | case EN0_ISR: |
303 | - s->isr &= ~val; | |
307 | + s->isr &= ~(val & 0x7f); | |
304 | 308 | ne2000_update_irq(s); |
305 | 309 | break; |
306 | 310 | case EN1_PHYS ... EN1_PHYS + 5: |
... | ... | @@ -337,6 +341,12 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) |
337 | 341 | case EN0_ISR: |
338 | 342 | ret = s->isr; |
339 | 343 | break; |
344 | + case EN0_RSARLO: | |
345 | + ret = s->rsar & 0x00ff; | |
346 | + break; | |
347 | + case EN0_RSARHI: | |
348 | + ret = s->rsar >> 8; | |
349 | + break; | |
340 | 350 | case EN1_PHYS ... EN1_PHYS + 5: |
341 | 351 | ret = s->phys[offset - EN1_PHYS]; |
342 | 352 | break; |
... | ... | @@ -357,24 +367,64 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) |
357 | 367 | return ret; |
358 | 368 | } |
359 | 369 | |
370 | +static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr, | |
371 | + uint32_t val) | |
372 | +{ | |
373 | + if (addr < 32 || | |
374 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | |
375 | + s->mem[addr] = val; | |
376 | + } | |
377 | +} | |
378 | + | |
379 | +static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr, | |
380 | + uint32_t val) | |
381 | +{ | |
382 | + addr &= ~1; /* XXX: check exact behaviour if not even */ | |
383 | + if (addr < 32 || | |
384 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | |
385 | + s->mem[addr] = val; | |
386 | + s->mem[addr + 1] = val >> 8; | |
387 | + } | |
388 | +} | |
389 | + | |
390 | +static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr) | |
391 | +{ | |
392 | + if (addr < 32 || | |
393 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | |
394 | + return s->mem[addr]; | |
395 | + } else { | |
396 | + return 0xff; | |
397 | + } | |
398 | +} | |
399 | + | |
400 | +static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr) | |
401 | +{ | |
402 | + addr &= ~1; /* XXX: check exact behaviour if not even */ | |
403 | + if (addr < 32 || | |
404 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | |
405 | + return s->mem[addr] | (s->mem[addr + 1] << 8); | |
406 | + } else { | |
407 | + return 0xffff; | |
408 | + } | |
409 | +} | |
410 | + | |
360 | 411 | static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
361 | 412 | { |
362 | 413 | NE2000State *s = opaque; |
363 | - uint8_t *p; | |
364 | 414 | |
365 | 415 | #ifdef DEBUG_NE2000 |
366 | 416 | printf("NE2000: asic write val=0x%04x\n", val); |
367 | 417 | #endif |
368 | - p = s->mem + s->rsar; | |
418 | + if (s->rcnt == 0) | |
419 | + return; | |
369 | 420 | if (s->dcfg & 0x01) { |
370 | 421 | /* 16 bit access */ |
371 | - p[0] = val; | |
372 | - p[1] = val >> 8; | |
422 | + ne2000_mem_writew(s, s->rsar, val); | |
373 | 423 | s->rsar += 2; |
374 | 424 | s->rcnt -= 2; |
375 | 425 | } else { |
376 | 426 | /* 8 bit access */ |
377 | - p[0] = val; | |
427 | + ne2000_mem_writeb(s, s->rsar, val); | |
378 | 428 | s->rsar++; |
379 | 429 | s->rcnt--; |
380 | 430 | } |
... | ... | @@ -391,18 +441,16 @@ static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
391 | 441 | static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) |
392 | 442 | { |
393 | 443 | NE2000State *s = opaque; |
394 | - uint8_t *p; | |
395 | 444 | int ret; |
396 | 445 | |
397 | - p = s->mem + s->rsar; | |
398 | 446 | if (s->dcfg & 0x01) { |
399 | 447 | /* 16 bit access */ |
400 | - ret = p[0] | (p[1] << 8); | |
448 | + ret = ne2000_mem_readw(s, s->rsar); | |
401 | 449 | s->rsar += 2; |
402 | 450 | s->rcnt -= 2; |
403 | 451 | } else { |
404 | 452 | /* 8 bit access */ |
405 | - ret = p[0]; | |
453 | + ret = ne2000_mem_readb(s, s->rsar); | |
406 | 454 | s->rsar++; |
407 | 455 | s->rcnt--; |
408 | 456 | } |
... | ... | @@ -455,5 +503,5 @@ void ne2000_init(int base, int irq, NetDriverState *nd) |
455 | 503 | |
456 | 504 | ne2000_reset(s); |
457 | 505 | |
458 | - qemu_add_fd_read_handler(nd->fd, ne2000_can_receive, ne2000_receive, s); | |
506 | + qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s); | |
459 | 507 | } | ... | ... |