--- /dev/null
+#include <assert.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "memory_manage.h"
+#include "type.h"
+#include "widget.h"
+#include "cui_gauge.h"
+#include "header.h"
+#include "reader_master.h"
+#include "reader_kazzo.h"
+#include "script_dump.h"
+#include "flash_device.h"
+#include "script_program.h"
+
+static void text_append_va(void *obj, const char *format, va_list list)
+{
+ vprintf(format, list);
+}
+
+static void text_append(void *obj, const char *format, ...)
+{
+ va_list list;
+ va_start(list, format);
+ text_append_va(obj, format, list);
+ va_end(list);
+}
+
+static void log_set(struct textcontrol *log)
+{
+ log->object = NULL;
+ log->append = text_append;
+ log->append_va = text_append_va;
+}
+
+static bool program_rom_set(const char *device, char trans, struct memory *m, struct flash_device *f)
+{
+ m->offset = 0;
+ if(flash_device_get(device, f) == false){
+ printf("unknown flash memory device %s\n", device);
+ return false;
+ }
+ switch(trans){
+ case 'f':
+ m->transtype = TRANSTYPE_FULL;
+ break;
+ case 't':
+ m->transtype = TRANSTYPE_TOP;
+ break;
+ case 'b':
+ m->transtype = TRANSTYPE_BOTTOM;
+ break;
+ case 'e':
+ default:
+ m->transtype = TRANSTYPE_EMPTY;
+ break;
+ }
+ return true;
+}
+
+static void program(int c, char **v)
+{
+ struct program_config config;
+ config.cpu.memory.data = NULL;
+ config.ppu.memory.data = NULL;
+ config.script = v[2];
+ config.target = v[3];
+ config.control = &DRIVER_KAZZO.control;
+ config.cpu.access = &DRIVER_KAZZO.cpu;
+ config.ppu.access = &DRIVER_KAZZO.ppu;
+ config.compare = false;
+ config.testrun = false;
+ switch(v[1][0]){
+ case 'a':
+// config.reader = &DRIVER_DUMMY;
+ config.testrun = true;
+ break;
+ case 'F':
+ config.compare = true;
+ break;
+ }
+
+ switch(c){
+ case 5: {//mode script target cpu_flash_device
+ char trans = 'f';
+ if(v[1][1] != '\0'){
+ trans = v[1][1];
+ }
+ if(program_rom_set(v[4], trans, &config.cpu.memory, &config.cpu.flash) == false){
+ return;
+ }
+ if(program_rom_set("dummy", 'e', &config.ppu.memory, &config.ppu.flash) == false){
+ assert(0);
+ return;
+ }
+ }break;
+ case 6: { //mode script target cpu_flash_device ppu_flash_device
+ char trans = 'f';
+ if(v[1][1] != '\0'){
+ trans = v[1][1];
+ }
+ if(program_rom_set(v[4], trans, &config.cpu.memory, &config.cpu.flash) == false){
+ return;
+ }
+ trans = 'f';
+ if(v[1][1] != '\0' && v[1][2] != '\0'){
+ trans = v[1][2];
+ }
+ if(program_rom_set(v[5], trans, &config.ppu.memory, &config.ppu.flash) == false){
+ return;
+ }
+ }break;
+ default:
+ puts("mode script target cpu_flash_device ppu_flash_device");
+ return;
+ }
+ log_set(&config.log);
+ cui_gauge_new(&config.cpu.gauge, "Program Flash", 2, -2);
+ cui_gauge_new(&config.ppu.gauge, "Charcter Flash", 1, -1);
+ script_program_execute(&config);
+ cui_gauge_destory(&config.cpu.gauge);
+ cui_gauge_destory(&config.ppu.gauge);
+}
+
+static void dump(int c, char **v)
+{
+ struct dump_config config;
+ if(c < 4){
+ puts("argument error");
+ return;
+ }
+ config.cpu.increase = 1;
+ config.ppu.increase = 1;
+ config.progress = true;
+ switch(v[1][0]){
+ case 'D':
+ config.progress = false;
+ break;
+ }
+ switch(v[1][1]){
+ case '2':
+ config.cpu.increase = 2;
+ break;
+ case '4':
+ config.cpu.increase = 4;
+ break;
+ }
+ if(v[1][1] != '\0'){
+ switch(v[1][2]){
+ case '2':
+ config.ppu.increase = 2;
+ break;
+ case '4':
+ config.ppu.increase = 4;
+ break;
+ }
+ }
+ config.script = v[2];
+ config.target = v[3];
+ config.control = &DRIVER_KAZZO.control;
+ config.cpu.access = &DRIVER_KAZZO.cpu;
+ config.ppu.access = &DRIVER_KAZZO.ppu;
+ cui_gauge_new(&config.cpu.gauge, "Program ROM", 2, -2);
+ cui_gauge_new(&config.ppu.gauge, "Charcter ROM", 1, -1);
+ config.mappernum = -1;
+ if(c == 5){
+ config.mappernum = atoi(v[4]);
+ }
+ config.battery = false;
+ log_set(&config.log);
+ script_dump_execute(&config);
+ cui_gauge_destory(&config.cpu.gauge);
+ cui_gauge_destory(&config.ppu.gauge);
+}
+
+static void usage(const char *v)
+{
+ puts("famicom bus simluator 'anago'");
+ printf("%s [mode] [script] [target] ....\n", v);
+}
+
+#ifdef WIN32
+int main(int c, char **v)
+#else
+int anago_cui(int c, char **v)
+#endif
+{
+ mm_init();
+ if(c >= 2){
+ switch(v[1][0]){
+ case 'a': case 'f': case 'F':
+ program(c, v);
+ break;
+ case 'd': case 'D':
+ dump(c,v);
+ break;
+ default:
+ usage(v[0]);
+ puts("mode are d, D, f, g");
+ break;
+ }
+ }else{
+ usage(v[0]);
+ }
+ mm_end();
+ return 0;
+}
--- /dev/null
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#ifdef WIN32
+ #include <windows.h>
+#endif
+#include "memory_manage.h"
+#include "widget.h"
+
+struct cui_gauge{
+ const char *name;
+ int value, range;
+ int lineback, lineforward;
+};
+
+static void range_set(void *obj, int value)
+{
+ struct cui_gauge *t = obj;
+ t->range = value;
+}
+
+static void console_move(int line)
+{
+ if(line == 0){
+ return;
+ }
+#ifdef WIN32
+ HANDLE c;
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ c = GetStdHandle(STD_OUTPUT_HANDLE);
+ if(GetConsoleScreenBufferInfo(c, &info) == 0){
+ //command.com, cygwin shell, mingw shell
+ if(line < 0){
+ printf("\x1b[%dA", -line);
+ }else if(line == 1){
+ printf("\n");
+ fflush(stdout);
+ }else{
+ printf("\n");
+ fflush(stdout);
+ printf("\x1b[%dB", line - 1);
+// printf("\x1b[%dB", line - 1);
+// fflush(stdout);
+ }
+ }else{
+ //cmd.exe
+ info.dwCursorPosition.X = 0;
+ info.dwCursorPosition.Y += line;
+ SetConsoleCursorPosition(c, info.dwCursorPosition);
+ }
+#else
+ if(line < 0){
+ printf("\x1b[%dA\x1b[35D", -line);
+ }else{
+ printf("\x1b[%dB\x1b[35D", line);
+ }
+#endif
+// fflush(stdout);
+}
+
+static void draw(const struct cui_gauge *t)
+{
+ const int barnum = 16;
+ const int unit = t->range / barnum;
+ int igeta = t->value / unit;
+ char bar[barnum + 3 + 1];
+ char *text = bar;
+ int i;
+ assert(igeta <= barnum);
+ printf("%s 0x%06x/0x%06x ", t->name, (int) t->value, (int) t->range);
+ *text++ = '|';
+ for(i = 0; i < igeta; i++){
+ if(i == barnum / 2){
+ *text++ = '|';
+ }
+ *text++ = '#';
+ }
+ for(; i < barnum; i++){
+ if(i == barnum / 2){
+ *text++ = '|';
+ }
+ *text++ = ' ';
+ }
+ *text++ = '|';
+ *text = '\0';
+ printf(bar);
+// fflush(stdout);
+}
+
+
+static void value_set(void *obj, void *d, int value)
+{
+ struct cui_gauge *t = (struct cui_gauge *) obj;
+ t->value = value;
+ if(t->range != 0){
+ draw(t);
+ }
+ console_move(1);
+}
+
+static void value_add(void *obj, void *d, int value)
+{
+ struct cui_gauge *t = (struct cui_gauge *) obj;
+ t->value += value;
+ console_move(t->lineback);
+ draw(t);
+ console_move(t->lineforward);
+}
+
+static void name_set(void *obj, const char *name, int lineforward, int lineback)
+{
+ struct cui_gauge *t = (struct cui_gauge *) obj;
+ t->name = name;
+ t->lineforward = lineforward;
+ t->lineback = lineback;
+}
+
+static void label_set(void *obj, const char *format, ...)
+{
+ va_list list;
+ const struct cui_gauge *t = (const struct cui_gauge *) obj;
+
+ va_start(list, format);
+ console_move(t->lineback);
+ printf("%s ", t->name);
+ vprintf(format, list);
+ console_move(t->lineforward);
+ va_end(list);
+}
+
+void cui_gauge_new(struct gauge *t, const char *name, int lineforward, int lineback)
+{
+ t->bar = Malloc(sizeof(struct cui_gauge));
+ t->label = t->bar;
+ name_set(t->bar, name, lineforward, lineback);
+ t->range_set = range_set;
+ t->value_set = value_set;
+ t->value_add = value_add;
+ t->label_set = label_set;
+}
+
+void cui_gauge_destory(struct gauge *t)
+{
+ Free(t->bar);
+ t->bar = NULL;
+ t->label = NULL;
+ t->range_set = NULL;
+ t->value_set = NULL;
+ t->value_add = NULL;
+ t->label_set = NULL;
+}