Пример #1
0
//---------------------------------------------------------------------------
void UpdateCentronicsBusyBit()
{
  if ((stick[N_JOY_PARALLEL_1] & BIT_4)==0){
    if (ParallelPort.IsOpen()){
      if (psg_reg[PSGR_MIXER] & BIT_7){  // Output
        // If there are bytes being sent then input is high
        mfp_gpip_set_bit(MFP_GPIP_CENTRONICS_BIT,ParallelPort.AreBytesToOutput());
      }else{                             // Input
        // If there are bytes being received then input is high
        mfp_gpip_set_bit(MFP_GPIP_CENTRONICS_BIT,ParallelPort.AreBytesToRead());
      }
    }else{
      mfp_gpip_set_bit(MFP_GPIP_CENTRONICS_BIT,true); // Always busy if port closed
    }
  }
}
Пример #2
0
/*---------------------------------------------------------------------------*/
void dma_sound_set_control(BYTE io_src_b)
{
  if ((dma_sound_control & BIT_0) && (io_src_b & BIT_0)==0){  //Stopping
    dma_sound_start=next_dma_sound_start;
    dma_sound_end=next_dma_sound_end;
    dma_sound_fetch_address=dma_sound_start;
  }else if ((dma_sound_control & BIT_0)==0 && (io_src_b & BIT_0)){ //Start playing
    dma_sound_start=next_dma_sound_start;
    dma_sound_end=next_dma_sound_end;
    dma_sound_fetch_address=dma_sound_start;
    if (dma_sound_on_this_screen==0){
      // Pad buffer with last byte from VBL to current position
      bool Mono=bool(dma_sound_mode & BIT_7);
      int freq_idx=0;
      if (shifter_freq_at_start_of_vbl==60) freq_idx=1;
      if (shifter_freq_at_start_of_vbl==MONO_HZ) freq_idx=2;
      WORD w1,w2;
      dma_sound_get_last_sample(&w1,&w2);
      for (int y=-scanlines_above_screen[freq_idx];y<scan_y;y++){
        if (Mono){  //play half as many words
          dma_sound_samples_countdown+=dma_sound_freq*scanline_time_in_cpu_cycles_at_start_of_vbl/2;
        }else{ //stereo, 1 word per sample
          dma_sound_samples_countdown+=dma_sound_freq*scanline_time_in_cpu_cycles_at_start_of_vbl;
        }
        int loop=int(Mono ? 2:1);
        while (dma_sound_samples_countdown>=0){
          for (int i=0;i<loop;i++){
            dma_sound_output_countdown+=sound_freq;
            while (dma_sound_output_countdown>=0){
              if (dma_sound_channel_buf_last_write_t>=DMA_SOUND_BUFFER_LENGTH) break;
              dma_sound_channel_buf[dma_sound_channel_buf_last_write_t++]=w1;
              dma_sound_channel_buf[dma_sound_channel_buf_last_write_t++]=w2;
              dma_sound_output_countdown-=dma_sound_freq;
            }
          }
          dma_sound_samples_countdown-=n_cpu_cycles_per_second;
        }
      }
      dma_sound_on_this_screen=1;
    }
  }
  log_to(LOGSECTION_SOUND,EasyStr("SOUND: ")+HEXSl(old_pc,6)+" - DMA sound control set to "+(io_src_b & 3)+" from "+(dma_sound_control & 3));
  dma_sound_control=io_src_b;
  if (tos_version>=0x106) mfp_gpip_set_bit(MFP_GPIP_MONO_BIT,bool(COLOUR_MONITOR)^bool(dma_sound_control & BIT_0));
}
Пример #3
0
//---------------------------------------------------------------------------
// MIDI Port
//---------------------------------------------------------------------------
void agenda_midi_replace(int)
{
  if (MIDIPort.AreBytesToCome()){
    MIDIPort.NextByte();

    if (ACIA_MIDI.rx_not_read){
      // discard data and set overrun
      log_to_section(LOGSECTION_MIDI,"MIDI: Overrun on ACIA! Byte lost!");
      if (ACIA_MIDI.overrun!=ACIA_OVERRUN_YES) ACIA_MIDI.overrun=ACIA_OVERRUN_COMING;
    }else{
      ACIA_MIDI.data=MIDIPort.ReadByte();
      ACIA_MIDI.rx_not_read=true;
    }
    log_to_section(LOGSECTION_MIDI,EasyStr("MIDI: Fire ACIA interrupt"));
    if (ACIA_MIDI.rx_irq_enabled) ACIA_MIDI.irq=true;
    mfp_gpip_set_bit(MFP_GPIP_ACIA_BIT,!(ACIA_IKBD.irq || ACIA_MIDI.irq));

    if (MIDIPort.AreBytesToCome()) agenda_add(agenda_midi_replace,ACIAClockToHBLS(ACIA_MIDI.clock_divide,true),0);
  }
}
Пример #4
0
//---------------------------------------------------------------------------
BYTE ASMCALL io_read_b(MEM_ADDRESS addr)
{
/*
  Allowed addresses

  000000 - 3FFFFF   RAM

  D00000 - D7FFFF
  E00000 - E3FFFF   TOS
  E40000 - EBFFFF

  FA0000 - FBFFFF   Cart

  FE0000 - FE1FFF

  FF8000 - FF800F   MMU
  FF8200 - FF820F   SHIFTER
  FF8240 - FF827F   pallette, res
  FF8608 - FF860F   FDC
  FF8800 - FF88FF   sound chip
  FF8900 - FF893F   DMA sound, microwire
  FF8A00 - FF8A3F   blitter
  FF9000 - FF9001   
  FF9201, FF9202, FF9203           paddles
  FF9211, FF9213, FF9215, FF9217   paddles
  FFFA01, odd addresses up to FFFA3F   MFP
  FFFC00 - FFFDFF   ACIA, realtime clock

  Word differences:

  FF8604 - FF860F   FDC
  FF9200, FF9202                   paddles
  FF9210, FF9212, FF9214, FF9216   paddles
  FF9220, FF9222                   paddles
  FFFA00 - FFFA3F   MFP
*/

  DEBUG_CHECK_READ_IO_B(addr);

#ifdef ONEGAME
  if (addr>=OG_TEXT_ADDRESS && addr<OG_TEXT_ADDRESS+OG_TEXT_LEN){
    return BYTE(OG_TextMem[addr-OG_TEXT_ADDRESS]);
  }
#endif
  switch (addr & 0xffff00){  //fffe00
    case 0xfffc00:      //----------------------------------- ACIAs
    {
      // Only cause bus jam once per word
      DEBUG_ONLY( if (mode==STEM_MODE_CPU) )
      {
        if (io_word_access==0 || (addr & 1)==0){
//          if (passed VBL or HBL point){
//            BUS_JAM_TIME(4);
//          }else{
          // Jorge Cwik:
          // Access to the ACIA is synchronized to the E signal. Which is a clock with
          // one tenth the frequency of the main CPU clock (800 Khz). So the timing
          // should depend on the phase relationship between both clocks.

          int rel_cycle=ABSOLUTE_CPU_TIME-shifter_cycle_base;
          rel_cycle=8000000-rel_cycle;
          rel_cycle%=10;
          BUS_JAM_TIME(rel_cycle+6);
//          BUS_JAM_TIME(8);
        }
      }

      switch (addr){
/******************** Keyboard ACIA ************************/

      case 0xfffc00:  //status
      {
        BYTE x=0;
        if (ACIA_IKBD.rx_not_read || ACIA_IKBD.overrun==ACIA_OVERRUN_YES) x|=BIT_0; //full bit
        if (ACIA_IKBD.tx_flag==0) x|=BIT_1; //empty bit
//        if (acia[ACIA_IKBD].rx_not_read && acia[ACIA_IKBD].rx_irq_enabled) x|=BIT_7; //irq bit
        if (ACIA_IKBD.irq) x|=BIT_7; //irq bit
        if (ACIA_IKBD.overrun==ACIA_OVERRUN_YES) x|=BIT_5; //overrun
        return x;
      }
      case 0xfffc02:  //data
      {
        DEBUG_ONLY( if (mode!=STEM_MODE_CPU) return ACIA_IKBD.data; )
//        if (acia[ACIA_IKBD].rx_not_read) keyboard_buffer_length--;
        ACIA_IKBD.rx_not_read=0;
        LOG_ONLY( bool old_irq=ACIA_IKBD.irq; )
        if (ACIA_IKBD.overrun==ACIA_OVERRUN_COMING){
          ACIA_IKBD.overrun=ACIA_OVERRUN_YES;
          if (ACIA_IKBD.rx_irq_enabled) ACIA_IKBD.irq=true;
          LOG_ONLY( log_to_section(LOGSECTION_IKBD,EasyStr("IKBD: ")+HEXSl(old_pc,6)+
                              " - OVERRUN! Read data ($"+HEXSl(ACIA_IKBD.data,2)+
                              "), changing ACIA IRQ bit from "+old_irq+" to "+ACIA_IKBD.irq); )
        }else{
          ACIA_IKBD.overrun=ACIA_OVERRUN_NO;
          // IRQ should be off for receive, but could be set for tx empty interrupt
          ACIA_IKBD.irq=(ACIA_IKBD.tx_irq_enabled && ACIA_IKBD.tx_flag==0);
          LOG_ONLY( if (ACIA_IKBD.irq!=old_irq) log_to_section(LOGSECTION_IKBD,Str("IKBD: ")+
                            HEXSl(old_pc,6)+" - Read data ($"+HEXSl(ACIA_IKBD.data,2)+
                            "), changing ACIA IRQ bit from "+old_irq+" to "+ACIA_IKBD.irq); )
        }
        mfp_gpip_set_bit(MFP_GPIP_ACIA_BIT,!(ACIA_IKBD.irq || ACIA_MIDI.irq));
        return ACIA_IKBD.data;
      }