commit 4392e93

zzo38  ·  2023-02-01 19:35:22 +0000 UTC
parent 07ad8db
Implement standard expanded memory (untested so far).
3 files changed,  +40, -57
M main.c
+0, -3
 1@@ -1,9 +1,6 @@
 2 
 3 === Command-line switches ===
 4 
 5--B
 6-  Bicycle mode; affects the meaning of some ports of the system device.
 7-
 8 -D
 9   Use double buffering for the display.
10 
M main.c
+17, -50
  1@@ -220,7 +220,6 @@ static volatile Uint8 timer_expired=0;
  2 static SDL_Surface*screen;
  3 static Uint8 layers;
  4 static Uint8 palet=7;
  5-static Uint8 bicycle=0;
  6 
  7 static Sint32*audio_option;
  8 static SDL_AudioSpec audiospec;
  9@@ -340,27 +339,9 @@ static void run(Uint16 pc) {
 10     break_pc=pc-1;
 11   }
 12   fflush(stdout);
 13-  if(bicycle) {
 14-    if(k=device[0].d[2]) {
 15-      memcpy(mem+(k<<8),ds.d,254);
 16-      mem[(k<<8)+0xFF]=ds.p;
 17-    }
 18-    if(k=device[0].d[3]) {
 19-      memcpy(mem+(k<<8),rs.d,254);
 20-      mem[(k<<8)+0xFF]=rs.p;
 21-    }
 22-  }
 23   return;
 24   error:
 25-  if(bicycle && (device[0].d[0] || device[0].d[1])) {
 26-    if(device[0].d[2]) mem[(device[0].d[2]<<8)+0xFE]=v; else fprintf(stderr,"Uxn error %d at 0x%04X\n",v,pc);
 27-    pc=GET16(device[0].d);
 28-    PUT16(device[0].d,0);
 29-    ds.p=rs.p=0;
 30-    goto start;
 31-  } else {
 32-    uxnerr(v,pc);
 33-  }
 34+  uxnerr(v,pc);
 35 }
 36 
 37 static void load_rom(void) {
 38@@ -375,39 +356,27 @@ static void load_rom(void) {
 39 static Uint8 default_in(Device*misc1,Uint8 misc2) { return misc1->d[misc2&15]; }
 40 static void default_out(Device*misc1,Uint8 misc2) {}
 41 
 42-static Uint8 system_in(Device*dev,Uint8 id) {
 43-  switch(id) {
 44-    case 2: return ds.p;
 45-    case 3: return rs.p;
 46-    default: return dev->d[id];
 47+static void expansion_command(Uint16 addr) {
 48+  Uint32 src,dst;
 49+  Uint16 len;
 50+  switch(mem[addr]) {
 51+    case 0x01:
 52+      len=GET16(mem+addr+1);
 53+      src=(GET16(mem+addr+3)<<8L)|(GET16(mem+addr+5));
 54+      dst=(GET16(mem+addr+7)<<8L)|(GET16(mem+addr+9));
 55+      if(src+len<=MEMSIZE && dst+len<=MEMSIZE) {
 56+        memmove(mem+dst,mem+src,len);
 57+      } else {
 58+        if(use_debug) fprintf(stderr,"! Access expanded memory out of range\n");
 59+      }
 60+      break;
 61   }
 62 }
 63 
 64 static void system_out(Device*dev,Uint8 id) {
 65   switch(id) {
 66-    case 2:
 67-      if(bicycle) {
 68-        if(dev->d[2]) {
 69-          memcpy(ds.d,mem+(dev->d[2]<<8),256);
 70-          ds.p=mem[(dev->d[2]<<8)+0xFF];
 71-        } else {
 72-          ds.p=0;
 73-        }
 74-      } else {
 75-        ds.p=dev->d[2];
 76-      }
 77-      break;
 78     case 3:
 79-      if(bicycle) {
 80-        if(dev->d[3]) {
 81-          memcpy(ds.d,mem+(dev->d[3]<<8),256);
 82-          rs.p=mem[(dev->d[3]<<8)+0xFF];
 83-        } else {
 84-          rs.p=0;
 85-        }
 86-      } else {
 87-        rs.p=dev->d[3];
 88-      }
 89+      expansion_command(GET16(dev->d+2));
 90       break;
 91     case 8 ... 13:
 92       colors[070].r=colors[074].r=(dev->d[8]>>4)*0x11;
 93@@ -1340,13 +1309,11 @@ int main(int argc,char**argv) {
 94     device[i].in=default_in;
 95     device[i].out=default_out;
 96   }
 97-  device[0].in=system_in;
 98   device[0].out=system_out;
 99   device[10].aux=&uxnfile0;
100   device[11].aux=&uxnfile1;
101   device[12].in=datetime_in;
102-  while((i=getopt(argc,argv,"+ABDFNQST:YZa:dh:ijnp:qs:t:w:xyz:"))>0) switch(i) {
103-    case 'B': bicycle=1; device[0].in=default_in; break;
104+  while((i=getopt(argc,argv,"+ADFNQST:YZa:dh:ijnp:qs:t:w:xyz:"))>0) switch(i) {
105     case 'D': scrflags|=SDL_DOUBLEBUF; break;
106     case 'F': scrflags|=SDL_FULLSCREEN; break;
107     case 'N': scrflags|=SDL_NOFRAME; break;
+23, -4
 1@@ -27,8 +27,8 @@ In the below lists, asterisks indicate 16-bit ports.
 2 === System ===
 3 
 4 00 = Vector *
 5-02 = Data stack
 6-03 = Return stack
 7+02 = Expansion *
 8+04 = Title *
 9 06 = Metadata *
10 08 = Colours (red) *
11 0A = Colours (green) *
12@@ -38,8 +38,13 @@ In the below lists, asterisks indicate 16-bit ports.
13 
14 Some implementations call the system vector if an error occurs.
15 
16-The data stack and return stack ports have a different meaning in different
17-implementations, and probably should not be used by most programs.
18+Writing an address to the expansion port will execute an expansion
19+operation, which is a record stored at that address; the first byte of
20+that data is the operation code, and the rest are the arguments. See the
21+below list of expansion operations.
22+
23+The title port points to a null-terminated ASCII string which may be used
24+as the window title (if supported by the emulator).
25 
26 The colours control the colours of the display, where the high nybble of
27 each controls the value for colour index 0, and the low nybble of each
28@@ -49,6 +54,11 @@ Writing nonzero to the debug port will display some debug info.
29 
30 Writing nonzero to the quit port terminates the program.
31 
32+In previous versions of this specification, port 02 is the data stack
33+port and port 03 is the return stack port. The data stack and return stack
34+ports have a different meaning in different implementations, and probably
35+should not be used by most programs.
36+
37 
38 === Standard I/O ===
39 
40@@ -159,6 +169,9 @@ design is not very good in my opinion).
41 80 = Vector *
42 82 = Joypad
43 83 = Key
44+85 = Player 2
45+86 = Player 3
46+87 = Player 4
47 
48 The vector is called if a key is pushed, or if any button on the joypad is
49 pushed or released.
50@@ -255,3 +268,9 @@ CA = Daylight saving time
51 Some programs use this device to seed a random number generator, and
52 will not work correctly if these values are all zero.
53 
54+
55+=== Expansion ===
56+
57+01 length* src_page* src_addr* dst_page* dst_addr*
58+  Allows accessing expanded memory.
59+