commit b0fb2c8

zzo38  ·  2022-11-24 19:55:05 +0000 UTC
parent eb07557
Implement debug menu (currently does not have single step, etc; may be added later), and fix some problems with restarting.
2 files changed,  +252, -6
M main.c
+3, -0
 1@@ -105,6 +105,9 @@ F5
 2 F6 / F7
 3   Palette selection.
 4 
 5+F8
 6+  Debug menu.
 7+
 8 F9
 9   Restart.
10 
M main.c
+249, -6
  1@@ -16,6 +16,57 @@ exit
  2 #include <time.h>
  3 #include <unistd.h>
  4 
  5+static const Uint8 fontdata[]={ // font for built-in menus
  6+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00,
  7+  0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00,
  8+  0x30,0x7C,0xC0,0x78,0x0C,0xF8,0x30,0x00,0x00,0xC6,0xCC,0x18,0x30,0x66,0xC6,0x00,
  9+  0x38,0x6C,0x38,0x76,0xDC,0xCC,0x76,0x00,0x60,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,
 10+  0x18,0x30,0x60,0x60,0x60,0x30,0x18,0x00,0x60,0x30,0x18,0x18,0x18,0x30,0x60,0x00,
 11+  0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00,
 12+  0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,
 13+  0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,
 14+  0x7C,0xC6,0xCE,0xDE,0xF6,0xE6,0x7C,0x00,0x30,0x70,0x30,0x30,0x30,0x30,0xFC,0x00,
 15+  0x78,0xCC,0x0C,0x38,0x60,0xCC,0xFC,0x00,0x78,0xCC,0x0C,0x38,0x0C,0xCC,0x78,0x00,
 16+  0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x1E,0x00,0xFC,0xC0,0xF8,0x0C,0x0C,0xCC,0x78,0x00,
 17+  0x38,0x60,0xC0,0xF8,0xCC,0xCC,0x78,0x00,0xFC,0xCC,0x0C,0x18,0x30,0x30,0x30,0x00,
 18+  0x78,0xCC,0xCC,0x78,0xCC,0xCC,0x78,0x00,0x78,0xCC,0xCC,0x7C,0x0C,0x18,0x70,0x00,
 19+  0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x60,
 20+  0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x00,0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00,
 21+  0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00,0x78,0xCC,0x0C,0x18,0x30,0x00,0x30,0x00,
 22+  0x7C,0xC6,0xDE,0xDE,0xDE,0xC0,0x78,0x00,0x30,0x78,0xCC,0xCC,0xFC,0xCC,0xCC,0x00,
 23+  0xFC,0x66,0x66,0x7C,0x66,0x66,0xFC,0x00,0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00,
 24+  0xF8,0x6C,0x66,0x66,0x66,0x6C,0xF8,0x00,0xFE,0x62,0x68,0x78,0x68,0x62,0xFE,0x00,
 25+  0xFE,0x62,0x68,0x78,0x68,0x60,0xF0,0x00,0x3C,0x66,0xC0,0xC0,0xCE,0x66,0x3E,0x00,
 26+  0xCC,0xCC,0xCC,0xFC,0xCC,0xCC,0xCC,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,
 27+  0x1E,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00,0xE6,0x66,0x6C,0x78,0x6C,0x66,0xE6,0x00,
 28+  0xF0,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00,
 29+  0xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x38,0x00,
 30+  0xFC,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,0x78,0xCC,0xCC,0xCC,0xDC,0x78,0x1C,0x00,
 31+  0xFC,0x66,0x66,0x7C,0x6C,0x66,0xE6,0x00,0x78,0xCC,0xE0,0x70,0x1C,0xCC,0x78,0x00,
 32+  0xFC,0xB4,0x30,0x30,0x30,0x30,0x78,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xFC,0x00,
 33+  0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x00,0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00,
 34+  0xC6,0xC6,0x6C,0x38,0x38,0x6C,0xC6,0x00,0xCC,0xCC,0xCC,0x78,0x30,0x30,0x78,0x00,
 35+  0xFE,0xC6,0x8C,0x18,0x32,0x66,0xFE,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x78,0x00,
 36+  0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x78,0x00,
 37+  0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
 38+  0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0x76,0x00,
 39+  0xE0,0x60,0x60,0x7C,0x66,0x66,0xDC,0x00,0x00,0x00,0x78,0xCC,0xC0,0xCC,0x78,0x00,
 40+  0x1C,0x0C,0x0C,0x7C,0xCC,0xCC,0x76,0x00,0x00,0x00,0x78,0xCC,0xFC,0xC0,0x78,0x00,
 41+  0x38,0x6C,0x60,0xF0,0x60,0x60,0xF0,0x00,0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0xF8,
 42+  0xE0,0x60,0x6C,0x76,0x66,0x66,0xE6,0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x78,0x00,
 43+  0x0C,0x00,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0xE0,0x60,0x66,0x6C,0x78,0x6C,0xE6,0x00,
 44+  0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0xCC,0xFE,0xFE,0xD6,0xC6,0x00,
 45+  0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xCC,0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0x78,0x00,
 46+  0x00,0x00,0xDC,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0x1E,
 47+  0x00,0x00,0xDC,0x76,0x66,0x60,0xF0,0x00,0x00,0x00,0x7C,0xC0,0x78,0x0C,0xF8,0x00,
 48+  0x10,0x30,0x7C,0x30,0x30,0x34,0x18,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0x76,0x00,
 49+  0x00,0x00,0xCC,0xCC,0xCC,0x78,0x30,0x00,0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x6C,0x00,
 50+  0x00,0x00,0xC6,0x6C,0x38,0x6C,0xC6,0x00,0x00,0x00,0xCC,0xCC,0xCC,0x7C,0x0C,0xF8,
 51+  0x00,0x00,0xFC,0x98,0x30,0x64,0xFC,0x00,0x1C,0x30,0x30,0xE0,0x30,0x30,0x1C,0x00,
 52+  0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0xE0,0x30,0x30,0x1C,0x30,0x30,0xE0,0x00,
 53+  0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
 54+};
 55+
 56 #define EXPANDED_MEMORY 8
 57 #define MEMSIZE ((EXPANDED_MEMORY+1)*0x10000)
 58 
 59@@ -174,6 +225,8 @@ static Uint8 bicycle=0;
 60 static Sint32*audio_option;
 61 static SDL_AudioSpec audiospec;
 62 
 63+static Uint8 debugger=0;
 64+
 65 static void debug(int i) {
 66   int j;
 67   if(i) fprintf(stderr,"Debug(%02X)\n",i);
 68@@ -858,15 +911,192 @@ static void run_audio(void) {
 69   }
 70 }
 71 
 72+static void debug_screen(Uint8*s,Uint8 k) {
 73+  static Sint8 page=0;
 74+  static Uint8 port=0;
 75+  static Uint8 din;
 76+  static Uint32 addr=0;
 77+  static Uint32 scrol=0;
 78+  char buf[81];
 79+  int i;
 80+  Stack*z;
 81+  FILE*f;
 82+  UxnFile*u;
 83+  if(s) {
 84+    memset(s,32,80*25);
 85+    show:
 86+    switch(page) {
 87+      case 0:
 88+        memcpy(s+80*0,buf,snprintf(buf,81,"* %s",rom_name));
 89+        memcpy(s+80*1,buf,snprintf(buf,81,"<c> Console: %s",use_console?"On":"Off"));
 90+        memcpy(s+80*2,buf,snprintf(buf,81,"<d> Debug: %s",use_debug?"On":"Off"));
 91+        memcpy(s+80*3,buf,snprintf(buf,81,"<F2> Sound: %s",audio_option?(audio_option['m'-'a']?"Mute":"On"):"N/A"));
 92+        memcpy(s+80*4,buf,snprintf(buf,81,"<F3> Mouse: %s",use_mouse?"On":"Off"));
 93+        memcpy(s+80*5,buf,snprintf(buf,81,"<F4> Layers: %s",layers?(layers==1?"fg":"bg"):"fg/bg"));
 94+        memcpy(s+80*6,buf,snprintf(buf,81,"<F6/F7> Palette: %d",palet));
 95+        memcpy(s+80*7,buf,snprintf(buf,81,"<F9> Restart"));
 96+        memcpy(s+80*8,buf,snprintf(buf,81,"<F10> Quit"));
 97+        if(audio_option) memcpy(s+80*9,buf,snprintf(buf,81,"<-/+> Volume: %d",(int)audio_option['v'-'a']));
 98+        memcpy(s+80*10,buf,snprintf(buf,81,"<PAUSE> Resume"));
 99+        memcpy(s+80*13,buf,snprintf(buf,81,"Pages: CTRL+"));
100+        memcpy(s+80*14,buf,snprintf(buf,81," A:Stack   B:Return  C:Device  D:Memory  E:Files "));
101+        memcpy(s+80*15,buf,snprintf(buf,81," F:        G:        N:        O:        P:      "));
102+        memcpy(s+80*16,buf,snprintf(buf,81," Q:        R:        S:        T:        U:      "));
103+        memcpy(s+80*17,buf,snprintf(buf,81," V:        W:        X:        Y:        Z:Main  "));
104+        break;
105+      case 1: case 2:
106+        if(page==1) z=&ds; else z=&rs;
107+        memcpy(s,buf,snprintf(buf,81,"%s Stack (%02x)",page==1?"Data":"Return",z->p));
108+        for(i=0;i<256;i++) memcpy(s+80*(i/16+1)+(i&15)*4,buf,snprintf(buf,81,"%c%02x%c",z->p==i?'[':' ',z->d[i],z->p==i?']':' '));
109+        break;
110+      case 3:
111+        memcpy(s,buf,snprintf(buf,81,"--   -0  -1  -2  -3  -4  -5  -6  -7  -8  -9  -a  -b  -c  -d  -e  -f"));
112+        for(i=0;i<16;i++) memcpy(s+80*(i+1),buf,snprintf(buf,81,"%x0:",i));
113+        for(i=0;i<256;i++) memcpy(s+80*(i/16+1)+(i&15)*4+4,buf,snprintf(buf,81,"%c%02x%c",port==i?'[':' ',device[i>>4].d[i&15],port==i?']':' '));
114+        memcpy(s+80*17,buf,snprintf(buf,81,"<i> In=%02x  <o> Out  <x> Execute",din));
115+        break;
116+      case 4:
117+        if(addr<0) addr=0;
118+        if(addr>=MEMSIZE) addr=MEMSIZE-1;
119+        if(scrol<0) scrol=0;
120+        if(addr>=0x100 && scrol<addr-0xF0) scrol=(addr-0xF0)&~15;
121+        if(scrol>addr) scrol=addr&~15;
122+        memcpy(s,buf,snprintf(buf,81,"-----   -0  -1  -2  -3  -4  -5  -6  -7  -8  -9  -a  -b  -c  -d  -e  -f"));
123+        for(i=0;i<16;i++) memcpy(s+80*(i+1),buf,snprintf(buf,81,"%05x:",i*16+scrol));
124+        for(i=0;i<256;i++) if(i+scrol<MEMSIZE) memcpy(s+80*(i/16+1)+(i&15)*4+7,buf,snprintf(buf,81,"%c%02x%c",addr==i+scrol?'[':' ',mem[i+scrol],addr==i+scrol?']':' '));
125+        memcpy(s+80*17,buf,snprintf(buf,81,"<x> Execute  <s> Save"));
126+        break;
127+      case 5:
128+        for(i=0;i<2;i++) {
129+          u=i?&uxnfile1:&uxnfile0;
130+          memcpy(s+80*(7*i+1),buf,snprintf(buf,81,"[File%d]",i));
131+          memcpy(s+80*(7*i+2),buf,snprintf(buf,81," name=%s",u->name));
132+          if(u->file) memcpy(s+80*(7*i+3),buf,snprintf(buf,81," File fd=%d offset=0x%lX",fileno(u->file),ftell(u->file)));
133+          if(u->dir) memcpy(s+80*(7*i+4),buf,snprintf(buf,81," Dir fd=%d offset=0x%lX",dirfd(u->dir),telldir(u->dir)));
134+          memcpy(s+80*(7*i+5),buf,snprintf(buf,81," mode=0x%02X",u->mode));
135+          memcpy(s+80*(7*i+6),buf,snprintf(buf,81," <%c> Close  <%c> Rewind","cC"[i],"rR"[i]));
136+        }
137+        break;
138+      default:
139+        if(page<0) page=5; else page=0;
140+        goto show;
141+    }
142+  } else {
143+    if(k==9 || k==']') {
144+      ++page;
145+    } else if(k=='[') {
146+      --page;
147+    } else if(k>=1 && k<=7) {
148+      page=k;
149+    } else if(k>=14 && k<=25) {
150+      page=k-6;
151+    } else if(k==26) {
152+      page=0;
153+    } else if(k==27) {
154+      debugger=0;
155+      return;
156+    } else switch(page) {
157+      case 0:
158+        if(k=='c') use_console^=1;
159+        if(k=='d') use_debug^=1;
160+        if(audio_option) {
161+          if((k=='-' || k==10) && audio_option['v'-'a']) --audio_option['v'-'a'];
162+          if(k=='+' || k==11) ++audio_option['v'-'a'];
163+          if(k==8) audio_option['v'-'a']/=10;
164+          if(k>='0' && k<='9') audio_option['v'-'a']=10*audio_option['v'-'a']+k-'0';
165+        }
166+        break;
167+      case 1: case 2:
168+        if(page==1) z=&ds; else z=&rs;
169+        if(k==8) z->p--;
170+        if(k==12) z->p++;
171+        if(k==10) z->p+=16;
172+        if(k==11) z->p-=16;
173+        if(k>='0' && k<='9') z->d[z->p]=(z->d[z->p]<<4)+(k-'0');
174+        if(k>='a' && k<='f') z->d[z->p]=(z->d[z->p]<<4)+(k+10-'a');
175+        break;
176+      case 3:
177+        i=port;
178+        if(k==8) port--;
179+        if(k==12) port++;
180+        if(k==10) port+=16;
181+        if(k==11) port-=16;
182+        if(k>='0' && k<='9') device[i>>4].d[i&15]=(device[i>>4].d[i&15]<<4)+(k-'0');
183+        if(k>='a' && k<='f') device[i>>4].d[i&15]=(device[i>>4].d[i&15]<<4)+(k+10-'a');
184+        if(k=='i') din=device[i>>4].in(device+(i>>4),i&15);
185+        if(k=='o') device[i>>4].out(device+(i>>4),i&15);
186+        if(k=='x') run(GET16(device[i>>4].d));
187+        break;
188+      case 4:
189+        if(k==8) addr--;
190+        if(k==12) addr++;
191+        if(k==10) addr+=16;
192+        if(k==11) addr-=16;
193+        if(k==',') scrol-=0x10,addr-=0x10;
194+        if(k=='.') scrol+=0x10,addr+=0x10;
195+        if(k=='<') scrol-=0x100,addr-=0x100;
196+        if(k=='>') scrol+=0x100,addr+=0x100;
197+        if(k=='q') scrol-=0x1000,addr-=0x1000;
198+        if(k=='w') scrol+=0x1000,addr+=0x1000;
199+        if(k=='Q') scrol-=0x10000,addr-=0x10000;
200+        if(k=='W') scrol+=0x10000,addr+=0x10000;
201+        if(k=='=') scrol=addr=0;
202+        if(addr>=MEMSIZE+0x1000) scrol=addr=0;
203+        if(k>='0' && k<='9') mem[addr]=(mem[addr]<<4)+(k-'0');
204+        if(k>='a' && k<='f') mem[addr]=(mem[addr]<<4)+(k+10-'a');
205+        if(k=='x' && addr<0x10000) run(addr);
206+        if(k=='s') {
207+          f=fopen("_uxn_memory","w");
208+          if(f) {
209+            fwrite(mem,1,MEMSIZE,f);
210+            fprintf(stderr,"Saved 0x%X bytes to file _uxn_memory\n",(int)(MEMSIZE));
211+            fclose(f);
212+          } else {
213+            warn("Cannot open file _uxn_memory");
214+          }
215+        }
216+        break;
217+      case 5:
218+        if(k=='c') files_set(device+10,0);
219+        if(k=='C') files_set(device+11,0);
220+        if(k=='r') files_seek(&uxnfile0,8,0);
221+        if(k=='R') files_seek(&uxnfile1,8,0);
222+        break;
223+    }
224+  }
225+}
226+
227 static void redraw(void) {
228+  static Uint8*s=0;
229   int a,r,u,v,x,y;
230   Uint8*p;
231+  if(debugger) {
232+    if(!s) s=calloc(80,26);
233+    if(!s) err(1,"Allocation failed");
234+    debug_screen(s,0);
235+  }
236+  if(size_changed) set_screen_mode(scr_w,scr_h);
237   picture_changed=0;
238   SDL_LockSurface(screen);
239   a=0;
240   p=screen->pixels;
241   r=screen->pitch;
242-  if(layers) {
243+  if(debugger) {
244+    for(y=0;y<scr_h*zoom;y++) {
245+      for(x=0;x<scr_w*zoom;x++) {
246+        if(y>=25*8-7 || x>=80*8 || (v=s[(y/8)*80+x/8]-32)<=0) p[x]=0;
247+        else p[x]=(fontdata[v*8+(y&7)]>>(7&~x))&1;
248+      }
249+      p+=r;
250+    }
251+    if(scr_h*zoom>9) {
252+      p=screen->pixels+r*(scr_h*zoom-8);
253+      for(y=0;y<8;y++) {
254+        for(a=0;a<scr_w*zoom;a++) p[a]=(a>>4)&7;
255+        p+=r;
256+      }
257+    }
258+  } else if(layers) {
259     for(y=0;y<scr_h;y++) {
260       for(x=0;x<scr_w;x++) {
261         u=(layers==1?fglayer:bglayer)[a];
262@@ -911,17 +1141,28 @@ static int run_screen(void) {
263           case SDLK_PAGEUP: i=-scroll_size; goto scroll;
264           case SDLK_PAGEDOWN: i=scroll_size; goto scroll;
265           case SDLK_F1: run(GET16(device[2].d)); timer_expired=0; break;
266-          case SDLK_F2: if(audio_option) audio_option['m'-'a']^=1; break;
267-          case SDLK_F3: use_mouse^=1; set_cursor(); break;
268+          case SDLK_F2: if(audio_option) audio_option['m'-'a']^=1; picture_changed=debugger; break;
269+          case SDLK_F3: use_mouse^=1; set_cursor(); picture_changed=debugger; break;
270           case SDLK_F4: layers=(layers+1)%3; redraw(); break;
271           case SDLK_F5: redraw(); if(SDL_GetModState()&KMOD_RSHIFT) debug(-1); break;
272           case SDLK_F6: palet=(palet+1)&7; SDL_SetColors(screen,colors+palet*8,0,8); redraw(); break;
273           case SDLK_F7: palet=(palet-1)&7; SDL_SetColors(screen,colors+palet*8,0,8); redraw(); break;
274+          case SDLK_F8: paused=picture_changed=debugger=1; break;
275           case SDLK_F9: return 1;
276           case SDLK_F10: return 0;
277-          case SDLK_PAUSE: paused^=1; set_cursor(); break;
278+          case SDLK_PAUSE: debugger=0; paused^=1; set_cursor(); picture_changed=1; break;
279+        }
280+        if(paused) {
281+          if(debugger) {
282+            if(i&0xF0) {
283+              debug_screen(0,i==0x10?11:i==0x20?10:i==0x40?8:i==0x80?12:0);
284+            } else if(i=e.key.keysym.unicode) {
285+              debug_screen(0,i);
286+            }
287+            picture_changed=1;
288+          }
289+          break;
290         }
291-        if(paused) break;
292         if(i) {
293           if(joypad_repeat || !(device[8].d[2]&i)) {
294             device[8].d[2]|=i;
295@@ -940,6 +1181,7 @@ static int run_screen(void) {
296         PUT16(device[9].d+12,0);
297         break;
298       case SDL_KEYUP:
299+        if(paused) break;
300         i=0;
301         switch(e.key.keysym.sym) {
302           case SDLK_LCTRL: case SDLK_END: i=0x01; break;
303@@ -951,7 +1193,6 @@ static int run_screen(void) {
304           case SDLK_LEFT: i=0x40; break;
305           case SDLK_RIGHT: i=0x80; break;
306         }
307-        if(paused) break;
308         if(device[8].d[2]&i) {
309           device[8].d[2]&=~i;
310           run(GET16(device[8].d));
311@@ -1069,6 +1310,8 @@ int main(int argc,char**argv) {
312   if(optind+1<argc) strncpy(uxnfile0.name,argv[optind+1],4095);
313   if(optind+2<argc) strncpy(uxnfile1.name,argv[optind+2],4095);
314   restart:
315+  size_changed=1;
316+  ds.p=rs.p=0;
317   run(0x0100);
318   if(device[1].d[0] || device[1].d[1]) for(i=optind+1;i<argc;i++) {
319     for(j=0;argv[i][j];j++) {