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() */ }
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; } } } }