commit fd4753c

zzo38  ·  2022-11-02 05:08:54 +0000 UTC
parent bcda6dc
Change the working of expanded memory.
2 files changed,  +47, -25
M main.c
+17, -11
 1@@ -114,8 +114,8 @@ Device fifteen is the extension device, which is defined as:
 2   f5
 3   f6 = transfer length *
 4   f7
 5-  f8 = transfer operation
 6-  f9 = device version
 7+  f8 = command code / expanded memory pages
 8+  f9 = device version / status
 9   fa = device seven UUID address *
10   fb
11   fc = device thirteen UUID address *
12@@ -123,18 +123,23 @@ Device fifteen is the extension device, which is defined as:
13   fe = device fourteen UUID address *
14   ff
15 
16-The transfer operation is used for copying data to/from expanded memory.
17-Use the bits as following:
18+(If the program file is too big to fit into conventional memory, then as
19+much as will fit of the rest will be loaded into expanded memory.)
20 
21-* bit0 = Set to transfer conventional to expanded memory, or clear to
22-transfer expanded to conventional memory.
23+Reading the command code port will be the number of expanded memory pages
24+(from 0 to 16). Writing the command code will execute the command, where
25+the high nybble specifies which command to do and the low nybble is the
26+parameter of that command. The command codes are:
27 
28-* bit1 = Selects which page of expanded memory to use.
29+* 0 = Copy conventional memory to expanded memory. The parameter is the
30+zero-based page number.
31 
32-Other bits are reserved and must be clear.
33+* 1 = Copy expanded memory to conventional memory. The parameter is the
34+zero-based page number.
35 
36-If the program file is too big to fit into conventional memory, then as
37-much as will fit of the rest will be loaded into expanded memory.
38+* 2 = Clear the screen. If bit0 is set then clear the background layer,
39+and if bit1 is set then clear the foreground layer (set both bits to clear
40+both layers).
41 
42 Writing to the UUID address ports will read sixteen bytes at that address
43 and then will set the device version field to the version number, which
44@@ -143,7 +148,8 @@ implementation, or an even number for a stable implementation. (The memory
45 that it points to can be reused afterward with no problem.)
46 
47 The vector is called after passing command-line arguments, but before any
48-other events occur.
49+other events occur. If accepting input from stdin, then it will also be
50+called after all input from stdin has been read.
51 
52 (Note: Using this feature will make the program not portable to other
53 implementations, and should be avoided if possible. However, it is
M main.c
+30, -14
 1@@ -15,6 +15,9 @@ exit
 2 #include <time.h>
 3 #include <unistd.h>
 4 
 5+#define EXPANDED_MEMORY 8
 6+#define MEMSIZE ((EXPANDED_MEMORY+1)*0x10000)
 7+
 8 #define GET16(p) (((p)[0]<<8)|(p)[1])
 9 #define PUT16(p,q) ((p)[0]=(q)>>8,(p)[1]=(q))
10 
11@@ -120,7 +123,7 @@ static const Uint8 blend[4][16]={
12   {2,3,1,2,2,3,1,2,2,3,1,2,2,3,1,2},
13 };
14 
15-static Uint8 mem[0x30000];
16+static Uint8 mem[MEMSIZE];
17 static Stack ds,rs;
18 static Device device[16];
19 static Uint16 scr_w,scr_h;
20@@ -274,8 +277,8 @@ static void run(Uint16 pc) {
21 static void load_rom(void) {
22   FILE*fp=fopen(rom_name,"r");
23   if(!fp) err(1,"Cannot load program file");
24-  memset(mem,0,0x30000);
25-  fread(mem+0x0100,1,0x30000-0x0100,fp);
26+  memset(mem,0,MEMSIZE);
27+  fread(mem+0x0100,1,MEMSIZE-0x0100,fp);
28   if(ferror(fp)) err(1,"Cannot load program file");
29   fclose(fp);
30 }
31@@ -341,11 +344,15 @@ static void system_out(Device*dev,Uint8 id) {
32   }
33 }
34 
35+static Uint8 extension_in(Device*dev,Uint8 id) {
36+  switch(id) {
37+    case 8: return EXPANDED_MEMORY;
38+    default: return dev->d[id];
39+  }
40+}
41+
42 static void extension_out(Device*dev,Uint8 id) {
43-  Uint8*p;
44-  Uint8*q;
45-  Uint16 x,y;
46-  Uint16 len;
47+  Uint16 x,y,len;
48   switch(id) {
49     case 8:
50       switch(dev->d[8]>>4) {
51@@ -353,14 +360,22 @@ static void extension_out(Device*dev,Uint8 id) {
52           x=GET16(dev->d+2);
53           y=GET16(dev->d+4);
54           len=GET16(dev->d+6);
55-          if(dev->d[8]&4) len=256;
56-          if(x+len>0x10000 || y+len>0x10000) uxnerr(5,x);
57-          *(dev->d[8]&1?&p:&q)=mem+x;
58-          *(dev->d[8]&1?&q:&p)=mem+y+(dev->d[8]&2?0x20000:0x10000);
59-          memcpy(q,p,len);
60+          if(x+len>0x10000 || y+len>0x10000 || (dev->d[8]&15)>=EXPANDED_MEMORY) uxnerr(5,x);
61+          memcpy(mem+y+((dev->d[8]&15)<<16)+0x10000,mem+x,len);
62+          break;
63+        case 1:
64+          x=GET16(dev->d+2);
65+          y=GET16(dev->d+4);
66+          len=GET16(dev->d+6);
67+          if(x+len>0x10000 || y+len>0x10000 || (dev->d[8]&15)>=EXPANDED_MEMORY) uxnerr(5,x);
68+          memcpy(mem+x,mem+y+((dev->d[8]&15)<<16)+0x10000,len);
69+          break;
70+        case 2:
71+          if(!screen) break;
72+          if(dev->d[8]&1) memset(bglayer,0,scr_w*scr_h);
73+          if(dev->d[8]&2) memset(fglayer,0,scr_w*scr_h);
74           break;
75       }
76-      dev->d[8]=0;
77       break;
78     case 11: case 13: case 15:
79       dev->d[9]=0;
80@@ -776,7 +791,7 @@ int main(int argc,char**argv) {
81     case 'q': use_console=0; break;
82     case 't': timer_rate=strtol(optarg,0,10); break;
83     case 'w': default_width=strtol(optarg,0,10); break;
84-    case 'x': device[15].out=extension_out; break;
85+    case 'x': device[15].in=extension_in; device[15].out=extension_out; break;
86     case 'y': allow_write=0; device[10].out=device[11].out=files_out; device[10].in=device[11].in=files_in; break;
87     case 'z': zoom=strtol(optarg,0,10); break;
88     default: return 1;
89@@ -827,6 +842,7 @@ int main(int argc,char**argv) {
90       device[1].d[2]=i;
91       run(GET16(device[1].d));
92     }
93+    if(device[15].out==extension_out) run(GET16(device[15].d));
94   }
95   return 0;
96 }