char *clipboard_read_screen_output(const char *line_ending) { char * outputbuffer = NULL; do { uint16_t base; uint8_t allrows, allcols; unsigned int row, col; unsigned int size; unsigned int line_ending_length = (unsigned int)strlen(line_ending); unsigned int i; int bank; char * p; mem_get_screen_parameter(&base, &allrows, &allcols, &bank); size = allrows * (allcols + line_ending_length) + 1; outputbuffer = lib_malloc(size); if (outputbuffer == NULL) { break; } p = outputbuffer; for (row = 0; row < allrows; row++) { char * last_non_whitespace = p - 1; for (col = 0; col < allcols; col++) { uint8_t data; data = mem_bank_peek(bank, base++, NULL); data = charset_p_toascii(charset_screencode_to_petcii(data), 1); if (data != ' ') { last_non_whitespace = p; } *p++ = data; } /* trim the line if there are only whitespace at the end */ if (last_non_whitespace < p) { p = last_non_whitespace + 1; } /* add a line-ending */ for (i = 0; i < line_ending_length; i++) { *p++ = line_ending[i]; } } *p = 0; assert(p < outputbuffer + size); } while (0); return outputbuffer; }
void mon_memory_display(int radix_type, MON_ADDR start_addr, MON_ADDR end_addr, mon_display_format_t format) { unsigned int i, cnt = 0, len, max_width, real_width; WORD addr = 0; char printables[50]; char prefix; MEMSPACE mem; WORD display_number; BYTE v; prefix = (format == DF_PETSCII) ? '>' : '*'; if (radix_type) { if (radix_type != e_hexadecimal && radix_type != e_decimal && radix_type != e_octal) { max_width = (console_log->console_xres - 12) / (radix_chars_per_byte[radix_type] + 2); } else { max_width = (4 * (console_log->console_xres - 12)) / (4 * (radix_chars_per_byte[radix_type] + 2) + 1); } max_width &= ~3; display_number = max_width * ((console_log->console_yres - 6) / 2); } else { max_width = 40; display_number = 128; } len = mon_evaluate_address_range(&start_addr, &end_addr, FALSE, display_number); mem = addr_memspace(start_addr); addr = addr_location(start_addr); while (cnt < len) { mon_out("%c%s:%04x ", prefix, mon_memspace_string[mem], addr); for (i = 0, real_width = 0; i < max_width; i++) { v = mon_get_mem_val(mem, (WORD)ADDR_LIMIT(addr + i)); switch (radix_type) { case 0: /* special case == petscii text */ if (format == DF_PETSCII) { mon_out("%c", charset_p_toascii(v, 1)); } else { mon_out("%c", charset_p_toascii( charset_screencode_to_petcii(v), 1)); } real_width++; cnt++; break; case e_decimal: memset(printables, 0, 50); if (!(cnt % 4)) { mon_out(" "); } if (cnt < len) { mon_out("%03d ", v); real_width++; cnt++; } else { mon_out(" "); } break; case e_hexadecimal: memset(printables, 0, 50); if (!(cnt % 4)) { mon_out(" "); } if (cnt < len) { mon_out("%02x ", v); real_width++; } else { mon_out(" "); } cnt++; break; case e_octal: memset(printables, 0, 50); if (!(cnt % 4)) { mon_out(" "); } if (cnt < len) { mon_out("%03o ", v); real_width++; cnt++; } else { mon_out(" "); } break; case e_binary: memset(printables, 0, 50); if (cnt < len) { mon_print_bin(v, '1', '0'); mon_out(" "); real_width++; cnt++; } else { mon_out(" "); } break; default: return; } } if (radix_type != 0) { memory_to_string(printables, mem, addr, real_width, FALSE); mon_out(" %s", printables); } mon_out("\n"); addr = ADDR_LIMIT(addr + real_width); if (mon_stop_output != 0) { break; } } set_addr_location(&(dot_addr[mem]), addr); }