]> git.sur5r.net Git - cc65/commitdiff
Made the Commodore version of exec() work in programs that are so big that they load... 214/head
authorGreg King <gregdk@users.sf.net>
Mon, 28 Sep 2015 15:27:39 +0000 (11:27 -0400)
committerGreg King <gregdk@users.sf.net>
Mon, 28 Sep 2015 15:27:39 +0000 (11:27 -0400)
The function won't cause an "out of memory" error.

asminc/c64.inc
asminc/pet.inc
asminc/plus4.inc
asminc/vic20.inc
libsrc/cbm/exec.c
libsrc/cbm/execvars.s

index f450fcc0b4386be060980e26f906e8a9f4172f81..5815bebf98208534efb8011e20639b62f8ec74fb 100644 (file)
@@ -6,6 +6,8 @@
 ; ---------------------------------------------------------------------------
 ; Zero page, Commodore stuff
 
+VARTAB          := $2D          ; Pointer to start of BASIC variables
+MEMSIZE         := $37          ; Pointer to highest BASIC RAM location (+1)
 TXTPTR          := $7A          ; Pointer into BASIC source code
 TIME            := $A0          ; 60 HZ clock
 FNAM_LEN        := $B7          ; Length of filename
index 1ebf391f9f5a41b8c3ce4f410660067a676600e0..a745a89c8b1693a4b1a065c4790f710627c457d1 100644 (file)
@@ -6,6 +6,7 @@
 ; ---------------------------------------------------------------------------
 ; Zero page, Commodore stuff
 
+VARTAB          := $2A          ; Pointer to start of BASIC variables
 MEMSIZE         := $34          ; Size of memory installed
 TXTPTR          := $77          ; Pointer into BASIC source code
 TIME            := $8D          ; 60HZ clock
index 17e250508b71e63fe43bca93c39ff2d90663abf1..69b2298a37977467d55584eafd418a15cb7455df 100644 (file)
@@ -7,6 +7,8 @@
 ; Zero page, Commodore stuff
 
 TMPPTR          := $22          ; Temporary ptr used by BASIC
+VARTAB          := $2D          ; Pointer to start of BASIC variables
+MEMSIZE         := $37          ; Pointer to highest BASIC RAM location (+1)
 TXTPTR          := $3B          ; Pointer into BASIC source code
 TIME            := $A3          ; 60HZ clock
 FNAM_LEN        := $AB          ; Length of filename
index c42db4258c4048f015b767a8e4ec4ac664aa527b..12424dc116626bc2267db0a812463430b068a927 100644 (file)
@@ -6,6 +6,8 @@
 ; ---------------------------------------------------------------------------
 ; Zero page, Commodore stuff
 
+VARTAB          := $2D          ; Pointer to start of BASIC variables
+MEMSIZE         := $37          ; Pointer to highest BASIC RAM location (+1)
 TXTPTR          := $7A          ; Pointer into BASIC source code
 TIME            := $A0          ; 60HZ clock
 FNAM_LEN        := $B7          ; Length of filename
index 36c3afe006bb428fb39aa392a1aa31f8fb3300d6..b9c1bdc961e9ca872b2979d84cf2117d9110c441 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ** Program-chaining function for Commodore platforms.
 **
-** 2013-09-04, Greg King
+** 2015-09-27, Greg King
 **
 ** This function exploits the program-chaining feature in CBM BASIC's ROM.
 **
 /* The struct below is a line of BASIC code.  It sits in the LOWCODE segment
 ** to make sure that it won't be hidden by a ROM when BASIC is re-enabled.
 ** The line is:
-**  0 LOAD""+""                    ,01
+**  0 CLR:LOAD""+""                    ,01
 ** After this function has written into the line, it might look like this:
-**  0 LOAD""+"program name"        ,08
+**  0 CLR:LOAD""+"program name"        ,08
 **
 ** When BASIC's LOAD command asks the Kernal to load a file, it gives the
 ** Kernal a pointer to a file-name string.  CC65's CBM programs use that
 ** pointer to give a copy of the program's name to main()'s argv[0] parameter.
-** But, when BASIC uses a string literal that's in a program, it points
+** But, when BASIC uses a string literal that is in a program, it points
 ** directly to that literal -- in the models that don't use banked RAM
 ** (Pet/CBM, VIC-20, and 64).  The literal is overwritten by the next program
-** that's loaded.  So, argv[0] would point to machine code.  String operations
+** that is loaded.  So, argv[0] would point to machine code.  String operations
 ** create a new result string -- even when that operation changes nothing.  The
 ** result is put in the string space at the top of BASIC's memory.  So, the ""+
 ** in this BASIC line guarantees that argv[0] will get a name from a safe place.
 */
 #pragma data-name(push, "LOWCODE")
 static struct line {
-    const char end_of_line;
-    const struct line *const next;
+    const char end_of_line;             /* fake previous line */
+    const struct lineconst next;
     const unsigned line_num;
-    const char load_token, quotes[2], add_token, quote;
+    const char CLR_token, colon, LOAD_token, quotes[2], add_token, quote;
     char name[21];
     const char comma;
     char unit[3];
 } basic = {
-    '\0', &basic + 1,           /* high byte of link must be non-zero */
-    0, 0x93, "\"\"", 0xaa, '\"',
-    "\"                    ",   /* format: "123:1234567890123456\"" */
+    '\0', &basic + 1,                   /* high byte of link must be non-zero */
+    0, 0x9C, ':', 0x93, "\"\"", 0xAA, '\"',
+    "\"                    ",           /* format: "123:1234567890123456\"" */
     ',', "01"
 };
 #pragma data-name(pop)
 
 /* These values are platform-specific. */
-extern const struct line *txtptr;
+extern const void* vartab;              /* points to BASIC program variables */
+#pragma zpsym("vartab")
+extern const void* memsize;             /* points to top of BASIC RAM */
+#pragma zpsym("memsize")
+extern const struct line* txtptr;       /* points to BASIC code */
 #pragma zpsym("txtptr")
-extern char basbuf[];           /* BASIC's input buffer */
+extern char basbuf[];                   /* BASIC's input buffer */
 extern void basbuf_len[];
 #pragma zpsym("basbuf_len")
 
@@ -75,43 +79,62 @@ extern void basbuf_len[];
 int __fastcall__ exec (const char* progname, const char* cmdline)
 {
     static int fd;
-    static unsigned char dv, n = 0;
+    static unsigned char dv, n;
 
     /* Exclude devices that can't load files. */
+    /* (Use hand optimization, to make smaller code.) */
     dv = getcurrentdevice ();
-    if (dv < 8 && dv != 1 || dv > 30) {
+    if (dv < 8 && __AX__ != 1 || __AX__ > 30) {
         return _mappederrno (9);        /* illegal device number */
     }
     utoa (dv, basic.unit, 10);
 
-    /* Don't try to run a program that can't be found. */
-    fd = open (progname, O_RDONLY);
-    if (fd < 0) {
-        return fd;
+    /* Tape files can be openned only once; skip this test for the Datasette. */
+    if (dv != 1) {
+        /* Don't try to run a program that can't be found. */
+        fd = open (progname, O_RDONLY);
+        if (fd < 0) {
+            return -1;
+        }
+        close (fd);
     }
-    close (fd);
 
+    n = 0;
     do {
         if ((basic.name[n] = progname[n]) == '\0') {
             break;
         }
-    } while (++n < 20);         /* truncate long names */
+    } while (++n < 20);                 /* truncate long names */
     basic.name[n] = '\"';
 
+/* This next part isn't needed by machines that put
+** BASIC source and variables in different RAM banks.
+*/
+#if !defined(__CBM510__) && !defined(__CBM610__) && !defined(__C128__)
+    /* cc65 program loads might extend beyond the end of the RAM that is allowed
+    ** for BASIC.  Then, the LOAD statement would complain that it is "out of
+    ** memory".  Some pointers that say where to put BASIC program variables
+    ** must be changed, so that we do not get that error.  One pointer is
+    ** changed here; a BASIC CLR statement changes the others.
+    */
+    vartab = (char*)memsize - 256;
+#endif
+
     /* Build the next program's argument list. */
-    basbuf[0] = 0x8f;           /* REM token */
+    basbuf[0] = 0x8F;                   /* REM token */
     basbuf[1] = '\0';
     if (cmdline != NULL) {
         strncat (basbuf, cmdline, (size_t)basbuf_len - 2);
     }
 
+    /* Tell the ROM where to find that BASIC program. */
 #if defined(__CBM510__) || defined(__CBM610__)
     pokewsys ((unsigned)&txtptr, (unsigned)&basic);
 #else
     txtptr = &basic;
 #endif
 
-    /* (The return code, in ST, will be destroyed by LOAD.
+    /* (The return code, in ST [status], will be destroyed by LOAD.
     ** So, don't bother to set it here.)
     */
     exit (__AX__);
index 02eabc12e2421be531538f590972bf982f9900ef..68f8a5d64e655a7f5b24f5296b46c4da10314e5c 100644 (file)
         .include        "vic20.inc"
 .endif
 
-        .export         _txtptr:zp, _basbuf, _basbuf_len:zp
+; exec() is written in C.
+; Provide the spellings that the C compiler wants to use.
 
-_txtptr         :=      TXTPTR
+.ifdef  VARTAB
+.exportzp _vartab       :=      VARTAB
+.exportzp _memsize      :=      MEMSIZE
+.endif
+
+.exportzp _txtptr       :=      TXTPTR
 
-_basbuf         :=      BASIC_BUF
-_basbuf_len     =       BASIC_BUF_LEN
+.export   _basbuf       :=      BASIC_BUF
+.exportzp _basbuf_len   =       BASIC_BUF_LEN