Example #1
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));
}
Example #2
0
//---------------------------------------------------------------------------
void dma_sound_set_mode(BYTE new_mode)
{
  dma_sound_mode=new_mode;
  dma_sound_freq=dma_sound_mode_to_freq[dma_sound_mode & 3];
  log_to(LOGSECTION_SOUND,EasyStr("SOUND: ")+HEXSl(old_pc,6)+" - DMA sound mode set to $"+HEXSl(dma_sound_mode,2)+" freq="+dma_sound_freq);
}
Example #3
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;
      }