Exemplo n.º 1
0
int main()
{	
	// no se usa idtr, el bootloader de Pure ya lo setea en 0x0 y usa ese



	set_idt_entry(0x20, 0x08, (uint64_t)&_irq00Handler, 0x8E);    
	set_idt_entry (0x21, 0x08, (uint64_t)&_irq01Handler, 0x8E );
	//Chequiar bootloader (idt)
	


	//Todas las interrupciones habilitadas.
	picMasterMask(0xFC);
	picSlaveMask(0xFF);
        
	_sti();
	

	ncPrint("[Finished]");
	ncNewline();

	while (1) {

	}

	return 0;
}
Exemplo n.º 2
0
kmain() {
	terminal_init();

	setup_IDT_entry (&idt[0x08], 0x08, (dword)&_int_08_hand, ACS_INT, 0);
	setup_IDT_entry (&idt[0x09], 0x08, (dword)&_int_09_hand, ACS_INT, 0);
	setup_IDT_entry (&idt[0x74], 0x08, (dword)&_int_74_hand, ACS_INT, 0);
	setup_IDT_entry (&idt[0x80], 0x08, (dword)&_int_80_hand, ACS_INT, 0);
	

	/* IDTR Setting */ 

	idtr.base = 0;  
	idtr.base +=(dword) &idt;
	idtr.limit = sizeof(idt)-1;
	
	_lidt(&idtr);

	/* Interrupt unmasking */
	
	_cli();

	_maskPIC1(0xF8);           /*0XF8*/
	_maskPIC2(0xEF);		/*0XEF*/
	
	_sti();

	video_init();
	timertick_init();
	rtc_init();
	mouse_init();
	shell_run();
}
Exemplo n.º 3
0
void restoreInts(int iflag) {

	/* Activo el iflag si no estab!a activado */
	if (iflag)
		_sti();
	return;
}
Exemplo n.º 4
0
static int soundblaster_stop_playback(soundcard_t sc) {
    struct sndsb_ctx *card = soundblaster_get_sndsb_ctx(sc);

    if (card == NULL) return -1;
    if (!sc->wav_state.playing) return 0;

    _cli();
    soundblaster_update_wav_dma_position(sc,card);
    soundblaster_update_wav_play_delay(sc,card);
    _sti();

    sndsb_stop_dsp_playback(card);

    _cli();
    sc->wav_state.playing = 0;
    _sti();

    return 0;
}
Exemplo n.º 5
0
void keDoSched()
{
	uint32 i;
	uint32 j;

	_cli();
	i=keSchedNextTask();
	while(i==0xFFFFFFFF)
	{
		_sti();
		_hlt();
		_cli();
		i=keSchedNextTask();
	}						// not any task can be sched

	if(i==currentTaskId)
	{
		_sti();
		return;				// only the current task can be sched
	}
	j=currentTaskId;
	currentTaskId=i;
	_switch(&(tasks[i]->esp), &(tasks[j]->esp));
}
Exemplo n.º 6
0
static int soundblaster_start_playback(soundcard_t sc) {
    struct sndsb_ctx *card = soundblaster_get_sndsb_ctx(sc);

    if (card == NULL) return -1;
    if (!sc->wav_state.prepared) return -1;
    if (sc->wav_state.playing) return 0;

    if (!sndsb_begin_dsp_playback(card))
        return -1;

    _cli();
    sc->wav_state.playing = 1;
    _sti();

    return 0;
}
Exemplo n.º 7
0
int main()
{	

	
	setup_IDT_entry(0x20, 0x8,(uint64_t) &_irq00Handler, 0x8E);	
	setup_IDT_entry(0x21, 0x8, (uint64_t)&_irq01Handler, 0x8E);
	setup_IDT_entry(0x80, 0x8,(uint64_t) &syscallHandler, 0x8E);
	

	picMasterMask(0xFC); 
	picSlaveMask(0xFF);

	_sti();

	ncPrint("[Kernel Main]");
	ncNewline();
	ncPrint("  Sample code module at 0x");
	ncPrintHex((uint64_t)sampleCodeModuleAddress);
	ncNewline();
	
	ncPrint("  Calling the sample code module returned: ");
	ncPrintHex(((EntryPoint)sampleCodeModuleAddress)());
	ncNewline();
	ncNewline();

	ncPrint("  Sample data module at 0x");
	ncPrintHex((uint64_t)sampleDataModuleAddress);
	ncNewline();
	ncPrint("  Sample data module contents: ");
	ncPrint((char*)sampleDataModuleAddress);
	ncNewline();

	ncPrint("[Finished]");

	while(1);

	ncClear();

	

	return 0;
}
Exemplo n.º 8
0
void direct_dac_test(void) {
    unsigned long time,bytes;
    unsigned char FAR *ptr;
    unsigned int i,count;
    unsigned int pc,c;

    doubleprintf("Direct DAC playback test.\n");

    /* FIXME: Why is the final rate SLOWER in DOSBox-X in 386 protected mode? */

    sndsb_reset_dsp(sb_card);
    sndsb_write_dsp(sb_card,0xD1); /* speaker on */

    _cli();
    time = 0;
    bytes = 0;
    c = read_8254(T8254_TIMER_INTERRUPT_TICK);
    for (count=0;count < 3;count++) {
        ptr = sb_dma->lin;
        for (i=0;i < sb_dma->length;i++) {
            sndsb_write_dsp(sb_card,SNDSB_DSPCMD_DIRECT_DAC_OUT); /* 0x10 */
            sndsb_write_dsp(sb_card,*ptr++);

            pc = c;
            c = read_8254(T8254_TIMER_INTERRUPT_TICK);
            time += (unsigned long)((pc - c) & 0xFFFFU); /* remember: it counts DOWN. assumes full 16-bit count */
        }
        bytes += sb_dma->length;
    }
    _sti();

    if (time == 0UL) time = 1;

    {
        double t = (double)time / T8254_REF_CLOCK_HZ;
        double rate = (double)bytes / t;

        doubleprintf(" - %lu bytes played in %.3f seconds\n",(unsigned long)bytes,t);
        doubleprintf(" - Sample rate is %.3fHz\n",rate);
    }
}
Exemplo n.º 9
0
void load_idt()
{

	setup_IDT_entry (0x20, 0x08, (uint64_t)&_irq00Handler, ACS_INT);
	setup_IDT_entry (0x21, 0x08, (uint64_t)&_irq01Handler, ACS_INT);
	setup_IDT_entry (0x80, 0x08, (uint64_t)&_syscallHandler, ACS_INT);

	idtr.base = 0;
	idtr.base += (uint64_t) &idt;
	idtr.limit = (uint16_t) sizeof(idt)-1;
	
	_lidt(&idtr);	


	//Solo interrupcion de teclado y timer tick habilitadas 
	picMasterMask(0xFC); 
	picSlaveMask(0xFF);
        
	_sti();

	
}
Exemplo n.º 10
0
void kernel_main(multiboot_info_t *mbi)
{		
	_cli();
	init_video();
	printk("=== Arcanum kernel ===\n");

	printk("Chargement de la GDT... ");
	gdt_init();
	__pok();
	
	printk("Chargement de l'IDT... ");
	idt_init();
	pic_init();
	_clock = 0;

	__pok();

	printk("Activation des interruptions. \n");
	_sti();
	

	for(;;) {}
}
Exemplo n.º 11
0
void sb1_sc_play_adpcm2_test(void) {
    unsigned long time,bytes,expect,tlen,timeout;
    unsigned int count;
    unsigned int pc,c;
    unsigned long d;
    uint32_t irqc;

    doubleprintf("SB 1.x ADPCM 2-bit single cycle DSP playback test.\n");

    timeout = T8254_REF_CLOCK_HZ * 4UL;

    for (count=0;count < 256;count++) {
        expect = 1000000UL / (unsigned long)(256 - count);

        _cli();
        if (sb_card->irq >= 8) {
            p8259_OCW2(8,P8259_OCW2_SPECIFIC_EOI | (sb_card->irq & 7));
            p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | 2);
        }
        else if (sb_card->irq >= 0) {
            p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | sb_card->irq);
        }
        _sti();

        tlen = (expect / 4UL) + 1; // 1 sec
        if (tlen > sb_card->buffer_size) tlen = sb_card->buffer_size;

        sb_card->buffer_dma_started_length = tlen;
        sb_card->buffer_dma_started = 0;

        sndsb_reset_dsp(sb_card);
        sndsb_write_dsp(sb_card,0xD1); /* speaker on */
        sndsb_setup_dma(sb_card);
        irqc = sb_card->irq_counter;

        sndsb_write_dsp_timeconst(sb_card,count);

        _cli();
        c = read_8254(T8254_TIMER_INTERRUPT_TICK);
        bytes = tlen;
        time = 0;
        _sti();

        {
            unsigned int lv = (unsigned int)(tlen - 1UL);

            sndsb_write_dsp(sb_card,SNDSB_DSPCMD_DMA_DAC_OUT_ADPCM_2BIT_REF); /* 0x17 */
            sndsb_write_dsp(sb_card,lv);
            sndsb_write_dsp(sb_card,lv >> 8);
        }

        while (1) {
            if (irqc != sb_card->irq_counter)
                break;

            _cli();
            pc = c;
            c = read_8254(T8254_TIMER_INTERRUPT_TICK);
            time += (unsigned long)((pc - c) & 0xFFFFU); /* remember: it counts DOWN. assumes full 16-bit count */
            _sti();

            if (time >= timeout) goto x_timeout;
        }

x_complete:
        if (time == 0UL) time = 1;

        {
            double t = (double)time / T8254_REF_CLOCK_HZ;
            double rate = (double)(((bytes - 1UL) * 4UL) + 1UL) / t; /* 4 samples/byte + 1 reference */

            doubleprintf(" - TC 0x%02X: expecting %luHz, %lub/%.3fs @ %.3fHz\n",count,expect,(unsigned long)bytes,t,rate);
        }

        if (kbhit()) {
            if (getch() == 27)
                break;
        }

        continue;
x_timeout:
        d = d8237_read_count(sb_card->dma8); /* counts DOWNWARD */
        if (d > tlen) d = 0; /* terminal count */
        d = tlen - d;

        if (irqc == sb_card->irq_counter && d == 0) bytes = 0; /* nothing happened if no IRQ and counter never changed */
        else if (bytes > d) bytes = d;
        goto x_complete;
    }

    _cli();
    if (sb_card->irq >= 8) {
        p8259_OCW2(8,P8259_OCW2_SPECIFIC_EOI | (sb_card->irq & 7));
        p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | 2);
    }
    else if (sb_card->irq >= 0) {
        p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | sb_card->irq);
    }
    _sti();

    sndsb_write_dsp_timeconst(sb_card,0x83); /* 8000Hz */

    sndsb_reset_dsp(sb_card);
}
Exemplo n.º 12
0
void sb16_sc_play_test(void) {
    unsigned char bytespersample = wav_16bit ? 2 : 1;
    unsigned long time,bytes,expect,tlen,timeout;
    unsigned long count;
    unsigned int pc,c;
    unsigned long d;
    uint32_t irqc;
    int dma;

    if (wav_16bit && sb_card->dma16 >= 4)
        dma = sb_card->dma16;
    else
        dma = sb_card->dma8;

    if (sb_card->dsp_vmaj >= 4) /* Sound Blaster 16 */
        { }
    else if (sb_card->is_gallant_sc6600) /* Reveal SC-4000 / Gallant SC-6600 */
        { }
    else 
        return;

    doubleprintf("SB16 4.x single cycle DSP playback test (%u bit).\n",wav_16bit?16:8);

    timeout = T8254_REF_CLOCK_HZ * 2UL;

    count = 0;
    do {
        expect = count;

        _cli();
        if (sb_card->irq >= 8) {
            p8259_OCW2(8,P8259_OCW2_SPECIFIC_EOI | (sb_card->irq & 7));
            p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | 2);
        }
        else if (sb_card->irq >= 0) {
            p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | sb_card->irq);
        }
        _sti();

        tlen = expect; // 1 sec
        if (tlen < 4000UL) tlen = 4000UL;
        if (tlen > (sb_card->buffer_size / (unsigned long)bytespersample)) tlen = sb_card->buffer_size / (unsigned long)bytespersample;

        sb_card->buffer_dma_started_length = tlen * (unsigned long)bytespersample;
        sb_card->buffer_dma_started = 0;

        sndsb_reset_dsp(sb_card);
        sndsb_write_dsp(sb_card,0xD1); /* speaker on */
        sndsb_setup_dma(sb_card);
        irqc = sb_card->irq_counter;

        sndsb_write_dsp_outrate(sb_card,count);

        _cli();
        c = read_8254(T8254_TIMER_INTERRUPT_TICK);
        bytes = tlen;
        time = 0;
        _sti();

        {
            unsigned int lv = (unsigned int)(tlen - 1UL);

            /* NTS: Reveal SC-4000 (Gallant 6600) cards DO support SB16 but only specific commands.
             *      Command 0xC0 is not recognized, but command 0xC6 works. */
            if (wav_16bit) {
                if (sb_card->is_gallant_sc6600)
                    sndsb_write_dsp(sb_card,SNDSB_DSPCMD_SB16_AUTOINIT_DMA_DAC_OUT_16BIT); /* 0xB6 */
                else
                    sndsb_write_dsp(sb_card,SNDSB_DSPCMD_SB16_DMA_DAC_OUT_16BIT); /* 0xB0 */

                sndsb_write_dsp(sb_card,0x10); /* mode (16-bit signed PCM) */
            }
            else {
                if (sb_card->is_gallant_sc6600)
                    sndsb_write_dsp(sb_card,SNDSB_DSPCMD_SB16_AUTOINIT_DMA_DAC_OUT_8BIT); /* 0xC6 */
                else
                    sndsb_write_dsp(sb_card,SNDSB_DSPCMD_SB16_DMA_DAC_OUT_8BIT); /* 0xC0 */

                sndsb_write_dsp(sb_card,0x00); /* mode (8-bit unsigned PCM) */
            }

            sndsb_write_dsp(sb_card,lv);
            sndsb_write_dsp(sb_card,lv >> 8);
        }

        while (1) {
            if (irqc != sb_card->irq_counter)
                break;

            _cli();
            pc = c;
            c = read_8254(T8254_TIMER_INTERRUPT_TICK);
            time += (unsigned long)((pc - c) & 0xFFFFU); /* remember: it counts DOWN. assumes full 16-bit count */
            _sti();

            if (time >= timeout) goto x_timeout;
        }

x_complete:
        if (time == 0UL) time = 1;

        {
            double t = (double)time / T8254_REF_CLOCK_HZ;
            double rate = (double)bytes / t;

            doubleprintf(" - Rate 0x%04lX: expecting %luHz, %lu%c/%.3fs @ %.3fHz\n",count,expect,(unsigned long)bytes,wav_16bit?'w':'b',t,rate);
        }

        if (kbhit()) {
            if (getch() == 27)
                break;
        }

        count += 0x80; /* count by 128 because enumerating all would take too long */
        if (count > 0xFFFFUL) break;

        continue;
x_timeout:
        d = d8237_read_count(dma) / (unsigned long)bytespersample; /* counts DOWNWARD */
        if (d > tlen) d = 0; /* terminal count */
        d = tlen - d;

        if (irqc == sb_card->irq_counter && d == 0) bytes = 0; /* nothing happened if no IRQ and counter never changed */
        else if (bytes > d) bytes = d;
        goto x_complete;
    } while (1);

    _cli();
    if (sb_card->irq >= 8) {
        p8259_OCW2(8,P8259_OCW2_SPECIFIC_EOI | (sb_card->irq & 7));
        p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | 2);
    }
    else if (sb_card->irq >= 0) {
        p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | sb_card->irq);
    }
    _sti();

    sndsb_reset_dsp(sb_card);

    sndsb_write_dsp_outrate(sb_card,8000U);
}
Exemplo n.º 13
0
VOID int21_service(iregs FAR * r)
{
  COUNT rc = 0,
	  rc1;
  psp FAR *p = MK_FP(cu_psp, 0);
  void FAR *FP_DS_DX = MK_FP(r->DS, r->DX); /* this is saved so often,
                                               that this saves ~100 bytes */

    
#define CLEAR_CARRY_FLAG()  r->FLAGS &= ~FLG_CARRY
#define SET_CARRY_FLAG()    r->FLAGS |= FLG_CARRY

  p->ps_stack = (BYTE FAR *) r;

#ifdef DEBUG 
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs, sizeof(iregs));
    printf("System call (21h): %02x\n", user_r->AX);
    dump_regs = TRUE;
    dump();
  }
#endif

  if(r->AH >=0x38 && r->AH <= 0x4F)
      CLEAR_CARRY_FLAG();
      /* Clear carry by default for these functions */

dispatch:

  /* Check for Ctrl-Break */
  switch (r->AH)
  {
    default:
      if (!break_ena)
        break;
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0a:
    case 0x0b:
      if (control_break())
        handle_break();
  }

  /* The dispatch handler                                         */
  switch (r->AH)
  {
      /* int 21h common error handler                                 */
    case 0x64:
    error_invalid:
      r->AX = -DE_INVLDFUNC;
      goto error_out;
    error_exit:
      r->AX = -rc;
    error_out:
      CritErrCode = r->AX;  /* Maybe set */
      SET_CARRY_FLAG();
      break;

       /* case 0x00:   --> Simulate a DOS-4C-00 */

      /* Read Keyboard with Echo                      */
    case 0x01:
      r->AL = _sti(TRUE);
      sto(r->AL);
      break;

      /* Display Character                                            */
    case 0x02:
      sto(r->DL);
      break;

      /* Auxiliary Input                                                      */
    case 0x03:
     {
      COUNT scratch;
      GenericRead(STDAUX, 1, (BYTE FAR *) & r->AL, (COUNT FAR *) & scratch, TRUE);
      break;
     }

      /* Auxiliary Output                                                     */
    case 0x04:
     {
      COUNT scratch;
      DosWrite(STDAUX, 1, (BYTE FAR *) & r->DL, (COUNT FAR *) &scratch);
      break;
     }
      /* Print Character                                                      */
    case 0x05:
     {       
      COUNT scratch;       
      DosWrite(STDPRN, 1, (BYTE FAR *) & r->DL, (COUNT FAR *) &scratch);
      break;      
     }

      /* Direct Console I/O                                            */
    case 0x06:
      if (r->DL != 0xff)
        sto(r->DL);
      else if (StdinBusy())
      {
        r->AL = 0x00;
        r->FLAGS |= FLG_ZERO;
      }
      else
      {
        r->FLAGS &= ~FLG_ZERO;
        r->AL = _sti(FALSE);
      }
      break;

      /* Direct Console Input                                         */
    case 0x07:
      r->AL = _sti(FALSE);
      break;

      /* Read Keyboard Without Echo                                   */
    case 0x08:
      r->AL = _sti(TRUE);
      break;

      /* Display String                                               */
    case 0x09:
      {
        BYTE FAR * q;
        q = FP_DS_DX;
        while (*q != '$')
          ++q;
        DosWrite(STDOUT, FP_OFF(q) - FP_OFF(FP_DS_DX), FP_DS_DX, (COUNT FAR *) & UnusedRetVal);
      }
      r->AL = '$';
      break;

      /* Buffered Keyboard Input                                      */
    case 0x0a:
      sti_0a((keyboard FAR *) FP_DS_DX);
      break;

      /* Check Stdin Status                                           */
    case 0x0b:
      if (StdinBusy())
        r->AL = 0x00;
      else
        r->AL = 0xFF;
      break;

      /* Flush Buffer, Read Keayboard                                 */
    case 0x0c:
      KbdFlush();
      switch (r->AL)
      {
        case 0x01:
        case 0x06:
        case 0x07:
        case 0x08:
        case 0x0a:
          r->AH = r->AL;
          goto dispatch;

        default:
          r->AL = 0x00;
          break;
      }
      break;

      /* Reset Drive                                                  */
    case 0x0d:
      flush();
      break;

      /* Set Default Drive                                            */
    case 0x0e:
      r->AL = DosSelectDrv(r->DL);
      break;

    case 0x0f:
      if (FcbOpen(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x10:
      if (FcbClose(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x11:
      if (FcbFindFirst(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x12:
      if (FcbFindNext(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x13:
      if (FcbDelete(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x14:
      {
        if (FcbRead(FP_DS_DX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

    case 0x15:
      {
        if (FcbWrite(FP_DS_DX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

    case 0x16:
      if (FcbCreate(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x17:
      if (FcbRename(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    default:
#ifdef DEBUG
       printf("Unsupported INT21 AH = 0x%x, AL = 0x%x.\n", r->AH, r->AL);
#endif
      /* Fall through. */

    /* CP/M compatibility functions                                 */
    case 0x18:
    case 0x1d:
    case 0x1e:
    case 0x20:
#ifndef TSC
    case 0x61:
#endif
    case 0x6b:
      r->AL = 0;
      break;

      /* Get Default Drive                                            */
    case 0x19:
      r->AL = default_drive;
      break;

      /* Set DTA                                                      */
    case 0x1a:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        p->ps_dta = FP_DS_DX;
        dos_setdta(p->ps_dta);
      }
      break;

      /* Get Default Drive Data                                       */
    case 0x1b:
      {
        BYTE FAR *p;

        FatGetDrvData(0,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Drive Data                                               */
    case 0x1c:
      {
        BYTE FAR *p;

        FatGetDrvData(r->DL,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get default DPB                                              */
      /* case 0x1f: see case 0x32 */

      /* Random read using FCB */
    case 0x21:
      {
        if (FcbRandomIO(FP_DS_DX, &CritErrCode, FcbRead))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Random write using FCB */
    case 0x22:
      {
        if (FcbRandomIO(FP_DS_DX, &CritErrCode, FcbWrite))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Get file size in records using FCB */
    case 0x23:
      if (FcbGetFileSize(FP_DS_DX))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

      /* Set random record field in FCB */
    case 0x24:
      FcbSetRandom(FP_DS_DX);
      break;

      /* Set Interrupt Vector                                         */
    case 0x25:
      {
        VOID(INRPT FAR * p) () = FP_DS_DX;

        setvec(r->AL, p);
      }
      break;

      /* Dos Create New Psp                                           */
    case 0x26:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        new_psp((psp FAR *) MK_FP(r->DX, 0), p->ps_size);
      }
      break;

      /* Read random record(s) using FCB */
    case 0x27:
      {
        if (FcbRandomBlockRead(FP_DS_DX, r->CX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Write random record(s) using FCB */
    case 0x28:
      {
        if (FcbRandomBlockWrite(FP_DS_DX, r->CX, &CritErrCode))
          r->AL = 0;
        else
          r->AL = CritErrCode;
        break;
      }

      /* Parse File Name                                              */
    case 0x29:
      {
        BYTE FAR *lpFileName;

        lpFileName = MK_FP(r->DS, r->SI);
        r->AL = FcbParseFname(r->AL,
                              &lpFileName,
                              MK_FP(r->ES, r->DI));
        r->DS = FP_SEG(lpFileName);
        r->SI = FP_OFF(lpFileName);
      }
      break;

      /* Get Date                                                     */
    case 0x2a:
      DosGetDate(
                  (BYTE FAR *) & (r->AL),	/* WeekDay              */
                  (BYTE FAR *) & (r->DH),	/* Month                */
                  (BYTE FAR *) & (r->DL),	/* MonthDay             */
                  (COUNT FAR *) & (r->CX));	/* Year                 */
      break;

      /* Set Date                                                     */
    case 0x2b:
      rc = DosSetDate(
                       (BYTE FAR *) & (r->DH),	/* Month                */
                       (BYTE FAR *) & (r->DL),	/* MonthDay             */
                       (COUNT FAR *) & (r->CX));	/* Year                 */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Get Time                                                     */
    case 0x2c:
      DosGetTime(
                  (BYTE FAR *) & (r->CH),	/* Hour                 */
                  (BYTE FAR *) & (r->CL),	/* Minutes              */
                  (BYTE FAR *) & (r->DH),	/* Seconds              */
                  (BYTE FAR *) & (r->DL));	/* Hundredths           */
      break;

      /* Set Date                                                     */
    case 0x2d:
      rc = DosSetTime(
                       (BYTE FAR *) & (r->CH),	/* Hour                 */
                       (BYTE FAR *) & (r->CL),	/* Minutes              */
                       (BYTE FAR *) & (r->DH),	/* Seconds              */
                       (BYTE FAR *) & (r->DL));	/* Hundredths           */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Set verify flag                                              */
    case 0x2e:
      verify_ena = (r->AL ? TRUE : FALSE);
      break;

      /* Get DTA                                                      */
    case 0x2f:
      r->ES = FP_SEG(dta);
      r->BX = FP_OFF(dta);
      break;

      /* Get DOS Version                                              */
    case 0x30:
      r->AL = os_major;
      r->AH = os_minor;
      r->BH = OEM_ID;
      r->CH = REVISION_MAJOR;   /* JPP */
      r->CL = REVISION_MINOR;
      r->BL = REVISION_SEQ;
      
      if (ReturnAnyDosVersionExpected)  
      {
                            /* TE for testing purpose only and NOT 
                               to be documented:
                               return programs, who ask for version == XX.YY
                               exactly this XX.YY. 
                               this makes most MS programs more happy.
                            */
        UBYTE FAR *retp = MK_FP(r->cs, r->ip);
        
        if (     retp[0] == 0x3d  &&     /* cmp ax, xxyy */
                (retp[3] == 0x75 || retp[3] == 0x74)) /* je/jne error    */
        {
            r->AL = retp[1];
            r->AH = retp[2];
        }
        else if(retp[0] == 0x86 &&      /* xchg al,ah   */
                retp[1] == 0xc4 &&
                retp[2] == 0x3d &&      /* cmp ax, xxyy */
               (retp[5] == 0x75 || retp[5] == 0x74)) /* je/jne error    */                               
        {
            r->AL = retp[4];
            r->AH = retp[3];
        }                
            
      }
      
      break;

      /* Keep Program (Terminate and stay resident) */
    case 0x31:
      DosMemChange(cu_psp, r->DX < 6 ? 6 : r->DX, 0);
      return_mode = 3;
      return_code = r->AL;
      tsr = TRUE;
      return_user();
      break;

      /* Get default BPB */
    case 0x1f:
      /* Get DPB                                                      */
    case 0x32:
      /* r->DL is NOT changed by MS 6.22 */
      /* INT21/32 is documented to reread the DPB */
      {
      struct dpb FAR *dpb;  
      UCOUNT drv = r->DL;
      
      if (drv == 0 || r->AH == 0x1f) drv = default_drive;
      else          drv--;

      if (drv >= lastdrive)
      {
        r->AL = 0xFF;
        CritErrCode = 0x0f;
        break;
      }  
        
      dpb = CDSp->cds_table[drv].cdsDpb;
      if (dpb == 0 ||
          CDSp->cds_table[drv].cdsFlags & CDSNETWDRV)
      {
        r->AL = 0xFF;
        CritErrCode = 0x0f;
        break;
      }  
      dpb->dpb_flags = M_CHANGED;       /* force reread of drive BPB/DPB */
          
      if (media_check(dpb) < 0)
      {
          r->AL = 0xff;
          CritErrCode = 0x0f;
          break;
      }
      r->DS = FP_SEG(dpb);
      r->BX = FP_OFF(dpb);
      r->AL = 0;
      }

      break;
/*
    case 0x33:  
    see int21_syscall
*/
      /* Get InDOS flag                                               */
    case 0x34:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) ((BYTE *) & InDOS);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Interrupt Vector                                         */
    case 0x35:
      {
        BYTE FAR *p;

        p = getvec((COUNT) r->AL);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Dos Get Disk Free Space                                      */
    case 0x36:
      DosGetFree(
                  r->DL,
                  (COUNT FAR *) & r->AX,
                  (COUNT FAR *) & r->BX,
                  (COUNT FAR *) & r->CX,
                  (COUNT FAR *) & r->DX);
      break;

      /* Undocumented Get/Set Switchar                                */
    case 0x37:
      switch (r->AL)
      {
          /* Get switch character */
        case 0x00:
          r->DL = switchar;
          r->AL = 0x00;
          break;

          /* Set switch character */
        case 0x01:
          switchar = r->DL;
          r->AL = 0x00;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Country Info                                         */
    case 0x38:
      {
      	UWORD cntry = r->AL;

      	if(cntry == 0)
      		cntry = (UWORD)-1;
      	else if(cntry == 0xff)
      		cntry = r->BX;

        if (0xffff == r->DX) {
        	/* Set Country Code */
            if((rc = DosSetCountry(cntry)) < 0)
        		goto error_invalid;
        } else {
        	/* Get Country Information */
            if((rc = DosGetCountryInformation(cntry, FP_DS_DX)) < 0)
        		goto error_invalid;
            /* HACK FIXME */
	    if(cntry == (UWORD)-1)
		cntry = 1;
            /* END OF HACK */
            r->AX = r->BX = cntry;
        }
      }
      break;

      /* Dos Create Directory                                         */
    case 0x39:
      rc = DosMkdir((BYTE FAR *) FP_DS_DX);
      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Dos Remove Directory                                         */
    case 0x3a:
      rc = DosRmdir((BYTE FAR *) FP_DS_DX);
      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Dos Change Directory                                         */
    case 0x3b:
      if ((rc = DosChangeDir((BYTE FAR *) FP_DS_DX)) < 0)
        goto error_exit;
      break;

      /* Dos Create File                                              */
    case 0x3c:
      if ((rc = DosCreat(FP_DS_DX, r->CX)) < 0)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Dos Open                                                     */
    case 0x3d:
      if ((rc = DosOpen(FP_DS_DX, r->AL)) < 0)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Dos Close                                                    */
    case 0x3e:
      if ((rc = DosClose(r->BX)) < 0)
        goto error_exit;
      break;

      /* Dos Read                                                     */
    case 0x3f:
      rc1 = DosRead(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc);
      if (rc != SUCCESS)
        goto error_exit;
      else
        r->AX = rc1;
      break;

      /* Dos Write                                                    */
    case 0x40:
      rc1 = DosWrite(r->BX, r->CX, FP_DS_DX, (COUNT FAR *) & rc);
      if (rc != SUCCESS)
        goto error_exit;
      else
        r->AX = rc1;
      break;

      /* Dos Delete File                                              */
    case 0x41:
      rc = DosDelete((BYTE FAR *) FP_DS_DX);
      if (rc < 0)
        goto error_exit;
      break;

      /* Dos Seek                                                     */
    case 0x42:
      {
      ULONG lrc;
      if ((rc = DosSeek(r->BX, (LONG) ((((LONG) (r->CX)) << 16) + r->DX), r->AL, &lrc)) < 0)
        goto error_exit;
      else
      {
        r->DX = (lrc >> 16);
        r->AX = (UWORD)lrc;
      }
      }
      break;

      /* Get/Set File Attributes                                      */
    case 0x43:
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFattr((BYTE FAR *) FP_DS_DX);
          if (rc >= SUCCESS)
              r->CX = rc;
          break;

        case 0x01:
          rc = DosSetFattr((BYTE FAR *) FP_DS_DX, r->CX);
          break;

        default:
          goto error_invalid;
      }
      if (rc < SUCCESS)
        goto error_exit;
      break;

      /* Device I/O Control                                           */
    case 0x44:
      rc = DosDevIOctl(r);

      if (rc != SUCCESS)
        goto error_exit;
      break;

      /* Duplicate File Handle                                        */
    case 0x45:
      rc = DosDup(r->BX);
      if (rc < SUCCESS)
        goto error_exit;
      else
        r->AX = rc;
      break;

      /* Force Duplicate File Handle                                  */
    case 0x46:
      rc = DosForceDup(r->BX, r->CX);
      if (rc < SUCCESS)
        goto error_exit;
      break;

      /* Get Current Directory                                        */
    case 0x47:
      if ((rc = DosGetCuDir(r->DL, MK_FP(r->DS, r->SI))) < 0)
        goto error_exit;
      else
        r->AX = 0x0100;         /*jpp: from interrupt list */
      break;

      /* Allocate memory */
    case 0x48:
      if ((rc = DosMemAlloc(r->BX, mem_access_mode, &(r->AX), &(r->BX))) < 0)
      {
        DosMemLargest(&(r->BX));
        goto error_exit;
      }
      else
        ++(r->AX);              /* DosMemAlloc() returns seg of MCB rather than data */
      break;

      /* Free memory */
    case 0x49:
      if ((rc = DosMemFree((r->ES) - 1)) < 0)
        goto error_exit;
      break;

      /* Set memory block size */
    case 0x4a:
      {
        UWORD maxSize;

        if ((rc = DosMemChange(r->ES, r->BX, &maxSize)) < 0)
        {
          if (rc == DE_NOMEM)
            r->BX = maxSize;

#if 0
          if (cu_psp == r->ES)
          {

            psp FAR *p;

            p = MK_FP(cu_psp, 0);
            p->ps_size = r->BX + cu_psp;
          }
#endif
          goto error_exit;
        }

        break;
      }

      /* Load and Execute Program */
    case 0x4b:
      break_flg = FALSE;

      if ((rc = DosExec(r->AL, MK_FP(r->ES, r->BX), FP_DS_DX))
          != SUCCESS)
        goto error_exit;
      break;

      /* Terminate Program                                            */
    case 0x00:
      r->AX = 0x4c00;

      /* End Program                                                  */
    case 0x4c:
      if (cu_psp == RootPsp
          || ((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
        break;
      tsr = FALSE;
      if (ErrorMode)
      {
        ErrorMode = FALSE;
        return_mode = 2;
      }
      else if (break_flg)
      {
        break_flg = FALSE;
        return_mode = 1;
      }
      else
      {
        return_mode = 0;
      }
      return_code = r->AL;
      if (DosMemCheck() != SUCCESS)
        panic("MCB chain corrupted");
#ifdef TSC
      StartTrace();
#endif
      return_user();
      break;

      /* Get Child-program Return Value                               */
    case 0x4d:
      r->AL = return_code;
      r->AH = return_mode;
      break;

      /* Dos Find First                                               */
    case 0x4e:
      /* dta for this call is set on entry.  This     */
      /* needs to be changed for new versions.        */
      if ((rc = DosFindFirst((UCOUNT) r->CX, (BYTE FAR *) FP_DS_DX)) < 0)
        goto error_exit;
      r->AX = 0;
      break;

      /* Dos Find Next                                                */
    case 0x4f:
      /* dta for this call is set on entry.  This     */
      /* needs to be changed for new versions.        */
      if ((rc = DosFindNext()) < 0)
      {
        if (rc == DE_FILENOTFND)
          rc = DE_NFILES;
        goto error_exit;
      }
      else
        r->AX = -SUCCESS;
      break;
/*
    case 0x50:  
    case 0x51:
    see int21_syscall
*/
      /* ************UNDOCUMENTED************************************* */
      /* Get List of Lists                                            */
    case 0x52:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) & DPBp;
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

    case 0x53:
      /*  DOS 2+ internal - TRANSLATE BIOS PARAMETER BLOCK TO DRIVE PARAM BLOCK */
      bpb_to_dpb((bpb FAR *)MK_FP(r->DS, r->SI), (struct dpb FAR *)MK_FP(r->ES, r->BP));
      break;
      
      /* Get verify state                                             */
    case 0x54:
      r->AL = (verify_ena ? TRUE : FALSE);
      break;

      /* ************UNDOCUMENTED************************************* */
      /* Dos Create New Psp & set p_size                              */
    case 0x55:
      new_psp((psp FAR *) MK_FP(r->DX, 0), r->SI);
      cu_psp = r->DX;
      break;

      /* Dos Rename                                                   */
    case 0x56:
      rc = DosRename((BYTE FAR *) FP_DS_DX, (BYTE FAR *) MK_FP(r->ES, r->DI));
      if (rc < SUCCESS)
        goto error_exit;
      else
        CLEAR_CARRY_FLAG();
      break;

      /* Get/Set File Date and Time                                   */
    case 0x57:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date FAR *) & r->DX,	/* FileDate             */
                            (time FAR *) & r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          break;

        case 0x01:
          rc = DosSetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date) r->DX,	/* FileDate             */
                            (time) r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Allocation Strategy                                  */
    case 0x58:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          r->AL = mem_access_mode;
          r->AH = 0;
          break;

        case 0x01:
        {
            switch (r->BL)
            {
            case LAST_FIT:
            case LAST_FIT_U:
            case LAST_FIT_UO:
            case BEST_FIT:
            case BEST_FIT_U:
            case BEST_FIT_UO:
            case FIRST_FIT:
            case FIRST_FIT_U:
            case FIRST_FIT_UO:
                mem_access_mode = r->BL;
                break;

            default:
                goto error_invalid;
            }
        }
            break;

        case 0x02:
            r->AL = uppermem_link;
            break;

        case 0x03:
            if (uppermem_root) {
                DosUmbLink(r->BL);
                break;
            } /* else fall through */            

        default:
          goto error_invalid;
#ifdef DEBUG
        case 0xff:
          show_chain();
          break;
#endif
      }
      break;

      /* Get Extended Error */
    case 0x59:
        r->AX = CritErrCode;
        r->ES = FP_SEG(CritErrDev);
        r->DI = FP_OFF(CritErrDev);
        r->CH = CritErrLocus;
        r->BH = CritErrClass;
        r->BL = CritErrAction;
        CLEAR_CARRY_FLAG();
      break;

      /* Create Temporary File */
    case 0x5a:
      if ((rc = DosMkTmp(FP_DS_DX, r->CX)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        CLEAR_CARRY_FLAG();
      }
      break;

      /* Create New File */
    case 0x5b:
      if (!IsDevice(FP_DS_DX) && (rc = DosOpen(FP_DS_DX, 0)) >= 0)
      {
        DosClose(rc);
        r->AX = 80;
        goto error_out;
      }
      else
      {
        if ((rc = DosCreat(FP_DS_DX, r->CX)) < 0)
          goto error_exit;
        else
        {
          r->AX = rc;
          CLEAR_CARRY_FLAG();
        }
      }
      break;

/* /// Added for SHARE.  - Ron Cemer */
      /* Lock/unlock file access */
    case 0x5c:
      if ((rc = DosLockUnlock
        (r->BX,
         (((unsigned long)r->CX)<<16)|(((unsigned long)r->DX)&0xffffL),
         (((unsigned long)r->SI)<<16)|(((unsigned long)r->DI)&0xffffL),
         ((r->AX & 0xff) != 0))) != 0)
          goto error_exit;
      CLEAR_CARRY_FLAG();
      break;
/* /// End of additions for SHARE.  - Ron Cemer */

      /* UNDOCUMENTED: server, share.exe and sda function             */
    case 0x5d:
      switch (r->AL)
      {
          /* Remote Server Call */
        case 0x00:
          {
            UWORD FAR *x = FP_DS_DX;
            r->AX = x[0];
            r->BX = x[1];
            r->CX = x[2];
            r->DX = x[3];
            r->SI = x[4];
            r->DI = x[5];
            r->DS = x[6];
            r->ES = x[7];
          }
          goto dispatch;

        case 0x06:
          r->DS = FP_SEG(internal_data);
          r->SI = FP_OFF(internal_data);
          r->CX = swap_always - internal_data;
          r->DX = swap_indos - internal_data;
          CLEAR_CARRY_FLAG();
          break;

        case 0x07:
        case 0x08:
        case 0x09:
	  rc = -int2f_Remote_call(REM_PRINTREDIR, 0, 0, r->DX, 0, 0, (MK_FP(0, Int21AX)));
	  if (rc != SUCCESS)
            goto error_exit;
          CLEAR_CARRY_FLAG();
          break;
        default:
          goto error_invalid;
      }
      break;

    case 0x5e:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x00:
          r->CX = get_machine_name(FP_DS_DX);
          break;

        case 0x01:
          set_machine_name(FP_DS_DX, r->CX);
          break;

        default:
          rc = -int2f_Remote_call(REM_PRINTSET, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
	  if (rc != SUCCESS) goto error_exit;
          r->AX=SUCCESS;
          break;
      }
      break;

    case 0x5f:
      CLEAR_CARRY_FLAG();
      switch (r->AL)
      {
        case 0x07:
          if (r->DL < lastdrive) {
            CDSp->cds_table[r->DL].cdsFlags |= 0x100;
	  }
          break;

        case 0x08:
          if (r->DL < lastdrive) {
            CDSp->cds_table[r->DL].cdsFlags &= ~0x100;
	  }
          break;

        default:
/*              
            void int_2f_111e_call(iregs FAR *r);
            int_2f_111e_call(r);          
          break;*/

          rc = -int2f_Remote_call(REM_DOREDIRECT, r->BX, r->CX, r->DX,
                                 (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
	  if (rc != SUCCESS)
            goto error_exit;
          r->AX=SUCCESS;
          break;
      }
      break;

    case 0x60:                 /* TRUENAME */
      CLEAR_CARRY_FLAG();
      if ((rc = truename(MK_FP(r->DS, r->SI),
                      adjust_far(MK_FP(r->ES, r->DI)), FALSE)) != SUCCESS)
        goto error_exit;
      break;

#ifdef TSC
      /* UNDOCUMENTED: no-op                                          */
      /*                                                              */
      /* DOS-C: tsc support                                           */
    case 0x61:
#ifdef DEBUG
      switch (r->AL)
      {
        case 0x01:
          bTraceNext = TRUE;
          break;

        case 0x02:
          bDumpRegs = FALSE;
          break;
      }
#endif
      r->AL = 0x00;
      break;
#endif

      /* UNDOCUMENTED: return current psp                             
    case 0x62: is in int21_syscall
      r->BX = cu_psp;
      break;
      */
      
      /* UNDOCUMENTED: Double byte and korean tables                  */
    case 0x63:
      {
#define DBLBYTE
#ifdef DBLBYTE
        static char dbcsTable[2] =
        {
          0, 0
        };
        void FAR *dp = &dbcsTable;

        r->DS = FP_SEG(dp);
        r->SI = FP_OFF(dp);
        r->AL = 0;
#else
        /* not really supported, but will pass.                 */
        r->AL = 0x00;           /*jpp: according to interrupt list */	
				/*Bart: fails for PQDI: use the above again */
#endif
        break;
      }
/*
    case 0x64:
      see above (invalid)
*/      

      /* Extended country info                                        */
    case 0x65:
    	switch(r->AL) {
    	case 0x20:				/* upcase single character */
            r->DL = DosUpChar(r->DL);
            break;
        case 0x21:				/* upcase memory area */
            DosUpMem(FP_DS_DX, r->CX);
            break;
        case 0x22:				/* upcase ASCIZ */
            DosUpString(FP_DS_DX);
            break;
    	case 0xA0:				/* upcase single character of filenames */
            r->DL = DosUpFChar(r->DL);
            break;
        case 0xA1:				/* upcase memory area of filenames */
            DosUpFMem(FP_DS_DX, r->CX);
            break;
        case 0xA2:				/* upcase ASCIZ of filenames */
            DosUpFString(FP_DS_DX);
            break;
        case 0x23:				/* check Yes/No response */
            r->AX = DosYesNo(r->DL);
            break;
      	default:
            if ((rc = DosGetData(
                         r->AL, r->BX, r->DX, r->CX,
                         MK_FP(r->ES, r->DI))) < 0) {
#ifdef NLS_DEBUG
   printf("DosGetData() := %d\n", rc);
#endif
               goto error_exit;
            }
#ifdef NLS_DEBUG
   printf("DosGetData() returned successfully\n", rc);
#endif

            break;
         }
		CLEAR_CARRY_FLAG();
      break;
      

      /* Code Page functions */
    case 0x66: {
    	int rc;
      switch (r->AL)
      {
        case 1:
          rc = DosGetCodepage(&r->BX, &r->DX);
			break;
        case 2:
          rc = DosSetCodepage(r->BX, r->DX);
          break;

        default:
          goto error_invalid;
      }
      if(rc != SUCCESS)
      	goto error_exit;
      CLEAR_CARRY_FLAG();
      break;
     }

      /* Set Max file handle count */
    case 0x67:
      if ((rc = SetJFTSize(r->BX)) != SUCCESS)
        goto error_exit;
      else
        CLEAR_CARRY_FLAG();
      break;

      /* Flush file buffer -- COMMIT FILE -- dummy function right now.  */
    case 0x68:
    case 0x6a:
      CLEAR_CARRY_FLAG();
      break;

      /* Get/Set Serial Number */
    case 0x69:
      rc = ( r->BL == 0 ? default_drive : r->BL - 1);
      if (rc < lastdrive)
      {
        UWORD saveCX = r->CX;
        if (CDSp->cds_table[rc].cdsFlags & CDSNETWDRV) {
          goto error_invalid;
        }
        switch(r->AL){
            case 0x00:
            r->AL = 0x0d;
            r->CX = 0x0866;
            rc = DosDevIOctl(r);
            break;

            case 0x01:
            r->AL = 0x0d;
            r->CX = 0x0846;
            rc = DosDevIOctl(r);
            break;
        }
        r->CX = saveCX;
        if (rc != SUCCESS)
          goto error_exit;
        CLEAR_CARRY_FLAG();
        break;
      }
      else
        r->AL = 0xFF;
      break;
/*
    case 0x6a: see case 0x68
    case 0x6b: dummy func: return AL=0
*/    
    /* Extended Open-Creat, not fully functional. (bits 4,5,6 of BH) */
    case 0x6c:
      {
        COUNT x = 0;
      
        if (r->AL != 0 || r->DH != 0 ||
              (r->DL&0x0f) > 0x2 || (r->DL&0xf0) > 0x10)
            goto error_invalid;
        CLEAR_CARRY_FLAG();
        if ((rc = DosOpen(MK_FP(r->DS, r->SI),
                          (r->DL&0x0f) == 0x1 ? r->BL : 0)) < 0)
        {
            if (r->DL < 0x10)
                goto error_exit;
            /* else try to create below */
        }
        else switch (r->DL & 0x0f)
        {
          case 0x0:
            /* fail if file exists */
            DosClose(rc);
            rc = DE_FILEEXISTS;
            goto error_exit;
          case 0x1:
            /* file exists and opened: OK */
            r->CX = 0x01;
            goto break_out;
          case 0x2:  
            /* file exists: replace/open */
            DosClose(rc);
            x = 1;
            break;
        }
        /* cases 0x00, 0x01 are finished now */
        if ((rc = DosCreat(MK_FP(r->DS, r->SI), r->CX)) < 0)
            goto error_exit;
            
        r->CX = x+2;
break_out:        
        r->AX = rc;
        break;
      }


    /* case 0x6d and above not implemented : see default; return AL=0 */
        
  }

#ifdef DEBUG
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs,
           sizeof(iregs));
    dump_regs = TRUE;
    dump();
  }
#endif
}
Exemplo n.º 14
0
/*
 * The `force_binary' parameter is a hack to allow functions 0x01, 0x06, 0x07,
 * and function 0x40 to use the same code for performing reads, even though the
 * two classes of functions behave quite differently: 0x01 etc. always do
 * binary reads, while for 0x40 the type of read (binary/text) depends on what
 * the SFT says. -- ror4
 */
UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err,
                   BOOL force_binary)
{
  sft FAR *s;
  WORD sys_idx;
  sfttbl FAR *sp;
  UCOUNT ReadCount;

  /* Test that the handle is valid                */
  if (hndl < 0)
  {
    *err = DE_INVLDHNDL;
    return 0;
  }

  /* Get the SFT block that contains the SFT      */
  if ((s = get_sft(hndl)) == (sft FAR *) - 1)
  {
    *err = DE_INVLDHNDL;
    return 0;
  }

  /* If not open or write permission - exit       */
  if (s->sft_count == 0 || (s->sft_mode & SFT_MWRITE))
  {
    *err = DE_INVLDACC;
    return 0;
  }

/*
   *   Do remote first or return error.
   *   must have been opened from remote.
 */
  if (s->sft_flags & SFT_FSHARED)
  {
    ReadCount = Remote_RW(REM_READ, n, bp, s, err);
    if (err)
    {
      *err = SUCCESS;
      return ReadCount;
    }
    else
      return 0;
  }
  /* Do a device read if device                   */
  if (s->sft_flags & SFT_FDEVICE)
  {
    request rq;

    /* First test for eof and exit          */
    /* immediately if it is                 */
    if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
    {
      s->sft_flags &= ~SFT_FEOF;
      *err = SUCCESS;
      return 0;
    }

    /* Now handle raw and cooked modes      */
    if (force_binary || (s->sft_flags & SFT_FBINARY))
    {
      rq.r_length = sizeof(request);
      rq.r_command = C_INPUT;
      rq.r_count = n;
      rq.r_trans = (BYTE FAR *) bp;
      rq.r_status = 0;
      execrh((request FAR *) & rq, s->sft_dev);
      if (rq.r_status & S_ERROR)
      {
        char_error(&rq, s->sft_dev);
      }
      else
      {
        *err = SUCCESS;
        return rq.r_count;
      }
    }
    else if (s->sft_flags & SFT_FCONIN)
    {
      kb_buf.kb_size = LINESIZE - 1;
      kb_buf.kb_count = 0;
      sti((keyboard FAR *) & kb_buf);
      fbcopy((BYTE FAR *) kb_buf.kb_buf, bp, kb_buf.kb_count);
      *err = SUCCESS;
      return kb_buf.kb_count;
    }
    else
    {
      *bp = _sti();
      *err = SUCCESS;
      return 1;
    }
  }
  else
    /* a block read                            */
  {
    COUNT rc;

    ReadCount = readblock(s->sft_status, bp, n, &rc);
    if (rc != SUCCESS)
    {
      *err = rc;
      return 0;
    }
    else
    {
      *err = SUCCESS;
      return ReadCount;
    }
  }
  *err = SUCCESS;
  return 0;
}
Exemplo n.º 15
0
void ess_sc_play_test(void) {
    unsigned char bytespersample = wav_16bit ? 2 : 1;
    unsigned long time,bytes,expect,tlen,timeout;
    unsigned long count;
    unsigned int pc,c;
    unsigned long d;
    uint32_t irqc;

    if (!sb_card->ess_extensions || sb_card->ess_chipset == 0)
        return;

    doubleprintf("ESS688 single cycle DSP playback test (%u bit).\n",wav_16bit?16:8);

    timeout = T8254_REF_CLOCK_HZ * 2UL;

    for (count=0;count < 256;count++) {
        if (count >= 128)
            expect = 795500UL / (256 - count);
        else
            expect = 397700UL / (128 - count);

        _cli();
        if (sb_card->irq >= 8) {
            p8259_OCW2(8,P8259_OCW2_SPECIFIC_EOI | (sb_card->irq & 7));
            p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | 2);
        }
        else if (sb_card->irq >= 0) {
            p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | sb_card->irq);
        }
        _sti();

        tlen = expect; // 1 sec
        if (tlen > (sb_card->buffer_size / (unsigned long)bytespersample)) tlen = sb_card->buffer_size / (unsigned long)bytespersample;

        /* NTS: We ask the card to use demand ISA, 4 bytes at a time.
         *      Behavior observed on real hardware, is that if you set up
         *      DMA this way and then set up a non-auto-init DMA transfer
         *      that isn't a multiple of 4, the DMA will stop short of
         *      the full transfer and the IRQ will never fire. Therefore
         *      the transfer length must be a multiple of 4! */
        tlen -= tlen & 3;
        if (tlen == 0) tlen = 4;

        sb_card->buffer_dma_started_length = tlen * (unsigned long)bytespersample;
        sb_card->buffer_dma_started = 0;

        sndsb_reset_dsp(sb_card);
        sndsb_write_dsp(sb_card,0xD1); /* speaker on */
        sndsb_ess_set_extended_mode(sb_card,1/*enable*/);
        sndsb_setup_dma(sb_card);
        irqc = sb_card->irq_counter;

        {
            /* ESS 688/1869 chipset specific DSP playback.
               using this mode bypasses a lot of the Sound Blaster Pro emulation
               and restrictions and allows us to run up to 48KHz 16-bit stereo */
            unsigned short t16;
            int b;

            _cli();

            /* clear IRQ */
            sndsb_interrupt_ack(sb_card,3);

            b = 0x00; /* DMA disable */
            b |= 0x00; /* no auto-init */
            b |= 0x00; /* [3]=DMA converter in ADC mode [1]=DMA read for ADC playback mode */
            sndsb_ess_write_controller(sb_card,0xB8,b);

            b = sndsb_ess_read_controller(sb_card,0xA8);
            b &= ~0xB; /* clear mono/stereo and record monitor (bits 3, 1, and 0) */
            b |= 2;	/* mono 10=mono 01=stereo */
            sndsb_ess_write_controller(sb_card,0xA8,b);

            /* NTS: The meaning of bits 1:0 in register 0xB9
             *
             *      00 single DMA transfer mode
             *      01 demand DMA transfer mode, 2 bytes/request
             *      10 demand DMA transfer mode, 4 bytes/request
             *      11 reserved
             *
             * NOTES on what happens if you set bits 1:0 (DMA transfer type) to the "reserved" 11 value:
             *
             *      ESS 688 (Sharp laptop)          Nothing, apparently. Treated the same as 4 bytes/request
             *
             *      ESS 1887 (Compaq Presario)      Triggers a hardware bug where the chip appears to fetch
             *                                      3 bytes per demand transfer but then only handle 1 byte,
             *                                      which translates to audio playing at 3x the sample rate
             *                                      it should be. NOT because the DAC is running any faster,
             *                                      but because the chip is only playing back every 3rd sample!
             *                                      This play only 3rds behavior is consistent across 8/16-bit
             *                                      PCM and mono/stereo.
             */

            b = 2;  /* demand transfer DMA 4 bytes per request */
            sndsb_ess_write_controller(sb_card,0xB9,b);

            sndsb_ess_write_controller(sb_card,0xA1,count);

            /* effectively disable the lowpass filter (NTS: 0xFF mutes the audio, apparently) */
            sndsb_ess_write_controller(sb_card,0xA2,0xFE);

            t16 = -(tlen * (uint16_t)bytespersample); /* DMA transfer count reload register value is 2's complement of length */
            sndsb_ess_write_controller(sb_card,0xA4,t16); /* DMA transfer count low */
            sndsb_ess_write_controller(sb_card,0xA5,t16>>8); /* DMA transfer count high */

            b = sndsb_ess_read_controller(sb_card,0xB1);
            b &= ~0xA0; /* clear compat game IRQ, fifo half-empty IRQs */
            b |= 0x50; /* set overflow IRQ, and "no function" */
            sndsb_ess_write_controller(sb_card,0xB1,b);

            b = sndsb_ess_read_controller(sb_card,0xB2);
            b &= ~0xA0; /* clear compat */
            b |= 0x50; /* set DRQ/DACKB inputs for DMA */
            sndsb_ess_write_controller(sb_card,0xB2,b);

            b = 0x51; /* enable FIFO+DMA, reserved, load signal */
	        b |= wav_16bit ? 0x20 : 0x00; /* signed complement mode or not */
            sndsb_ess_write_controller(sb_card,0xB7,b);

            b = 0x90; /* enable FIFO+DMA, reserved, load signal */
	        b |= wav_16bit ? 0x20 : 0x00; /* signed complement mode or not */
            b |= 0x40; /* [3]=stereo [6]=!stereo */
            b |= wav_16bit ? 0x04 : 0x00; /* [2]=16bit */
            sndsb_ess_write_controller(sb_card,0xB7,b);

            b = sndsb_ess_read_controller(sb_card,0xB8);
            sndsb_ess_write_controller(sb_card,0xB8,b | 1);
        }

        _cli();
        c = read_8254(T8254_TIMER_INTERRUPT_TICK);
        bytes = tlen;
        time = 0;
        _sti();

        while (1) {
            if (irqc != sb_card->irq_counter)
                break;

            _cli();
            pc = c;
            c = read_8254(T8254_TIMER_INTERRUPT_TICK);
            time += (unsigned long)((pc - c) & 0xFFFFU); /* remember: it counts DOWN. assumes full 16-bit count */
            _sti();

            if (time >= timeout) goto x_timeout;
        }

x_complete:
        if (time == 0UL) time = 1;

        {
            int b;

            b = sndsb_ess_read_controller(sb_card,0xB8);
            if (b != -1) {
                b &= ~0x01; /* stop DMA */
                sndsb_ess_write_controller(sb_card,0xB8,b);
            }
        }

        {
            double t = (double)time / T8254_REF_CLOCK_HZ;
            double rate = (double)bytes / t;

            doubleprintf(" - TC 0x%02lX: expecting %luHz, %lu%c/%.3fs @ %.3fHz\n",count,expect,(unsigned long)bytes,wav_16bit?'w':'b',t,rate);
        }

        if (kbhit()) {
            if (getch() == 27)
                break;
        }

        continue;
x_timeout:
        d = d8237_read_count(sb_card->dma8) / (unsigned long)bytespersample; /* counts DOWNWARD */
        if (d > tlen) d = 0; /* terminal count */
        d = tlen - d;

        if (irqc == sb_card->irq_counter && d == 0) bytes = 0; /* nothing happened if no IRQ and counter never changed */
        else if (bytes > d) bytes = d;
        goto x_complete;
    }

    _cli();
    if (sb_card->irq >= 8) {
        p8259_OCW2(8,P8259_OCW2_SPECIFIC_EOI | (sb_card->irq & 7));
        p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | 2);
    }
    else if (sb_card->irq >= 0) {
        p8259_OCW2(0,P8259_OCW2_SPECIFIC_EOI | sb_card->irq);
    }
    _sti();

    sndsb_reset_dsp(sb_card);
}
Exemplo n.º 16
0
int main() {
	struct t8254_readback_t readback;
	t8254_time_t tick[3];
	unsigned int i;

	printf("8254 library test program\n");
	if (!probe_8254()) {
		printf("Chip not present. Your computer might be 2010-era hardware that dropped support for it.\n");
		return 1;
	}
	if (!probe_8259()) {
		printf("8259 interrupt controller not present. Your computer might be 2010-era hardware that dropped support for it.\n");
		return 1;
	}

	printf("8254 base clock: %luHz\n",T8254_REF_CLOCK_HZ);

	speaker_rate = T8254_REF_CLOCK_HZ / 400UL;	/* 400Hz */

	prev_irq0 = _dos_getvect(T8254_IRQ+0x08);
	_dos_setvect(T8254_IRQ+0x8,irq0);

	_cli();
	write_8254_pc_speaker(speaker_rate);
	write_8254_system_timer(max);
	_sti();

#ifdef TARGET_PC98
	/* PC-98 does not have IRQ0 running by default */
	p8259_unmask(T8254_IRQ);
#endif

	while (1) {
		if (kbhit()) {
			int c = getch();
			if (c == 27)
				break;
			else if (c == '-') {
				max -= 80;
				if (max > (0xFFFF-80))
					max = 0xFFFF;

				_cli();
				write_8254_system_timer(max);
				_sti();
			}
			else if (c == '=') {
				max += 110;
				if (max < 110 || max > (0xFFFF-110))
					max = 0xFFFF;
	
				_cli();
				write_8254_system_timer(max);
				_sti();
			}
			/* play with timer 2 and the PC speaker gate */
			else if (c == 'p') {
				unsigned char on = (t8254_pc_speaker_read_gate() != 0) ? 1 : 0;
				if (on) t8254_pc_speaker_set_gate(0);
				else t8254_pc_speaker_set_gate(3);
			}
			else if (c == '1') {
#ifndef TARGET_PC98
				unsigned char v = t8254_pc_speaker_read_gate();
				t8254_pc_speaker_set_gate(v ^ PC_SPEAKER_OUTPUT_TTL_AND_GATE);
#endif
			}
			else if (c == '2') {
#ifndef TARGET_PC98
				unsigned char v = t8254_pc_speaker_read_gate();
				t8254_pc_speaker_set_gate(v ^ PC_SPEAKER_COUNTER_2_GATE);
#endif
			}
			else if (c == '[') {
				speaker_rate += 110;
				if (speaker_rate > (0xFFFF-110) || speaker_rate < 110)
					speaker_rate = 0xFFFF;

				write_8254_pc_speaker(speaker_rate);
			}
			else if (c == ']') {
				speaker_rate -= 110;
				if (speaker_rate > (0xFFFF-110))
					speaker_rate = 0;

				write_8254_pc_speaker(speaker_rate);
			}
			else if (c == 'w') {
				printf("\n");
				pulse_width_test();
				_cli();
				write_8254_system_timer(max);
				_sti();
				printf("\n");
			}
			else if (c == 'z') {
				/* sleep-wait loop test */
				unsigned long delay_ticks;
				unsigned long z;
				unsigned int c,cmax;

				printf("\nDelay interval in us? ");
				z = 1000000; scanf("%lu",&z);

				delay_ticks = t8254_us2ticks(z);
				printf("  %lu = %lu ticks\n",z,delay_ticks);

				if (delay_ticks == 0UL)	cmax = (unsigned int)(T8254_REF_CLOCK_HZ / 20UL);
				else			cmax = (unsigned int)(T8254_REF_CLOCK_HZ / 20UL / (unsigned long)delay_ticks);
				if (cmax == 0) cmax = 1;

				write_8254_pc_speaker(T8254_REF_CLOCK_HZ / 400UL); /* tick as fast as possible */
				while (1) {
					if (kbhit()) {
						if (getch() == 27) break;
					}

					for (c=0;c < cmax;c++) {
						t8254_pc_speaker_set_gate(3);
						t8254_wait(delay_ticks);
						t8254_pc_speaker_set_gate(0);
						t8254_wait(delay_ticks);
					}
				}
			}
			else if (c == 'd') {
				printf("\n                                    \nDetail mode, hit 'd' again to exit: [WARNING: 8254 only]\n");
				while (1) {
					if (kbhit()) {
						int c = getch();
						if (c == 'd') {
							break;
						}
					}

					_cli();
					readback_8254(T8254_READBACK_ALL,&readback);
					_sti();
					printf("\x0D");
					for (i=0;i <= 2;i++) {
						printf("[%u] stat=%02x count=%04x  ",i,
							readback.timer[i].status,
							readback.timer[i].count);
					}
					fflush(stdout);
				}
				printf("\n");
			}
		}

		for (i=0;i <= 2;i++) tick[i] = read_8254(i);

		/* BUG: DOSBox/DOSBox-X appear to have a bug where the PC speaker readback toggles
		 *      regardless of the GATE input to Counter 2. Bring GATE low (setting bit 1
		 *      of port 61h to 0) is supposed to cause Counter 2 to stop. The AND gate
		 *      after the output (bit 0 of port 61h) is not supposed to affect the readback. */
		printf("\x0D %04x %04x %04x max=%04x count=%04x SPKR=%u",tick[0],tick[1],tick[2],
			max,counter,read_8254_pc_speaker_output()!=0?1:0);
		fflush(stdout);
	}
	printf("\n");

#ifdef TARGET_PC98
	/* PC-98 does not have IRQ0 running by default */
	p8259_mask(T8254_IRQ);
#endif

	_cli();
	write_8254_pc_speaker(0);
	t8254_pc_speaker_set_gate(0);
	_dos_setvect(T8254_IRQ+0x8,prev_irq0);
	_sti();

	write_8254_system_timer(0xFFFF); /* restore normal function to prevent BIOS from going crazy */
	return 0;
}
Exemplo n.º 17
0
void pulse_width_test() {
	int fd;
	unsigned char cc;
	unsigned int play;
	unsigned char plan_b=0;
	unsigned int patience = 10000;

	_cli();
	write_8254_system_timer(0xFFFF);	/* BUGFIX: Personal experience tells me BIOSes would fail reading the floppy if the IRQ 0 timer isn't ticking along at 18Hz */
	_sti();

	fd = open("..\\test1_22.wav",O_RDONLY|O_BINARY);
	if (fd < 0) fd = open("test1_22.wav",O_RDONLY|O_BINARY);
	if (fd < 0) {
		fprintf(stderr,"Cannot open test WAV\n");
		return;
	}
	lseek(fd,44,SEEK_SET);
	read(fd,tmp,sizeof(tmp));
	for (play=0;play < sizeof(tmp);play++) tmp[play] = (((tmp[play]) * 53) / 255) + 1; /* add "noise" to dither */
	close(fd);

	/* set timer 0 to 54 ticks (1.191MHz / 54 ~ 22050Hz) */
	_cli();
	t8254_pc_speaker_set_gate(0);
	write_8254_pc_speaker(1);
	write_8254_system_timer(54);
	_sti();

	_cli();
	{
		outp(T8254_CONTROL_PORT,(0 << 6) | (0 << 4) | 0);	/* latch counter N, counter latch read */
		do {
			if (--patience == 1) break;
			cc = inp(T8254_TIMER_PORT(0));
			inp(T8254_TIMER_PORT(0));
		} while (cc < (54/2));
		do {
			if (--patience == 0) break;
			cc = inp(T8254_TIMER_PORT(0));
			inp(T8254_TIMER_PORT(0));
		} while (cc >= (54/2));
		if (patience <= 2) {
			write_8254_system_timer(0xFFFF);	/* BUGFIX: on very old slow machines, the 54-count tick can easily cause the printf() below to absolutely CRAWL... */
			_sti();
			fprintf(stderr,"Oops! Either your CPU is too fast or the timer countdown trick doesn't work.\n");
			_cli();
			write_8254_system_timer(54);
			plan_b = 1;
		}
	}
	_sti();

	while (1) {
		if (kbhit()) {
			int c = getch();
			if (c == 27) break;
		}

		if (plan_b) {
			/* run with interrupts enabled, use IRQ0 to know when to tick */
			_cli();
			counter = 0;
			t8254_pc_speaker_set_gate(3);
			for (play=0;play < sizeof(tmp);) {
				outp(T8254_CONTROL_PORT,(2 << 6) | (1 << 4) | (T8254_MODE_0_INT_ON_TERMINAL_COUNT << 1)); /* MODE 0, low byte only, counter 2 */
				outp(T8254_TIMER_PORT(2),tmp[play]);
				_sti();
				while (counter == 0);
				_cli();
				play += counter;
				counter = 0;
			}
			_sti();
		}
		else {
			_cli();
			t8254_pc_speaker_set_gate(3);
			outp(T8254_CONTROL_PORT,(0 << 6) | (0 << 4) | 0);	/* latch counter N, counter latch read */
			for (play=0;play < sizeof(tmp);play++) {
				outp(T8254_CONTROL_PORT,(2 << 6) | (1 << 4) | (T8254_MODE_0_INT_ON_TERMINAL_COUNT << 1)); /* MODE 0, low byte only, counter 2 */
				outp(T8254_TIMER_PORT(2),tmp[play]);

				do {
					cc = inp(T8254_TIMER_PORT(0));
					inp(T8254_TIMER_PORT(0));
				} while (cc < (54/2));

				do {
					cc = inp(T8254_TIMER_PORT(0));
					inp(T8254_TIMER_PORT(0));
				} while (cc >= (54/2));
			}
			_sti();
		}
	}

	t8254_pc_speaker_set_gate(0);
}
Exemplo n.º 18
0
qword sys_addTimerEvent(qword timerEventFunc, qword interval, qword rcx, qword r8, qword r9){
    _cli();
    addTimerListener((timerEventT) timerEventFunc,interval);
    _sti();
    return 0;
}
Exemplo n.º 19
0
/* this is used to probe for ports in standard locations, when we really don't know if it's there */
int probe_8250(uint16_t port) {
    unsigned char ier,dlab1,dlab2,c,fcr;
    struct info_8250 *inf;

    if (already_got_8250_port(port))
        return 0;
    if (base_8250_full())
        return 0;

    inf = &info_8250_port[base_8250_ports];
    inf->type = TYPE_8250_IS_8250;
    inf->port = port;
    inf->irq = -1;
    if (windows_mode == WINDOWS_NONE || windows_mode == WINDOWS_REAL) {
        /* in real-mode DOS we can play with the UART to our heart's content. so we play with the
         * DLAB select and interrupt enable registers to detect the UART in a manner non-destructive
         * to the hardware state. */

        /* there's no way to autodetect the COM port's IRQ, we have to guess */
        if (port == 0x3F8 || port == 0x3E8)
            inf->irq = 4;
        else if (port == 0x2F8 || port == 0x2E8)
            inf->irq = 3;

        /* switch registers 0+1 back to RX/TX and interrupt enable, and then test the Interrupt Enable register */
        _cli();
        outp(port+3,inp(port+3) & 0x7F);
        if (inp(port+3) == 0xFF) { _sti(); return 0; }
        ier = inp(port+1);
        outp(port+1,0);
        if (inp(port+1) == 0xFF) { _sti(); return 0; }
        outp(port+1,ier);
        if ((inp(port+1) & 0xF) != (ier & 0xF)) { _sti(); return 0; }
        /* then switch 0+1 to DLAB (divisor registers) and see if values differ from what we read the first time */
        outp(port+3,inp(port+3) | 0x80);
        dlab1 = inp(port+0);
        dlab2 = inp(port+1);
        outp(port+0,ier ^ 0xAA);
        outp(port+1,ier ^ 0x55);
        if (inp(port+1) == ier || inp(port+0) != (ier ^ 0xAA) || inp(port+1) != (ier ^ 0x55)) {
            outp(port+0,dlab1);
            outp(port+1,dlab2);
            outp(port+3,inp(port+3) & 0x7F);
            _sti();
            return 0;
        }
        outp(port+0,dlab1);
        outp(port+1,dlab2);
        outp(port+3,inp(port+3) & 0x7F);

        /* now figure out what type */
        fcr = inp(port+2);
        outp(port+2,0xE7);  /* write FCR */
        c = inp(port+2);    /* read IIR */
        if (c & 0x40) { /* if FIFO */
            if (c & 0x80) {
                if (c & 0x20) inf->type = TYPE_8250_IS_16750;
                else inf->type = TYPE_8250_IS_16550A;
            }
            else {
                inf->type = TYPE_8250_IS_16550;
            }
        }
        else {
            unsigned char oscratch = inp(port+7);

            /* no FIFO. try the scratch register */
            outp(port+7,0x55);
            if (inp(port+7) == 0x55) {
                outp(port+7,0xAA);
                if (inp(port+7) == 0xAA) {
                    outp(port+7,0x00);
                    if (inp(port+7) == 0x00) {
                        inf->type = TYPE_8250_IS_16450;
                    }
                }
            }

            outp(port+7,oscratch);
        }

        outp(port+2,fcr);
        _sti();
    }
    else {
        unsigned int i;

        /* if we were to actually do our self-test in a VM, Windows would mistakingly assume we
         * were trying to use it and would allocate the port. we're just enumerating at this point.
         * play it safe and assume it works if the port is listed as one of the BIOS ports.
         * we also don't use interrupts. */
        for (i=0;i < bios_8250_ports && port != get_8250_bios_port(i);) i++;
        if (i >= bios_8250_ports) return 0;
    }

    base_8250_port[base_8250_ports++] = port;
    return 1;
}
Exemplo n.º 20
0
qword sys_removeTimerEvent(qword timerEventFunc, qword rdx, qword rcx, qword r8, qword r9) {
    _cli();
    deleteTimerListener((timerEventT) timerEventFunc);
    _sti();
    return 0;
}
Exemplo n.º 21
0
int main(int argc,char *argv[],char *envp[]) {
	rdtsc_t start,measure,ticks_per_sec;
    unsigned char force = 0;
	double t;
	int c;

    {
        int i = 1;
        char *a;

        while (i < argc) {
            a = argv[i++];

            if (*a == '-') {
                do { a++; } while (*a == '-');

                if (!strcmp(a,"f") || !strcmp(a,"force"))
                    force = 1;
                else
                    return 1;
            }
            else {
                return 1;
            }
        }
    }

	cpu_probe();
	printf("Your CPU is basically a %s or higher\n",cpu_basic_level_to_string(cpu_basic_level));
	if (cpu_v86_active)
		printf(" - Your CPU is currently running me in virtual 8086 mode\n");

    if (force) {
        printf(" - You're forcing me to use RDTSC. I may crash if your CPU doesn't\n");
        printf("   support it or the environment doesn't enable it.\n");
        printf("   OK! Here we go....!\n");
    }
    else {
        if (!(cpu_flags & CPU_FLAG_CPUID)) {
            printf(" - Your CPU doesn't support CPUID, how can it support RDTSC?\n");
            return 1;
        }

        if (!(cpu_cpuid_features.a.raw[2] & 0x10)) {
            printf(" - Your CPU does not support RDTSC\n");
            return 1;
        }

        if (cpu_flags & CPU_FLAG_DONT_USE_RDTSC) {
            printf(" - Your CPU does support RDTSC but it's not recommended in this environment.\n");
            printf("   This is usually due to running a 16-bit build in pure DOS under EMM386.EXE.\n");
            return 1;
        }
    }

#if defined(TARGET_OS2)
# if TARGET_MSDOS == 32
	/* OS/2 32-bit: We can use DosQuerySysInfo() */
	printf("Measuring CPU speed, using DosQuerySysInfo(), over 3 seconds\n");
	{
		ULONG startTick,tmp;
		start = cpu_rdtsc();
		startTick = GetMsCount();
		do { tmp = GetMsCount();
		} while ((tmp - startTick) < 3000); /* NTS: <- I know this rolls over in 49 days,
		the math though should overflow the 32-bit integer and produce correct results anyway */
		measure = cpu_rdtsc();

		/* use the precise tick count to better compute ticks_per_sec */
		ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
		printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
		printf("             From 0x%llX to 0x%llX\n",start,measure);
	}
# else
	/* OS/2 16-bit: There is no API (that I know of) to get tick count. Use system clock. */
	printf("Measuring CPU speed, using system clock with 1-second resolution, across 3 seconds\n");
	{
		time_t startTick,tmp;

		/* wait for the immediate start of a one-second tick, then record RDTSC and count until 3 seconds */
		startTick = time(NULL);
		do { tmp = time(NULL); } while (tmp == startTick);
		start = cpu_rdtsc(); startTick = tmp;

		/* NOW! Count 3 seconds and measure CPU ticks */
		do { tmp = time(NULL);
		} while ((tmp - startTick) < 3);
		measure = cpu_rdtsc();

		/* use the precise tick count to better compute ticks_per_sec */
		ticks_per_sec = ((measure - start) * 1ULL) / ((rdtsc_t)(tmp - startTick));
		printf("Measurement: %lu seconds = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
		printf("             From 0x%llX to 0x%llX\n",start,measure);
	}
# endif
#elif defined(TARGET_WINDOWS)
# if TARGET_MSDOS == 16
	/* Windows 2.x/3.0/3.1: Use GetTickCount() or
	 * Windows 3.1: Use TOOLHELP.DLL TimerCount() which is more accurate (really?) */
	if (ToolHelpInit()) {
		TIMERINFO ti;

		ti.dwSize = sizeof(ti);
		printf("Measuring CPU speed, using TOOLHELP TimerCount() over 1 second\n");
		{
			DWORD startTick,tmp;
			start = cpu_rdtsc();
			if (!__TimerCount(&ti)) {
				printf("TimerCount() failed\n");
				return 1;
			}
			startTick = ti.dwmsSinceStart;
			do {
#  if defined(WIN_STDOUT_CONSOLE)
				_win_pump(); /* <- you MUST call this. The message pump must run, or else the timer won't advance and this loop will run forever.
			                           The fact that GetTickCount() depends on a working message pump under Windows 3.1 seems to be a rather serious
						   oversight on Microsoft's part. Note that the problem described here does not apply to Windows 9x/ME. Also note
						   the Toolhelp function TimerCount() relies on GetTickCount() as a basic for time (though Toolhelp uses VxD services
						   or direct I/O port hackery to refine the timer count) */
#  endif

				if (!__TimerCount(&ti)) {
					printf("TimerCount() failed\n");
					return 1;
				}

				tmp = ti.dwmsSinceStart;
			} while ((tmp - startTick) < 1000); /* NTS: <- I know this rolls over in 49 days,
			the math though should overflow the 32-bit integer and produce correct results anyway */
			measure = cpu_rdtsc();

			/* use the precise tick count to better compute ticks_per_sec */
			ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
			printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
			printf("             From 0x%llX to 0x%llX\n",start,measure);
		}
	}
	else {
# else
	{
# endif
		printf("Measuring CPU speed, using GetTickCount() over 3 second\n");
		{
			DWORD startTick,tmp;
			start = cpu_rdtsc();
			startTick = GetTickCount();
			/* NTS: Dunno yet about Windows 3.1, but Windows 95 seems to require we Yield(). If we don't, the GetTickCount() return
			 *      value never updates and we're forever stuck in a loop. */
			do {
#  if defined(WIN_STDOUT_CONSOLE)
				_win_pump(); /* <- you MUST call this. The message pump must run, or else the timer won't advance and this loop will run forever.
			                           The fact that GetTickCount() depends on a working message pump under Windows 3.1 seems to be a rather serious
						   oversight on Microsoft's part. Note that the problem described here does not apply to Windows 9x/ME */
#  endif
				tmp = GetTickCount();
			} while ((tmp - startTick) < 3000); /* NTS: <- I know this rolls over in 49 days,
			the math though should overflow the 32-bit integer and produce correct results anyway */
			measure = cpu_rdtsc();

			/* use the precise tick count to better compute ticks_per_sec */
			ticks_per_sec = ((measure - start) * 1000ULL) / ((rdtsc_t)(tmp - startTick));
			printf("Measurement: %lums = %lld ticks\n",tmp - startTick,(int64_t)ticks_per_sec);
			printf("             From 0x%llX to 0x%llX\n",start,measure);
		}
	}
#else
	/* MS-DOS: Init the 8254 timer library for precise measurement */
	if (!probe_8254()) {
		printf("Cannot init 8254 timer\n");
		return 1;
	}

    /* DOSBox-X and most motherboards leave the PIT in a mode that counts down by 2.
     * Our code sets the counter and puts it in a mode that counts down by 1.
     * We have to do this or our wait functions exit in half the time (which explains
     * why testing this code in DOSBox-X often comes up with RDTSC running at 2x
     * normal speed. */
    write_8254_system_timer(0); /* 18.2 tick/sec on our terms (proper PIT mode) */

	printf("Measuring CPU speed (relative to 8254 timer)\n");

	_cli();
	start = cpu_rdtsc();
	t8254_wait(t8254_us2ticks(1000000));
	measure = cpu_rdtsc();
	_sti();

	printf("Measurement: 1 sec = %lld ticks\n",(int64_t)(measure - start));
	printf("             From 0x%llX to 0x%llX\n",start,measure);
	ticks_per_sec = (measure - start);
#endif

	if ((int64_t)ticks_per_sec < 0) {
		printf("Cannot determine CPU cycle count\n");
		ticks_per_sec = 100000ULL;
	}

	while (1) {
		measure = cpu_rdtsc();
		t = (double)((int64_t)(measure - start));
		t /= ticks_per_sec;

		printf("\x0D" "0x%llX = %.3f   ",measure,t);
#if !defined(WINFCON_STOCK_WIN_MAIN)
		fflush(stdout); /* FIXME: The fake console code should intercept fflush() too */
#endif

		if (kbhit()) {
			c = getch();
			if (c == 0) c = getch() << 8;

			if (c == 27)
				break;
			else if (c == 'r' || c == 'R') {
				if (c == 'r' || (cpu_flags & CPU_FLAG_DONT_WRITE_RDTSC)) {
					printf("\nI am not able to write the TSC register within this environment\nYou can force me by typing SHIFT+R, don't blame me when I crash...\n");
				}
				else {
					printf("\nUsing MSR to reset TSC to 0\n");
					/* demonstrating WRMSR to write the TSC (yes, you can!) */
					cpu_rdtsc_write(start = 0ULL);
					printf("Result: 0x%llX\n",cpu_rdtsc());
				}
			}
			else if (c == 's') {
				if (c == 's' && (cpu_flags & CPU_FLAG_DONT_WRITE_RDTSC)) {
					printf("\nI am not able to write the TSC register within this environment\nYou can force me by typing SHIFT+S, don't blame me when I crash...\n");
				}
				else {
					printf("\nUsing MSR to reset TSC to 0x123456789ABCDEF\n");
					/* demonstrating WRMSR to write the TSC (yes, you can!) */
					cpu_rdtsc_write(start = 0x123456789ABCDEFULL);
					printf("Result: 0x%llX\n",cpu_rdtsc());
				}
			}
		}
	}
	printf("\n");

	return 0;
}
Exemplo n.º 22
0
VOID int21_service(iregs FAR * r)
{
  COUNT rc,
    rc1;
  ULONG lrc;
  psp FAR *p = MK_FP(cu_psp, 0);

  p->ps_stack = (BYTE FAR *) r;

#ifdef DEBUG
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs, sizeof(iregs));
    printf("System call (21h): %02x\n", user_r->AX);
    dump_regs = TRUE;
    dump();
  }
#endif

dispatch:

  /* Check for Ctrl-Break */
  switch (r->AH)
  {
    default:
      if (!break_ena)
        break;
    case 0x01:
    case 0x02:
    case 0x03:
    case 0x04:
    case 0x05:
    case 0x08:
    case 0x09:
    case 0x0a:
    case 0x0b:
      if (control_break())
        handle_break();
  }

  /* The dispatch handler                                         */
  switch (r->AH)
  {
      /* int 21h common error handler                                 */
    case 0x64:
    case 0x6b:
    default:
    error_invalid:
      r->AX = -DE_INVLDFUNC;
      goto error_out;
    error_exit:
      r->AX = -rc;
    error_out:
      r->FLAGS |= FLG_CARRY;
      break;

#if 0
      /* Moved to simulate a 0x4c00 -- 1999/04/21 ska */
      /* Terminate Program                                            */
    case 0x00:
      if (cu_psp == RootPsp)
        break;
      else if (((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
        break;
      tsr = FALSE;
      return_mode = break_flg ? 1 : 0;
      return_code = r->AL;
      if (DosMemCheck() != SUCCESS)
        panic("MCB chain corrupted");
#ifdef TSC
      StartTrace();
#endif
      return_user();
      break;
#endif

      /* Read Keyboard with Echo                      */
    case 0x01:
      Do_DosIdle_loop();
      r->AL = _sti();
      sto(r->AL);
      break;

      /* Display Character                                            */
    case 0x02:
      sto(r->DL);
      break;

      /* Auxiliary Input                                                      */
    case 0x03:
      r->AL = _sti();
      break;

      /* Auxiliary Output                                                     */
    case 0x04:
      sto(r->DL);
      break;

      /* Print Character                                                      */
    case 0x05:
      sto(r->DL);
      break;

      /* Direct Cosole I/O                                            */
    case 0x06:
      if (r->DL != 0xff)
        sto(r->DL);
      else if (StdinBusy())
      {
        r->AL = 0x00;
        r->FLAGS |= FLG_ZERO;
      }
      else
      {
        r->FLAGS &= ~FLG_ZERO;
        r->AL = _sti();
      }
      break;

      /* Direct Console Input                                         */
    case 0x07:
      /* Read Keyboard Without Echo                                   */
    case 0x08:
      Do_DosIdle_loop();
      r->AL = _sti();
      break;

      /* Display String                                               */
    case 0x09:
      {
        static COUNT scratch;
        BYTE FAR *p = MK_FP(r->DS, r->DX),
          FAR * q;
        q = p;
        while (*q != '$')
          ++q;
        DosWrite(STDOUT, q - p, p, (COUNT FAR *) & scratch);
      }
      r->AL = '$';
      break;

      /* Buffered Keyboard Input                                      */
    case 0x0a:
      ((keyboard FAR *) MK_FP(r->DS, r->DX))->kb_count = 0;
      sti((keyboard FAR *) MK_FP(r->DS, r->DX));
      ((keyboard FAR *) MK_FP(r->DS, r->DX))->kb_count -= 2;
      break;

      /* Check Stdin Status                                           */
    case 0x0b:
      if (StdinBusy())
        r->AL = 0xFF;
      else
        r->AL = 0x00;
      break;

      /* Flush Buffer, Read Keayboard                                 */
    case 0x0c:
      KbdFlush();
      switch (r->AL)
      {
        case 0x01:
        case 0x06:
        case 0x07:
        case 0x08:
        case 0x0a:
          r->AH = r->AL;
          goto dispatch;

        default:
          r->AL = 0x00;
          break;
      }
      break;

      /* Reset Drive                                                  */
    case 0x0d:
      flush();
      break;

      /* Set Default Drive                                            */
    case 0x0e:
      r->AL = DosSelectDrv(r->DL);
      break;

    case 0x0f:
      if (FcbOpen(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x10:
      if (FcbClose(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x11:
      if (FcbFindFirst(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x12:
      if (FcbFindNext(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x13:
      if (FcbDelete(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x14:
      {
        COUNT nErrorCode;

        if (FcbRead(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

    case 0x15:
      {
        COUNT nErrorCode;

        if (FcbWrite(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

    case 0x16:
      if (FcbCreate(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

    case 0x17:
      if (FcbRename(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

      /* CP/M compatibility functions                                 */
    case 0x18:
    case 0x1d:
    case 0x1e:
    case 0x20:
#ifndef TSC
    case 0x61:
#endif
      r->AL = 0;
      break;

      /* Get Default Drive                                            */
    case 0x19:
      r->AL = default_drive;
      break;

      /* Set DTA                                                      */
    case 0x1a:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        p->ps_dta = MK_FP(r->DS, r->DX);
        dos_setdta(p->ps_dta);
      }
      break;

      /* Get Default Drive Data                                       */
    case 0x1b:
      {
        BYTE FAR *p;

        FatGetDrvData(0,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Drive Data                                               */
    case 0x1c:
      {
        BYTE FAR *p;

        FatGetDrvData(r->DL,
                      (COUNT FAR *) & r->AX,
                      (COUNT FAR *) & r->CX,
                      (COUNT FAR *) & r->DX,
                      (BYTE FAR **) & p);
        r->DS = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get default DPB                                              */
    case 0x1f:
      if (default_drive < lastdrive)
      {
        struct dpb FAR *dpb = (struct dpb FAR *)CDSp->cds_table[default_drive].cdsDpb;
        if (dpb == 0)
        {
          r->AL = 0xff;
          break;
        }

        r->DS = FP_SEG(dpb);
        r->BX = FP_OFF(dpb);
        r->AL = 0;
      }
      else
        r->AL = 0xff;
      break;

      /* Random read using FCB */
    case 0x21:
      {
        COUNT nErrorCode;

        if (FcbRandomRead(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Random write using FCB */
    case 0x22:
      {
        COUNT nErrorCode;

        if (FcbRandomWrite(MK_FP(r->DS, r->DX), &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Get file size in records using FCB */
    case 0x23:
      if (FcbGetFileSize(MK_FP(r->DS, r->DX)))
        r->AL = 0;
      else
        r->AL = 0xff;
      break;

      /* Set random record field in FCB */
    case 0x24:
      FcbSetRandom(MK_FP(r->DS, r->DX));
      break;

      /* Set Interrupt Vector                                         */
    case 0x25:
      {
        VOID(INRPT FAR * p) () = MK_FP(r->DS, r->DX);

        setvec(r->AL, p);
      }
      break;

      /* Dos Create New Psp                                           */
    case 0x26:
      {
        psp FAR *p = MK_FP(cu_psp, 0);

        new_psp((psp FAR *) MK_FP(r->DX, 0), p->ps_size);
      }
      break;

      /* Read random record(s) using FCB */
    case 0x27:
      {
        COUNT nErrorCode;

        if (FcbRandomBlockRead(MK_FP(r->DS, r->DX), r->CX, &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Write random record(s) using FCB */
    case 0x28:
      {
        COUNT nErrorCode;

        if (FcbRandomBlockWrite(MK_FP(r->DS, r->DX), r->CX, &nErrorCode))
          r->AL = 0;
        else
          r->AL = nErrorCode;
        break;
      }

      /* Parse File Name                                              */
    case 0x29:
      {
        BYTE FAR *lpFileName;

        lpFileName = MK_FP(r->DS, r->SI);
        r->AL = FcbParseFname(r->AL,
                              &lpFileName,
                              MK_FP(r->ES, r->DI));
        r->DS = FP_SEG(lpFileName);
        r->SI = FP_OFF(lpFileName);
      }
      break;

      /* Get Date                                                     */
    case 0x2a:
      DosGetDate(
                  (BYTE FAR *) & (r->AL),	/* WeekDay              */
                  (BYTE FAR *) & (r->DH),	/* Month                */
                  (BYTE FAR *) & (r->DL),	/* MonthDay             */
                  (COUNT FAR *) & (r->CX));	/* Year                 */
      break;

      /* Set Date                                                     */
    case 0x2b:
      rc = DosSetDate(
                       (BYTE FAR *) & (r->DH),	/* Month                */
                       (BYTE FAR *) & (r->DL),	/* MonthDay             */
                       (COUNT FAR *) & (r->CX));	/* Year                 */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Get Time                                                     */
    case 0x2c:
      DosGetTime(
                  (BYTE FAR *) & (r->CH),	/* Hour                 */
                  (BYTE FAR *) & (r->CL),	/* Minutes              */
                  (BYTE FAR *) & (r->DH),	/* Seconds              */
                  (BYTE FAR *) & (r->DL));	/* Hundredths           */
      break;

      /* Set Date                                                     */
    case 0x2d:
      rc = DosSetTime(
                       (BYTE FAR *) & (r->CH),	/* Hour                 */
                       (BYTE FAR *) & (r->CL),	/* Minutes              */
                       (BYTE FAR *) & (r->DH),	/* Seconds              */
                       (BYTE FAR *) & (r->DL));	/* Hundredths           */
      if (rc != SUCCESS)
        r->AL = 0xff;
      else
        r->AL = 0;
      break;

      /* Set verify flag                                              */
    case 0x2e:
      verify_ena = (r->AL ? TRUE : FALSE);
      break;

      /* Get DTA                                                      */
    case 0x2f:
      r->ES = FP_SEG(dta);
      r->BX = FP_OFF(dta);
      break;

      /* Get DOS Version                                              */
    case 0x30:
      r->AL = os_major;
      r->AH = os_minor;
      r->BH = OEM_ID;
      r->CH = REVISION_MAJOR;   /* JPP */
      r->CL = REVISION_MINOR;
      r->BL = REVISION_SEQ;
      break;

      /* Keep Program (Terminate and stay resident) */
    case 0x31:
      DosMemChange(cu_psp, r->DX < 6 ? 6 : r->DX, 0);
      return_mode = 3;
      return_code = r->AL;
      tsr = TRUE;
      return_user();
      break;

      /* Get DPB                                                      */
    case 0x32:
      if (r->DL < lastdrive)
      {
        struct dpb FAR *dpb = CDSp->cds_table[r->DL].cdsDpb;
        if (dpb == 0)
        {
          r->AL = 0xff;
          break;
        }
        r->DS = FP_SEG(dpb);
        r->BX = FP_OFF(dpb);
        r->AL = 0;
      }
      else
        r->AL = 0xFF;
      break;

      /* Get InDOS flag                                               */
    case 0x34:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) ((BYTE *) & InDOS);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get Interrupt Vector                                         */
    case 0x35:
      {
        BYTE FAR *p;

        p = getvec((COUNT) r->AL);
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Dos Get Disk Free Space                                      */
    case 0x36:
      DosGetFree(
                  (COUNT) r->DL,
                  (COUNT FAR *) & r->AX,
                  (COUNT FAR *) & r->BX,
                  (COUNT FAR *) & r->CX,
                  (COUNT FAR *) & r->DX);
      break;

      /* Undocumented Get/Set Switchar                                */
    case 0x37:
      switch (r->AL)
      {
          /* Get switch character */
        case 0x00:
          r->DL = switchar;
          r->AL = 0x00;
          break;

          /* Set switch character */
        case 0x01:
          switchar = r->DL;
          r->AL = 0x00;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Country Info                                         */
    case 0x38:
      {
        BYTE FAR *lpTable
        = (BYTE FAR *) MK_FP(r->DS, r->DX);
        BYTE nRetCode;

        if (0xffff == r->DX)
        {
          r->BX = SetCtryInfo(
                               (UBYTE FAR *) & (r->AL),
                               (UWORD FAR *) & (r->BX),
                               (BYTE FAR *) & lpTable,
                               (UBYTE *) & nRetCode);

          if (nRetCode != 0)
          {
            r->AX = 0xff;
            r->FLAGS |= FLG_CARRY;
          }
          else
          {
            r->AX = nRetCode;
            r->FLAGS &= ~FLG_CARRY;
          }
        }
        else
        {
          r->BX = GetCtryInfo(&(r->AL), &(r->BX), lpTable);
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* Dos Create Directory                                         */
    case 0x39:
      rc = dos_mkdir((BYTE FAR *) MK_FP(r->DS, r->DX));
      if (rc != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Remove Directory                                         */
    case 0x3a:
      rc = dos_rmdir((BYTE FAR *) MK_FP(r->DS, r->DX));
      if (rc != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Change Directory                                         */
    case 0x3b:
      if ((rc = DosChangeDir((BYTE FAR *) MK_FP(r->DS, r->DX))) < 0)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Create File                                              */
    case 0x3c:
      if ((rc = DosCreat(MK_FP(r->DS, r->DX), r->CX)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Open                                                     */
    case 0x3d:
      if ((rc = DosOpen(MK_FP(r->DS, r->DX), r->AL)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Dos Close                                                    */
    case 0x3e:
      if ((rc = DosClose(r->BX)) < 0)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Dos Read                                                     */
    case 0x3f:
      rc = DosRead(r->BX, r->CX, MK_FP(r->DS, r->DX), (COUNT FAR *) & rc1);

      if (rc1 != SUCCESS)
      {
        r->FLAGS |= FLG_CARRY;
        r->AX = -rc1;
      }
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = rc;
      }
      break;

      /* Dos Write                                                    */
    case 0x40:
      rc = DosWrite(r->BX, r->CX, MK_FP(r->DS, r->DX), (COUNT FAR *) & rc1);
      if (rc1 != SUCCESS)
      {
        r->FLAGS |= FLG_CARRY;
        r->AX = -rc1;
      }
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = rc;
      }
      break;

      /* Dos Delete File                                              */
    case 0x41:
      rc = dos_delete((BYTE FAR *) MK_FP(r->DS, r->DX));
      if (rc < 0)
      {
        r->FLAGS |= FLG_CARRY;
        r->AX = -rc1;
      }
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Dos Seek                                                     */
    case 0x42:
      if ((rc = DosSeek(r->BX, (LONG) ((((LONG) (r->CX)) << 16) + r->DX), r->AL, &lrc)) < 0)
        goto error_exit;
      else
      {
        r->DX = (lrc >> 16);
        r->AX = lrc & 0xffff;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Get/Set File Attributes                                      */
    case 0x43:
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFattr((BYTE FAR *) MK_FP(r->DS, r->DX), (UWORD FAR *) & r->CX);
          if (rc < SUCCESS)
            goto error_exit;
          else
          {
            r->FLAGS &= ~FLG_CARRY;
          }
          break;

        case 0x01:
          rc = DosSetFattr((BYTE FAR *) MK_FP(r->DS, r->DX), (UWORD FAR *) & r->CX);
          if (rc != SUCCESS)
            goto error_exit;
          else
            r->FLAGS &= ~FLG_CARRY;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Device I/O Control                                           */
    case 0x44:
      {
        rc = DosDevIOctl(r, (COUNT FAR *) & rc1);

        if (rc1 != SUCCESS)
        {
          r->FLAGS |= FLG_CARRY;
          r->AX = -rc1;
        }
        else
        {
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* Duplicate File Handle                                        */
    case 0x45:
      rc = DosDup(r->BX);
      if (rc < SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = rc;
      }
      break;

      /* Force Duplicate File Handle                                  */
    case 0x46:
      rc = DosForceDup(r->BX, r->CX);
      if (rc < SUCCESS)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Get Current Directory                                        */
    case 0x47:
      if ((rc = DosGetCuDir(r->DL, MK_FP(r->DS, r->SI))) < 0)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
        r->AX = 0x0100;         /*jpp: from interrupt list */
      }
      break;

      /* Allocate memory */
    case 0x48:
      if ((rc = DosMemAlloc(r->BX, mem_access_mode, &(r->AX), &(r->BX))) < 0)
      {
        DosMemLargest(&(r->BX));
        goto error_exit;
      }
      else
      {
        ++(r->AX);              /* DosMemAlloc() returns seg of MCB rather than data */
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Free memory */
    case 0x49:
      if ((rc = DosMemFree((r->ES) - 1)) < 0)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Set memory block size */
    case 0x4a:
      {
        UWORD maxSize;

        if ((rc = DosMemChange(r->ES, r->BX, &maxSize)) < 0)
        {
          if (rc == DE_NOMEM)
            r->BX = maxSize;

#if 0
          if (cu_psp == r->ES)
          {

            psp FAR *p;

            p = MK_FP(cu_psp, 0);
            p->ps_size = r->BX + cu_psp;
          }
#endif
          goto error_exit;
        }
        else
          r->FLAGS &= ~FLG_CARRY;

        break;
      }

      /* Load and Execute Program */
    case 0x4b:
      break_flg = FALSE;

      if ((rc = DosExec(r->AL, MK_FP(r->ES, r->BX), MK_FP(r->DS, r->DX)))
          != SUCCESS)
        goto error_exit;
      else
        r->FLAGS &= ~FLG_CARRY;
      break;

      /* Terminate Program                                            */
    case 0x00:
      r->AX = 0x4c00;

      /* End Program                                                  */
    case 0x4c:
      if (cu_psp == RootPsp
          || ((psp FAR *) (MK_FP(cu_psp, 0)))->ps_parent == cu_psp)
        break;
      tsr = FALSE;
/*      int2f_Remote_call(0x1122, 0, 0, 0, 0, 0, 0);
   int2f_Remote_call(REM_CLOSEALL, 0, 0, 0, 0, 0, 0);
 */
      if (ErrorMode)
      {
        ErrorMode = FALSE;
        return_mode = 2;
      }
      else if (break_flg)
      {
        break_flg = FALSE;
        return_mode = 1;
      }
      else
      {
        return_mode = 0;
      }
      return_code = r->AL;
      if (DosMemCheck() != SUCCESS)
        panic("MCB chain corrupted");
#ifdef TSC
      StartTrace();
#endif
      return_user();
      break;

      /* Get Child-program Return Value                               */
    case 0x4d:
      r->AL = return_code;
      r->AH = return_mode;
      break;

      /* Dos Find First                                               */
    case 0x4e:
      {
        /* dta for this call is set on entry.  This     */
        /* needs to be changed for new versions.        */
        if ((rc = DosFindFirst((UCOUNT) r->CX, (BYTE FAR *) MK_FP(r->DS, r->DX))) < 0)
          goto error_exit;
        else
        {
          r->AX = 0;
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* Dos Find Next                                                */
    case 0x4f:
      {
        /* dta for this call is set on entry.  This     */
        /* needs to be changed for new versions.        */
        if ((rc = DosFindNext()) < 0)
        {
          r->AX = -rc;

          if (r->AX == 2)
            r->AX = 18;

          r->FLAGS |= FLG_CARRY;
        }
        else
        {
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* ************UNDOCUMENTED************************************* */
      /* Get List of Lists                                            */
    case 0x52:
      {
        BYTE FAR *p;

        p = (BYTE FAR *) & DPBp;
        r->ES = FP_SEG(p);
        r->BX = FP_OFF(p);
      }
      break;

      /* Get verify state                                             */
    case 0x54:
      r->AL = (verify_ena ? TRUE : FALSE);
      break;

      /* ************UNDOCUMENTED************************************* */
      /* Dos Create New Psp & set p_size                              */
    case 0x55:
      new_psp((psp FAR *) MK_FP(r->DX, 0), r->SI);
      break;

      /* Dos Rename                                                   */
    case 0x56:
      rc = dos_rename(
                       (BYTE FAR *) MK_FP(r->DS, r->DX),	/* OldName      */
                       (BYTE FAR *) MK_FP(r->ES, r->DI));	/* NewName      */
      if (rc < SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Get/Set File Date and Time                                   */
    case 0x57:
      switch (r->AL)
      {
        case 0x00:
          rc = DosGetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date FAR *) & r->DX,	/* FileDate             */
                            (time FAR *) & r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          else
            r->FLAGS &= ~FLG_CARRY;
          break;

        case 0x01:
          rc = DosSetFtime(
                            (COUNT) r->BX,	/* Handle               */
                            (date FAR *) & r->DX,	/* FileDate             */
                            (time FAR *) & r->CX);	/* FileTime             */
          if (rc < SUCCESS)
            goto error_exit;
          else
            r->FLAGS &= ~FLG_CARRY;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Get/Set Allocation Strategy                                  */
    case 0x58:
      switch (r->AL)
      {
        case 0x00:
          r->AX = mem_access_mode;
          break;

        case 0x01:
          if (((COUNT) r->BX) < 0 || r->BX > 2)
            goto error_invalid;
          else
          {
            mem_access_mode = r->BX;
            r->FLAGS &= ~FLG_CARRY;
          }
          break;

        default:
          goto error_invalid;
#ifdef DEBUG
        case 0xff:
          show_chain();
          break;
#endif
      }
      break;

      /* Create Temporary File */
    case 0x5a:
      if ((rc = DosMkTmp(MK_FP(r->DS, r->DX), r->CX)) < 0)
        goto error_exit;
      else
      {
        r->AX = rc;
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Create New File */
    case 0x5b:
      if ((rc = DosOpen(MK_FP(r->DS, r->DX), 0)) >= 0)
      {
        DosClose(rc);
        r->AX = 80;
        r->FLAGS |= FLG_CARRY;
      }
      else
      {
        if ((rc = DosCreat(MK_FP(r->DS, r->DX), r->CX)) < 0)
          goto error_exit;
        else
        {
          r->AX = rc;
          r->FLAGS &= ~FLG_CARRY;
        }
      }
      break;

      /* UNDOCUMENTED: server, share.exe and sda function             */
    case 0x5d:
      switch (r->AL)
      {
          /* Remote Server Call */
        case 0x00:
          {
            UWORD FAR *x = MK_FP(r->DS, r->DX);
            r->AX = x[0];
            r->BX = x[1];
            r->CX = x[2];
            r->DX = x[3];
            r->SI = x[4];
            r->DI = x[5];
            r->DS = x[6];
            r->ES = x[7];
          }
          goto dispatch;

        case 0x06:
          r->DS = FP_SEG(internal_data);
          r->SI = FP_OFF(internal_data);
          r->CX = swap_always - internal_data;
          r->DX = swap_indos - internal_data;
          r->FLAGS &= ~FLG_CARRY;
          break;

        case 0x07:
        case 0x08:
        case 0x09:
          int2f_Remote_call(REM_PRINTREDIR, 0, 0, r->DX, 0, 0, (MK_FP(0, Int21AX)));
          break;

        default:
          goto error_invalid;
      }
      break;

    case 0x5e:
      switch (r->AL)
      {
        case 0x00:
          r->CX = get_machine_name(MK_FP(r->DS, r->DX));
          break;

        case 0x01:
          set_machine_name(MK_FP(r->DS, r->DX), r->CX);
          break;

        default:
          int2f_Remote_call(REM_PRINTSET, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
          break;
      }
      break;

    case 0x5f:
      switch (r->AL)
      {
        case 0x07:
          CDSp->cds_table[r->DL].cdsFlags |= 0x100;
          break;

        case 0x08:
          CDSp->cds_table[r->DL].cdsFlags &= ~0x100;
          break;

        default:
          int2f_Remote_call(REM_DOREDIRECT, r->BX, r->CX, r->DX, (MK_FP(r->ES, r->DI)), r->SI, (MK_FP(r->DS, Int21AX)));
          break;
      }
      break;

    case 0x60:                 /* TRUENAME */
      if ((rc = truename(MK_FP(r->DS, r->SI),
                      adjust_far(MK_FP(r->ES, r->DI)), TRUE)) != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

#ifdef TSC
      /* UNDOCUMENTED: no-op                                          */
      /*                                                              */
      /* DOS-C: tsc support                                           */
    case 0x61:
#ifdef DEBUG
      switch (r->AL)
      {
        case 0x01:
          bTraceNext = TRUE;
          break;

        case 0x02:
          bDumpRegs = FALSE;
          break;
      }
#endif
      r->AL = 0x00;
      break;
#endif

      /* UNDOCUMENTED: return current psp                             */
    case 0x62:
      r->BX = cu_psp;
      break;

      /* UNDOCUMENTED: Double byte and korean tables                  */
    case 0x63:
      {
#ifdef DBLBYTE
        static char dbcsTable[2] =
        {
          0, 0
        };
        void FAR *dp = &dbcsTable;

        r->DS = FP_SEG(dp);
        r->SI = FP_OFF(dp);
        r->AL = 0;
#else
        /* not really supported, but will pass.                 */
        r->AL = 0x00;           /*jpp: according to interrupt list */
#endif
        break;
      }

      /* Extended country info                                        */
    case 0x65:
      if (r->AL <= 0x7)
      {
        if (ExtCtryInfo(
                         r->AL,
                         r->BX,
                         r->CX,
                         MK_FP(r->ES, r->DI)))
          r->FLAGS &= ~FLG_CARRY;
        else
          goto error_invalid;
      }
      else if ((r->AL >= 0x20) && (r->AL <= 0x22))
      {
        switch (r->AL)
        {
          case 0x20:
            r->DL = upChar(r->DL);
            goto okay;

          case 0x21:
            upMem(
                   MK_FP(r->DS, r->DX),
                   r->CX);
            goto okay;

          case 0x22:
            upString(MK_FP(r->DS, r->DX));
          okay:
            r->FLAGS &= ~FLG_CARRY;
            break;

          case 0x23:
            r->AX = yesNo(r->DL);
            goto okay;

          default:
            goto error_invalid;
        }
      }
      else
        r->FLAGS |= FLG_CARRY;
      break;

      /* Code Page functions */
    case 0x66:
      switch (r->AL)
      {
        case 1:
          GetGlblCodePage(
                           (UWORD FAR *) & (r->BX),
                           (UWORD FAR *) & (r->DX));
          goto okay_66;

        case 2:
          SetGlblCodePage(
                           (UWORD FAR *) & (r->BX),
                           (UWORD FAR *) & (r->DX));
        okay_66:
          r->FLAGS &= ~FLG_CARRY;
          break;

        default:
          goto error_invalid;
      }
      break;

      /* Set Max file handle count */
    case 0x67:
      if ((rc = SetJFTSize(r->BX)) != SUCCESS)
        goto error_exit;
      else
      {
        r->FLAGS &= ~FLG_CARRY;
      }
      break;

      /* Flush file buffer -- dummy function right now.  */
    case 0x68:
      r->FLAGS &= ~FLG_CARRY;
      break;
  }

#ifdef DEBUG
  if (bDumpRegs)
  {
    fbcopy((VOID FAR *) user_r, (VOID FAR *) & error_regs,
           sizeof(iregs));
    dump_regs = TRUE;
    dump();
  }
#endif
}
Exemplo n.º 23
0
//-----------------------------------------------------------------------------
//
// 命令コマンドを解釈してバイナリに変換
//
//-----------------------------------------------------------------------------
bool encode(char* instName, char* buffer, map<uint32_t, string>& labelNames, uint32_t currentLine, uint32_t& code, bool& useLabel)
{
	uint32_t rs = 0;
	uint32_t rt = 0;
	uint32_t rd = 0;
	uint32_t imm = 0;
	double d = 0;
	char label[MAX_LINE_SIZE];
	char dummy[MAX_LINE_SIZE];

	if (eq(instName, "add"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _add(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "sub"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _sub(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "mul"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _mul(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "and"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _and(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "or"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _or(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "nor"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _nor(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "xor"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _xor(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "addi"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _addi(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "subi"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _subi(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "muli"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _muli(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "slli"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _slli(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "srai"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _srai(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "andi"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _andi(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "ori"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _ori(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "nori"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _nori(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "xori"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _xori(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fadd"))
	{
		int n = sscanf(buffer, formFFF, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _fadd(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fsub"))
	{
		int n = sscanf(buffer, formFFF, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _fsub(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fmul"))
	{
		int n = sscanf(buffer, formFFF, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _fmul(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fmuln"))
	{
		int n = sscanf(buffer, formFFF, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _fmuln(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "finv"))
	{
		int n = sscanf(buffer, formFF, dummy, &rd, &rs);
		if (n == 3)
		{
			code = _finv(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fsqrt"))
	{
		int n = sscanf(buffer, formFF, dummy, &rd, &rs);
		if (n == 3)
		{
			code = _fsqrt(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fmov"))
	{
		int n = sscanf(buffer, formFF, dummy, &rd, &rs);
		if (n == 3)
		{
			code = _fmov(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fneg"))
	{
		int n = sscanf(buffer, formFF, dummy, &rd, &rs);
		if (n == 3)
		{
			code = _fneg(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "imovf"))
	{
		int n = sscanf(buffer, formFR, dummy, &rt, &rs);
		if (n == 3)
		{
			code = _imovf(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fmovi"))
	{
		int n = sscanf(buffer, formRF, dummy, &rt, &rs);
		if (n == 3)
		{
			code = _fmovi(rs, rt, rd);
			return true;
		}
	}
	// to use ALU
	if (eq(instName, "mvlo"))
	{
		int n = sscanf(buffer, formRI, dummy, &rt, &imm);
		if (n == 3)
		{
			code = _mvlo(rt, rt, imm);
			return true;
		}
	}
	if (eq(instName, "mvhi"))
	{
		int n = sscanf(buffer, formRI, dummy, &rt, &imm);
		if (n == 3)
		{
			code = _mvhi(rt, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fmvlo"))
	{
		int n = sscanf(buffer, formFI, dummy, &rt, &imm);
		if (n == 3)
		{
			code = _fmvlo(rt, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fmvhi"))
	{
		int n = sscanf(buffer, formFI, dummy, &rt, &imm);
		if (n == 3)
		{
			code = _fmvhi(rt, rt, imm);
			return true;
		}
	}
	if (eq(instName, "j"))
	{
		int n = sscanf(buffer, formL, dummy, label);
		if (n == 2)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _j(0);
			return true;
		}
	}
	if (eq(instName, "beq"))
	{
		int n = sscanf(buffer, formRRL, dummy, &rs, &rt, label);
		if (n == 4)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _beq(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "blt"))
	{
		int n = sscanf(buffer, formRRL, dummy, &rs, &rt, label);
		if (n == 4)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _blt(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "ble"))
	{
		int n = sscanf(buffer, formRRL, dummy, &rs, &rt, label);
		if (n == 4)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _ble(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fbeq"))
	{
		int n = sscanf(buffer, formFFL, dummy, &rs, &rt, label);
		if (n == 4)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _fbeq(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fblt"))
	{
		int n = sscanf(buffer, formFFL, dummy, &rs, &rt, label);
		if (n == 4)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _fblt(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fble"))
	{
		int n = sscanf(buffer, formFFL, dummy, &rs, &rt, label);
		if (n == 4)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _fble(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "jr"))
	{
		int n = sscanf(buffer, formR, dummy, &rs);
		if (n == 2)
		{
			code = _jr(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "call"))
	{
		int n = sscanf(buffer, formL, dummy, label);
		if (n == 2)
		{
			labelNames[currentLine] = string(label);
//			cerr << "assigned (" << currentLine << ", " << string(label) << ") in labelNames" << endl;
			useLabel = true;
			code = _call(0);
			return true;
		}
	}
	if (eq(instName, "callr"))
	{
		int n = sscanf(buffer, formR, dummy, &rs);
		if (n == 2)
		{
			code = _callr(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "return"))
	{
		int n = sscanf(buffer, form, dummy);
		if (n == 1)
		{
			code = _return(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "ldr"))
	{
		int n = sscanf(buffer, formRRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _ldr(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "fldr"))
	{
		int n = sscanf(buffer, formFRR, dummy, &rd, &rs, &rt);
		if (n == 4)
		{
			code = _fldr(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "sti"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _sti(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "ldi"))
	{
		int n = sscanf(buffer, formRRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _ldi(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fsti"))
	{
		int n = sscanf(buffer, formFRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _fsti(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "fldi"))
	{
		int n = sscanf(buffer, formFRI, dummy, &rt, &rs, &imm);
		if (n == 4)
		{
			code = _fldi(rs, rt, imm);
			return true;
		}
	}
	if (eq(instName, "inputb"))
	{
		int n = sscanf(buffer, formR, dummy, &rt);
		if (n == 2)
		{
			code = _inputb(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "outputb"))
	{
		int n = sscanf(buffer, formR, dummy, &rt);
		if (n == 2)
		{
			code = _outputb(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "halt"))
	{
		int n = sscanf(buffer, form, dummy);
		if (n == 1)
		{
			code = _halt(rs, rt, rd);
			return true;
		}
	}
	if (eq(instName, "dump"))
	{
		int n = sscanf(buffer, form, dummy);
		if (n == 1)
		{
			code = _dump(rs, rt, rd);
			return true;
		}
	}
	
	return false;
}
Exemplo n.º 24
0
/* private */
static void soundblaster_update_wav_dma_position(soundcard_t sc,struct sndsb_ctx *card) {
    _cli();
    sc->wav_state.dma_position = sndsb_read_dma_buffer_position(card);
    _sti();
}