\ Save a copy of the current Forth core with all contents of the user flash

\ -----------------------------------------------------------------------------
\ reading and writing ELF headers
\ -----------------------------------------------------------------------------

\ retrieve program headers
: elfhdr>phdrs ( elfhdr -- phdrs )
  dup $1c + @ + ;

\ update program header file size
: p_filesz! ( phdr filesz -- )
  swap $10 + ! ;

\ retrieve section headers
: elfhdr>shdrs ( elfhdr -- shdrs )
  dup $20 + @ + ;

\ retrieve section header size
: elfhdr>shentsize ( elfhdr -- entsize )
  $2e + h@ ;

\ retrieve the desired section header
: elfhdr>shdr ( elfhdr i -- shdr )
  >r dup elfhdr>shdrs swap elfhdr>shentsize r> * + ;

\ adjust section end
: sh_end! ( shdr end -- )
  over $0c + @ -         \ compute sh_size from sh_addr and end
  swap $14 + ! ;         \ update sh_size

\ adjust section base address in image and memory
: sh_addr! ( shdr addr -- )
  over $0c + @ - >r         \ compute adjustment
  r@ over $0c + +!          \ adjust sh_addr
  r@ over $10 + +!          \ adjust sh_offset
  $14 + r> negate swap +! ; \ adjust sh_size

\ ELF section numbers (see elfheader.s)
2 constant #mecrisp
3 constant #userdictionary

\ adjust our own ELF header according to here
: adjustelf ( -- )
  incipit elfhdr>phdrs here incipit - p_filesz!
  incipit #mecrisp elfhdr>shdr here sh_end!
  incipit #userdictionary elfhdr>shdr here sh_addr! ;

\ -----------------------------------------------------------------------------
\ saving the program image back to disk
\ -----------------------------------------------------------------------------


: save ( addr len -- ) \ Save a copy of the whole Forth core with flash dictionary contents

  compiletoram? compiletoflash >r

  adjustelf
  [ 8 base ! ]
  777 sys-creat \ open new program image
  [ decimal ]
  if
    dup incipit here incipit - sys-write 2drop
    sys-close drop
  else
    perror" Cannot create program image"
  then

  r> if compiletoram then
;

: save" ( -- ) [char] " parse save ;

\ -----------------------------------------------------------------------------
