[openfirmware] r838 - cpu/x86/pc/lxdevel cpu/x86/pc/olpc dev dev/geode dev/olpc/spiflash ofw/confvar ofw/core ofw/fs

svn at openfirmware.info svn at openfirmware.info
Wed Jun 25 01:14:57 CEST 2008


Author: wmb
Date: 2008-06-25 01:14:57 +0200 (Wed, 25 Jun 2008)
New Revision: 838

Added:
   dev/flashpkg.fth
   dev/flashrb.fth
   dev/flashwrite.fth
   dev/subrange.fth
Modified:
   cpu/x86/pc/lxdevel/config.fth
   cpu/x86/pc/lxdevel/devices.fth
   cpu/x86/pc/lxdevel/fw.bth
   cpu/x86/pc/olpc/devices.fth
   dev/geode/lpcflash.fth
   dev/olpc/spiflash/flashec.fth
   dev/olpc/spiflash/spiflash.fth
   dev/olpc/spiflash/spiui.fth
   ofw/confvar/nameval.fth
   ofw/core/ofwcore.fth
   ofw/fs/dropinfs.fth
Log:
Big revision of the FLASH infrastructure so it's easier to
integrate FLASH write drivers into the system.  For OLPC,
there is no functional difference at the top level, but
the internal arrangement of the FLASH device node subtree
has changed.  It's now possible to compile an OLPC ROM
that can save configuration variables in an SPI FLASH
block (see config.fth:use-flash-nvram).  For the lxdevel
build, that option is now chosen by default.

Modified: cpu/x86/pc/lxdevel/config.fth
===================================================================
--- cpu/x86/pc/lxdevel/config.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ cpu/x86/pc/lxdevel/config.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -39,7 +39,8 @@
 create no-floppy-node
 create use-pci-isa
 
-create use-null-nvram
+\ create use-null-nvram  \ Don't store configuration variables
+create use-flash-nvram  \ Store configuration variables in SPI FLASH
 
 fload ${BP}/cpu/x86/pc/lxdevel/addrs.fth
 

Modified: cpu/x86/pc/lxdevel/devices.fth
===================================================================
--- cpu/x86/pc/lxdevel/devices.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ cpu/x86/pc/lxdevel/devices.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -76,11 +76,12 @@
 0 0  dropin-base <# u#s u#>  " /" begin-package
    " flash" device-name
 
-[ifdef] addresses-assigned  dropin-size  [else]  h# 4.0000  [then]
+[ifdef] addresses-assigned  dropin-size  [else]  h# 8.0000  [then]
    dup value /device
    constant /device-phys
    my-address my-space /device-phys reg
-   fload ${BP}/cpu/x86/pc/flashpkg.fth
+   fload ${BP}/dev/flashpkg.fth
+   fload ${BP}/dev/flashwrite.fth
 
    : init  ( comp$ /device -- )
       to /device  2>r
@@ -92,10 +93,29 @@
       /device /device-phys <>  if  enable-flash-select  then
 [then]
    ;
+end-package
 
+\ Create a node below the top-level FLASH node to accessing the portion
+\ containing the dropin modules.
+\ The number in the line below is the offset from the beginning of the
+\ FLASH to the block that contains the dropin modules.
+0 0  " 0"  " /flash" begin-package
+   " dropins" device-name
+
+   h# 70000 constant /device      \ Size of the area for dropin modules
+   fload ${BP}/dev/subrange.fth
 end-package
-" rom"  dropin-base <# u#s " /flash@" hold$ u#>  $devalias
 
+devalias dropins /dropins
+
+\ Create a pseudo-device that presents the dropin modules as a filesystem.
+0 0 " "  " /" begin-package
+   fload ${BP}/ofw/fs/dropinfs.fth
+end-package
+
+\ This devalias lets us say, for example, "dir rom:"
+devalias rom     /dropin-fs
+
 fload ${BP}/cpu/x86/forthint.fth	\ Low-level interrupt handling code
 fload ${BP}/dev/isa/irq.fth		\ ISA interrupt dispatcher
 fload ${BP}/cpu/x86/pc/isatick.fth	        \ Use ISA timer as the alarm tick timer
@@ -112,11 +132,7 @@
 devalias d disk
 devalias n nand
 devalias u /usb/disk
-devalias sd /sd/disk
 
-\ If we don't do the ctlr-selftest, the keyboard won't start on the LX devel board
-\ dev /8042      patch false ctlr-selftest open   device-end
-
 0 0  " i70"  " /isa" begin-package   	\ Real-time clock node
    fload ${BP}/dev/ds1385r.fth
    8 encode-int  0 encode-int encode+    " interrupts" property
@@ -159,6 +175,10 @@
 [then]
 
 [ifdef] use-null-nvram
+\ For not storing configuration variable changes across reboots ...
+\ This is useful for "turnkey" systems where configurability would
+\ increase support costs.
+
 fload ${BP}/cpu/x86/pc/nullnv.fth
 stand-init: Null-NVRAM
    " /null-nvram" open-dev  to nvram-node
@@ -166,6 +186,29 @@
 ;
 [then]
 
+[ifdef] use-flash-nvram
+\ For configuration variables stored in a sector of the boot FLASH ...
+
+\ Create a node below the top-level FLASH node to access the portion
+\ containing the configuration variables.
+
+\ The number in the line below is the offset from the beginning of the
+\ FLASH to the block that contains the configuration variables.
+0 0  " 70000"  " /flash" begin-package
+   " nvram" device-name
+
+   \ Size of configuration variable area.  Typically the size of
+   \ a FLASH block (erase unit).
+   h# 10000 constant /device
+   fload ${BP}/dev/subrange.fth
+end-package
+
+stand-init: NVRAM
+   " /nvram" open-dev  to nvram-node
+   ['] init-config-vars catch drop
+;
+[then]
+
 \ Create the alias unless it already exists
 : $?devalias  ( alias$ value$ -- )
    2over  not-alias?  if  $devalias exit  then  ( alias$ value$ alias$ )
@@ -220,7 +263,7 @@
    dend
 ;
 
-\ fload ${BP}/dev/geode/lpcflash.fth           \ Reflasher for PLCC FLASH on A-test
+fload ${BP}/dev/geode/lpcflash.fth           \ Reflasher for LPC FLASH
 
 : +i encode-int encode+  ;  : 0+i  0 +i  ;
 

Modified: cpu/x86/pc/lxdevel/fw.bth
===================================================================
--- cpu/x86/pc/lxdevel/fw.bth	2008-06-20 23:37:28 UTC (rev 837)
+++ cpu/x86/pc/lxdevel/fw.bth	2008-06-24 23:14:57 UTC (rev 838)
@@ -188,6 +188,8 @@
 fload ${BP}/cpu/x86/pc/mmusetup.fth	\ Initial values for MMU lists
 [then]
 
+: background-rgb  ( -- r g b )  h# ff h# ff h# ff  ;
+
 fload ${BP}/cpu/x86/pc/lxdevel/devices.fth
 
 [ifdef] rom-loaded

Modified: cpu/x86/pc/olpc/devices.fth
===================================================================
--- cpu/x86/pc/olpc/devices.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ cpu/x86/pc/olpc/devices.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -79,29 +79,36 @@
 ;
 warning !
 
-0 0  dropin-base <# u#s u#>  " /" begin-package
+\ Create the top-level device node to access the entire boot FLASH device
+0 0  " fff00000"  " /" begin-package
    " flash" device-name
 
-   h# 10.0000
-   dup value /device
-   constant /device-phys
+   h# 10.0000 value /device
+   h# 10.0000 constant /device-phys
    my-address my-space /device-phys reg
-   fload ${BP}/cpu/x86/pc/flashpkg.fth
+   fload ${BP}/dev/flashpkg.fth
+   fload ${BP}/dev/flashwrite.fth
+end-package
 
-   : init  ( comp$ /device -- )
-      to /device  2>r
-      0 0 encode-bytes
-      2r> encode-string encode+
-      " rom" encode-string encode+
-      " compatible" property
-[ifdef] enable-flash-select      
-      /device /device-phys <>  if  enable-flash-select  then
-[then]
-   ;
+\ Create a node below the top-level FLASH node to accessing the portion
+\ containing the dropin modules
+0 0  " 10000"  " /flash" begin-package
+   " dropins" device-name
 
+   h# c0000 constant /device
+   fload ${BP}/dev/subrange.fth
 end-package
-" rom"  dropin-base <# u#s " /flash@" hold$ u#>  $devalias
 
+devalias dropins /dropins
+
+\ Create a pseudo-device that presents the dropin modules as a filesystem.
+0 0 " "  " /" begin-package
+   fload ${BP}/ofw/fs/dropinfs.fth
+end-package
+
+\ This devalias lets us say, for example, "dir rom:"
+devalias rom     /dropin-fs
+
 fload ${BP}/cpu/x86/forthint.fth	\ Low-level interrupt handling code
 fload ${BP}/dev/isa/irq.fth		\ ISA interrupt dispatcher
 fload ${BP}/cpu/x86/pc/isatick.fth	        \ Use ISA timer as the alarm tick timer
@@ -156,22 +163,11 @@
 devalias nand /nandflash
 devalias mtd  /nandflash
 
-[ifdef] pseudo-nvram
-fload ${BP}/cpu/x86/pc/biosload/filenv.fth
-dev /file-nvram
-: floppy-nv-file  ( -- )  " a:\nvram.dat"  ;
-' floppy-nv-file to nv-file
-device-end
-stand-init: Pseudo-NVRAM
-   " /file-nvram" open-dev  to nvram-node
-   nvram-node 0=  if
-      ." The configuration EEPROM is not working" cr
-   then
-   ['] init-config-vars catch drop
-;
-[then]
+[ifdef] use-null-nvram
+\ For not storing configuration variable changes across reboots ...
+\ This is useful for "turnkey" systems where configurability would
+\ increase support costs.
 
-[ifdef] use-null-nvram
 fload ${BP}/cpu/x86/pc/nullnv.fth
 stand-init: Null-NVRAM
    " /null-nvram" open-dev  to nvram-node
@@ -179,6 +175,24 @@
 ;
 [then]
 
+[ifdef] use-flash-nvram
+\ For configuration variables stored in a sector of the boot FLASH ...
+
+\ Create a node below the top-level FLASH node to access the portion
+\ containing the configuration variables.
+0 0  " d0000"  " /flash" begin-package
+   " nvram" device-name
+
+   h# 10000 constant /device
+   fload ${BP}/dev/subrange.fth
+end-package
+
+stand-init: NVRAM
+   " /nvram" open-dev  to nvram-node
+   ['] init-config-vars catch drop
+;
+[then]
+
 \ Create the alias unless it already exists
 : $?devalias  ( alias$ value$ -- )
    2over  not-alias?  if  $devalias exit  then  ( alias$ value$ alias$ )

Added: dev/flashpkg.fth
===================================================================
--- dev/flashpkg.fth	                        (rev 0)
+++ dev/flashpkg.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -0,0 +1,107 @@
+purpose: Package for FLASH ROM device
+\ See license at end of file
+
+headerless
+0 value device-base
+0 value open-count
+0 instance value seek-ptr
+
+: clip-size  ( adr len -- len' adr len' )
+   seek-ptr +   /device min  seek-ptr -     ( adr len' )
+   tuck
+;
+: update-ptr  ( len' -- len' )  dup seek-ptr +  to seek-ptr  ;
+
+headers
+external
+: seek  ( d.offset -- status )
+   0<>  over /device u>  or  if  drop true  exit  then \ Seek offset too big
+   to seek-ptr
+   false
+;
+
+: open  ( -- flag )
+   \ This lets us open the node during compilation
+   standalone?  0=  if  true exit  then
+
+   open-count  dup 1+  to open-count   0=  if       ( )
+[ifdef] eprom-va
+      eprom-va
+[else]
+      my-address my-space /device  " map-in" $call-parent
+[then]
+      to device-base
+   then                                             ( )
+   0 to seek-ptr                                    ( )
+   true                                             ( true )
+;
+: close  ( -- )
+   \ This lets us open the node during compilation
+   standalone?  0=  if  exit  then
+
+   open-count dup 1- 0 max to open-count  ( old-count )
+[ifdef] eprom-va
+   drop
+[else]
+   1 =  if  device-base /device " map-out" $call-parent  then
+[then]
+;
+: size  ( -- d.size )  /device u>d  ;
+: read  ( adr len -- actual )
+   clip-size                        ( len' adr len' )
+   seek-ptr device-base +  -rot     ( len' device-adr adr len' )
+   move                             ( len' )
+   update-ptr                       ( len' )
+;
+
+0 [if]
+\ Write support is complicated by the need to erase before
+\ writing and the possibly-different erase and write granularity.
+\
+\ For NOR FLASH, where you can write as many times as you want
+\ while turning 1's into 0's, the algorithm is:
+\
+\ Break the entire write range into pieces each contained in one
+\ erase unit.  For each piece:
+\
+\   Compare the existing and new contents to see if the unit needs erasing
+\
+\   If no bits need to go from 0 to 1, erase is unnecessary, so just write.
+\   (It's a little more complicated if the write granularity is >1 byte.)
+\
+\   Otherwise, copy the existing contents of the erase unit to a buffer,
+\   merge in the new data, erase, then write back the buffer.
+[then]
+
+\ These permit subordinate nodes for subranges of the device, for
+\ purposes like dropin driver collections, configuration variables, etc.
+1 " #address-cells" integer-property
+
+: decode-unit  ( adr len -- phys )  push-hex  $number  if  0  then  pop-base  ;
+: encode-unit  ( phys -- adr len )  push-hex  (u.)  pop-base  ;
+: map-in   ( offset size -- virt )  drop  device-base +  ;
+: map-out  ( virt size -- virt )  2drop  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/flashrb.fth
===================================================================
--- dev/flashrb.fth	                        (rev 0)
+++ dev/flashrb.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -0,0 +1,106 @@
+purpose: Driver for storing reboot info in a FLASH sector
+\ See license at end of file
+
+\ This device is subordinate to the "flash" device node.
+\ It accesses reboot information stored in a FLASH sector.
+
+\ The reboot information could be updated on every system reboot. To
+\ extend the lifetime of the FLASH, we use an incremental writing strategy
+\ that minimizes the number of times that the sector must be rewritten.
+\ It works as follows:
+\
+\ The sector contains all h# ff bytes when it is completely erased.
+\ If it contains all ff's, this is a normal boot, not a reboot.
+\ Otherwise, the first non-ff byte is the reboot count byte.  If that
+\ count byte is 0, this is a normal boot, not a reboot.
+\ Otherwise, this is a reboot, and the count-1 following bytes
+\ are the reboot argument string.  (If count is 1, this is a reboot with
+\ a null argument string.)
+\ When the firmware reads the reboot info during the reboot process, it sets
+\ the count byte to zero (which can be done without erasing the sector), thus
+\ cancelling the reboot information.
+\ To initiate a new reboot, the driver places the new count and argument
+\ string before the old one.  The driver erases the entire sector only
+\ when it fills up so there isn't enough space for the new string.
+
+" reboot-info" device-name
+
+\ Requires that /device be defined externally
+my-address my-space /device reg
+
+: sector-buf  ( -- adr )  " 'base-adr" $call-parent  my-space +  ;
+
+external
+: open  ( -- flag )  true  ;
+: close  ( -- )  ;
+
+: reboot-byte  ( -- adr byte )
+   sector-buf   /device  0  do     ( adr )
+      dup c@  h# ff <>  if                        ( adr )
+         dup c@ unloop exit                       ( adr byte )
+      then                                        ( adr )
+      1+                                          ( adr' )
+   loop                                           ( adr )
+   0                                              ( adr byte )
+;
+
+: write-byte  ( byte offset -- )
+   my-space +  " write-byte" $call-parent
+   " read-mode" $call-parent
+;
+: write-bytes  ( adr offset len -- )
+   swap my-space + swap  " write-bytes" $call-parent
+;
+
+: erase-sector  ( -- )  my-space  " sector-erase" $call-parent  ;
+
+: find-offset  ( len -- actual offset )
+   /device min                      ( actual )
+   reboot-byte drop  sector-buf -   ( actual last-offset )
+   over -                           ( actual new-offset )
+   dup 0<  if                       ( actual new-offset )
+      drop  erase-sector            ( actual )
+      /device  over -               ( actual offset )
+   then                             ( actual offset )
+;
+
+: read  ( adr len -- actual )
+   reboot-byte                        ( adr len reboot-adr count )
+   dup 0=  if  4drop -1 exit  then    ( adr len reboot-adr count )
+   0 2 pick sector-buf -  write-byte  ( adr len reboot-adr count )
+   1 /string  rot min                 ( adr reboot-adr' actual )
+   >r  swap r@ move  r>               ( reboot-adr actual )
+;
+
+: write  ( adr len -- actual )
+   1+ find-offset                   ( adr actual+1 offset )
+   2dup write-byte                  ( adr actual+1 offset )
+   swap  1 /string                  ( adr offset+1 actual )
+   dup >r  write-bytes              ( r: actual )
+   r>
+;
+: size  ( -- d )  /device 0  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: dev/flashwrite.fth
===================================================================
--- dev/flashwrite.fth	                        (rev 0)
+++ dev/flashwrite.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -0,0 +1,104 @@
+0 [if]
+\ Write support is complicated by the need to erase before
+\ writing and the possibly-different erase and write granularity.
+\
+\ For NOR FLASH, where you can write as many times as you want
+\ while turning 1's into 0's, the algorithm is:
+\
+\ Break the entire write range into pieces each contained in one
+\ erase unit.  For each piece:
+\
+\   Compare the existing and new contents to see if the unit needs erasing
+\
+\   If no bits need to go from 0 to 1, erase is unnecessary, so just write.
+\   (It's a little more complicated if the write granularity is >1 byte.)
+\
+\   Otherwise, copy the existing contents of the erase unit to a buffer,
+\   merge in the new data, erase, then write back the buffer.
+[then]
+
+\ dev /flash
+
+[ifndef] flash-write-enable
+also forth definitions
+defer flash-write-enable   ( -- )
+defer flash-write-disable  ( -- )
+defer flash-erase-block    ( offset -- )
+defer flash-write          ( adr len offset -- )
+defer flash-read           ( adr len offset -- )
+defer flash-verify         ( adr len offset -- )
+h# 10.0000 value /flash
+h# 10000 value /flash-block
+previous definitions
+[then]
+
+
+: left-in-block  ( len offset -- #left )
+   \ Determine how many bytes are left in the page containing offset
+   /flash-block  swap /flash-block 1- and -  ( len left-in-page )
+   min                                       ( #left )
+;
+
+: must-erase?  ( adr len -- flag )
+   device-base seek-ptr +         ( adr len dev-adr )
+   swap  0  ?do                   ( adr dev-adr )
+      over i + c@  over i + c@    ( adr dev-adr new-byte old-byte )
+      \ Must erase if a bit in old-byte is 0 and that bit in new-byte is 1
+      invert and  if              ( adr dev-adr )
+         2drop true unloop exit
+      then                        ( adr dev-adr )
+   loop                           ( adr dev-adr )
+   2drop false
+;
+
+: erase+write  ( adr len -- )
+   dup /flash-block =  if
+      \ If we are going to overwrite the entire block, there's no need to
+      \ preserve the old data.  This can only happen if we are already
+      \ aligned on an erase block boundary.
+      seek-ptr flash-erase-block           ( adr len )
+      seek-ptr flash-write                 ( )
+   else
+      \ Allocate a buffer to save the old block contents
+      /flash-block alloc-mem  >r                 ( adr len )
+
+      seek-ptr /flash-block round-down           ( adr len block-start )
+
+      \ Copy existing data from FLASH block to the buffer
+      dup device-base +  r@  /flash-block lmove  ( adr len block-start )
+
+      \ Merge new bytes into the buffer
+      -rot                                       ( block-start adr len )
+      seek-ptr /flash-block mod                  ( block-start adr len buf-offset )
+      r@ +  swap move                            ( block-start )
+
+      \ Erase the block and rewrite it from the buffer
+      dup  flash-erase-block                     ( block-start )
+      r@  /flash-block  rot  flash-write         ( )
+
+      \ Release the buffer
+      r> /flash-block free-mem
+   then
+;
+
+: handle-block  ( adr len -- adr' len' )
+   dup seek-ptr left-in-block         ( adr len #left )
+   >r                                 ( adr len r: #left )
+   over r@ must-erase?  if            ( adr len r: #left )
+      over r@ erase+write             ( adr len r: #left )
+   else                               ( adr len r: #left )
+      over r@ seek-ptr flash-write    ( adr len r: #left )
+   then                               ( adr len r: #left )
+   seek-ptr r@ + to seek-ptr          ( adr len r: #left )
+   r> /string                         ( adr' len' )
+;
+
+: write  ( adr len -- #written )
+   flash-write-enable
+   tuck                                       ( len adr len )
+   begin  dup  while  handle-block  repeat    ( len adr' remain' )
+   2drop                                      ( len )
+   flash-write-disable
+;
+
+\ dend

Modified: dev/geode/lpcflash.fth
===================================================================
--- dev/geode/lpcflash.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ dev/geode/lpcflash.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -1,20 +1,22 @@
 \ See license at end of file.
-purpose: LPC/FWH FLASH writer.  This assumes a 1 MiB device.
+purpose: LPC/FWH FLASH writer.
 
 : geode-lpc-write-enable  ( -- )
    h# 1808 rdmsr  h# ff.ffff and  h# 2100.0000 or  h# 1808 wrmsr
 ;
+: geode-lpc-write-disable  ( -- )
+   h# 1808 rdmsr  h# ff.ffff and  h# 2500.0000 or  h# 1808 wrmsr
+;
 
 h# 1.0000 constant /lpc-block
 h# fff0.0000 constant lpc-flash-base
 
-: ?lpc  ( -- )
+: lpc-flash-write-enable  ( -- )
    h# ffbc.0000 c@  ( id0 )
    dup 0=  swap h# ff =  or  abort" LPC FLASH not present"
    geode-lpc-write-enable
 ;
 
-
 : >lpc-adr  ( offset -- )  lpc-flash-base +  ;
 : lpc-jedec!  ( byte -- )  h# 5555 >lpc-adr  c!  ;
 
@@ -45,34 +47,115 @@
    lpc-wait-toggle
 ;
 
-: lpc-write-block  ( adr len offset -- )
-   dup lpc-erase-block         ( adr len offset )
+: lpc-flash-read  ( adr len offset -- )
+   lpc-flash-base +  -rot  move
+;
+: lpc-flash-verify  ( adr len offset -- )
+   lpc-flash-base +  -rot  comp
+   abort" LPC FLASH verify failed"
+;
+
+: lpc-flash-write  ( adr len offset -- )
    -rot  bounds  ?do           ( offset )
       i c@ over lpc!   1+      ( offset' )
    loop                        ( offset )
    drop
 ;
+: lpc-write-block  ( adr len offset -- )
+   dup lpc-erase-block         ( adr len offset )
+   lpc-flash-write
+;
 
-: lpc-reflash   ( -- )   \ Flash from data already in memory
-   ?file
+\ Create defer words for generic FLASH writing routines if necessary
+[ifndef] flash-write-enable
+defer flash-write-enable   ( -- )
+defer flash-write-disable  ( -- )
+defer flash-write          ( adr len offset -- )
+defer flash-read           ( adr len offset -- )
+defer flash-verify         ( adr len offset -- )
+defer flash-erase-block    ( offset -- )
+h# 10.0000 value /flash-block
+h# 10000 value /flash-block
+[then]
 
-[ifdef] crc2-offset
-   \ Insert another CRC, this time including the mfg data
-   flash-buf  /flash  crc                  ( crc )
-   flash-buf  /flash +  crc2-offset -  l!  ( )
+\ Install the LPC FLASH versions as their implementations.
+
+: use-lpc-flash  ( -- )
+   ['] lpc-flash-write-enable  to flash-write-enable
+   ['] geode-lpc-write-disable to flash-write-disable
+   ['] lpc-flash-write         to flash-write
+   ['] lpc-flash-read          to flash-read
+   ['] lpc-flash-verify        to flash-verify
+   ['] lpc-erase-block         to flash-erase-block
+   h# 8.0000  to /flash        \ Should be determined dynamically
+   /lpc-block to /flash-block
+;
+use-lpc-flash
+
+[ifndef] reflash
+\ Simple UI for reflashing, assuming that you want to overwrite
+\ the entire FLASH contents.  That's not always a good assumption;
+\ some systems use certain FLASH blocks for persistent data like
+\ configuration variables or manufacturing data ("Vital Product Data").
+
+[ifdef] load-base
+: flash-buf  load-base  ;
+[else]
+/flash buffer: flash-buf
 [then]
+0 value file-loaded?
 
-   ?lpc
+: ?image-valid   ( len -- )
+   /flash <> abort" Image file is the wrong length"
+;
+
+: $get-file  ( "filename" -- )
+   $read-open
+   flash-buf  /flash  ifd @ fgets   ( len )
+   ifd @ fclose
+
+   ?image-valid
+
+   true to file-loaded?
+;
+
+: ?file  ( -- )
+   file-loaded?  0=  if
+      ." You must first load a valid FLASH image file with" cr
+      ."    get-file filename" cr
+      abort
+   then
+;
+
+: reflash   ( -- )   \ Flash from data already in memory
+   ?file
+
+   flash-write-enable
    ." Writing" cr
 
    /flash  0  ?do
       (cr i .
-      flash-buf i +  /lpc-block  i  lpc-write-block  ( )
-   /lpc-block +loop
+      flash-buf i +  /flash-block  i  flash-write  ( )
+   /flash-block +loop
+
+   flash-write-disable
 ;
 
-: lpc-flash  ( ["filename"] -- )  get-file lpc-reflash  ;
+\ Set this defer word to return a string naming the default
+\ filename for firmware updates
+defer fw-filename$  ' null$ to fw-filename$
 
+: get-file  ( ["filename"] -- )
+   parse-word   ( adr len )
+   dup 0=  if  2drop fw-filename$  then  ( adr len )
+   ." Reading " 2dup type cr                     ( adr len )
+   $get-file
+;
+
+: flash  ( ["filename"] -- )  get-file reflash  ;
+[then]
+
+
 \ LICENSE_BEGIN
 \ Copyright (c) 2006 FirmWorks
 \ 

Modified: dev/olpc/spiflash/flashec.fth
===================================================================
--- dev/olpc/spiflash/flashec.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ dev/olpc/spiflash/flashec.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -13,8 +13,7 @@
 
    /ec <> abort" EC image file is the wrong length"
 
-   spi-start
-   spi-identify .spi-id cr
+   flash-write-enable
 
    \ merge-mfg-data
 

Modified: dev/olpc/spiflash/spiflash.fth
===================================================================
--- dev/olpc/spiflash/spiflash.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ dev/olpc/spiflash/spiflash.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -310,8 +310,33 @@
    then
 ;
 
+: spi-flash-write-enable  ( -- )  spi-start spi-identify  .spi-id cr  ;
 
+\ Create defer words for generic FLASH writing routines if necessary
+[ifndef] flash-write-enable
+defer flash-write-enable   ( -- )
+defer flash-write-disable  ( -- )
+defer flash-write          ( adr len offset -- )
+defer flash-read           ( adr len offset -- )
+defer flash-verify         ( adr len offset -- )
+defer flash-erase-block    ( offset -- )
+h# 10.0000 value /flash-block
+h# 10000 value /flash-block
+[then]
 
+\ Install the SPI FLASH versions as their implementations.
+: use-spi-flash  ( -- )
+   ['] spi-flash-write-enable  to flash-write-enable
+   ['] spi-reprogrammed        to flash-write-disable
+   ['] write-spi-flash         to flash-write
+   ['] read-spi-flash          to flash-read
+   ['] verify-spi-flash        to flash-verify
+   ['] erase-spi-block         to flash-erase-block
+   h# 10.0000  to /flash
+   /spi-eblock to /flash-block
+;
+use-spi-flash
+
 0 [if]
 \ Command support by device
 \ Numbers are #address_bytes, #dummy_bytes, #data_bytes

Modified: dev/olpc/spiflash/spiui.fth
===================================================================
--- dev/olpc/spiflash/spiui.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ dev/olpc/spiflash/spiui.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -7,24 +7,26 @@
 \ access the FLASH device are defined elsewhere.
 
 h# 4000 constant /chunk   \ Convenient sized piece for progress reports
-h# 100000 constant /flash
-h# 10000 constant /flash-block \ Size of erase block
 
+[ifdef] use-flash-nvram
+h# d.0000 constant nvram-offset
+[then]
+
 h# e.0000 constant mfg-data-offset
 mfg-data-offset /flash-block +  constant mfg-data-end-offset
 
 : write-flash-range  ( adr end-offset start-offset -- )
    ." Erasing" cr
    2dup  ?do
-      i .x (cr  i erase-spi-block
-   /spi-eblock +loop  ( adr end start )
-   cr                 ( adr end start )
+      i .x (cr  i flash-erase-block
+   /flash-block +loop  ( adr end start )
+   cr                  ( adr end start )
    
    ." Writing" cr
    ?do                ( adr )
-      i .x (cr                         ( adr )
-      dup  /chunk  i  write-spi-flash  ( adr )
-      /chunk +                         ( adr' )
+      i .x (cr                           ( adr )
+      dup  /chunk  i  flash-write        ( adr )
+      /chunk +                           ( adr' )
    /chunk +loop       ( adr )
    cr  drop           ( )
 ;
@@ -33,7 +35,7 @@
    ." Verifying" cr
    ?do                ( adr )
       i .x (cr
-      dup  i +  /chunk  i  verify-spi-flash
+      dup  i +  /chunk  i  flash-verify
    /chunk +loop       ( adr )
    cr  drop           ( )
 ;
@@ -85,6 +87,10 @@
 
    flash-buf mfg-data-offset +  /flash-block  ['] ?erased  catch
    abort" Firmware image has data in the manufacturing data block"
+[ifdef] use-flash-nvram
+   flash-buf nvram-offset +  /flash-block  ['] ?erased  catch
+   abort" Firmware image has data in the NVRAM block"
+[then]
 ;
 
 : $get-file  ( "filename" -- )
@@ -109,7 +115,7 @@
    writing
    /flash  0  do
       i .x (cr
-      flash-buf  i +  /chunk i  read-spi-flash
+      flash-buf  i +  /chunk i  flash-read
    /chunk +loop
    flash-buf  /flash  ofd @ fputs
    ofd @ fclose
@@ -162,11 +168,11 @@
    2dup ifd @ fgets drop                ( adr len )
    ifd @ fclose
 
-   spi-start spi-identify
-   mfg-data-offset erase-spi-block      ( adr len )
+   flash-write-enable
+   mfg-data-offset flash-erase-block    ( adr len )
    mfg-data-end-offset over -           ( adr len offset )
-   write-spi-flash                      ( )
-   spi-reprogrammed                     ( )
+   flash-write                          ( )
+   flash-write-disable                  ( )
 ;
 
 [then]
@@ -177,16 +183,16 @@
    flash-base -1 =  if
       \ Read the manufacturing data from the other FLASH
       \ First try the new location in the e.0000 block
-      flash-buf mfg-data-offset +  /flash-block  mfg-data-offset  read-spi-flash
+      flash-buf mfg-data-offset +  /flash-block  mfg-data-offset  flash-read
 
-      \ If there is no mfg data in the e.000 block, get whatever is in the
+      \ If there is no mfg data in the e.0000 block, get whatever is in the
       \ last 2K of the 0 block, where the mfg data used to live.
       flash-buf mfg-data-end-offset + invalid-tag?  if
          flash-buf mfg-data-offset +  /flash-block  h# ff  erase
 
          flash-buf mfg-data-end-offset + h# 800 -  h# 800   ( adr len )
          mfg-data-end-offset h# 800 -                       ( adr len offset )
-         read-spi-flash                                     ( )
+         flash-read                                         ( )
       then
       exit
    then
@@ -202,9 +208,9 @@
       2dup 2>r  move  2r>                     ( ram-adr len )                              
 
       \ Write from the memory buffer to the FLASH
-      mfg-data-offset erase-spi-block         ( ram-adr len )
+      mfg-data-offset flash-erase-block       ( ram-adr len )
       mfg-data-end-offset over -              ( ram-adr len offset )
-      write-spi-flash                         ( )
+      flash-write                             ( )
    else
       \ Copy the entire block containing the manufacturing data into the
       \ memory buffer.  This make verification easier.
@@ -216,7 +222,11 @@
 ;
 
 : write-firmware  ( -- )
+[ifdef] use-flash-nvram
+   flash-buf  nvram-offset     0  write-flash-range      \ Write first part
+[else]
    flash-buf  mfg-data-offset  0  write-flash-range      \ Write first part
+[then]
 
    \ Don't write the block containing the manufacturing data
 
@@ -232,10 +242,8 @@
 
 : reflash   ( -- )   \ Flash from data already in memory
    ?file
-   spi-start
+   flash-write-enable
 
-   spi-identify .spi-id cr
-
    ?move-mfg-data
 
    write-firmware
@@ -247,7 +255,7 @@
          write-firmware
          verify
       then
-      spi-reprogrammed
+      flash-write-disable
    else
       .verify-msg
    then   
@@ -301,20 +309,20 @@
 0 [if]
 \ Erase the first block containing the EC microcode.  This is dangerous...
 
-: erase-spi-ec  ( -- )  0 erase-spi-block  ;
+: erase-ec  ( -- )  0 flash-erase-block  ;
 \ Erase everything after the first sector, thus preserving
 \ the EC microcode in the first sector.
 
-: erase-spi-firmware  ( -- )
-   h# 100000 /spi-eblock  do   (cr i .x  i erase-spi-block  /spi-eblock +loop  cr
+: erase-firmware  ( -- )
+   h# 100000 /flash-block  do   (cr i .x  i flash-erase-block  /flash-block +loop  cr
 ;
 
 : reprogram-firmware  ( adr len -- )
    check-firmware-image       ( adr len )
-   /spi-eblock  /string       ( adr+ len- )   \ Remove EC ucode from the beginning
+   /flash-block  /string      ( adr+ len- )   \ Remove EC ucode from the beginning
    ." Erasing ..." cr erase-spi-firmware  ( adr len )
-   ." Programming..."  2dup /spi-eblock  write-spi-flash  cr    ( adr len )
-   ." Verifying..."  /spi-eblock verify-spi-flash  cr  ( )
+   ." Programming..."  2dup /flash-block  flash-write  cr    ( adr len )
+   ." Verifying..."  /flash-block flash-verify  cr  ( )
 ;
 
 : flash-bios  ( -- )

Added: dev/subrange.fth
===================================================================
--- dev/subrange.fth	                        (rev 0)
+++ dev/subrange.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -0,0 +1,64 @@
+purpose: Device that represents a subrange of its parent
+\ See license at end of file
+
+\ This is device that accesses a subrange of its parent's address space
+
+\ /device must be defined externally as the length of the subrange
+\ my-space is the base of the subrange
+my-address my-space /device reg
+
+0 value offset			\ seek pointer
+
+: clip-size  ( adr len -- adr actual )
+   offset +   /device min  offset -     ( adr actual )
+;
+: update-ptr  ( actual -- actual )  dup offset +  to offset  ;
+
+: seek-parent  ( n -- )  my-space +  u>d " seek" $call-parent drop  ;
+
+external
+: open  ( -- flag )  0 to offset  true  ;
+: close  ( -- )  ;
+
+: seek  ( d.offset -- status )
+   0<>  over /device u>  or  if  drop true  exit  then  \ Seek offset too large
+   to offset
+   false
+;
+: read  ( adr len -- actual )
+   clip-size					( adr actual )
+   offset seek-parent                           ( adr actual )
+   " read" $call-parent				( actual )
+   update-ptr
+;
+: write  ( adr len -- actual )
+   clip-size					( adr actual )
+   offset seek-parent                           ( adr actual )
+   " write" $call-parent			( actual )
+   update-ptr
+;
+: size  ( -- d )  /device 0  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Modified: ofw/confvar/nameval.fth
===================================================================
--- ofw/confvar/nameval.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ ofw/confvar/nameval.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -20,9 +20,9 @@
 \ Generic version that just looks for an obviously broken initial name
 : (config-checksum?)  ( -- flag )
    cv-area drop  d# 32  bounds  ?do    ( )
-      \ Good if we encounter an "=" or a null before an unprintable character
-      i c@  dup 0=  swap [char] = =  or  if  unloop  true exit  then
-      \ Bad if we encounter an unprintable character before the first = or \0
+      \ Good if we encounter '=' or \0 or ff before an unprintable character
+      i c@  dup 0=  over [char] = =  or  swap h# ff = or  if  unloop  true exit  then
+      \ Bad if we encounter an unprintable character before the first = or \0 or ff
       i c@  bl 1+  h# 7f within  0=  if  unloop false exit  then
    loop
    \ Bad if the first name is too long
@@ -35,6 +35,7 @@
 
 : another-ge-var?  ( adr len -- false | adr' len' value$ name$ true )
    dup 0=  if  2drop false exit  then         ( adr len )
+   over c@ h# ff =  if  2drop false exit  then ( adr len )
    0  left-parse-string                       ( adr' len' var$ )
    dup 0=  if  4drop false  exit  then        ( adr' len' var$ )
    [char] = left-parse-string                 ( adr' len' value$ name$ )
@@ -76,14 +77,20 @@
    \ Clear the new piece at the top (from name+(top-rem) to top) 
    2 pick - over +                  ( rem-adr name-adr name+top-rem )
    -rot -                           ( name+top-rem rem-name )
-   erase
+   h# ff fill
 ;
 : ?delete-ge-var  ( $name -- )
    find-ge-var  0=  if  delete-ge-var  then
 ;
 : find-available  ( -- adr len )
-   cv-area
-   begin  0 left-parse-string  while  drop  repeat  ( rem$ adr )
+   cv-area  begin              ( rem$ )
+      dup  if                  ( rem$ )
+         over c@ h# ff =  if   ( rem$ )
+            exit
+         then                  ( rem$ )
+      then                     ( rem$ )
+      0 left-parse-string      ( rem$ env$ )
+   while  drop  repeat         ( rem$ adr )
    -rot  + over -                                   ( adr len )
 ;
 : (cv-unused)  ( -- len )  find-available nip  ;
@@ -108,7 +115,8 @@
       tuck r@ swap move		  ( $value name-len )
       r> +  [char] = over c!  1+  ( $value nv-value-adr )
       2dup 2>r  swap move  2r>	  ( value-len nv-value-adr )
-      over +  0 over c!		  ( value-len terminator-adr )
+      over +  1-                  ( value-len last-char-adr )
+\       over +  0 over c!		  ( value-len terminator-adr )
       update-modified-adr	  ( value-len )
    then				  ( value-len | -1 )
 ;
@@ -134,8 +142,10 @@
 ' show-ge-var to show-extra-env-var	\ Install in user interface
 
 : clear-ge-vars  ( -- )
-   cv-area erase
-   cv-area bounds  update-modified-adr  update-modified-adr 
+   cv-area h# ff fill
+   \ The 1- is necessary because update-modified-adr refers to
+   \ a byte that is touched, not the one just after it.
+   cv-area bounds  update-modified-adr  1- update-modified-adr 
 ;
 ' clear-ge-vars  to erase-user-env-vars
 
@@ -195,7 +205,7 @@
 : clear-nvram  ( -- )
    config-rw
    0 update-modified-range drop  config-size update-modified-range drop
-   config-mem config-size  erase
+   config-mem config-size  h# ff fill
    set-mfg-defaults
    config-ro
    init-modified-range

Modified: ofw/core/ofwcore.fth
===================================================================
--- ofw/core/ofwcore.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ ofw/core/ofwcore.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -4516,7 +4516,7 @@
 partial-headers
 : open-drop-in  ( -- 0 )
    di-count dup  1+  to di-count  0=  if
-      " rom" open-dev  to rom-dev
+      " dropins" open-dev  to rom-dev
    else
       0 seek-rom
    then

Modified: ofw/fs/dropinfs.fth
===================================================================
--- ofw/fs/dropinfs.fth	2008-06-20 23:37:28 UTC (rev 837)
+++ ofw/fs/dropinfs.fth	2008-06-24 23:14:57 UTC (rev 838)
@@ -1,14 +1,19 @@
+purpose: Present dropins as a filesystem
 \ See license at end of file
-purpose: Support package for "dropin file system"
 
+0 0  " "  " /" begin-package
+" dropin-fs" name
+
 headerless
 0 instance value base-adr
 0 instance value image-size
+0 value open-count
+false value written?
 0 instance value seek-ptr
-0 instance value offset
 
-: clip-size  ( adr len -- adr len' )
-   seek-ptr +   image-size umin  seek-ptr -
+: clip-size  ( adr len -- len' adr len' )
+   seek-ptr +   image-size min  seek-ptr -     ( adr len' )
+   tuck
 ;
 : update-ptr  ( len' -- len' )  dup seek-ptr +  to seek-ptr  ;
 
@@ -17,98 +22,45 @@
 : seek  ( d.offset -- status )
    0<>  over image-size u>  or  if  drop true  exit  then \ Seek offset too big
    to seek-ptr
-   seek-ptr offset +  0  " seek" $call-parent
+   false
 ;
-: size  ( -- d.size )  image-size 0  ;
-: read  ( adr len -- actual )
-   clip-size                     ( adr len' )
-   " read" $call-parent          ( len' )
-   update-ptr                    ( len' )
-;
 
-d# 32 buffer: di-buffer
+: open  ( -- flag )
+   \ This lets us open the node during compilation
+   standalone?  0=  if  true exit  then
 
-\ ID of the header that's currently in the buffer
--1 instance value header-id
-
-: difield  \ name  ( offset -- offset' )
-   create  over ,  +  does> @ di-buffer +
+   0 to base-adr
+   0 to seek-ptr                                    ( )
+   my-args  dup  if                                 ( adr len )
+      2dup  " \"  $=  0=  if                        ( adr len )
+         over c@  [char] \  =  if  1 /string  then  ( adr' len' )
+         find-drop-in  dup  if                      ( di-adr di-len true )
+            -rot  to image-size  to base-adr        ( true )
+         then                                       ( flag )
+         exit                                       ( flag )
+      then                                          ( adr len )
+   then                                             ( adr len )
+   2drop                                            ( )
+   false
 ;
+: close  ( -- )
+   \ This lets us open the node during compilation
+   standalone?  0=  if  exit  then
 
-d# 16 constant max-di-name
-struct
-   /l difield di-magic
-   /l difield di-size
-   /l difield di-sum
-   /l difield di-expansion
-max-di-name difield di-name
-constant /di-header
-
-: load  ( adr -- len )  0 0 seek drop  image-size read  ;
-
-: ?get-header  ( id -- id )
-   dup  header-id  <>  if                ( id )
-      dup /di-header -  0  seek drop     ( id )
-      di-buffer  /di-header  read drop   ( id )
-      dup to header-id                   ( id )
-   then                                  ( id )
+   base-adr 0<>  if  base-adr image-size release-dropin  then
 ;
-
-: di-magic?  ( -- flag )  di-magic 4  " OBMD" $=  ;
-: first-header  ( -- id )
-   d# 2000  /di-header  do
-      i ?get-header drop
-      di-magic?  if  i unloop exit  then
-   /di-header +loop
-   0
+: size  ( -- d.size )  image-size u>d  ;
+: read  ( adr len -- actual )
+   clip-size                     ( len' adr len' )
+   seek-ptr base-adr +  -rot     ( len' device-adr adr len' )
+   move                          ( len' )
+   update-ptr                    ( len' )
 ;
-
-: another-dropin?  ( id -- false  | id' true )
-   ?dup  if                  ( id )    \ Not the first call
-      ?get-header            ( id )    \ Get the old header into the buffer
-      di-size be-l@ +        ( id+ )   \ Skip the old dropin
-      4 round-up             ( id' )   \ Finish skipping
-      /di-header +           ( id' )   \ Set ID to image offset
-      ?get-header            ( id' )   \ Get the new header
-   else                      ( )
-      first-header           ( id' )
-   then                      ( id' )
-
-   di-magic?  dup  0=  if  nip  then
+: load  ( adr -- len )
+   base-adr swap image-size move  image-size
 ;
-
-headerless
-: find-drop-in  ( name-adr,len -- false  | drop-in-adr,len true )
-   0                                      ( name-adr,len id )
-   begin  another-dropin?  while          ( name-adr,len id )
-      2 pick 2 pick                       ( name-adr,len id name-adr,len )
-      di-name cscount  $=  if             ( name-adr,len id )
-         nip nip                          ( id )
-         di-size be-l@  true              ( adr len true )
-         exit
-      then                                ( name-adr,len id )
-   repeat                                 ( name-adr,len )
-   2drop false
-;
-
-: open  ( -- flag )
-   -1 to image-size  0 to offset
-   my-args  2dup  " \"  $=  if                   ( adr len )
-      2drop                                      ( )
-      true exit                                  ( true )
-   else                                          ( adr len )
-      over c@  [char] \  =  if  1 /string  then  ( adr' len' )
-      find-drop-in  dup  if                      ( di-adr di-len true )
-         -rot  to image-size  to offset          ( true )
-         0. seek drop                            ( true )
-      then                                       ( flag )
-      exit                                       ( flag )
-   then                                          ( adr len )
-   2drop false                                   ( false )
-;
-: close  ( -- )  ;
-
 : next-file-info  ( id -- false | id' s m h d m y len attributes name$ true )
+   ?dup 0=  if  open-drop-in  then      ( id )
    another-dropin?  if                  ( id )
       " built-time-int" $find  if       ( id s m h xt )
          execute                        ( id s m h packed-date )
@@ -122,27 +74,29 @@
       else                              ( id s m h adr len )
          2drop  0 0 0                   ( id s m h d m y )
       then                              ( id s m h d m y )
-\     di-expansion be-l@                ( id s m h d m y size )
-\     ?dup 0=  if  di-size be-l@  then  ( id s m h d m y size )
-      di-size be-l@                     ( id s m h d m y size )
+      di-expansion be-l@                ( id s m h d m y size )
+      ?dup 0=  if  di-size be-l@  then  ( id s m h d m y size )
       o# 100444                         ( id s m h d m y size attributes )
-      di-name cscount  max-di-name min  ( id s m h d m y size attr name$ )
+      di-name cscount                   ( id s m h d m y size attr name$ )
       true                              ( id s m h d m y size attr name$ true )
    else                                 ( )
-      false                             ( false )
+      close-drop-in  false              ( false )
    then
 ;
 
 : free-bytes  ( -- d.#bytes )
-   0                                  ( high-water )
+   open-drop-in  0                    ( high-water )
    0  begin  another-dropin?  while   ( high-water id )
       nip  di-size be-l@ 4 round-up   ( id size )
       over +  swap                    ( high-water' id )
    repeat                             ( high-water )
-   " size" $call-parent  rot 0  d-    ( d.#bytes )
+   size  rot 0  d-                    ( d.#bytes )
 ;
+
+end-package
+
 \ LICENSE_BEGIN
-\ Copyright (c) 2006 FirmWorks
+\ Copyright (c) 2008 FirmWorks
 \ 
 \ Permission is hereby granted, free of charge, to any person obtaining
 \ a copy of this software and associated documentation files (the




More information about the openfirmware mailing list