Exemplo n.º 1
0
void ieee_mainloop(void) {
  int16_t cmd = 0;

  set_error(ERROR_DOSVERSION);

  ieee_data.bus_state = BUS_IDLE;
  ieee_data.device_state = DEVICE_IDLE;
  for(;;) {
    switch(ieee_data.bus_state) {
      case BUS_SLEEP:                               /* BUS_SLEEP */
        set_atn_irq(0);
        ieee_bus_idle();
        set_error(ERROR_OK);
        set_busy_led(0);
        uart_puts_P(PSTR("ieee.c/sleep ")); set_dirty_led(1);

        /* Wait until the sleep key is used again */
        while (!key_pressed(KEY_SLEEP))
          system_sleep();
        reset_key(KEY_SLEEP);

        set_atn_irq(1);
        update_leds();

        ieee_data.bus_state = BUS_IDLE;
        break;

      case BUS_IDLE:                                /* BUS_IDLE */
        ieee_bus_idle();
        while(IEEE_ATN) {   ;               /* wait for ATN */
          if (key_pressed(KEY_NEXT | KEY_PREV | KEY_HOME)) {
            change_disk();
          } else if (key_pressed(KEY_SLEEP)) {
            reset_key(KEY_SLEEP);
            ieee_data.bus_state = BUS_SLEEP;
            break;
          } else if (display_found && key_pressed(KEY_DISPLAY)) {
            display_service();
            reset_key(KEY_DISPLAY);
          }
          system_sleep();
      }

      if (ieee_data.bus_state != BUS_SLEEP)
        ieee_data.bus_state = BUS_FOUNDATN;
      break;

      case BUS_FOUNDATN:                            /* BUS_FOUNDATN */
        ieee_data.bus_state = BUS_ATNPROCESS;
        cmd = ieee_getc();
      break;

      case BUS_ATNPROCESS:                          /* BUS_ATNPROCESS */
        if(cmd < 0) {
          uart_putc('c');
          ieee_data.bus_state = BUS_IDLE;
          break;
        } else cmd &= 0xFF;
        uart_puts_p("ATN "); uart_puthex(cmd);
        uart_putcrlf();

        if (cmd == 0x3f) {                                  /* UNLISTEN */
          if(ieee_data.device_state == DEVICE_LISTEN) {
            ieee_data.device_state = DEVICE_IDLE;
            uart_puts_p("UNLISTEN\r\n");
          }
          ieee_data.bus_state = BUS_IDLE;
          break;
        } else if (cmd == 0x5f) {                           /* UNTALK */
          if(ieee_data.device_state == DEVICE_TALK) {
            ieee_data.device_state = DEVICE_IDLE;
            uart_puts_p("UNTALK\r\n");
          }
          ieee_data.bus_state = BUS_IDLE;
          break;
        } else if (cmd == (0x40 + device_address)) {        /* TALK */
          uart_puts_p("TALK ");
          uart_puthex(device_address); uart_putcrlf();
          ieee_data.device_state = DEVICE_TALK;
          /* disk drives never talk immediatly after TALK, so stay idle
             and wait for a secondary address given by 0x60-0x6f DATA */
          ieee_data.bus_state = BUS_IDLE;
          break;
        } else if (cmd == (0x20 + device_address)) {        /* LISTEN */
          ieee_data.device_state = DEVICE_LISTEN;
          uart_puts_p("LISTEN ");
          uart_puthex(device_address); uart_putcrlf();
          ieee_data.bus_state = BUS_IDLE;
          break;
        } else if ((cmd & 0xf0) == 0x60) {                  /* DATA */
          /* 8250LP sends data while ATN is still active, so wait
             for bus controller to release ATN or we will misinterpret
             data as a command */
          while(!IEEE_ATN);
          if(ieee_data.device_state == DEVICE_LISTEN) {
            cmd = ieee_listen_handler(cmd);
            cmd_handler();
            break;
          } else if (ieee_data.device_state == DEVICE_TALK) {
            ieee_data.secondary_address = cmd & 0x0f;
            uart_puts_p("DATA T ");
            uart_puthex(ieee_data.secondary_address);
            uart_putcrlf();
            if(ieee_talk_handler() == TIMEOUT_ABORT) {
              ieee_data.device_state = DEVICE_IDLE;
            }
            ieee_data.bus_state = BUS_IDLE;
            break;
          } else {
            ieee_data.bus_state = BUS_IDLE;
            break;
          }
        } else if (ieee_data.device_state == DEVICE_IDLE) {
          ieee_data.bus_state = BUS_IDLE;
          break;
          /* ----- if we reach this, we're LISTENer or TALKer ----- */
        } else if ((cmd & 0xf0) == 0xe0) {                  /* CLOSE */
          ieee_data.secondary_address = cmd & 0x0f;
          uart_puts_p("CLOSE ");
          uart_puthex(ieee_data.secondary_address);
          uart_putcrlf();
          /* Close all buffers if sec. 15 is closed */
          if(ieee_data.secondary_address == 15) {
            free_multiple_buffers(FMB_USER_CLEAN);
          } else {
            /* Close a single buffer */
            buffer_t *buf;
            buf = find_buffer (ieee_data.secondary_address);
            if (buf != NULL) {
              buf->cleanup(buf);
              free_buffer(buf);
            }
          }
          ieee_data.bus_state = BUS_IDLE;
          break;
        } else if ((cmd & 0xf0) == 0xf0) {                  /* OPEN */
          cmd = ieee_listen_handler(cmd);
          cmd_handler();
          break;
        } else {
          /* Command for other device or unknown command */
          ieee_data.bus_state = BUS_IDLE;
        }
      break;
    }   /* switch   */
  }     /* for()    */
}
Exemplo n.º 2
0
void load_gijoe(UNUSED_PARAMETER) {
  buffer_t *buf;

  set_data(1);
  set_clock(1);
  set_atn_irq(0);

  /* Wait until the bus has settled */
  delay_ms(10);
  while (!IEC_DATA || !IEC_CLOCK) ;

  while (1) {
    /* Handshake */
    set_clock(0);

    while (IEC_DATA)
      if (check_keys())
        return;

    set_clock(1);
    uart_flush();

    /* First byte is ignored */
    if (gijoe_read_byte() < 0)
      return;

    /* Read two file name characters */
    command_buffer[0] = gijoe_read_byte();
    command_buffer[1] = gijoe_read_byte();

    set_clock(0);

    command_buffer[2] = '*';
    command_buffer[3] = 0;
    command_length = 3;

    /* Open the file */
    file_open(0);
    uart_flush();
    buf = find_buffer(0);
    if (!buf) {
      set_clock(1);
      gijoe_send_byte(0xfe);
      gijoe_send_byte(0xfe);
      gijoe_send_byte(0xac);
      gijoe_send_byte(0xf7);
      continue;
    }

    /* file is open, transfer */
    while (1) {
      uint8_t i = buf->position;

      set_clock(1);
      delay_us(2);

      do {
        if (buf->data[i] == 0xac)
          gijoe_send_byte(0xac);

        gijoe_send_byte(buf->data[i]);
      } while (i++ < buf->lastused);

      /* Send end marker and wait for the next name */
      if (buf->sendeoi) {
        gijoe_send_byte(0xac);
        gijoe_send_byte(0xff);

        cleanup_and_free_buffer(buf);
        break;
      }

      /* Send "another sector following" marker */
      gijoe_send_byte(0xac);
      gijoe_send_byte(0xc3);
      delay_us(50);
      set_clock(0);

      /* Read next block */
      if (buf->refill(buf)) {
        /* Send error marker */
        gijoe_send_byte(0xfe);
        gijoe_send_byte(0xfe);
        gijoe_send_byte(0xac);
        gijoe_send_byte(0xf7);

        cleanup_and_free_buffer(buf);
        break;
      }
    }
  }
}