static uint8_t ieee_talk_handler (void) { buffer_t *buf; uint8_t finalbyte; uint8_t c; uint8_t res; buf = find_buffer(ieee_data.secondary_address); if(buf == NULL) return -1; while (buf->read) { do { finalbyte = (buf->position == buf->lastused); c = buf->data[buf->position]; if (finalbyte && buf->sendeoi) { /* Send with EOI */ res = ieee_putc(c, 1); if(!res) uart_puts_p("EOI: "); } else { /* Send without EOI */ res = ieee_putc(c, 0); } if(res) { if(res==0xfc) { uart_puts_P(PSTR("*** TIMEOUT ABORT***")); uart_putcrlf(); } if(res!=0xfd) { uart_putc('c'); uart_puthex(res); } return 1; } else { uart_putc('>'); uart_puthex(c); uart_putc(' '); if(isprint(c)) uart_putc(c); else uart_putc('?'); uart_putcrlf(); } } while (buf->position++ < buf->lastused); if(buf->sendeoi && ieee_data.secondary_address != 0x0f && !buf->recordlen && buf->refill != directbuffer_refill) { buf->read = 0; break; } if (buf->refill(buf)) { return -1; } /* Search the buffer again, it can change when using large buffers */ buf = find_buffer(ieee_data.secondary_address); } return 0; }
void pcf8583_init(void) { uint8_t tmp[4]; rtc_state = RTC_NOT_FOUND; uart_puts_P(PSTR("RTC ")); if (i2c_write_register(PCF8583_ADDR, REG_CONTROL, CTL_START_CLOCK) || i2c_read_registers(PCF8583_ADDR, REG_YEAR1, 4, tmp)) { uart_puts_P(PSTR("not found")); } else { if (tmp[0] == (tmp[2] ^ 0xff) && tmp[1] == (tmp[3] ^ 0xff)) { rtc_state = RTC_OK; uart_puts_P(PSTR("ok")); /* Dummy RTC read to update the year if required */ struct tm time; read_rtc(&time); } else { rtc_state = RTC_INVALID; uart_puts_P(PSTR("invalid")); } } uart_putcrlf(); }
/* DS1307 version, checks clock halt bit in seconds register */ void dsrtc_init(void) { int16_t tmp; rtc_state = RTC_NOT_FOUND; uart_puts_P(PSTR("DS1307 ")); tmp = i2c_read_register(RTC_ADDR, REG_SECOND); if (tmp < 0) { uart_puts_P(PSTR("not found")); } else { if (tmp & STATUS_OSF) { rtc_state = RTC_INVALID; uart_puts_P(PSTR("invalid")); } else { rtc_state = RTC_OK; uart_puts_P(PSTR("ok")); } } uart_putcrlf(); }
uint16_t mos6502_dis(uint16_t start, uint16_t stop) { const mos6502_instruction_t* pi; int len; base = start; while (base <= stop) { /* print address */ uart_putc('$'); uart_puthex_padded(4, base); uart_putc(' '); /* Get opcode and it's properties */ opcode = mos6502_read_mem(base++); pi = inst_map + opcode; cmd = mnemonics[pi->mnemonic_idx]; len = addr_mode_length[pi->addr_mode_idx]; /* Print opcode hexdump */ switch (len) { case 1: single_byte_opcode(); break; case 2: two_bytes_opcode(); break; default: three_bytes_opcode(); } /* Print opcode disassembly */ addr_mode_fn[pi->addr_mode_idx](); uart_putcrlf(); } return base; }
void uart_trace(void *ptr, uint16_t start, uint16_t len) { uint16_t i; uint8_t j; uint8_t ch; uint8_t *data = ptr; data+=start; for(i=0;i<len;i+=16) { uart_puthex(start>>8); uart_puthex(start&0xff); uart_putc('|'); uart_putc(' '); for(j=0;j<16;j++) { if(i+j<len) { ch=*(data + j); uart_puthex(ch); } else { uart_putc(' '); uart_putc(' '); } uart_putc(' '); } uart_putc('|'); for(j=0;j<16;j++) { if(i+j<len) { ch=*(data++); if(ch<32 || ch>0x7e) ch='.'; uart_putc(ch); } else { uart_putc(' '); } } uart_putc('|'); uart_putcrlf(); start+=16; } }
/******************************************************************************* * Do it. * ******************************************************************************/ int main() { clock_init(); uart_init(); uart_puts("\r\nInitializing...\r\n"); timer_init(); io_init(); uart_puts("Starting drive...\r\n"); c1541_init(); cli_init(); for (;;) { #ifdef CONFIG_GDBSIM uart_putdec(demon_clock()); uart_putcrlf(); #endif cli_check(); } return 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() */ }
static int16_t ieee_listen_handler (uint8_t cmd) /* Receive characters from IEEE-bus and write them to the listen buffer adressed by ieee_data.secondary_address. If a new command is received (ATN set), return it */ { buffer_t *buf; int16_t c; ieee_data.secondary_address = cmd & 0x0f; buf = find_buffer(ieee_data.secondary_address); /* Abort if there is no buffer or it's not open for writing */ /* and it isn't an OPEN command */ if ((buf == NULL || !buf->write) && (cmd & 0xf0) != 0xf0) { uart_putc('c'); return -1; } switch(cmd & 0xf0) { case 0x60: uart_puts_p("DATA L "); break; case 0xf0: uart_puts_p("OPEN "); break; default: uart_puts_p("Unknown LH! "); break; } uart_puthex(ieee_data.secondary_address); uart_putcrlf(); c = -1; for(;;) { /* Get a character ignoring timeout but but watching ATN */ while((c = ieee_getc()) < 0); if (c & FLAG_ATN) return c; uart_putc('<'); if (c & FLAG_EOI) { uart_puts_p("EOI "); ieee_data.ieeeflags |= EOI_RECVD; } else ieee_data.ieeeflags &= ~EOI_RECVD; uart_puthex(c); uart_putc(' '); c &= 0xff; /* needed for isprint */ if(isprint(c)) uart_putc(c); else uart_putc('?'); uart_putcrlf(); if((cmd & 0x0f) == 0x0f || (cmd & 0xf0) == 0xf0) { if (command_length < CONFIG_COMMAND_BUFFER_SIZE) command_buffer[command_length++] = c; if (ieee_data.ieeeflags & EOI_RECVD) /* Filenames are just a special type of command =) */ ieee_data.ieeeflags |= COMMAND_RECVD; } else { /* Flush buffer if full */ if (buf->mustflush) { if (buf->refill(buf)) return -2; /* Search the buffer again, */ /* it can change when using large buffers */ buf = find_buffer(ieee_data.secondary_address); } buf->data[buf->position] = c; mark_buffer_dirty(buf); if (buf->lastused < buf->position) buf->lastused = buf->position; buf->position++; /* Mark buffer for flushing if position wrapped */ if (buf->position == 0) buf->mustflush = 1; /* REL files must be syncronized on EOI */ if(buf->recordlen && (ieee_data.ieeeflags & EOI_RECVD)) { if (buf->refill(buf)) return -2; } } /* else-buffer */ } /* for(;;) */ }
void menu_browse_files(void) { buffer_t *buf; buffer_t *buf_tbl; buffer_t *buf_cur; buffer_t *first_buf; path_t path; cbmdirent_t dent; uint16_t entries; uint8_t entry_num; bool fat_filesystem; uint8_t i; uint8_t my; uint16_t mp; bool action; uint16_t stack_mp[MAX_LASTPOS]; uint8_t stack_my[MAX_LASTPOS]; uint8_t pos_stack; uint8_t save_active_buffers; pos_stack = 0; memset(stack_mp, 0, sizeof(stack_mp)); memset(stack_my, 0, sizeof(stack_my)); save_active_buffers = active_buffers; start: lcd_clear(); lcd_puts_P(PSTR("Reading...")); buf = buf_tbl = buf_cur = first_buf = NULL; entries = entry_num = mp = 0; fat_filesystem = false; // Allocate one buffer, used to read a single directory entry if ((buf = alloc_system_buffer()) == NULL) return; // Allocate buffers with continuous data segments // Stores pointers to directory entries for qsort if ((buf_tbl = alloc_linked_buffers(CONFIG_DIR_BUFFERS)) == NULL) return; // Buffers to store the actual diretory entries. // Whilst the directory grows, new buffers get allocated and linked if ((buf_cur = alloc_system_buffer()) == NULL) return; first_buf = buf_cur; // Allocating buffers affects the LEDs set_busy_led(false); set_dirty_led(true); path.part = current_part; path.dir = partition[path.part].current_dir; uart_trace(&path.dir, 0, sizeof(dir_t)); uart_putcrlf(); uart_flush(); if (opendir(&buf->pvt.dir.dh, &path)) return; for (;;) { if (next_match(&buf->pvt.dir.dh, buf->pvt.dir.matchstr, buf->pvt.dir.match_start, buf->pvt.dir.match_end, buf->pvt.dir.filetype, &dent) == 0) { uint8_t e_flags = 0; if (dent.opstype == OPSTYPE_FAT) { fat_filesystem = true; if (check_imageext(dent.pvt.fat.realname) != IMG_UNKNOWN) e_flags |= E_IMAGE; } // Current block full? if (entry_num == ENTRIES_PER_BLOCK) { entry_num = 0; buffer_t *old_buf = buf_cur; if ((buf_cur = alloc_system_buffer()) == NULL) { printf("alloc buf_cur failed, %d entries", entries); goto cleanup; } set_busy_led(false); set_dirty_led(true); buf_cur->pvt.buffer.next = NULL; old_buf->pvt.buffer.next = buf_cur; } // Store entry ep[entries] = (entry_t *) (buf_cur->data + entry_num * sizeof(entry_t)); ustrncpy(ep[entries]->filename, dent.name, 16); ep[entries]->filesize = dent.blocksize; if ((dent.typeflags & EXT_TYPE_MASK) == TYPE_DIR) e_flags |= E_DIR; ep[entries]->flags = e_flags; entries++; entry_num++; } else { // No more directory entries to read break; } } printf("%d entries\r\n", entries); if (fat_filesystem) qsort(ep, entries, sizeof(entry_t*), compare); for (uint16_t i = 0; i < entries; i++) { printf("%3u: ", i); if (ep[i]->flags & E_DIR) uart_puts_P(PSTR(" DIR ")); else if (ep[i]->flags & E_IMAGE) uart_puts_P(PSTR(" IMG ")); else printf("%4u ", ep[i]->filesize); uint8_t filename[16 + 1]; ustrncpy(filename, ep[i]->filename, 16); filename[16] = '\0'; pet2asc(filename); printf("%s\r\n", filename); uart_flush(); } uart_putcrlf(); #define DIRNAV_OFFSET 2 #define NAV_ABORT 0 #define NAV_PARENT 1 mp = stack_mp[pos_stack]; my = stack_my[pos_stack]; printf("mp set to %d\r\n", mp); if (mp < (LCD_LINES - 1)) my = mp; else my = 0; action = false; for (i=0; i < MAX_LASTPOS; i++) { if (pos_stack == i) uart_putc('>'); printf("%d ", stack_mp[i]); } uart_putcrlf(); for (;;) { lcd_clear(); for (i = 0; i < LCD_LINES; i++) { lcd_locate(0, i); int8_t y = mp - my + i; if (y < 0) return; // should not happen! if (y < DIRNAV_OFFSET) { rom_menu_browse(y); } else { y -= DIRNAV_OFFSET; if (y >= entries) { lcd_puts_P(PSTR("-- End of dir --")); break; } else { lcd_print_dir_entry(y); } } } lcd_cursor(true); for (;;) { lcd_locate(0, my); //printf("mp: %u my: %u\r\n", mp, my); //while (!get_key_state(KEY_ANY)); if (get_key_autorepeat(KEY_PREV)) { if (mp > 0) { --mp; if (my > 0) --my; else { my = LCD_LINES - 1; if (mp < LCD_LINES) { while ((mp - my) >= DIRNAV_OFFSET) { --my; // TODO: is this really necessary? uart_puts_P(PSTR("my fixed\r\n")); } } break; } } else { my = LCD_LINES - 2; mp = entries + DIRNAV_OFFSET - 1; break; } } if (get_key_autorepeat(KEY_NEXT)) { if (mp < (entries -1 + DIRNAV_OFFSET)) { ++mp; if (my < (LCD_LINES - 1)) ++my; else { my = 0; break; } } else { mp = 0; my = 0; break; } } if (get_key_press(KEY_SEL)) { action = true; break; } } lcd_cursor(false); if (!action) continue; if (mp == NAV_ABORT) goto cleanup; if (mp == NAV_PARENT) { uart_puts_P(PSTR("CD_\r\n")); ustrcpy_P(command_buffer, PSTR("CD_")); command_length = 3; parse_doscommand(); clear_command_buffer(); stack_mp[pos_stack] = 0; stack_my[pos_stack] = 0; if (pos_stack > 0) --pos_stack; printf("pos_stack set to %d\r\n", pos_stack); if (current_error != ERROR_OK) goto cleanup; goto reread; } if (ep[mp - DIRNAV_OFFSET]->flags & E_DIR || ep[mp - DIRNAV_OFFSET]->flags & E_IMAGE) { clear_command_buffer(); ustrcpy_P(command_buffer, PSTR("CD:")); ustrncpy(command_buffer + 3, ep[mp - DIRNAV_OFFSET]->filename, 16); command_length = ustrlen(command_buffer); parse_doscommand(); clear_command_buffer(); if (current_error != ERROR_OK) goto cleanup; if (pos_stack < MAX_LASTPOS) { stack_mp[pos_stack] = mp; stack_my[pos_stack++] = my; printf("pos_stack set to %d\r\n", pos_stack); } goto reread; } } reread: free_buffer(buf); buffer_t *p = buf_tbl; do { p->allocated = 0; p = p->pvt.buffer.next; } while (p != NULL); p = first_buf; if (p != NULL) do { p->allocated = 0; p = p->pvt.buffer.next; } while (p != NULL); set_busy_led(false); set_dirty_led(true); active_buffers = save_active_buffers; if (mp == NAV_ABORT) return; goto start; cleanup: mp = NAV_ABORT; goto reread; }
int main(void) { /* Early system initialisation */ board_init(); system_init_early(); leds_init(); set_busy_led(1); set_dirty_led(0); /* Due to an erratum in the LPC17xx chips anything that may change */ /* peripheral clock scalers must come before system_init_late() */ uart_init(); #ifndef SPI_LATE_INIT spi_init(SPI_SPEED_SLOW); #endif timer_init(); bus_interface_init(); i2c_init(); /* Second part of system initialisation, switches to full speed on ARM */ system_init_late(); enable_interrupts(); /* Internal-only initialisation, called here because it's faster */ buffers_init(); buttons_init(); /* Anything that does something which needs the system clock */ /* should be placed after system_init_late() */ bus_init(); // needs delay rtc_init(); // accesses I2C disk_init(); // accesses card read_configuration(); fatops_init(0); change_init(); uart_puts_P(PSTR("\r\nsd2iec " VERSION " #")); uart_puthex(device_address); uart_putcrlf(); #ifdef CONFIG_REMOTE_DISPLAY /* at this point all buffers should be free, */ /* so just use the data area of the first to build the string */ uint8_t *strbuf = buffers[0].data; ustrcpy_P(strbuf, versionstr); ustrcpy_P(strbuf+ustrlen(strbuf), longverstr); if (display_init(ustrlen(strbuf), strbuf)) { display_address(device_address); display_current_part(0); } #endif set_busy_led(0); #if defined(HAVE_SD) && BUTTON_PREV != 0 /* card switch diagnostic aid - hold down PREV button to use */ if (!(buttons_read() & BUTTON_PREV)) { while (buttons_read() & BUTTON_NEXT) { set_dirty_led(sdcard_detect()); # ifndef SINGLE_LED set_busy_led(sdcard_wp()); # endif } reset_key(0xff); } #endif bus_mainloop(); while (1); }