diff --git a/asminc/c64.inc b/asminc/c64.inc
index 5815bebf9..ababb1ea0 100644
--- a/asminc/c64.inc
+++ b/asminc/c64.inc
@@ -24,6 +24,7 @@ SCREEN_PTR      := $D1          ; Pointer to current char in text screen
 CURS_X          := $D3          ; Cursor column
 CURS_Y          := $D6          ; Cursor row
 CRAM_PTR        := $F3          ; Pointer to current char in color RAM
+FREKZP          := $FB          ; Five unused bytes
 
 BASIC_BUF       := $200         ; Location of command-line
 BASIC_BUF_LEN   = 89            ; Maximum length of command-line
@@ -212,4 +213,3 @@ CASSMOT         = $20           ; Cassette motor on
 TP_FAST         = $80           ; Switch Rossmoeller TurboProcess to fast mode
 
 RAMONLY         = $F8           ; (~(LORAM | HIRAM | IOEN)) & $FF
-
diff --git a/cfg/c64-overlay.cfg b/cfg/c64-overlay.cfg
index 2f7693e6e..07ce9e4b6 100644
--- a/cfg/c64-overlay.cfg
+++ b/cfg/c64-overlay.cfg
@@ -1,64 +1,70 @@
+FEATURES {
+    STARTADDRESS:     default = $0801;
+}
 SYMBOLS {
-    __LOADADDR__:    type = import;
-    __EXEHDR__:      type = import;
-    __OVERLAYADDR__: type = import;
-    __STACKSIZE__:   type = weak, value = $0800; # 2k stack
-    __OVERLAYSIZE__: type = weak, value = $1000; # 4k overlay
+    __LOADADDR__:     type = import;
+    __EXEHDR__:       type = import;
+    __OVERLAYADDR__:  type = import;
+    __STACKSIZE__:    type = weak,   value = $0800; # 2k stack
+    __OVERLAYSIZE__:  type = weak,   value = $1000; # 4k overlay
+    __HIMEM__:        type = weak,   value = $D000;
+    __OVERLAYSTART__: type = export, value = __HIMEM__ - __OVERLAYSIZE__;
 }
 MEMORY {
-    ZP:       file = "", define = yes, start = $0002,                   size = $001A;
-    LOADADDR: file = %O,               start = $07FF,                   size = $0002;
-    HEADER:   file = %O,               start = $0801,                   size = $000C;
-    RAM:      file = %O, define = yes, start = $080D,                   size = $C7F3 - __OVERLAYSIZE__ - __STACKSIZE__;
-    OVL1ADDR: file = "%O.1",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL1:     file = "%O.1",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL2ADDR: file = "%O.2",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL2:     file = "%O.2",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL3ADDR: file = "%O.3",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL3:     file = "%O.3",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL4ADDR: file = "%O.4",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL4:     file = "%O.4",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL5ADDR: file = "%O.5",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL5:     file = "%O.5",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL6ADDR: file = "%O.6",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL6:     file = "%O.6",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL7ADDR: file = "%O.7",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL7:     file = "%O.7",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL8ADDR: file = "%O.8",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL8:     file = "%O.8",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
-    OVL9ADDR: file = "%O.9",           start = $CFFE - __OVERLAYSIZE__, size = $0002;
-    OVL9:     file = "%O.9",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
+    ZP:       file = "", define = yes, start = $0002,                size = $001A;
+    LOADADDR: file = %O,               start = %S - 2,               size = $0002;
+    HEADER:   file = %O, define = yes, start = %S,                   size = $000D;
+    RAM:      file = %O, define = yes, start = __HEADER_LAST__,      size = __OVERLAYSTART__ - __STACKSIZE__ - __HEADER_LAST__;
+    MOVE:     file = %O,               start = __ZPSAVE_LOAD__,      size = __HIMEM__ - __INIT_RUN__;
+    OVL1ADDR: file = "%O.1",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL1:     file = "%O.1",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL2ADDR: file = "%O.2",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL2:     file = "%O.2",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL3ADDR: file = "%O.3",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL3:     file = "%O.3",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL4ADDR: file = "%O.4",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL4:     file = "%O.4",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL5ADDR: file = "%O.5",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL5:     file = "%O.5",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL6ADDR: file = "%O.6",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL6:     file = "%O.6",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL7ADDR: file = "%O.7",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL7:     file = "%O.7",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL8ADDR: file = "%O.8",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL8:     file = "%O.8",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
+    OVL9ADDR: file = "%O.9",           start = __OVERLAYSTART__ - 2, size = $0002;
+    OVL9:     file = "%O.9",           start = __OVERLAYSTART__,     size = __OVERLAYSIZE__;
 }
 SEGMENTS {
-    LOADADDR: load = LOADADDR, type = ro;
-    EXEHDR:   load = HEADER,   type = ro;
-    STARTUP:  load = RAM,      type = ro;
-    LOWCODE:  load = RAM,      type = ro,                optional = yes;
-    INIT:     load = RAM,      type = ro,  define = yes, optional = yes;
-    CODE:     load = RAM,      type = ro;
-    RODATA:   load = RAM,      type = ro;
-    DATA:     load = RAM,      type = rw;
-    ZPSAVE:   load = RAM,      type = bss;
-    BSS:      load = RAM,      type = bss, define = yes;
-    ZEROPAGE: load = ZP,       type = zp;
-    OVL1ADDR: load = OVL1ADDR, type = ro;
-    OVERLAY1: load = OVL1,     type = ro,  define = yes, optional = yes;
-    OVL2ADDR: load = OVL2ADDR, type = ro;
-    OVERLAY2: load = OVL2,     type = ro,  define = yes, optional = yes;
-    OVL3ADDR: load = OVL3ADDR, type = ro;
-    OVERLAY3: load = OVL3,     type = ro,  define = yes, optional = yes;
-    OVL4ADDR: load = OVL4ADDR, type = ro;
-    OVERLAY4: load = OVL4,     type = ro,  define = yes, optional = yes;
-    OVL5ADDR: load = OVL5ADDR, type = ro;
-    OVERLAY5: load = OVL5,     type = ro,  define = yes, optional = yes;
-    OVL6ADDR: load = OVL6ADDR, type = ro;
-    OVERLAY6: load = OVL6,     type = ro,  define = yes, optional = yes;
-    OVL7ADDR: load = OVL7ADDR, type = ro;
-    OVERLAY7: load = OVL7,     type = ro,  define = yes, optional = yes;
-    OVL8ADDR: load = OVL8ADDR, type = ro;
-    OVERLAY8: load = OVL8,     type = ro,  define = yes, optional = yes;
-    OVL9ADDR: load = OVL9ADDR, type = ro;
-    OVERLAY9: load = OVL9,     type = ro,  define = yes, optional = yes;
+    ZEROPAGE: load = ZP,              type = zp;
+    LOADADDR: load = LOADADDR,        type = ro;
+    EXEHDR:   load = HEADER,          type = ro;
+    STARTUP:  load = RAM,             type = ro;
+    LOWCODE:  load = RAM,             type = ro,                optional = yes;
+    CODE:     load = RAM,             type = ro;
+    RODATA:   load = RAM,             type = ro;
+    DATA:     load = RAM,             type = rw;
+    ZPSAVE:   load = RAM,             type = bss, define = yes;
+    BSS:      load = RAM,             type = bss, define = yes;
+    INIT:     load = MOVE, run = RAM, type = ro,  define = yes;
+    OVL1ADDR: load = OVL1ADDR,        type = ro;
+    OVERLAY1: load = OVL1,            type = ro,  define = yes, optional = yes;
+    OVL2ADDR: load = OVL2ADDR,        type = ro;
+    OVERLAY2: load = OVL2,            type = ro,  define = yes, optional = yes;
+    OVL3ADDR: load = OVL3ADDR,        type = ro;
+    OVERLAY3: load = OVL3,            type = ro,  define = yes, optional = yes;
+    OVL4ADDR: load = OVL4ADDR,        type = ro;
+    OVERLAY4: load = OVL4,            type = ro,  define = yes, optional = yes;
+    OVL5ADDR: load = OVL5ADDR,        type = ro;
+    OVERLAY5: load = OVL5,            type = ro,  define = yes, optional = yes;
+    OVL6ADDR: load = OVL6ADDR,        type = ro;
+    OVERLAY6: load = OVL6,            type = ro,  define = yes, optional = yes;
+    OVL7ADDR: load = OVL7ADDR,        type = ro;
+    OVERLAY7: load = OVL7,            type = ro,  define = yes, optional = yes;
+    OVL8ADDR: load = OVL8ADDR,        type = ro;
+    OVERLAY8: load = OVL8,            type = ro,  define = yes, optional = yes;
+    OVL9ADDR: load = OVL9ADDR,        type = ro;
+    OVERLAY9: load = OVL9,            type = ro,  define = yes, optional = yes;
 }
 FEATURES {
     CONDES: type    = constructor,
diff --git a/cfg/c64.cfg b/cfg/c64.cfg
index 5d8befd02..8fe1c0c6f 100644
--- a/cfg/c64.cfg
+++ b/cfg/c64.cfg
@@ -1,26 +1,31 @@
+FEATURES {
+    STARTADDRESS:  default = $0801;
+}
 SYMBOLS {
     __LOADADDR__:  type = import;
     __EXEHDR__:    type = import;
     __STACKSIZE__: type = weak, value = $0800; # 2k stack
+    __HIMEM__:     type = weak, value = $D000;
 }
 MEMORY {
-    ZP:       file = "", define = yes, start = $0002, size = $001A;
-    LOADADDR: file = %O,               start = $07FF, size = $0002;
-    HEADER:   file = %O,               start = $0801, size = $000C;
-    RAM:      file = %O, define = yes, start = $080D, size = $C7F3 - __STACKSIZE__;
+    ZP:       file = "", define = yes, start = $0002,           size = $001A;
+    LOADADDR: file = %O,               start = %S - 2,          size = $0002;
+    HEADER:   file = %O, define = yes, start = %S,              size = $000D;
+    RAM:      file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__;
+    MOVE:     file = %O,               start = __ZPSAVE_LOAD__, size = __HIMEM__ - __INIT_RUN__;
 }
 SEGMENTS {
-    LOADADDR: load = LOADADDR, type = ro;
-    EXEHDR:   load = HEADER,   type = ro;
-    STARTUP:  load = RAM,      type = ro;
-    LOWCODE:  load = RAM,      type = ro,                optional = yes;
-    INIT:     load = RAM,      type = ro,  define = yes, optional = yes;
-    CODE:     load = RAM,      type = ro;
-    RODATA:   load = RAM,      type = ro;
-    DATA:     load = RAM,      type = rw;
-    ZPSAVE:   load = RAM,      type = bss;
-    BSS:      load = RAM,      type = bss, define = yes;
-    ZEROPAGE: load = ZP,       type = zp;
+    ZEROPAGE: load = ZP,              type = zp;
+    LOADADDR: load = LOADADDR,        type = ro;
+    EXEHDR:   load = HEADER,          type = ro;
+    STARTUP:  load = RAM,             type = ro;
+    LOWCODE:  load = RAM,             type = ro,                optional = yes;
+    CODE:     load = RAM,             type = ro;
+    RODATA:   load = RAM,             type = ro;
+    DATA:     load = RAM,             type = rw;
+    ZPSAVE:   load = RAM,             type = bss, define = yes;
+    BSS:      load = RAM,             type = bss, define = yes;
+    INIT:     load = MOVE, run = RAM, type = ro,  define = yes;
 }
 FEATURES {
     CONDES: type    = constructor,
diff --git a/libsrc/c64/crt0.s b/libsrc/c64/crt0.s
index 24fe4376b..a2abe91af 100644
--- a/libsrc/c64/crt0.s
+++ b/libsrc/c64/crt0.s
@@ -4,12 +4,12 @@
 
         .export         _exit
         .export         __STARTUP__ : absolute = 1      ; Mark as startup
+
         .import         initlib, donelib
-        .import         zerobss
-        .import         callmain
-        .import         RESTOR, BSOUT, CLRCH
+        .import         moveinit, zerobss, callmain
+        .import         BSOUT
         .import         __RAM_START__, __RAM_SIZE__     ; Linker generated
-        .import         __STACKSIZE__                   ; Linker generated
+        .import         __STACKSIZE__                   ; from configure file
         .importzp       ST
 
         .include        "zeropage.inc"
@@ -23,14 +23,6 @@
 
 Start:
 
-; Save the zero-page locations that we need.
-
-        ldx     #zpspace-1
-L1:     lda     sp,x
-        sta     zpsave,x
-        dex
-        bpl     L1
-
 ; Switch to the second charset.
 
         lda     #14
@@ -39,35 +31,30 @@ L1:     lda     sp,x
 ; Switch off the BASIC ROM.
 
         lda     $01
-        pha                     ; Remember the value
+        sta     mmusave         ; Save the memory configuration
         and     #$F8
         ora     #$06            ; Enable Kernal+I/O, disable BASIC
         sta     $01
 
-; Clear the BSS data.
-
-        jsr     zerobss
-
-; Save some system settings; and, set up the stack.
-
-        pla
-        sta     mmusave         ; Save the memory configuration
-
         tsx
         stx     spsave          ; Save the system stack ptr
 
-        lda     #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
-        sta     sp
-        lda     #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
-        sta     sp+1            ; Set argument stack ptr
+; Allow some re-entrancy by skipping the next task if it already was done.
+; This sometimes can let us rerun the program without reloading it.
 
-; Call the module constructors.
+        ldx     move_init
+        beq     L0
 
-        jsr     initlib
+; Move the INIT segment from where it was loaded (over ZPSAVE and BSS)
+; into where it must be run (in the heap).
 
-; Push the command-line arguments; and, call main().
+        jsr     moveinit
+        dec     move_init       ; set to false
 
-        jsr     callmain
+; Save space by putting the rest of the start-up code in the INIT segment,
+; which can be re-used by the heap and the C stack.
+
+L0:     jsr     initstart
 
 ; Back from main() [this is also the exit() entry]. Run the module destructors.
 
@@ -98,14 +85,55 @@ L2:     lda     zpsave,x
 
         rts
 
+
+; ------------------------------------------------------------------------
+
+.segment        "INIT"
+
+initstart:
+
+; Save the zero-page locations that we need.
+
+        ldx     #zpspace-1
+L1:     lda     sp,x
+        sta     zpsave,x
+        dex
+        bpl     L1
+
+; Clear the BSS data.
+
+        jsr     zerobss
+
+; Set up the stack.
+
+        lda     #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
+        ldx     #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
+        sta     sp
+        stx     sp+1            ; Set argument stack ptr
+
+; Call the module constructors.
+
+        jsr     initlib
+
+; Push the command-line arguments; and, call main().
+
+        jmp     callmain
+
+
 ; ------------------------------------------------------------------------
 ; Data
 
+.data
+
+; These two variables were moved out of the BSS segment, and into DATA, because
+; we need to use them before INIT is moved off of BSS, and before BSS is zeroed.
+
+mmusave:.res    1
+spsave: .res    1
+
+move_init:
+        .byte   1
+
 .segment        "ZPSAVE"
 
 zpsave: .res    zpspace
-
-.bss
-
-spsave: .res    1
-mmusave:.res    1
diff --git a/libsrc/common/moveinit.s b/libsrc/common/moveinit.s
new file mode 100644
index 000000000..2186adf0e
--- /dev/null
+++ b/libsrc/common/moveinit.s
@@ -0,0 +1,45 @@
+;
+; 2015-10-07, Greg King
+;
+
+        .export         moveinit
+
+        .import         __INIT_LOAD__, __INIT_RUN__, __INIT_SIZE__ ; Linker-generated
+
+        .macpack        cpu
+        .macpack        generic
+
+
+; Put this in the DATA segment because it is self-modifying code.
+
+.data
+
+; Move the INIT segment from where it was loaded (over the bss segments)
+; into where it must be run (in the heap).  The two areas might overlap; and,
+; the segment is moved upwards.  Therefore, this code starts at the highest
+; address, and decrements to the lowest address.  The low bytes of the starting
+; pointers are not sums.  The high bytes are sums; but, they do not include the
+; carry.  Both the low-byte sums and the carries will be done when the pointers
+; are indexed by the .Y register.
+
+moveinit:
+
+; First, move the last, partial page.
+; Then, move all of the full pages.
+
+        ldy     #<__INIT_SIZE__         ; size of partial page
+        ldx     #>__INIT_SIZE__ + (<__INIT_SIZE__ <> 0)  ; number of pages, including partial
+
+L1:     dey
+init_load:
+        lda     __INIT_LOAD__ + (__INIT_SIZE__ & $FF00) - $0100 * (<__INIT_SIZE__ = 0),y
+init_run:
+        sta     __INIT_RUN__  + (__INIT_SIZE__ & $FF00) - $0100 * (<__INIT_SIZE__ = 0),y
+        tya
+        bnz     L1                      ; page not finished
+
+        dec     init_load+2
+        dec     init_run+2
+        dex
+        bnz     L1                      ; move next page
+        rts