[OpenBIOS] r461 - in cpu: . ppc ppc/Linux ppc/olpc ppc/ppcsim

svn at openbios.org svn at openbios.org
Thu Jul 5 19:19:18 CEST 2007


Author: wmb
Date: 2007-07-05 19:19:17 +0200 (Thu, 05 Jul 2007)
New Revision: 461

Added:
   cpu/ppc/
   cpu/ppc/Linux/
   cpu/ppc/Linux/Makefile
   cpu/ppc/aiport.fth
   cpu/ppc/asmmacro.fth
   cpu/ppc/asmtools.fth
   cpu/ppc/assem.fth
   cpu/ppc/banner.fth
   cpu/ppc/basefw.bth
   cpu/ppc/bat.fth
   cpu/ppc/bat601.fth
   cpu/ppc/batf601.fth
   cpu/ppc/batfault.fth
   cpu/ppc/batmap.fth
   cpu/ppc/boot.fth
   cpu/ppc/build/
   cpu/ppc/builder.bth
   cpu/ppc/cache601.fth
   cpu/ppc/cache603.fth
   cpu/ppc/cache823.fth
   cpu/ppc/call.fth
   cpu/ppc/catchexc.fth
   cpu/ppc/centry.fth
   cpu/ppc/code.fth
   cpu/ppc/cpubpsup.fth
   cpu/ppc/cpuclass.fth
   cpu/ppc/cpunode.fth
   cpu/ppc/cpustate.fth
   cpu/ppc/ctrace.fth
   cpu/ppc/debugm.fth
   cpu/ppc/decompm.fth
   cpu/ppc/dectrap.fth
   cpu/ppc/disinflt.fth
   cpu/ppc/epic.fth
   cpu/ppc/fb8-ops.fth
   cpu/ppc/field.fth
   cpu/ppc/filecode.fth
   cpu/ppc/filefld.fth
   cpu/ppc/finish.fth
   cpu/ppc/fixvoc.fth
   cpu/ppc/flipdic.fth
   cpu/ppc/flips.fth
   cpu/ppc/forthint.fth
   cpu/ppc/ftrace.fth
   cpu/ppc/gdb.fth
   cpu/ppc/getms.fth
   cpu/ppc/hacks.fth
   cpu/ppc/htabmmu.fth
   cpu/ppc/inflate.fth
   cpu/ppc/initpgm.fth
   cpu/ppc/kerncode.fth
   cpu/ppc/kernel.bth
   cpu/ppc/kernrel.fth
   cpu/ppc/loadmach.fth
   cpu/ppc/loadvmem.fth
   cpu/ppc/metainit.fth
   cpu/ppc/metarel.fth
   cpu/ppc/minifth.fth
   cpu/ppc/msr.fth
   cpu/ppc/ntctrace.fth
   cpu/ppc/objects.fth
   cpu/ppc/objsup.fth
   cpu/ppc/occhksum.fth
   cpu/ppc/olpc/
   cpu/ppc/olpc/build/
   cpu/ppc/olpc/devalias.fth
   cpu/ppc/olpc/elf.fth
   cpu/ppc/olpc/flash.fth
   cpu/ppc/olpc/fw.bth
   cpu/ppc/olpc/fwuboot.bth
   cpu/ppc/olpc/mappci.fth
   cpu/ppc/olpc/pciconfig.fth
   cpu/ppc/olpc/pcinode.fth
   cpu/ppc/olpc/probemem.fth
   cpu/ppc/olpc/reports.fth
   cpu/ppc/olpc/reset.fth
   cpu/ppc/olpc/rootnode.fth
   cpu/ppc/pause.fth
   cpu/ppc/ppcboot.fth
   cpu/ppc/ppcsim/
   cpu/ppc/ppcsim/ppcsim.c
   cpu/ppc/ppcsim/simrom.c
   cpu/ppc/realcif.fth
   cpu/ppc/reboot.fth
   cpu/ppc/reenter.fth
   cpu/ppc/regacc.fth
   cpu/ppc/register.fth
   cpu/ppc/resetvec.fth
   cpu/ppc/rombp.fth
   cpu/ppc/rootnode.fth
   cpu/ppc/savefort.fth
   cpu/ppc/savemeta.fth
   cpu/ppc/scrub.fth
   cpu/ppc/scrub601.fth
   cpu/ppc/scrub823.fth
   cpu/ppc/segreg.fth
   cpu/ppc/spr.fth
   cpu/ppc/swapdic.fth
   cpu/ppc/syscall.fth
   cpu/ppc/tagwords.fth
   cpu/ppc/target.fth
   cpu/ppc/testmmu.fth
   cpu/ppc/tlb.fth
   cpu/ppc/tlb601.fth
   cpu/ppc/tlbmiss.fth
   cpu/ppc/tlbms823.fth
   cpu/ppc/tmmu823.fth
   cpu/ppc/tools.bth
   cpu/ppc/touchall.fth
   cpu/ppc/unalign.fth
   cpu/ppc/xadd.fth
Log:
PowerPC - initial checkin of PowerPC Open Firmware files.


Added: cpu/ppc/Linux/Makefile
===================================================================
--- cpu/ppc/Linux/Makefile	                        (rev 0)
+++ cpu/ppc/Linux/Makefile	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,51 @@
+# Flags for the simulator version
+WRAPPER = pforth
+OPT = -O
+# OPT =
+CFLAGS = -DUNIX -DSYS5 -DSIM -DPOWERPC -DARGREGS -DSIMNEXT
+
+CC = gcc
+
+WRDIR = ${BP}/forth/wrapper
+ZIPDIR = ${WRDIR}/zip
+SIMDIR = ../ppcsim
+
+ZIPOBJS = zipmem.o deflate.o trees.o bits.o util.o inflate.o
+
+OBJS = wrapper.o ppcsim.o logger.o ${ZIPOBJS}
+TRACEOBJS = wrapper.o ppcsim.trace.o logger.o ${ZIPOBJS}
+SIMROMOBJS = simrom.o ppcsim.simrom.o
+
+all: ppcforth ppcforth.trace
+
+ppcforth: $(OBJS)
+	$(CC) $(LFLAGS)  $(OBJS)  -o $@
+
+ppcforth.trace: $(TRACEOBJS)
+	$(CC) $(LFLAGS)  $(TRACEOBJS)  -o $@
+
+simrom: $(SIMROMOBJS)
+	$(CC) $(LFLAGS)  $(SIMROMOBJS)  -o $@
+
+%.o: ${WRDIR}/%.c
+	${CC} -c ${CFLAGS} $< -o $@
+
+%.o: ${ZIPDIR}/%.c
+	${CC} -c ${CFLAGS} -I${ZIPDIR} $< -o $@
+
+ppcsim.o: $(SIMDIR)/ppcsim.c
+	$(CC) $(OPT) $(CFLAGS) -c $< -o $@
+
+ppcsim.trace.o: $(SIMDIR)/ppcsim.c
+	$(CC) $(OPT) $(CFLAGS) -DTRACE -c $< -o $@
+
+ppcsim.simrom.o: $(SIMDIR)/ppcsim.c
+	$(CC) $(CFLAGS) -DTRACE -DSIMROM -c $< -o $@
+
+simrom.o: $(SIMDIR)/simrom.c
+	$(CC) $(CFLAGS) -DTRACE -DSIMROM -c $< -o $@
+
+clean:
+	@rm -f *.o ppcforth ppcforth.trace
+
+FRC:

Added: cpu/ppc/aiport.fth
===================================================================
--- cpu/ppc/aiport.fth	                        (rev 0)
+++ cpu/ppc/aiport.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,76 @@
+purpose: Assembly-language driver for Promice Analysis Interface "serial port"
+\ See copyright at end of file
+
+\ Requires the following external definitions:
+\ ai-serial  ( -- n )	\ Returns the base address of the AI port registers
+
+label init-serial  ( -- )  \ Destroys: r3
+   begin
+      ai-serial  set  r3,*
+      lbz     r3,3(r3)		\ Read status register
+      cmpi    0,0,r3,h#cc	\ 0xcc is status_invalid
+   <> until			\ Wait for port to become active
+
+   ai-serial  set r3,*
+   lbz     r3,2(r3)		\ Read data port (because the docs say to)
+   bclr    20,0
+end-code
+
+label putchar  ( r3 -- )  \ Destroys: r1, r2
+   ai-serial   set  r1,*
+   begin
+      lbz     r2,3(r1)		\ Read status register
+      andi.   r0,r2,1		\ Transmitter ready bit
+   0= until			\ Wait for ready
+
+   \ send char
+   lbz   r2,1(r1)		\ start bit
+
+   andi. r3,r3,h#ff		\ Clear high bits just in case
+
+   ori   r3,r3,h#100		\ merge in stop bit
+   begin
+      \ use the fact that ONE = 1 and ZERO = 0
+      andi.  r2,r3,1
+      lbzx   r2,r1,r2		\ send bit
+      rlwinm. r3,r3,31,1,31	\ last bit will be stop bit
+   0= until
+
+   bclr  20,0
+end-code
+
+label getchar  ( -- r3 )
+   begin			\ wait for byte
+      ai-serial  set r3,*
+      lbz     r3,3(r3)		\ Read status register
+      andi.   r0,r3,2		\ Test received byte available bit
+   0<> until
+
+   ai-serial  set r3,*
+   lbz     r3,2(r3)		\ Read received byte
+   bclr    20,0
+end-code
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/asmmacro.fth
===================================================================
--- cpu/ppc/asmmacro.fth	                        (rev 0)
+++ cpu/ppc/asmmacro.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,42 @@
+purpose: Handy assembler macros
+\ See copyright at end of file
+
+also forth definitions
+: c$,  ( adr len -- )
+   1+  here swap note-string dup allot move 4 (align)
+;
+previous definitions
+
+also ppc-assembler definitions
+: $-to-r3  ( adr len -- )
+   dup 5 + 4 round-up here +  " bl *" evaluate  \ Assemble code to skip string
+   c$,						\ Place string
+   " mfspr r3,lr" evaluate   			\ Assemble code to get str adr
+;
+: pop-to-t0       " lwz  t0,0(sp)   addi sp,sp,1cell"    evaluate  ;
+previous definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/asmtools.fth
===================================================================
--- cpu/ppc/asmtools.fth	                        (rev 0)
+++ cpu/ppc/asmtools.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,111 @@
+purpose: Tools for creating disembodied assembly code sequences
+\ See license at end of file
+
+[ifndef] set-transize
+fload ${BP}/forth/lib/transien.fth
+true is suppress-transient?	\ Disable transient definitions for now
+[then]
+
+\needs suppress-headerless?  fload ${BP}/forth/lib/headless.fth
+
+[ifndef] ppc-assembler
+fload ${BP}/cpu/ppc/assem.fth
+fload ${BP}/cpu/ppc/code.fth
+fload ${BP}/forth/lib/loclabel.fth
+[then]
+
+also ppc-assembler definitions
+\needs $-to-r3 fload ${BP}/cpu/ppc/asmmacro.fth
+
+: $find-dropin,  ( adr len -- )
+   $-to-r3					\ Assemble string and skip it
+   " find-dropin bl *" evaluate			\ and call find routine
+;
+previous definitions
+
+false value transient-labels?
+0 value asm-origin
+0 value asm-base
+: pad-to  ( n -- )
+   begin  dup  here asm-base -  asm-origin +   u>  while  0 ,  repeat  drop
+;
+: align-to  ( boundary -- )
+   here asm-base -  swap round-up  pad-to
+;
+
+: put-call  ( target-adr branch-adr -- )
+   tuck [ also assembler ] offset-26  [ previous ]
+   h# 4800.0001 + swap 
+   [ also assembler ] asm! [ previous ]		\ bl offset
+;
+
+[ifndef] enable-transient?
+: enable-transient  ( -- )
+   suppress-transient?  if
+      unused 4 /  d# 1000  set-transize
+      false is suppress-transient?
+      false is suppress-headerless?
+   then
+;
+[then]
+enable-transient
+
+: tconstant  ( value "name" -- )
+   transient? 0= dup >r  if  transient  then
+   constant
+   r> if  resident  then
+;
+: label  ( "name" -- )
+   transient-labels?  if
+      here  tconstant
+      [ also assembler ] init-labels [ previous ]  !csp entercode
+   else
+      label
+   then
+;
+
+: set-asm-origin  ( -- )
+   here to asm-base
+   0 to asm-origin
+;
+
+0 0 2value old-asms
+: start-assembling  ( -- )
+   \ Use "is" instead of "to" in the next line because "to" is a PowerPC
+   \ assembly mnemonic (trap on overflow).
+   [ also assembler ]
+      ['] asm@ behavior   ['] asm! behavior  to old-asms
+      ['] be-l@ is asm@  ['] be-l! is asm!
+   [ previous ]
+   set-asm-origin
+   true to transient-labels?
+;
+: end-assembling  ( -- )
+   [ also assembler ]  old-asms  is asm!   is asm@  [ previous ]
+   false to transient-labels?
+;
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/assem.fth
===================================================================
--- cpu/ppc/assem.fth	                        (rev 0)
+++ cpu/ppc/assem.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,1324 @@
+purpose: PowerPC assembler
+\ See license at end of file
+
+decimal
+
+\needs $vfind            fload ${BP}/forthlang/lib/strings.fth
+\needs left-parse-string fload ${BP}/forthlang/lib/parses1.fth
+
+vocabulary ppc-assembler
+
+also ppc-assembler definitions
+
+headerless
+false value disassembling?
+variable instruction
+variable end-found
+headers
+variable pc
+variable display-offset  0 display-offset !
+: +offset  ( adr -- adr' )  display-offset @  +  ;
+' ul.  is showaddr
+
+headerless
+h#  40 /token      *  constant /op-map  create op-map /op-map allot
+h#  10 /token /n + *  constant /19-map  create 19-map /19-map allot
+h# 400 /token      *  constant /31-map  create 31-map /31-map allot
+h#  20 /token      *  constant /59-map  create 59-map /59-map allot
+h#  20 /token /n + *  constant /63-map  create 63-map /63-map allot
+
+: unimp  ( -- )
+   end-found on
+   ." Not an instruction: "  instruction @ 
+   base @ >r hex  9 u.r  r> base !  space
+   false is disassembling?
+;
+
+: (.name)  ( acf -- )
+   dup ['] unimp  =  if  execute  else  >name name>string type  then
+;
+
+: find-sparse-entry  ( entry map -- acf )
+   begin  dup @ -1  <>  while     ( entry mapp )
+      2dup @ =  if              ( entry mapp )
+         nip na1+ token@  exit  ( acf )
+      then                      ( entry mapp )
+      na1+ ta1+
+   repeat
+   2drop  ['] unimp
+;
+: find-indexed-entry  ( entry map -- acf )  swap ta+ token@  ;
+
+: init-map  ( adr len -- )  bounds  ?do  ['] unimp  i token!  /token +loop  ;
+: init-sparse-map  ( adr len -- )
+   bounds  ?do  -1 i !  ['] unimp  i na1+ token!  /token na1+  +loop
+;
+
+variable start-column
+variable need-comma
+: ?,  ( -- )  need-comma @  if  ." ,"  else  need-comma on  then  ;
+: to-operand-column  ( -- )  d# 8 start-column @ +  to-column  need-comma off ;
+: ibits  ( right-bit# width -- bits )
+   tuck - 1+  instruction l@ swap <<  32 rot - >>
+;
+
+: init-maps  ( -- )
+   op-map  /op-map  init-map
+   31-map  /31-map  init-map
+   59-map  /59-map  init-map
+   19-map  /19-map  init-sparse-map
+   63-map  /63-map  init-sparse-map
+;   
+init-maps
+
+headers
+defer here
+defer asm-allot
+defer asm@
+defer asm!
+
+\ Install as a resident assembler
+\ : xx see ; immediate
+: resident-assembler  ( -- )
+   [ forth ] ['] here          [ ppc-assembler ] is here
+   [ forth ] ['] allot         [ ppc-assembler ] is asm-allot
+   [ forth ] ['] @             [ ppc-assembler ] is asm@
+   [ forth ] ['] instruction!  [ ppc-assembler ] is asm!
+;
+resident-assembler
+
+headerless
+2variable operands
+
+: get-field  ( -- adr len )
+   operands 2@  ascii ,  left-parse-string  2swap operands 2!  ( adr len )
+;
+: field-or-number  ( ? -- n true | adr len false )
+   disassembling?  if  false exit  then
+   get-field
+   2dup  " *"  $=  dup  if  nip nip  then
+;
+\ If adr2,len2 is an initial substring of adr1,len1, return the remainder
+\ of the adr1,len1 string following that initial substring.
+\ Otherwise, return adr1,len1
+: ?remove  ( adr1 len1 adr2 len2 -- adr3 len3 removed? )
+   2 pick  over  u<  if  2drop false exit  then      \ len2 too long?
+   3 pick  rot  2 pick   ( adr len1 len2  adr1 adr2 len2 )
+   caps-comp 0=  if  /string true  else  drop false  then
+;
+: set-base  ( adr len -- adr' len' )
+   " h#" ?remove  if  hex     exit  then
+   " 0x" ?remove  if  hex     exit  then
+   " d#" ?remove  if  decimal exit  then
+   " o#" ?remove  if  octal   exit  then
+   " b#" ?remove  if  binary  exit  then
+;
+
+headers
+\ Define symbolic names for constants in this vocabulary
+vocabulary constant-names
+
+headerless
+: get-based-number  ( adr len -- true | n false )
+   ['] constant-names $vfind  if  execute false exit  then
+   base @ >r decimal
+   set-base
+   $number
+   r> base !
+;
+: number  ( -- n )
+   disassembling?  if  ?, exit  then
+   field-or-number  if  exit  then
+   get-based-number abort" Bad number"
+;
+
+: reg-name  ( adr1 len1 adr2 len2 -- n )  \ adr2 len2 is the register prefix
+   disassembling?  if  ?,  type exit  then
+   ?remove drop
+   base @ >r decimal
+   $number
+   r> base !
+   abort" Bad register number"
+;
+
+\ The two 5-bit halves of the special register field are interchanged
+: flip5  ( n -- n' )  dup h# 1f and  5 <<  swap  5 >>  or  ;
+
+headers
+: sp-reg:  ( n -- )  flip5  constant  ;
+
+vocabulary sp-registers
+also sp-registers definitions
+1011 sp-reg: tbar	\ This is not really a PowerPC register;
+			\ I invented it as a way of communicating
+			\ the trap base address to the simulator
+			\ to avoid slowing the simulator down with
+			\ absolute addressing
+
+   0 sp-reg: mq
+   1 sp-reg: xer
+   4 sp-reg: rtcu  \ mfspr version
+   5 sp-reg: rtcl  \ mfspr version
+   8 sp-reg: lr
+   9 sp-reg: ctr
+  18 sp-reg: dsisr
+  19 sp-reg: dar
+  20 sp-reg: rtcu  \ mtspr version
+  21 sp-reg: rtcl  \ mtspr version
+  22 sp-reg: dec
+  25 sp-reg: sdr1
+  26 sp-reg: srr0
+  27 sp-reg: srr1
+ 268 sp-reg: tb		\ For reading
+ 269 sp-reg: tbu	\ For reading
+ 272 sp-reg: sprg0
+ 273 sp-reg: sprg1
+ 274 sp-reg: sprg2
+ 275 sp-reg: sprg3
+ 280 sp-reg: asr	\ 620-specific
+ 282 sp-reg: ear
+ 284 sp-reg: tb.w	\ For writing
+ 285 sp-reg: tbu.w	\ For writing
+ 287 sp-reg: pvr
+ 528 sp-reg: ibat0u
+ 529 sp-reg: ibat0l
+ 530 sp-reg: ibat1u
+ 531 sp-reg: ibat1l
+ 532 sp-reg: ibat2u
+ 533 sp-reg: ibat2l
+ 534 sp-reg: ibat3u
+ 535 sp-reg: ibat3l
+ 536 sp-reg: dbat0u
+ 537 sp-reg: dbat0l
+ 538 sp-reg: dbat1u
+ 539 sp-reg: dbat1l
+ 540 sp-reg: dbat2u
+ 541 sp-reg: dbat2l
+ 542 sp-reg: dbat3u
+ 543 sp-reg: dbat3l
+
+1008 sp-reg: check	\ Exponential 704-specific
+1008 sp-reg: checkstop  1008 sp-reg: hid0
+1009 sp-reg: debug-mode 1009 sp-reg: hid1
+1010 sp-reg: iabr       1010 sp-reg: hid2
+1013 sp-reg: dabr       1013 sp-reg: hid5
+1016 sp-reg: buscsr	\ 620-specific
+1017 sp-reg: l2cr	\ 620-specific
+1018 sp-reg: l2sr	\ 620-specific
+1023 sp-reg: pir        1023 sp-reg: hid15
+
+ \ 603-specific
+ 976 sp-reg: dmiss
+ 977 sp-reg: dcmp
+ 978 sp-reg: hash1
+ 979 sp-reg: hash2
+ 980 sp-reg: imiss
+ 981 sp-reg: icmp
+ 982 sp-reg: rpa
+
+\ 604-specific
+ 952 sp-reg: mmcr0	\ 604-specific reg
+ 953 sp-reg: pmc1	\ 604-specific reg
+ 954 sp-reg: pmc2	\ 604-specific reg
+ 955 sp-reg: sia	\ 604-specific reg
+ 959 sp-reg: sda	\ 604-specific reg
+
+\ Exponential 704-specific: also uses some 603-specific registers
+ 276 sp-reg: sprg4	\ Exponential 704-specific
+ 277 sp-reg: sprg5	\ Exponential 704-specific
+ 278 sp-reg: sprg6	\ Exponential 704-specific
+ 279 sp-reg: sprg7	\ Exponential 704-specific
+ 953 sp-reg: event	\ Exponential 704-specific
+ 954 sp-reg: modes	\ Exponential 704-specific
+ 977 sp-reg: cmp	\ Similar to 603 dcmp
+ 982 sp-reg: tlblru0	\ Similar to 603 rpa
+ 983 sp-reg: tlbmrf	\ Exponential 704-specific
+ 985 sp-reg: bpctl	\ Exponential 704-specific
+ 987 sp-reg: tlblru1	\ Exponential 704-specific
+ 988 sp-reg: misr	\ Exponential 704-specific
+ 989 sp-reg: mar	\ Exponential 704-specific
+1012 sp-reg: l2cdr	\ Exponential 704-specific
+1014 sp-reg: xdabr	\ Exponential 704-specific
+1019 sp-reg: l2ctl	\ Exponential 704-specific
+
+\ 823-specific
+  80 sp-reg: eie
+  81 sp-reg: eid
+  82 sp-reg: nri
+ 144 sp-reg: cmpa
+ 145 sp-reg: cmpb
+ 146 sp-reg: cmpc
+ 147 sp-reg: cmpd
+ 148 sp-reg: icr
+ 149 sp-reg: der
+ 150 sp-reg: counta
+ 151 sp-reg: countb
+ 152 sp-reg: cmpe
+ 153 sp-reg: cmpf
+ 154 sp-reg: cmpg
+ 155 sp-reg: cmph
+ 156 sp-reg: lctrl1
+ 157 sp-reg: lctrl2
+ 158 sp-reg: ictrl
+ 159 sp-reg: bar
+ 560 sp-reg: ic-csr
+ 561 sp-reg: ic-adr
+ 562 sp-reg: ic-dat
+ 568 sp-reg: dc-csr
+ 569 sp-reg: dc-adr
+ 570 sp-reg: dc-dat
+ 630 sp-reg: dpdr
+ 631 sp-reg: dpir
+ 638 sp-reg: immr
+ 784 sp-reg: mi-ctr
+ 786 sp-reg: mi-ap
+ 787 sp-reg: mi-epn
+ 789 sp-reg: mi-twc
+ 790 sp-reg: mi-rpn
+ 816 sp-reg: mi-cam
+ 817 sp-reg: mi-ram0
+ 818 sp-reg: mi-ram1
+ 792 sp-reg: md-ctr
+ 793 sp-reg: m-casid
+ 794 sp-reg: md-ap
+ 795 sp-reg: md-epn
+ 796 sp-reg: m-twb
+ 797 sp-reg: md-twc
+ 798 sp-reg: md-rpn
+ 799 sp-reg: m-tw
+ 824 sp-reg: md-cam
+ 825 sp-reg: md-ram0
+ 826 sp-reg: md-ram1
+
+
+previous definitions
+
+\ Define symbolic names for registers in this vocabulary
+vocabulary register-names
+
+headerless
+: r-reg-name  ( adr len -- n )
+   disassembling?  0=  if
+      ['] register-names $vfind  if  execute exit  then
+   then
+   " r"   reg-name
+;
+: r-register    ( -- n )
+   field-or-number  if  exit  then
+   r-reg-name
+;
+: crf-register  ( -- n )  field-or-number  if  exit  then  " crf" reg-name  ;
+: crb-bit       ( -- n )  field-or-number  if  exit  then  " crb" reg-name  ;
+: fr-register   ( -- n )  field-or-number  if  exit  then  " fr"  reg-name  ;
+: u.d  ( n -- )  base @ >r decimal  (u.) type  r> base !  ;
+
+\ Nasty hack to handle the RTCU/RTCL SPR encoding difference
+\ between mfspr and mtspr
+: ?fix-rtc  ( sp-reg# -- sp-reg#' )
+   dup h# 280 =  over h# 2a0 =  or  if          \ rtcu or rtcl?
+      here /l - asm@ h# 100 and  0=  if   \ mfspr?
+         h# 200 -
+      then
+   then
+;
+
+: sp-register   ( -- n )
+   disassembling?  if
+      ?,
+      20 10 ibits               ( n )
+      ['] sp-registers  follow
+      begin  another?  while
+         name>  dup execute                     ( n acf constant )
+	 2 pick =  if  (.name) drop exit  then  ( n acf )
+         drop
+      repeat
+      ." spr" flip5 u.d
+   else
+      field-or-number  if  exit  then
+      ['] sp-registers  $vfind 0=  if
+         ." Bad special register name: " type cr  abort
+      then
+      execute
+      ?fix-rtc
+   then
+;
+: relative?  ( -- flag )  here 4 -  asm@  2 and  0=  ;
+: ?aligned  ( adr -- adr )
+   dup 3 and  abort" Misaligned branch target"
+;
+: convert-target  ( adr -- n )
+   ?aligned
+   relative?  if  here 4 -  -  then
+;
+: safe-get-number  ( adr len -- n )
+   get-based-number  abort" Bad branch target address"
+;
+: branch-target  ( -- adr )
+   field-or-number  0=  if   ( adr len )
+      dup 2 >=  if           ( adr len )
+         over " .+" comp  0=  if   ( adr len )
+            2 /string  safe-get-number  here /l - +  exit
+         then                ( adr len )
+         over " .-" comp  0=  if   ( adr len )
+            2 /string  safe-get-number  negate  here /l - +  exit
+         then
+      then
+      safe-get-number
+   then
+;
+
+: add-bits  ( n -- )
+   here /l - dup  asm@  rot or  swap asm!
+;
+
+: >16-bits?  ( n -- u flag )
+   dup h# ffff and  swap  h# -8000  h# 8000 within  0=
+;
+: ?simm  ( n -- n )
+   >16-bits?  abort" Signed immediate value out of range"
+;
+
+: high-mask  ( #low-zeroes -- mask )  1 swap << 1- invert  ;
+: bit-field  ( n shift width -- )
+   disassembling?  if   ibits  u.d  exit  then
+   high-mask 2 pick  and  abort" Value too large for bit field"
+   31 swap -  << add-bits
+;
+: 5bit-field   ( -- )  5 bit-field  ;
+: rd-field  ( n -- )  10 5bit-field  ;
+: ra-field  ( n -- )  15 5bit-field  ;
+: rb-field  ( n -- )  20 5bit-field  ;
+: rc-bit    ( n -- )  31 1 bit-field  ;
+: oe-bit    ( n -- )  21 1 bit-field  ;
+
+: imm-field  ( n -- )  31 16 bit-field  ;
+: sign-extend-16  ( n1 -- n2 )  16 << 16 >>a   ;
+: h#.x  ( n -- )
+   dup -9 9 between  0=  if  ." h#"  then
+   base @ >r  hex  (.) type  r> base !
+;
+: simm  ( n -- )
+   disassembling?  if
+      ?,  31 16 ibits  sign-extend-16  h#.x
+   else
+      number ?simm  imm-field
+   then
+;
+: ?uimm  ( u -- u )
+   dup h# ffff u>  abort" Unsigned immediate value too large"
+;
+: uimm  ( u -- )
+   disassembling?  if
+      ?,  31 16 ibits  h#.x
+   else
+      number ?uimm
+      imm-field
+   then
+;
+\ In principle, this is a signed field, but it makes the code
+\ incredibly hard to read if we display it as such.
+: simms  ( n -- )
+   disassembling?  if
+      ?,  31 16 ibits  ( sign-extend-16 )  h#.x  ." ...."
+   else
+      simm
+   then
+;
+: uimms  ( n -- )
+   disassembling?  if
+      \ 64-bit: we will need to handle this differently for the 64-bit version
+      simms
+   else
+      uimm
+   then
+;
+: imm  ( -- )  number       19 4 bit-field  ;
+: rd   ( -- )  r-register   rd-field  ;
+: ra   ( -- )  r-register   ra-field  ;
+: rb   ( -- )  r-register   rb-field  ;
+: rs   ( -- )  rd  ;
+: crfd ( -- )  crf-register  8 3 bit-field  ;
+: crfs ( -- )  crf-register 13 3 bit-field  ;
+: crbd ( -- )  crb-bit      rd-field  ;
+: crba ( -- )  crb-bit      ra-field  ;
+: crbb ( -- )  crb-bit      rb-field  ;
+: fm   ( -- )  number       14 8 bit-field  ;
+: l    ( -- )  number       10 1 bit-field  ;
+false value numeric-conditionals?
+variable suppress-cond
+: bo   ( -- )
+   disassembling?  if
+      10 5 ibits
+      numeric-conditionals?  if  ?, u.d  exit  then
+      dup h# 14 and  h# 14 =  if
+         ?, ." always" suppress-cond on
+      else
+         dup h#  4 and  0=  if	\ Decrement and test counter register
+            ?, ." ctr"
+            dup 2 and  if  ." =0"  then
+         then
+         dup h# 10 and  if
+            suppress-cond on
+         else
+            suppress-cond off
+            dup h#  8 and  0=  if  ?, ." not"  then
+         then
+      then
+      1 and  if  ?,  ." Y"  then
+   else
+      number       rd-field
+   then
+;
+
+headers
+: set-y  ( -- )  h# 0020.0000 add-bits  ;
+
+headerless
+string-array condnames   ," lt"  ," gt"  ," eq"  ," so"  end-string-array
+: bi   ( -- )
+   disassembling?  if
+      15 5 ibits
+      numeric-conditionals?  if  ?,  u.d  exit  then
+      suppress-cond @  if
+         drop
+      else
+         ?,
+         4 /mod  ?dup  if  ." cr" u.d ." +"  then
+         condnames ".
+      then
+   else
+      number       ra-field
+   then
+;
+: frd  ( -- )  fr-register  rd-field  ;
+: frs  ( -- )  fr-register  rd-field  ;
+: fra  ( -- )  fr-register  ra-field  ;
+: frb  ( -- )  fr-register  rb-field  ;
+: frc  ( -- )  fr-register  25    5bit-field  ;
+: spr  ( -- )  sp-register  disassembling?  0=  if  20  10 bit-field  then  ;
+: tbr  ( -- )  sp-register  disassembling?  0=  if  20  10 bit-field  then  ;
+: sr   ( -- )  number       15      4 bit-field  ;
+: crm  ( -- )  number       19      8 bit-field  ;
+\ Don't overload the Forth word "to"
+: tox  ( -- )  number       rd-field  ;
+: mb   ( -- )  number       25 5bit-field  ;
+: me   ( -- )  number       30 5bit-field  ;
+: md   ( -- )  number   dup h# 1f and 25 5bit-field  5 >> 26 1 bit-field  ;
+: sh   ( -- )  number       rb-field  ;
+: shd  ( -- )  number   dup h# 1f and rb-field  5 >> 30 1 bit-field  ;
+: nb   ( -- )  number       rb-field  ;
+: set-bd-field  ( adr -- )  convert-target  ?simm 2 >>   29 14 bit-field  ;
+: bd   ( -- )
+   disassembling?  if
+      ?,  29 14 ibits  2 <<
+      30 1 ibits  0=  if  sign-extend-16 pc @  +  then  showaddr
+   else
+      branch-target  set-bd-field
+   then
+;
+: ?offset-26  ( target -- target-masked )
+   dup  h# fe00.0000  h# 200.0000 within  0=
+   abort" Branch target out of 26-bit range"
+   h# 3ff.ffff and
+;
+: lif   ( -- )
+   disassembling?  if
+      ?,  29 24 ibits  8 <<  6 >>a  \ Sign extend
+      30 1 ibits  0=  if  pc @  +  then  showaddr
+   else
+      branch-target
+      convert-target
+      ?offset-26  2 >>  29  24 bit-field
+   then
+
+;
+: parse-d(ra)  ( -- disp ra )
+   field-or-number  if  exit  then               ( adr len )
+   ascii (  left-parse-string                    ( rem-str disp-str )
+   dup 0=  if                                    ( rem-str disp-str )
+      2drop 0                                    ( rem-str 0 )
+   else                                          ( rem-str disp-str )
+      get-based-number abort" Bad displacement"  ( rem-str disp )
+   then                                          ( rem-str disp )
+   -rot  ascii ) left-parse-string               ( disp rem-str reg-str )
+   2swap 2drop  r-reg-name                       ( disp ra )
+;
+: d(ra)  ( -- )
+   disassembling?  if
+      ?,
+      31 16 ibits  sign-extend-16  h#.x
+      need-comma off
+      15  5 ibits  if  ." (" ra ." )"  then
+   else
+      parse-d(ra)  ra-field   ?simm  imm-field
+   then
+;
+: ds(ra)  ( -- )
+   disassembling?  if
+      ?,
+      29 14 ibits  2 lshift  sign-extend-16  h#.x
+      need-comma off
+      15  5 ibits  if  ." (" ra ." )"  then
+   else
+      parse-d(ra)  ra-field   ?simm
+      dup 3 and  abort" offset must be 4-byte aligned"
+      imm-field
+   then
+;
+
+\ Operand formats
+: rd,ra  rd ra  ;
+: rd,ra,rb  rd,ra rb  ;
+: rd,ra,simm   rd,ra simm   ;
+: rd,ra,simms  rd,ra simms  ;
+: crbd,crba,crbb  crbd crba crbb  ;
+: ra,rs     ra rs  ;
+: ra,rb     ra rb  ;
+: rs,ra,rb  rs ra rb  ;
+: rs,rb     rs rb  ;
+: ra,rs,rb  ra,rs rb  ;
+: ra,rs,uimm   ra,rs uimm   ;
+: ra,rs,uimms  ra,rs uimms  ;
+: bo,bi     bo bi  end-found on  ;
+: bo,bi,bd  bo bi bd  ;
+: crfd,l,ra     crfd l ra ;
+: crfd,crfs     crfd crfs ;
+: crfd,l,ra,rb  crfd,l,ra rb  ;
+: frd,frb frd frb ;
+: frd,fra,frb frd fra frb ;
+: frd,fra,frc frd fra frc ;
+: crfd,fra,frb  crfd fra frb ;
+: frd,fra,frc,frb  frd fra frc frb  ;
+: crfd,imm crfd imm ;
+: crfd,l,ra,uimm  crfd,l,ra uimm  ;
+: crfd,l,ra,simm  crfd,l,ra simm  ;
+: frs,ra,rb  frs ra rb  ;
+: frd,ra,rb  frd ra rb  ;
+: rd,spr  rd spr  ;
+: rd,tbr  rd tbr  ;
+: rd,sr  rd sr  ;
+: crm,rs  crm rs  ;
+: spr,rs  spr rs  ;
+: sr,rs  sr rs  ;
+: to,ra,rb tox ra rb  ;
+: to,ra,simm tox ra simm  ;
+: rd,d(ra)  rd d(ra)  ;
+: rs,d(ra)  rs d(ra)  ;
+: rd,ds(ra)  rd ds(ra)  ;
+: rs,ds(ra)  rs ds(ra)  ;
+: frd,d(ra)  frd d(ra)  ;
+: frs,d(ra)  frs d(ra)  ;
+: ra,rs,rb,mb,me  ra rs rb mb me  ;
+: ra,rs,sh,mb,me  ra rs sh mb me  ;
+: ra,rs,shd,md  ra rs shd md  ;
+: ra,rs,rb,md   ra rs rb md  ;
+: ra,rs,sh  ra rs sh  ;
+: ra,rs,shd  ra rs shd  ;
+: fm,frb  fm frb  ;
+: rd,ra,nb  rd ra nb  ;
+: rs,ra,nb  rs ra nb  ;
+: rd,rb  rd rb  ;
+: no-args  ;
+
+: no-. ;
+
+alias power noop
+\ alias power \
+
+\ alias 64bit \
+alias 64bit noop
+
+: >op2-field  ( template -- op2 )  1 >>  h# 3fff and  ;
+: find-free  ( map -- entry-adr )
+   begin  dup @ -1 <>  while  na1+ ta1+  repeat
+;
+headers
+
+transient
+: set-indexed-map  ( op2 map -- )  swap ta+  lastacf swap token!  ;
+: set-sparse-map   ( op2 map -- )
+   find-free  tuck !  lastacf  swap na1+  token!
+;
+: set-map  ( opcode-template -- )
+   dup >op2-field  swap 26 >>     ( op2 opcd )
+   case
+      19  of   19-map  set-sparse-map   endof
+      31  of   31-map  set-indexed-map  endof
+      59  of   59-map  set-indexed-map  endof
+      63  of   63-map  set-sparse-map   endof
+   ( default ) op-map  set-indexed-map
+   endcase
+;
+resident
+
+: asm,  ( n -- )  here  /l asm-allot  asm!  ;
+
+headerless
+: ?.  ( -- )  31 1 ibits  if  ." ."  then  ;
+: dis-operands  ( acf -- )
+   dup  ['] unimp  =  if  drop exit  then
+   to-operand-column  >body na1+ token@ execute
+;
+variable op-class   \ Used for handling the "." forms of the rlw... opcodes
+: dis-name&operands  ( acf -- )
+   dup (.name)
+   op-class @ d# 20 d# 23 between  if  ?.  then
+   dis-operands
+;
+
+: bust  ( n -- )
+   base @ >r decimal
+   dup 26 >>  2 u.r
+   dup 21 >>  h# 1f and  3 u.r
+   dup 16 >>  h# 1f and  3 u.r
+   dup 11 >>  h# 1f and  3 u.r
+   dup  1 >>  h# 3ff and 5 u.r
+   1 and 2 u.r ( cr )
+   r> base !
+;
+
+headers
+: ppc-disasm  ( 32b -- )
+   dup instruction l!
+   true is disassembling?
+   26 >>  dup op-class !  op-map  find-indexed-entry  execute
+;
+also forth definitions
+alias disasm ppc-disasm
+: dis1  ( -- )
+   ??cr
+   pc @ showaddr  4 spaces
+   #out @  start-column !
+   pc @ +offset l@ disasm  cr
+   /l pc +!
+;
+: +dis  ( -- )
+   base @ >r  hex
+   end-found off
+   begin   dis1  end-found @  exit? or  until
+   r> base !
+;
+: dis  ( adr -- )   pc l!   +dis  ;
+alias (dis dis
+previous definitions
+
+headerless
+\ Try to interpret the word with the "." removed, and then with the "o"
+\ removed.
+: interpreted?  ( adr len -- adr len false | true )
+   $find  dup  if  swap execute  then
+;
+: ?peel  ( adr1 len1 char -- adr2 len2 flag )
+   >r 2dup 1- + c@  r> =  if  1- true  else  false  then
+;
+: $ppc-assem-do-undefined  ( adr len -- )
+   ascii .  ?peel  if                         ( adr len )
+      interpreted?  if  1 rc-bit exit  then   ( adr len )
+      ascii o  ?peel  if                      ( adr len )
+            interpreted?  if  1 oe-bit  1 rc-bit exit  then
+      then                                    ( adr len )
+   else
+      ascii o  ?peel  if
+         interpreted?  if  1 oe-bit  exit  then
+      then
+   then                                       ( adr len )
+   .not-found  abort
+;
+: get-operands  ( -- )  parse-word  operands 2!  ;
+
+: op:  ( opcode-template -- )
+   create  dup set-map  ,		\ Remember opcode template
+
+   \ Remember argument parsing word
+   parse-word $find  0= abort" Missing argument specification"  token,
+
+   does>
+      disassembling?  if
+         body> dis-name&operands
+         false is disassembling?
+      else
+         dup @  asm,    \ Place opcode
+         na1+ token@  dup  ['] no-args <>  if  get-operands  then
+         execute               \ Handle arguments
+      then
+;
+
+[ifdef] notdef
+: .binary  ( n -- )
+   base @ >r  2 base !
+   <#  32 0 do  #  loop  #>  type space
+   r> base !
+;
+[then]
+
+headers
+transient
+: can-.  ( -- )  ;  \ "." form is available
+: can-o  ( -- )  ;  \ "o" form is available
+
+\ Opcode formats
+resident
+: >op  ( op0 -- )  26 <<  ;
+
+transient
+: d:   ( op0 -- )                          >op    op:  ;
+: b:   ( op0 aa lk -- )  swap 1 << +  swap >op +  op:  ;
+: o:   ( op1 op0 -- )    swap 1 <<    swap >op +  op:  ;
+
+: dl:  ( op0 low -- )                 swap >op +  op:  ;
+: rd:  ( low -- )             2 <<      30 >op +  op:  ;
+ 
+: r:   ( op0 -- )  d:  can-.  ;
+
+: xl:  ( op1 -- )  19 o:  ;
+: x:   ( op1 -- )  31 o:  ;
+: s:   ( op1 -- )  59 o:  can-.  ;
+: f:   ( op1 -- )  63 o:  can-.  ;
+
+\ : x:  31 swap  1 <<  swap >op +  .binary  newline word ".  cr  ;
+
+: xc:  ( op1 -- )     x:   can-.  ;
+: xo:  ( op1 oe -- )  xc:  can-o  ;
+resident
+
+\ Put a branch instruction from high-level Forth code
+
+: offset-26  ( target-address branch-address -- masked-displacement )
+   swap ?aligned  swap ?aligned
+   - ?offset-26
+; 
+
+also forth definitions
+: put-branch  ( target-adr branch-adr -- )
+   tuck offset-26 h# 4800.0000 + swap asm!	\ b offset
+;
+previous definitions
+
+: cond  ( bo bi -- )
+   swap 5 <<  or  16 <<  create ,  does>  @ 
+;
+: -cond  ( condition -- not-condition )
+   dup  h# 0080.0000 and  0=  if  h# 0040.0000 xor  then  \ CTR condition
+   dup  h# 0200.0000 and  0=  if  h# 0100.0000 xor  then  \ CR condition
+;
+
+headerless
+: offset-16  ( target-address branch-address -- masked-displacement )
+   dup 3 and  abort" Unaligned branch displacement"
+   -
+   >16-bits?  abort" branch displacement out of 16-bit range"
+; 
+
+headers
+: brif  ( address condition -- )
+   h# 4000.0000 or  swap here offset-16 or  asm,
+;
+
+: mr  ( -- )  \ rdest,rsrc
+   444 1 <<  31 >op +  asm,	\ "or  rdest,rsrc,rsrc"
+   get-operands
+   ra  r-register  dup rd-field rb-field
+;
+: li  ( -- )    \ rdest,value
+   get-operands
+   14 >op  asm,			\ "addi  rdest,r0,value"
+   r-register rd-field   0 ra-field   number ?simm  imm-field
+;
+: lis  ( -- )
+   15 >op  asm,			\ "addis  rdest,r0,high(value)"
+   get-operands
+   r-register rd-field   0 ra-field   number 16 >>a imm-field
+;
+: set  ( -- )   \ rdest,value
+   \ We can't keep rd on the stack because a number might be there,
+   \ waiting for a "*" in the number field to pick it up
+   get-operands  r-register >r  number   ( value )  ( r: register )
+   dup >16-bits?  if                                     ( value val.low )
+      swap                                               ( val.low value )
+      15 >op  asm,	\ "addis  rdest,r0,high(value)"  ( val.low value )
+      r@ rd-field  0 ra-field  16 >> imm-field           ( val.low )
+      ?dup  if
+         24 >op asm,	\ "ori    rdest,rdest,low(value) ( )
+         imm-field  r@ rd-field  r@ ra-field
+      then                          ( )
+   else                                                  ( value val.low )
+      nip
+      14 >op  asm,	\ "addi  rdest,r0,value"         ( val.low reg )  
+      r@ rd-field  0 ra-field  imm-field                 ( )
+   then
+   r> drop
+;
+: countdown  ( adr -- )  16 >op asm,  16 rd-field  0 ra-field  set-bd-field  ;
+: nop  ( -- )  24 >op asm,  ;	\ ori  r0,r0,0
+
+      \ 0,1 are unassigned
+
+64bit   2 d: tdi     to,ra,simm
+        3 d: twi     to,ra,simm
+
+      \ 4,5,6 are unassigned
+
+        7 d: mulli   rd,ra,simm
+        8 d: subfic  rd,ra,simm
+power   9 d: dozi    rd,ra,simm
+       10 d: cmpli   crfd,l,ra,uimm
+       11 d: cmpi    crfd,l,ra,simm
+       12 d: addic   rd,ra,simm
+       13 d: addic.  rd,ra,simm
+       14 d: addi    rd,ra,simm
+       15 d: addis   rd,ra,simms
+       
+     \ 16 is bcX
+     \ 17 is sc
+     \ 18 is bX
+     \ 19 is xl: and bclr,bctr
+
+       20 r: rlwimi  ra,rs,sh,mb,me
+       21 r: rlwinm  ra,rs,sh,mb,me
+power  22 r: rlmi    ra,rs,rb,mb,me
+       23 r: rlwnm   ra,rs,rb,mb,me
+
+       24 d: ori     ra,rs,uimm
+       25 d: oris    ra,rs,uimms
+       26 d: xori    ra,rs,uimm
+       27 d: xoris   ra,rs,uimms
+       28 d: andi.   ra,rs,uimm
+       29 d: andis.  ra,rs,uimms
+       
+64bit  0 rd: rldicl ra,rs,shd,md
+64bit  1 rd: rldicr ra,rs,shd,md
+64bit  2 rd: rldic  ra,rs,shd,md
+64bit  3 rd: rldimi ra,rs,shd,md
+64bit  8 rd: rldcl  ra,rs,rb,md
+64bit  9 rd: rldcr  ra,rs,rb,md
+
+     \ 31 is x:  xc:  xo:
+
+       32 d: lwz     rd,d(ra)
+       33 d: lwzu    rd,d(ra)
+       34 d: lbz     rd,d(ra)
+       35 d: lbzu    rd,d(ra)
+       36 d: stw     rs,d(ra)
+       37 d: stwu    rs,d(ra)
+       38 d: stb     rs,d(ra)
+       39 d: stbu    rs,d(ra)
+       40 d: lhz     rd,d(ra)
+       41 d: lhzu    rd,d(ra)
+       42 d: lha     rd,d(ra)
+       43 d: lhau    rd,d(ra)
+       44 d: sth     rs,d(ra)
+       45 d: sthu    rs,d(ra)
+       46 d: lmw     rd,d(ra)
+       47 d: stmw    rs,d(ra)
+       48 d: lfs     frd,d(ra)
+       49 d: lfsu    frd,d(ra)
+       50 d: lfd     frd,d(ra)
+       51 d: lfdu    frd,d(ra)
+       52 d: stfs    frs,d(ra)
+       53 d: stfsu   frs,d(ra)
+       54 d: stfd    frs,d(ra)
+       55 d: stfdu   frs,d(ra)
+
+\  56,57 are unassigned
+
+64bit  58 0 dl: ld   rd,ds(ra)
+64bit  58 1 dl: ldu  rd,ds(ra)
+64bit  58 2 dl: lwa  rd,ds(ra)
+
+\  59 is s: words
+\  60,61 are unassigned
+
+64bit  62 0 dl: std  rs,ds(ra)
+64bit  62 1 dl: stdu rs,ds(ra)
+
+\  63 is f:
+
+       
+       16   0 0 b: bc      bo,bi,bd
+       16   0 1 b: bca     bo,bi,bd
+       16   1 0 b: bcl     bo,bi,bd
+       16   1 1 b: bcla    bo,bi,bd
+       
+       17   1 0 b: sc      no-args
+       
+       18   0 0 b: b       lif
+       18   0 1 b: bl      lif
+       18   1 0 b: ba      lif
+       18   1 1 b: bla     lif
+       
+\ Opcode 19
+
+       19  16 0 b: bclr    bo,bi
+       19  16 1 b: bclrl   bo,bi
+       
+       19 528 0 b: bcctr   bo,bi
+       19 528 1 b: bcctrl  bo,bi
+       
+         0 xl: mcrf    crfd,crfs
+       
+        50 xl: rfi     no-args
+       150 xl: isync   no-args
+       
+        33 xl: crnor   crbd,crba,crbb
+       129 xl: crandc  crbd,crba,crbb
+       193 xl: crxor   crbd,crba,crbb
+       225 xl: crnand  crbd,crba,crbb
+       257 xl: crand   crbd,crba,crbb
+       289 xl: creqv   crbd,crba,crbb
+       417 xl: crorc   crbd,crba,crbb
+       449 xl: cror    crbd,crba,crbb
+
+\ Opcode 31
+
+         8 xo: subfc   rd,ra,rb
+        10 xo: addc    rd,ra,rb
+        40 xo: subf    rd,ra,rb
+       104 xo: neg     rd,ra
+power  107 xo: mul     rd,ra,rb
+       136 xo: subfe   rd,ra,rb
+       138 xo: adde    rd,ra,rb
+       200 xo: subfze  rd,ra
+       202 xo: addze   rd,ra
+       232 xo: subfme  rd,ra
+       234 xo: addme   rd,ra
+       235 xo: mullw   rd,ra,rb
+power  264 xo: doz     rd,ra,rb
+       266 xo: add     rd,ra,rb
+       331 xo: div     rd,ra,rb
+power  360 xo: abs     rd,ra
+       363 xo: divs    rd,ra,rb
+64bit  457 xo: divdu   rd,ra,rb
+       459 xo: divwu   rd,ra,rb
+       491 xo: divw    rd,ra,rb
+power  488 xo: nabs    rd,ra
+64bit  233 xo: mulld   rd,ra,rb
+64bit  489 xo: divd    rd,ra,rb
+       
+        28 xc: and     ra,rs,rb
+        60 xc: andc    ra,rs,rb
+       124 xc: nor     ra,rs,rb
+       284 xc: eqv     ra,rs,rb
+       316 xc: xor     ra,rs,rb
+       412 xc: orc     ra,rs,rb
+       444 xc: or      ra,rs,rb
+       476 xc: nand    ra,rs,rb
+        
+        11 xc: mulhwu  rd,ra,rb
+        75 xc: mulhw   rd,ra,rb
+64bit    9 xc: mulhdu  rd,ra,rb
+64bit   73 xc: mulhd   rd,ra,rb
+       922 xc: extsh   ra,rs
+       954 xc: extsb   ra,rs
+64bit  986 xc: extsw   ra,rs
+       
+        24 xc: slw     ra,rs,rb
+       536 xc: srw     ra,rs,rb
+       792 xc: sraw    ra,rs,rb
+       824 xc: srawi   ra,rs,sh
+64bit   27 xc: sld     ra,rs,rb
+64bit  539 xc: srd     ra,rs,rb
+64bit  413 xc: sradi   ra,rs,shd
+64bit  794 xc: srad    ra,rs,rb
+       
+        26 xc: cntlzw  ra,rs
+64bit   58 xc: cntlzd  ra,rs
+       
+       150 xc: stwcx   rs,ra,rb   \ XXX the non-dotted form doesn't exist!
+64bit  214 xc: stdcx   rs,ra,rb   \ XXX the non-dotted form doesn't exist!
+       
+power  277 xc: lscbx   rd,ra,rb
+       
+power   29 xc: maskg   ra,rs,rb
+power  541 xc: maskir  ra,rs,rb
+power  537 xc: rrib    ra,rs,rb
+power  153 xc: sle     ra,rs,rb
+power  217 xc: sleq    ra,rs,rb
+power  216 xc: sllq    ra,rs,rb
+power  152 xc: slq     ra,rs,rb
+power  184 xc: sliq    ra,rs,sh
+power  248 xc: slliq   ra,rs,sh
+power  952 xc: sraiq   ra,rs,sh
+power  920 xc: sraq    ra,rs,rb
+power  665 xc: sre     ra,rs,rb
+power  921 xc: srea    ra,rs,rb
+power  729 xc: sreq    ra,rs,rb
+power  696 xc: sriq    ra,rs,sh
+power  760 xc: srliq   ra,rs,sh
+power  728 xc: srlq    ra,rs,rb
+power  664 xc: srq     ra,rs,rb
+       
+       531  x: clcs    rd,ra
+       
+         0  x: cmp     crfd,l,ra,rb
+        32  x: cmpl    crfd,l,ra,rb
+       
+        86  x: dcbf    ra,rb
+       470  x: dcbi    ra,rb
+        54  x: dcbst   ra,rb
+       278  x: dcbt    ra,rb
+       246  x: dcbtst  ra,rb
+      1014  x: dcbz    ra,rb
+       
+       310  x: eciwx   rd,ra,rb
+       438  x: ecowx   rs,ra,rb
+       854  x: eieio   no-args
+       
+       982  x: icbi    ra,rb
+       
+        87  x: lbzx    rd,ra,rb
+       119  x: lbzux   rd,ra,rb
+       343  x: lhax    rd,ra,rb
+       375  x: lhaux   rd,ra,rb
+       790  x: lhbrx   rd,ra,rb
+       279  x: lhzx    rd,ra,rb
+       311  x: lhzux   rd,ra,rb
+        23  x: lwzx    rd,ra,rb
+        55  x: lwzux   rd,ra,rb
+        20  x: lwarx   rd,ra,rb
+       534  x: lwbrx   rd,ra,rb
+       533  x: lswx    rd,ra,rb
+       597  x: lswi    rd,ra,nb
+
+64bit   21  x: ldx     rd,ra,rb
+64bit   53  x: ldux    rd,ra,rb
+64bit   84  x: ldarx   rd,ra,rb
+64bit  341  x: lwax    rd,ra,rb
+64bit  373  x: lwaux   rd,ra,rb
+       
+       542 x: lwdx   rd,ra,rb	\ exponential
+       670 x: stwdx  rd,ra,rb	\ exponential
+
+       215  x: stbx    rs,ra,rb
+       247  x: stbux   rs,ra,rb
+       407  x: sthx    rs,ra,rb
+       439  x: sthux   rs,ra,rb
+       918  x: sthbrx  rs,ra,rb
+       662  x: stwbrx  rs,ra,rb
+       151  x: stwx    rs,ra,rb
+       183  x: stwux   rs,ra,rb
+
+64bit  149  x: stdx    rs,ra,rb
+64bit  181  x: stdux   rs,ra,rb
+       
+       725  x: stswi   rs,ra,nb
+       661  x: stswx   rs,ra,rb
+       
+       727  x: stfdx   frs,ra,rb
+       759  x: stfdux  frs,ra,rb
+       663  x: stfsx   frs,ra,rb
+       695  x: stfsux  frs,ra,rb
+
+64bit  983  x: stfiwx  frs,ra,rb
+       
+       631  x: lfdux   frd,ra,rb
+       599  x: lfdx    frd,ra,rb
+       567  x: lfsux   frd,ra,rb
+       535  x: lfsx    frd,ra,rb
+       
+       512  x: mcrxr   crfd
+        19  x: mfcr    rd
+       
+        83  x: mfmsr   rd
+       339  x: mfspr   rd,spr
+       595  x: mfsr    rd,sr
+       659  x: mfsrin  rd,rb
+       144  x: mtcrf   crm,rs
+       146  x: mtmsr   rs
+       467  x: mtspr   spr,rs
+       210  x: mtsr    sr,rs
+       242  x: mtsrin  rs,rb
+       371  x: mftb    rd,tbr	\ tbr register is tb or tbu
+       
+64bit  434  x: slbie   no-args
+64bit  498  x: slbia   no-args
+       566  x: tlbsync no-args
+64bit  370  x: tlbia   no-args
+       598  x: sync    no-args
+       306  x: tlbie   rb
+       978  x: tlbld   rb		\ 603-specific
+      1010  x: tlbli   rb		\ 603-specific
+         4  x: tw      to,ra,rb
+64bit   68  x: td      to,ra,rb
+
+\ Opcode 59
+
+        18  s: fdivw   frd,fra,frb
+        20  s: fsubs   frd,fra,frb
+        21  s: fadds   frd,fra,frb
+        25  s: fmuls   frd,fra,frc
+        28  s: fmsubs  frd,fra,frc,frb
+        29  s: fmadds  frd,fra,frc,frb
+        30  s: fnmsubs frd,fra,frc,frb
+        31  s: fnmadds frd,fra,frc,frb
+
+\ Opcode 63
+
+        18  f: fdiv    frd,fra,frb
+        20  f: fsub    frd,fra,frb
+        21  f: fadd    frd,fra,frb
+        25  f: fmul    frd,fra,frc
+        28  f: fmsub   frd,fra,frc,frb
+        29  f: fmadd   frd,fra,frc,frb
+        30  f: fnmsub  frd,fra,frc,frb
+        31  f: fnmadd  frd,fra,frc,frb
+       
+        12  f: frsp    frd,frb
+        14  f: fctiw   frd,frb
+        15  f: fctiwz  frd,frb
+64bit   22  f: fsqrt   frd,frb
+64bit   23  f: fsel    frd,frb
+64bit   24  f: fres    frd,frb
+64bit   26  f: fsqrte  frd,frb
+        40  f: fneg    frd,frb
+        72  f: fmr     frd,frb
+       136  f: fnabs   frd,frb
+       264  f: fabs    frd,frb
+       
+64bit  814  f: fctid   frd,frb
+64bit  815  f: fctidz  frd,frb
+64bit  846  f: fcfid   frd,frb
+
+         0  f: fcmpu   crfd,fra,frb
+        32  f: fcmpo   crfd,fra,frb
+       
+        38  f: mtfsb1  crbd
+        64  f: mcrfs   crfd,crfs  ( no-. )
+        70  f: mtfsxl  crbd
+       134  f: mtfsfi  crfd,imm
+       583  f: mffs    frd
+       711  f: mtfsf   fm,frb
+
+\ This definition prevents "add." from being parsed as a number.
+: add.  ( -- )  add  1 rc-bit  ;
+
+headerless
+: dis-16  ( -- )
+   31 2 ibits  case
+      0  of  ['] bc    endof
+      1  of  ['] bcl   endof
+      2  of  ['] bca   endof
+      3  of  ['] bcla  endof
+   endcase
+   dis-name&operands
+;
+
+16 op-map  set-indexed-map
+: dis-18  ( -- )
+   31 2 ibits  case
+      0  of  ['] b    endof
+      1  of  ['] bl   endof
+      2  of  ['] ba   endof
+      3  of  ['] bla  endof
+   endcase
+   dis-name&operands
+;
+18 op-map  set-indexed-map
+
+: dis-19  ( -- )
+   30 10 ibits  19-map find-sparse-entry 
+   dup (.name)                                       ( acf )
+   31 1 ibits  if  ." l"  then
+   dis-operands
+;
+19 op-map  set-indexed-map
+
+: dis-31  ( -- )
+   28 3 ibits  2 =  if		\ xo form, with o and . modifiers
+      30 9 ibits  31-map  find-indexed-entry   dup (.name)   ( acf )
+      21 1 ibits  if  ." o"  then
+   else
+      30 10 ibits  31-map  find-indexed-entry  dup (.name)   ( acf )
+   then                           ( acf )
+   ?.  dis-operands
+;
+31 op-map  set-indexed-map
+
+: dis-59  ( -- )
+   30 5 ibits  59-map  find-indexed-entry  dup (.name)  ?.  dis-operands
+;
+59 op-map  set-indexed-map
+
+: dis-63  ( -- )
+   30 10 ibits  63-map  find-sparse-entry  dup (.name)  ?.  dis-operands
+;
+63 op-map  set-indexed-map
+
+
+headers
+\ Structured conditionals
+
+\ Condition names.  There are more of these near the end of the file.
+\ BO bits:    16 no-cond   8 cc bit true   4 no-ctr   2 ctr=0
+\ B1 values:   0 lt   1 gt   2 eq
+
+20  0 cond always
+12 00 cond lt       04 00 cond ge
+12 01 cond gt       04 01 cond le
+12 02 cond eq       04 02 cond ne  
+12 03 cond vs       04 03 cond vc      
+
+: ctr<>0  ( cond -- cond' )
+   h# 0080.0000 invert [ also forth ] and [ previous ]
+;
+: ctr=0   ( cond -- cond' )
+   ctr<>0  h# 0040.0000 [ also forth ] or [ previous ]
+;
+
+headerless
+: <mark  ( -- <mark )  here  ;
+: >mark  ( -- >mark )  here  ;
+: >resolve  ( >mark -- )  here   over offset-16 over asm@ +  swap asm!  ;
+: <resolve  ( -- )  ;
+
+headers
+: but     ( mark1 mark2 -- mark2 mark1 )  swap  ;
+: yet     ( mark -- mark mark )  dup  ;
+
+: ahead   ( -- >mark )          >mark  here always brif  ;
+: if      ( cond -- >mark )     >mark  here  rot -cond  brif  ;
+: then    ( >mark -- )          >resolve  ;
+: else    ( >mark -- >mark1 )   ahead  but then  ;
+: begin   ( -- <mark )          <mark  ;
+: until   ( <mark cond -- )     -cond brif  ;
+: again   ( <mark -- )          always brif  ;
+: repeat  ( >mark <mark -- )    again  then  ;
+: while   ( <mark cond -- >mark <mark )  if  but  ;
+
+\ Define these last to delay overloading of the forth versions
+
+\ There are no explicit condition codes for unsigned comparison;
+\ there is a "cmpl" instruction that performs an unsigned ("logical")
+\ comparison, setting the regular less-than and greater-than bits.
+
+12 00 cond 0<   04 00 cond 0>=
+12 00 cond  <   04 00 cond  >=
+12 01 cond 0>   04 01 cond 0<=
+12 01 cond  >   04 01 cond  <=
+12 02 cond 0=   04 02 cond 0<>
+12 02 cond  =   04 02 cond  <>
+
+previous definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/banner.fth
===================================================================
--- cpu/ppc/banner.fth	                        (rev 0)
+++ cpu/ppc/banner.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,35 @@
+purpose: Displays banner describing system configuration
+\ See license at end of file
+
+\ Display the startup message.
+
+: fw-title  ( -- )
+   ." Power Firmware(TM) by FirmWorks"
+   " build-date"  $find  if  ." , Built " execute type  else  2drop  then  cr
+   ?spaces ." Copyright (c) 1995-2000, FirmWorks.  All Rights Reserved." cr
+;
+' fw-title to .firmware
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/basefw.bth
===================================================================
--- cpu/ppc/basefw.bth	                        (rev 0)
+++ cpu/ppc/basefw.bth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,113 @@
+purpose: Load file for base firmware - no platform specifics
+\ See license at end of file
+
+dictionary: ${BP}/cpu/ppc/build/tools.dic
+command: &ppcforth &dictionary &this
+build-now
+
+hex
+
+\ ' $report-name is include-hook
+
+\ create use-prep-nvram
+
+create include-help			\ Include help facility
+
+fload ${BP}/cpu/ppc/occhksum.fth	\ IP checksum primitive
+
+alias cfill fill
+fload ${BP}/ofw/core/ofwcore.fth	\ Device tree and other OBP routines
+fload ${BP}/ofw/core/ofwfw.fth		\ FirmWorks enhancements
+
+fload ${BP}/ofw/core/memops.fth		\ Call memory node methods
+fload ${BP}/ofw/core/mmuops.fth		\ Call MMU node methods
+\ : cfill fill ;
+
+fload ${BP}/cpu/ppc/cpuclass.fth	\ CPU characterization
+
+\ Load millisecond timer
+fload ${BP}/cpu/ppc/getms.fth		\ Timer access
+
+fload ${BP}/cpu/ppc/call.fth		\ Primitive subroutine calls
+fload ${BP}/cpu/ppc/centry.fth		\ Low-level client entry and exit
+fload ${BP}/cpu/ppc/fb8-ops.fth		\ S Machine code for fb8
+
+fload ${BP}/ofw/confvar/loadcv.fth	\ Configuration variables
+fload ${BP}/ofw/core/silentmd.fth	\ NVRAM variable silent-mode?
+
+fload ${BP}/ofw/termemu/loadfb.fth	\ Frame buffer support
+fload ${BP}/ofw/termemu/difont.fth	\ Get font from a dropin module
+
+fload ${BP}/ofw/gui/alert.fth		\ Basic dialogs and alerts
+fload ${BP}/dev/stringio.fth		\ Output diversion
+
+fload ${BP}/ofw/core/loadmore.fth	\ Load additional core stuff
+
+fload ${BP}/ofw/inet/loadtftp.fth	\ Trivial File Transfer Protocol pkg.
+
+fload ${BP}/cpu/ppc/forthint.fth	\ Alarm handler
+
+fload ${BP}/cpu/ppc/regacc.fth		\ Register access words
+
+fload ${BP}/ofw/fcode/loadfcod.fth	\ S Fcode interpreter
+
+fload ${BP}/ofw/fcode/regcodes.fth	\ Register access words
+fload ${BP}/ofw/fcode/extcodes.fth	\ Firmworks extension FCodes
+
+\ File system readers
+fload ${BP}/ofw/core/initprog.fth	\ FCode and Forth source load formats 
+
+fload ${BP}/ofw/core/infltdi.fth	\ Support for compressed dropin drivers
+' in-little-endian? to flip-code?	\ Flip inflated code when in LE mode
+
+[ifdef] resident-packages
+support-package: fat-file-system
+   fload ${BP}/ofw/fs/fatfs/loadpkg.fth	\ FAT file system reader
+end-support-package
+
+support-package: iso9660-file-system
+   fload ${BP}/ofw/fs/cdfs/loadpkg.fth	\ ISO 9660 CD-ROM file system reader
+end-support-package
+
+support-package: disk-label
+   fload ${BP}/ofw/disklabel/loadpkg.fth	\ Disk label package
+end-support-package
+[then]
+
+[ifdef] resident-packages
+fload ${BP}/ofw/fs/fatfs/fdisk2.fth	\ Partition map administration
+[else]
+autoload: fdisk2.fth
+defines: $.partitions
+defines: .partitions
+\ defines: init-nt-disk
+defines: $partition
+[then]
+
+[ifndef] no-heads
+.( --- Saving basefw.dic --- )  cr "" basefw.dic save-forth
+[then]
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/bat.fth
===================================================================
--- cpu/ppc/bat.fth	                        (rev 0)
+++ cpu/ppc/bat.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,236 @@
+purpose: Block Address Translation register access
+\ See license at end of file
+
+hex
+
+headerless
+code ibat!  ( bat-lo bat-hi ibat# -- )
+	lwz	t0,0(sp)
+	lwz	t1,1cell(sp)
+
+	cmpi	0,0,tos,0
+	=  if
+           sync  isync
+	   mtspr  ibat0u,t0
+	   mtspr  ibat0l,t1
+           sync  isync
+	else
+
+	cmpi	0,0,tos,1
+	=  if
+           sync  isync
+	   mtspr  ibat1u,t0
+	   mtspr  ibat1l,t1
+           sync  isync
+	else
+
+	cmpi	0,0,tos,2
+	=  if
+           sync  isync
+	   mtspr  ibat2u,t0
+	   mtspr  ibat2l,t1
+           sync  isync
+	else
+
+	cmpi	0,0,tos,3
+	=  if
+           sync  isync
+	   mtspr  ibat3u,t0
+	   mtspr  ibat3l,t1
+           sync  isync
+	then then then then
+
+	lwz	tos,2cells(sp)
+	addi	sp,sp,3cells
+c;
+
+code dbat!  ( bat-lo bat-hi dbat# -- )
+	lwz	t0,0(sp)
+	lwz	t1,1cell(sp)
+
+	cmpi	0,0,tos,0
+	=  if
+           sync  isync
+	   mtspr  dbat0u,t0
+	   mtspr  dbat0l,t1
+           sync  isync
+	else
+
+	cmpi	0,0,tos,1
+	=  if
+           sync  isync
+	   mtspr  dbat1u,t0
+	   mtspr  dbat1l,t1
+           sync  isync
+	else
+
+	cmpi	0,0,tos,2
+	=  if
+           sync  isync
+	   mtspr  dbat2u,t0
+	   mtspr  dbat2l,t1
+           sync  isync
+	else
+
+	cmpi	0,0,tos,3
+	=  if
+           sync  isync
+	   mtspr  dbat3u,t0
+	   mtspr  dbat3l,t1
+           sync  isync
+	then then then then
+
+	lwz	tos,2cells(sp)
+	addi	sp,sp,3cells
+c;
+
+code ibat@  ( ibat# -- bat-lo bat-hi )
+	cmpi	0,0,tos,0
+	=  if
+	   mfspr  tos,ibat0u
+	   mfspr  t1,ibat0l
+	else
+
+	cmpi	0,0,tos,1
+	=  if
+	   mfspr  tos,ibat1u
+	   mfspr  t1,ibat1l
+	else
+
+	cmpi	0,0,tos,2
+	=  if
+	   mfspr  tos,ibat2u
+	   mfspr  t1,ibat2l
+	else
+
+	cmpi	0,0,tos,3
+	=  if
+	   mfspr  tos,ibat3u
+	   mfspr  t1,ibat3l
+	then then then then
+
+	stwu	t1,-1cell(sp)
+c;
+
+code dbat@  ( dbat# -- bat-lo bat-hi )
+	cmpi	0,0,tos,0
+	=  if
+	   mfspr  tos,dbat0u
+	   mfspr  t1,dbat0l
+	else
+
+	cmpi	0,0,tos,1
+	=  if
+	   mfspr  tos,dbat1u
+	   mfspr  t1,dbat1l
+	else
+
+	cmpi	0,0,tos,2
+	=  if
+	   mfspr  tos,dbat2u
+	   mfspr  t1,dbat2l
+	else
+
+	cmpi	0,0,tos,3
+	=  if
+	   mfspr  tos,dbat3u
+	   mfspr  t1,dbat3l
+	then then then then
+
+	stwu	t1,-1cell(sp)
+c;
+
+headers
+0 constant ibat
+1 constant dbat
+2 constant i&dbats
+
+headerless
+false value l1-writethru?
+
+: cache-mode  ( io? -- mode )
+   if  38  else  10  l1-writethru?  if  40 or  then  then
+;
+: mask-bat-adr  ( adr -- hi-bits  )  1.ffff invert and  ;
+
+headers
+: bat!  ( pa va len io? bat# which -- )
+   >r >r >r >r                              ( pa va ) ( R: which bat# io? len )
+   mask-bat-adr r>                          ( pa BEPI len ) ( R: which bat# io)
+   1- h# 11 >> 2 << or  2 or ( supervisor ) ( pa bat-hi )
+   swap mask-bat-adr                        ( bat-hi BRPN )
+   \ Coherent in both cases, no cache for I/O
+   r>  cache-mode  or                       ( bat-hi BRPN|WIMG ) ( R: wh bat# )
+   2 or ( r/w )  swap                       ( bat-lo bat-hi ) ( R: which bat# )
+   r> r>  case
+      dbat     of  dbat!  endof
+      ibat     of  ibat!  endof
+      i&dbats  of  3dup  dbat! ibat!  endof
+   endcase
+;
+
+: bat@  ( bat# which -- false | pa va len flags true )
+   dbat =  if  dbat@  else  ibat@  then         ( bat-lo bat-hi )
+   dup 3 and  0=  if  2drop false exit  then    ( bat-lo bat-hi )
+   over h# 7f and >r                            ( bat-lo bat-hi r: flags )
+   swap mask-bat-adr swap                       ( pa bat-hi )
+   dup mask-bat-adr swap                        ( pa va bat-hi )
+   2 >> 7ff and 1+ h# 11 <<                     ( pa va len )
+   r> true
+;
+headerless
+
+\ Motorola says that the BAT registers can become corrupted if
+\ two of them happen to map overlapping ranges, even if address
+\ translation is turned off, and that said corruption can be prevented
+\ by invalidating all the BAT registers before programming any of them.
+
+: clear-bats  ( -- )  4 0  do  0 0 i ibat!  0 0 i dbat!  loop  ;
+: clear-srs   ( -- )  10 0 do  0 i sr!  loop  ;
+
+: .xbats  ( ibat|dbat -- )
+   4 0  do
+      dup ibat =  if  ." I"  else  ." D"  then
+      i .
+      i over bat@  if   ( pa va len flags )
+         rot 9 u.r  rot d# 10 u.r  swap 9 u.r   ( flags )
+         binary 2 spaces  <# u# u# 2/ ascii . hold u# u# u# u# u#> type  hex
+      else
+         ."  --invalid--"
+      then
+      cr
+   loop
+   drop
+;
+headers
+: .bats  ( -- )
+   base @ >r hex
+   ."  #   Virtual  Physical   Length  WIMG.PP" cr
+   ibat .xbats
+   dbat .xbats
+   r> base !
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/bat601.fth
===================================================================
--- cpu/ppc/bat601.fth	                        (rev 0)
+++ cpu/ppc/bat601.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,100 @@
+purpose: Block Address Translation register access for PowerPC 601
+\ See license at end of file
+
+hex
+
+\ PPC 601 has a unified cache and a single set of BAT registers, accessed
+\ with the SPR numbers used for IBATs
+
+\ The layout of the 601 BAT bits is different from the standard PPC layout
+
+: bat!-601  ( pa va len io? bat# which -- )
+   drop >r >r >r                             ( pa va )     ( R: bat# io? len )
+
+   swap mask-bat-adr      \ phys block #     ( va PBN )
+   r>  1-  h# 11 >>  or   \ block length     ( va PBN|BL)  ( R: bat# io? )
+   h# 40 or               \ valid bit        ( va bat-lo )
+
+   swap mask-bat-adr      \ log. page index  ( bat-lo BLPI )
+   \ no cache for I/O, coherent and no protection in both cases
+   r>  if  h# 32  else  h# 12  then  or      ( bat-lo bat-hi ) ( R: bat# )
+
+   r>  ibat!
+;
+
+: bat at -601  ( bat# which -- false | pa va len flags true )
+   drop ibat@                                      ( bat-lo bat-hi )
+   over h# 40 and  0=  if  2drop false exit  then  ( bat-lo bat-hi )
+   over mask-bat-adr                               ( bat-lo bat-hi pa )
+   over mask-bat-adr                               ( bat-lo bat-hi pa va )
+   2swap  swap  h# 3f and 1+  h# 11 <<             ( pa va bat-hi len )
+   swap h# 7f and true                             ( pa va len flags t )
+;
+
+\ On some processors, the BAT registers can become corrupted if
+\ two of them happen to map overlapping ranges, even if address
+\ translation is turned off, and that said corruption can be prevented
+\ by invalidating all the BAT registers before programming any of them.
+
+: clear-bats-601  ( -- )
+   4 0  do  0 0 i ibat!  loop  
+;
+
+: .bats-601  ( -- )
+   base @ >r hex
+   ." #   Virtual  Physical  Length  WIMsuPP" cr
+   4 0  do
+      i .
+      i ibat bat at -601  if   ( pa va len flags )
+         rot 9 u.r  rot d# 10 u.r  swap 8 u.r   ( flags )
+         binary 2 spaces  <# u# u# u# u# u# u# u# u#> type  hex
+      else
+         ."  --invalid--"
+      then
+      cr
+   loop
+   r> base !
+;
+
+warning @ warning off
+\ Overlay standard PowerPC versions with switchable versions
+: bat@  ( pa va len io? bat# which -- )
+   601?  if  bat at -601  exit  then
+   bat@
+;
+: bat!  ( pa va len io? bat# which -- )
+   601?  if  bat!-601  exit  then
+   bat!
+;
+: clear-bats  ( -- )
+   601?  if  clear-bats-601 exit  then
+   clear-bats
+;
+: .bats  ( -- )
+   601?  if  .bats-601 exit  then  .bats
+;
+warning !
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/batf601.fth
===================================================================
--- cpu/ppc/batf601.fth	                        (rev 0)
+++ cpu/ppc/batf601.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,184 @@
+purpose: Block address translation (BAT) fault handler
+\ See license at end of file
+
+\ This handler for the DSI interrupt treats the BAT registers
+\ as a 4-entry software-filled TLB.  4 BAT registers are not
+\ enough to hold all of the translations that the firmware and
+\ the client program might need, so we use the BATs as a translation
+\ cache.  When a translation fault occurs, we pick a BAT register
+\ and change its value to translate the address at which the fault
+\ occurred.
+
+\ The 601 BAT registers are not compliant with the PowerPC architecture.
+\ The locations of some fields are different, and each 601 BAT can only
+\ map 8 MBytes, as opposed to 256 MBytes for PPC BATs.  In order to
+\ minimize memory usage, and to keep the same mapping granularity
+\ between the 601 and PPC, we allow mapping only at 256 MByte granularity,
+\ simulating that granularity in software in this implementation by
+\ copying logical address bits 4-8 to the physical address.
+
+\ This allows us to make the mapping table quite small, so it will
+\ fit nicely in otherwise-unused space in the trap vector.
+
+\ Each table entry uses 8 bits - 4 for the physical block number
+\ and 4 for the WIMG bits - so we use 8-bit table entries.
+\ The other BAT register bits are either fixed values or can be
+\ derived from the logical address.
+
+\ For 601, the BAT registers do not support the "G" bit, so we mask it out.
+
+\ We use a round-robin replacement policy.
+
+\ Low memory usage:
+\    Firmware private area:
+\        e0:  save r3 and t1
+\        e4:  save lr and t2
+\        e8:  save t0
+\    DSI vector:
+\       300.. jump to dsi-handler
+\       37f:  next-bat (1 byte)
+\       380:  bat-table (16 bytes)
+
+headerless
+
+label bat-fault-handler-601
+   \ We assume that t0 has been saved at location f8 and now contains
+   \ the fault address.
+
+   lwz    r3,h#e4(r0)		\ Restore lr
+   mtspr  lr,r3
+   lwz    r3,h#e0(r0)		\ Restore r3
+
+   stw    t1,h#e0(r0)
+   stw    t2,h#e4(r0)
+   mfcr   t2
+   stw    t2,h#ec(r0)		\ Save CR
+
+\ [ifdef] notyet
+\    \ Determine the fault type
+\    mfspr  t1,dsisr		\ SPR18
+\    add.   t1,t1,t1		\ Test bit 1 by shifting it to the sign bit
+\    0>=  if			\ Not a translation fault
+\       \ Restore registers and jump to unexpected exception handler
+\    then
+\ [then]      
+
+   \ Fault address is in t0
+
+   \ Index into translation table and get translation info
+   rlwinm  t2,t0,4,28,31	\ Convert high 4 bits to a table index
+   lbz     t2,h#380(t2)		\ Translation entry in t2
+
+   \ Format lower BAT entry
+   rlwinm  t1,t2,24,0,3		\ Shift up physical block number      
+   rlwimi  t1,t0,0,4,8		\ Merge in bits 4-8 of virtual address
+   ori     t1,t1,h#7f		\ valid (40 bit) and 8 MByte size (3f bits)
+
+   \ Format upper BAT entry
+
+   rlwinm  t0,t0,0,0,8		\ Mask out lower bits, leaving page index
+   rlwimi  t0,t2,3,25,27	\ Shift WIMG bits into place, masking out G
+   ori     t0,t0,2		\ Allow all accesses
+
+   lbz     t2,h#37f(r0)		\ Select a BAT
+
+   \ Replace BAT value
+   \ On average, it takes more instructions to do an indexed jump
+   \ than to do explicit compares for this number of cases.
+
+   cmpi	0,0,t2,0
+   =  if
+      sync  isync
+      mtspr  ibat0u,t0
+      mtspr  ibat0l,t1
+      sync  isync
+      set    t2,1
+   else
+
+   cmpi	0,0,t2,1
+   =  if
+      sync  isync
+      mtspr  ibat1u,t0
+      mtspr  ibat1l,t1
+      sync  isync
+      set    t2,2
+   else
+
+   cmpi	0,0,t2,2
+   =  if
+      sync  isync
+      mtspr  ibat2u,t0
+      mtspr  ibat2l,t1
+      sync  isync
+      set    t2,3
+   else
+
+      sync  isync
+      mtspr  ibat3u,t0
+      mtspr  ibat3l,t1
+      sync  isync
+      set    t2,0
+   then then then
+
+   stb    t2,h#37f(r0)	\ Update BAT replacement pointer
+
+
+   \ Restore registers
+   lwz    t0,h#ec(r0)
+   mtcrf  h#ff,t0	\ Restore CR
+   lwz    t0,h#e8(r0)	\ Restore t0
+   lwz    t1,h#e0(r0)	\ Restore t1
+   lwz    t2,h#e4(r0	\ Restore t2
+
+   \ Return from interrupt
+   rfi
+end-code
+
+label bat-dsi-handler-601
+   stw    t0,h#e8(r0)		\ Save t0 in the exception table area
+   mfspr  t0,dar		\ Get fault address
+   bat-fault-handler-601 again	\ Jump to common code
+end-code
+
+label bat-isi-handler-601
+   stw    t0,h#e8(r0)		\ Save t0 in the exception table area
+   mfspr  t0,srr0		\ Get fault address
+   bat-fault-handler-601 again	\ Jump to common code
+end-code
+
+: install-bat-handler-601  ( -- )
+   init-paged-mmu
+
+   bat-dsi-handler-601  h# 300  put-exception
+   bat-isi-handler-601  h# 400  put-exception
+;
+warning @ warning off
+: install-bat-handler  ( -- )
+   601?  if  install-bat-handler-601 exit  then
+   install-bat-handler
+;
+warning !
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/batfault.fth
===================================================================
--- cpu/ppc/batfault.fth	                        (rev 0)
+++ cpu/ppc/batfault.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,321 @@
+purpose: Block address translation (BAT) fault handler
+\ See license at end of file
+
+\ This handler for the DSI interrupt treats the BAT registers
+\ as a 4-entry software-filled TLB.  4 BAT registers are not
+\ enough to hold all of the translations that the firmware and
+\ the client program might need, so we use the BATs as a translation
+\ cache.  When a translation fault occurs, we pick a BAT register
+\ and change its value to translate the address at which the fault
+\ occurred.
+
+\ For simplicity, we use a fixed block size.  For memory economy,
+\ we use the largest possible block size (256 MBytes), thus requiring
+\ a 16-entry in-memory translation table indexed by the high 4 bits
+\ of the logical address.
+
+\ Each table entry uses 8 bits - 4 for the physical block number
+\ and 4 for the WIMG bits - so we use 8-bit table entries.
+\ The other BAT register bits are either fixed values or can be
+\ derived from the logical address.
+
+\ We use a round-robin replacement policy.
+
+\ We store the translation table in the DSI handler vector area so
+\ it is easy to access from the fault handlers.
+
+h# 300 /exc + constant bat-table
+bat-table h# 10 + constant 'next-bat
+\ /exc h# 18 + constant /dsi-footprint
+
+\ On entry:
+\ r2, r3, and lr have been saved. r2 points to this cpu's exception-area,
+
+\ Low memory usage:
+\    Firmware private area:
+\        0:  save r3 and t1
+\        4:  save r2
+\        8:  save lr and t2
+\        c:  save t0
+\       10:  save cr
+\    DSI vector:
+\       300.. jump to dsi-handler
+\       3x0:  bat-table (16 bytes)
+\       3y0:  next-bat (1 byte)
+
+\ Note:  next-bat should be cpu specific: 3yc ?
+
+label bat-dsi-handler
+   mfcr   r3
+   stw    r3,h#10(r2)		\ Save CR
+
+   \ Determine the fault type
+   mfspr   r3,dsisr		\ SPR18
+   rlwinm. r3,r3,0,1,1		\ Test bit 1
+   0=  if			\ Not a translation fault
+( Label )   begin but
+      \ Restore registers and jump to unexpected exception handler
+      lwz    r3,h#10(r2)
+      mtcrf  h#ff,r3		\ Restore CR
+      addi  r3,r0,h#300		\ Exception address
+\ XXX we need to jump to the physical address of save-state
+      save-state  b  *  	\ branch to exception handler
+   then
+
+   mfspr   r3,dar		\ Get fault address
+   rlwinm  r3,r3,4,28,31	\ Convert high 4 bits to a table index
+   lbz     r3,h#380(r3)		\ Translation entry in t2
+   cmpi    0,0,r3,0
+   <> until			\ Jump back to Label if no translation
+
+   lwz    r3,h#08(r2)		\ Restore lr
+   mtspr  lr,r3
+
+   stw    t0,h#0c(r2)		\ Save t0 in the exception table area
+   stw    t2,h#08(r2)		\ Save t2
+
+   mfspr  t0,dar		\ Get fault address
+
+   \ Index into translation table and get translation info
+   rlwinm  t2,t0,4,28,31	\ Convert high 4 bits to a table index
+   lbz     t2,h#380(t2)		\ Translation entry in t2
+
+   \ Format Upper BAT entry
+   rlwinm  t0,t0,0,0,3		\ Mask out lower bits, leaving page index
+   ori     t0,t0,h#1ffe		\ 256M block size, supervisor mode
+
+   \ Format Lower BAT entry
+   rlwinm  r3,t2,24,0,3		\ Shift up physical block number
+   rlwimi  r3,t2,3,25,28	\ Shift WIMG bits into place
+   ori     r3,r3,2		\ Allow all accesses
+
+   lbz     t2,h#37f(r0)		\ Select a BAT
+
+   \ Replace BAT value
+   \ On average, it takes more instructions to do an indexed jump
+   \ than to do explicit compares for this number of cases.
+
+   cmpi	0,0,t2,0  =  if
+      sync  isync  mtspr dbat0u,t0   mtspr dbat0l,r3  sync  isync
+      set    t2,1
+   else
+
+   cmpi	0,0,t2,1  =  if
+      sync  isync  mtspr dbat1u,t0   mtspr dbat1l,r3  sync  isync
+      set    t2,2
+   else
+
+[ifdef]  NTkludge
+      \ Some earlier NT HALs have a bug that causes them to hang
+      \ if the KSEG0 (virt 8000.0000 -> phys 0) mapping resides in
+      \ IBAT3, so to be safe, we avoid using either IBAT3 or DBAT3.
+      sync  isync  mtspr dbat2u,t0   mtspr dbat2l,r3  sync  isync
+      set    t2,0
+   then then
+[else]
+   cmpi	0,0,t2,2  =  if
+      sync  isync  mtspr dbat2u,t0   mtspr dbat2l,r3  sync  isync
+      set    t2,3
+   else
+      sync  isync  mtspr dbat3u,t0   mtspr dbat3l,r3  sync  isync
+      set    t2,0
+   then then then
+[then]
+
+   stb    t2,h#37f(r0)	\ Update BAT replacement pointer
+
+   \ Restore registers
+   lwz    t0,h#10(r2)
+   mtcrf  h#ff,t0	\ Restore CR
+   lwz    t0,h#0c(r2)	\ Restore t0
+   lwz    r3,h#00(r2)	\ Restore r3
+   lwz    t2,h#08(r2)	\ Restore t2
+   lwz    r2,h#04(r2)	\ Restore r2
+
+   \ Return from interrupt
+   rfi
+end-code
+
+label bat-isi-handler
+   mfcr   r3
+   stw    r3,h#10(r2)		\ Save CR
+
+   \ In violation of the PowerPC architecture definition, the 603 does
+   \ not implement the translation fault bit for instruction accesses,
+   \ so we assume that any 603 instruction fault is a translation fault.
+   \ This is tolerable because instruction accesses to non-existent devices
+   \ do not occur on purpose - probing to determine the presence of devices
+   \ is done with data accesses.
+   
+\ However, the 603 ISI exception is front-ended by the ITLB miss handler,
+\ in which we set the translation fault bit.
+
+\   mfspr  r3,pvr
+\   rlwinm r3,r3,16,16,31
+\   cmpi   0,0,r3,3
+\   0<>  if
+
+   \ Determine the fault type
+   mfspr   r3,srr1		\ Fault type is in SRR1 for I faults
+   rlwinm. r3,r3,0,1,1		\ Test bit 1
+   0=  if			\ Not a translation fault
+( Label )   begin but
+      \ Restore registers and jump to unexpected exception handler
+      lwz    r3,h#10(r2)
+      mtcrf  h#ff,r3		\ Restore CR
+      addi  r3,r0,h#400		\ Exception address
+      save-state  b  *  	\ branch to exception handler
+   then
+\   then
+
+   mfspr   r3,srr0		\ Get fault address
+   rlwinm  r3,r3,4,28,31	\ Convert high 4 bits to a table index
+   lbz     r3,h#380(r3)		\ Translation entry in t2
+   cmpi    0,0,r3,0
+   <> until			\ Jump back to Label if no translation
+
+   lwz    r3,h#08(r2)		\ Restore lr
+   mtspr  lr,r3
+
+   stw    t0,h#0c(r2)		\ Save t0 in the exception table area
+   stw    t2,h#08(r2)		\ Save t2
+
+   mfspr  t0,srr0		\ Get fault address
+
+   \ Index into translation table and get translation info
+   rlwinm  t2,t0,4,28,31	\ Convert high 4 bits to a table index
+   lbz     t2,h#380(t2)		\ Translation entry in t2
+
+   \ Format Upper BAT entry
+   rlwinm  t0,t0,0,0,3		\ Mask out lower bits, leaving page index
+   ori     t0,t0,h#1ffe		\ 256M block size, supervisor mode
+
+   \ Format Lower BAT entry
+   rlwinm  r3,t2,24,0,3		\ Shift up physical block number
+   rlwimi  r3,t2,3,25,27	\ Shift WIM  bits into place, masking off G
+   ori     r3,r3,2		\ Allow all accesses
+
+   lbz     t2,h#37f(r0)		\ Select a BAT
+
+   \ Replace BAT value
+   \ On average, it takes more instructions to do an indexed jump
+   \ than to do explicit compares for this number of cases.
+
+   cmpi	0,0,t2,0  =  if
+      sync  isync  mtspr ibat0u,t0   mtspr ibat0l,r3  sync  isync
+      set    t2,1
+   else
+
+   cmpi	0,0,t2,1  =  if
+      sync  isync  mtspr ibat1u,t0   mtspr ibat1l,r3  sync  isync
+      set    t2,2
+   else
+
+   cmpi	0,0,t2,2  =  if
+      sync  isync  mtspr ibat2u,t0   mtspr ibat2l,r3  sync  isync
+      set    t2,3
+   else
+      sync  isync  mtspr ibat3u,t0   mtspr ibat3l,r3  sync  isync
+      set    t2,0
+   then then then
+
+   stb    t2,h#37f(r0)	\ Update BAT replacement pointer
+
+   \ Restore registers
+   lwz    t0,h#10(r2)
+   mtcrf  h#ff,t0	\ Restore CR
+   lwz    t0,h#0c(r2)	\ Restore t0
+   lwz    r3,h#00(r2)	\ Restore r3
+   lwz    t2,h#08(r2)	\ Restore t2
+   lwz    r2,h#04(r2)	\ Restore r2
+
+   \ Return from interrupt
+   rfi
+end-code
+
+label tlb-miss-template		\ 603-specific
+   mfspr   r3,srr1
+   set     r2,h#40000000	\ Translation fault bit
+   rlwinm. r1,r3,0,13,13
+   0<>  if			\ Itlb
+      mtcrf  h#80,r3		\ Restore Condition Register
+      or     r3,r3,r2		\ Set instruction translation fault bit
+      mtspr  srr1,r3		\ .. in SRR1
+   else
+      mtcrf  h#80,r3		\ Restore Condition Register
+      mtspr  dsisr,r2		\ Set data translation fault bit
+      mfspr  r2,dmiss		\ Put the miss address
+      mtspr  dar,r2		\ in the data address register
+   then
+
+   mfmsr  r3
+   rlwinm r3,r3,0,15,13		\ Clear TGPR bit to reveal real registers
+   mtmsr  r3
+end-code
+here tlb-miss-template - constant /miss
+
+/miss la1+ to /rm-tlbmiss
+
+: put-tlb-miss-entry  ( entry-vector target-vector -- )
+   swap
+   tlb-miss-template  /miss  bounds  ?do  ( target-vector entry-vector )
+      i l@ over instruction!  la1+
+   /l +loop                               ( target-vector entry-vector' )
+   put-branch
+;
+
+code invalidate-tlbs  ( #entries -- )
+   sync isync
+
+   rlwinm tos,tos,12,0,19
+
+   begin
+      addic.  tos,tos,h#-1000
+      tlbie   tos
+   0= until
+   
+   tlbsync
+
+   lwz    tos,0(sp)
+   addi   sp,sp,1cell
+c;
+
+: install-bat-handler  ( -- )
+   init-paged-mmu
+
+   bat-dsi-handler  h# 300  put-exception
+   bat-isi-handler  h# 400  put-exception
+
+   software-tlb-miss?  if
+      h# 1000  h# 400 put-tlb-miss-entry  \ Instruction fetch TLB miss
+      h# 1100  h# 300 put-tlb-miss-entry  \ Data load TLB
+      h# 1200  h# 300 put-tlb-miss-entry  \ Data store TLB
+   else
+   then
+
+   configure-tlb  #tlb-lines invalidate-tlbs
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/batmap.fth
===================================================================
--- cpu/ppc/batmap.fth	                        (rev 0)
+++ cpu/ppc/batmap.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,57 @@
+purpose: Block address translation (BAT) mapping setup
+\ See license at end of file
+
+\ This code's data structures are shared with the low-level code
+\ in batfault.fth and batf601.fth .  See those files for a description.
+
+: >bat-map  ( va -- adr )  h# 380  swap d# 28 rshift ca+  ;
+: bat-invalid  ( va -- )  0 swap >bat-map c!  ;
+: bat-mapping  ( va -- false | pa wim true )
+   >bat-map c@  dup  if  dup 4 >> d# 28 <<  swap h# f and  true  then
+;
+: bat-set  ( pa wimg va -- )
+   -rot swap d# 28 rshift  d# 4 lshift  or  ( va bte )
+   swap >bat-map c!
+;
+: bat-map  ( pa io? va -- )
+   \   WIM bits - don't cache,coherent,guarded for I/O,  coherent for memory
+   -rot  if  7  else  2  then  rot     ( pa WIMG va )
+   bat-set
+;
+h# 1000.0000 constant /bat-region
+: clear-bat-table  ( -- )
+   0 h# 37f c!		\ bat entry 0 is next in line for replacement
+
+   \ Invalidate all entries in the bat translation table
+   0  0  do  i bat-invalid   /bat-region +loop
+;
+: setup-real-bat-table  ( -- )
+   0 h# 37f c!		\ bat entry 0 is next in line for replacement
+   
+   \ map first half of address space cacheable, rest non-cacheable.
+   0 0 do   i  i 0<  i  bat-map   /bat-region +loop
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/boot.fth
===================================================================
--- cpu/ppc/boot.fth	                        (rev 0)
+++ cpu/ppc/boot.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,183 @@
+purpose: Boot code (cold and warm start) for PowerPC
+\ See license at end of file
+
+\ Version for running Forth underneath a "wrapper" program
+
+\ The cold start code is executed when Forth is initially started.
+\ Its job is to initialize the Forth virtual machine registers.
+\ The warm start code is executed when Forth is re-entered,
+\ perhaps as a result of an exception.
+
+hex
+
+only forth also labels also meta also definitions
+
+0 constant main-task
+: init-user  (s -- )
+;
+
+\ Stuff initialized at cold start time
+
+nuser memtop		\ The top of the memory used by Forth
+0 value #args		\ The process's argument count
+0 value  args		\ The process's argument list
+
+\ Defining these two in code is a significant performance optimization
+\ for Open Firmware
+code package(  ( ihandle -- )  
+   'user my-self  lwz  t0,*
+   stwu    t0,-1cell(rp)
+   'user my-self  stw  tos,*
+   pop-tos
+c;
+code )package  ( -- )
+   lwz   t0,0(rp)
+   rdrop
+   'user my-self  stw t0,*
+c;
+
+headerless
+
+label cold-code  ( -- )
+
+\ called with   forth_startup(header-adr, functions, mem_end, &gargc, &gargv)
+\ 				 r3	    r4	      r5	r6	r7
+
+\ Get some registers
+   \ XXX should save registers
+
+\  here origin - . cr
+
+   nop
+
+\ Find the base address
+   here-t 4 +   bl   *          \ Absolute address of next instruction
+   here-t       set  base,*	\ Relative address of this instruction
+   mfspr   t0,lr
+   subfc   base,base,t0		\ Base address of Forth kernel
+				\ ( Use subfc for POWER compatibility)
+ \ Synchronize caches
+   addi    t1,r5,31		\ round end address up ...
+   rlwinm  t1,t1,0,0,26		\ ... to next cache line boundary
+
+   sync isync
+   
+   begin
+      addi t1,t1,-32  cmpl 0,0,t1,r3		\ Down one cache line
+      dcbst r0,t1  sync isync  icbi r0,t1	\ Synchronize it
+   <= until
+
+   sync isync
+   
+\ Find the user area size from the header
+   lwz   t1,4(r3)		\ Text size = offset to start of data
+   lwz   t0,8(r3)		\ Data size = user area size in t4 
+
+   mr    t5,r5			\ We'll need this later for memtop
+
+\ Allocate high memory for the stacks and stuff, starting at memtop and
+\ allocating downwards.  r5 is the allocation pointer.
+
+\ Allocate the RAM copy of the User Area
+   subfc   r5,t0,r5		\ ( Use subfc for POWER compatibility)
+   rlwinm  r5,r5,0,0,26		\ cache-line-align by clearing 5 low bits 
+   mr      up,r5		\ Set user pointer
+
+   'body main-task   set  t2,*	\ Allow the exception handler to find the
+        			\ user area by storing the address of the
+   stwx  up,base,t2		\ main user area in the "constant" main-task
+
+   \ Copy the initial User Area image to the RAM copy
+   add   t3,t1,base		\ Init-up pointer in t3 
+   mr    t2,up			\ Destination pointer
+
+   srawi  t0,t0,2
+   mtspr  ctr,t0
+   addi   t3,t3,-4		\ Account for pre-incrementing
+   addi   t2,t2,-4		\ Account for pre-incrementing
+   begin
+      lwzu  t0,4(t3)
+      stwu  t0,4(t2)
+   countdown
+
+\ Synchronize the caches in the "next" region
+   sync isync  dcbst r0,up  sync isync  icbi r0,up  sync isync
+
+   'user powerpc?  stw  r8,*	\ Set the PowerPC flag
+
+\ Now the user area has been copied to the proper place, so we can set
+\ some important user variables whose initial values are determined at
+\ run time.
+
+\ Top of memory and dictionary limit
+   'user memtop  stw  t5,*
+
+\ Set the up0 user variable
+   'user up0  stw  up,*
+
+\ Establish the return stack and set the rp0 user variable
+   mr    rp,r5			\ Set rp
+   'user rp0  stw  rp,*
+   rs-size-t negate  addi  r5,r5,*	\ allocate space for the return stack
+
+\ Establish the Parameter Stack
+   'user sp0   stw  r5,*
+   addi   sp,r5,4		\ account for the top of stack register
+
+   ps-size-t negate  addi  r5,r5,*	\ Allocate the stuff on the stack
+
+   'user limit   stw  r5,*	\ Top of dictionary growth area
+
+\ Set the dictionary pointer
+   add   t1,t1,base		\ Base + text size
+   'user dp   stw   t1,*	\ Set dp
+
+\ Save the address of the system call table in the user variable syscall-vec
+   'user syscall-vec  stw  r4,*
+
+\ Set the value of #args and args
+   'user #args   stw  r6,*
+   'user args    stw  r7,*
+
+\ Set the next pointer
+   mtspr  ctr,up
+
+\ Enter Forth
+   'body cold 4 -   set  ip,*
+   add   ip,ip,base
+c;
+
+headers
+
+[ifdef] little-endian-under-simulator
+: sys-init-io
+   sys-init-io
+   ['] default-type is (type
+   ['] dumb-expect  is expect
+   ['] lf-pstr      is newline-pstring
+;
+[then]
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/builder.bth
===================================================================
--- cpu/ppc/builder.bth	                        (rev 0)
+++ cpu/ppc/builder.bth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,35 @@
+purpose: Build file for PowerPC builder
+\ See license at end of file
+
+dictionary: ${BP}/cpu/ppc/build/tools.dic
+command: &ppcforth &dictionary &this
+build-now
+
+fload ${BP}/ofw/tokenizer/tokenize.fth
+fload ${BP}/forth/lib/builder.fth
+
+.( --- Saving builder.dic --- )  cr "" builder.dic save-forth
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/cache601.fth
===================================================================
--- cpu/ppc/cache601.fth	                        (rev 0)
+++ cpu/ppc/cache601.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,53 @@
+purpose: Cache driver for PowerPC 601 chip
+\ See license at end of file
+
+code stand-sync-cache-601  ( adr len -- )
+   lwz   t0,0(sp)
+
+   cmpi  0,0,t0,0
+   <>  if
+      addi      tos,tos,-1	\ Prevents touching the line past the end
+      begin   
+         dcbst  t0,tos
+         sync
+         icbi   t0,tos
+         isync
+         addic. tos,tos,-32
+      0< until
+      sync
+   then
+
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+c;
+
+warning @ warning off
+: stand-init  ( -- )
+   stand-init
+   601?  if  ['] stand-sync-cache-601 to sync-cache  then
+;
+warning !
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/cache603.fth
===================================================================
--- cpu/ppc/cache603.fth	                        (rev 0)
+++ cpu/ppc/cache603.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,233 @@
+purpose: Cache driver for 603 PowerPC chip
+\ See license at end of file
+
+\ XXX - Dcache size is 1MB for Pegakid, because L2 cache is always on.
+\ Fix this! Maybe parameterize /dcache?
+
+headerless
+d# 32 constant /dcache-block
+d# 32 constant /icache-block
+
+code (603-dcache-off)  ( -- )
+   \ Don't do anything if the data cache is already off
+   mfspr  t1,hid0
+   andi.  t1,t1,h#4000
+   0=  if
+      next
+   then
+
+   \ Disable data translations before the flush loop: we'll run
+   \ in real mode to make sure there are no mapping problems.
+   mfmsr   t2
+   rlwinm  t1,t2,0,28,26	\ Disable translation by clearing h#10 bit
+   sync isync
+   mtmsr   t1
+   sync isync
+   
+   \ Flush Dcache before turning it off
+   set     t1,h#10.0000         \ Fill Dcache with known addresses
+   begin
+      addic.  t1,t1,-32
+      lwz     r0,0(t1)
+   = until
+
+   set     t1,h#10.0000         \ Size of dcache
+   begin
+      addic.  t1,t1,-32         \ Size of cache line
+      dcbf    r0,t1             \ Flush Dcache line
+   = until
+   sync
+
+   isync
+   mtmsr   t2			\ Restore original MSR
+   sync isync
+   mfspr   t0,hid0		\ Old HID0 value
+   rlwinm  t0,t0,0,18,16	\ Disable cache by clearing h#4000 bit
+   isync
+   mtspr   hid0,t0
+   isync
+c;
+headers
+: 603-dcache-off  ( -- )   lock[ (603-dcache-off) ]unlock  ;
+defer dcache-off	' 603-dcache-off to dcache-off
+headerless
+
+\ Warning: it is tempting to subtract one from the length, so that it refers
+\ to the last byte in the range, and then decrement the index inside the loop.
+\ However, that doesn't work because some PowerPC processors (e.g 604), when
+\ in little-endian mode, do not appear to perform the following cache
+\ operations properly when the effective address is unaligned.  This was
+\ determined empirically.
+
+code invalidate-603-i$-range  ( adr len -- )
+   mr    t2,tos
+   lwz   t0,0(sp)
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,hid0
+   andi.  t1,t1,h#8000
+   0<>  if
+      add       t0,t0,t2	\ Bias the base so we can increment the index
+      neg.      t2,t2		\ Bias the index
+      ahead begin   
+         icbi   t0,t2
+         addic. t2,t2,32
+      but then  0>= until
+      sync
+   then
+c;
+defer invalidate-i$-range   ' invalidate-603-i$-range to invalidate-i$-range
+
+code flush-603-d$-range  ( adr len -- )
+   mr    t2,tos
+   lwz   t0,0(sp)
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,hid0
+   andi.  t1,t1,h#4000
+   0<>  if
+      add       t0,t0,t2	\ Bias the base so we can increment the index
+      neg.      t2,t2		\ Bias the index
+      ahead begin   
+         dcbf   t0,t2
+         addic. t2,t2,32
+      but then  0>= until
+      sync
+   then
+c;
+headers
+defer flush-d$-range	' flush-603-d$-range to flush-d$-range
+headerless
+
+code invalidate-603-d$-range  ( adr len -- )
+   mr    t2,tos
+   lwz   t0,0(sp)
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,hid0
+   andi.  t1,t1,h#4000
+   0<>  if
+      add       t0,t0,t2	\ Bias the base so we can increment the index
+      neg.      t2,t2		\ Bias the index
+      ahead begin   
+         dcbi   t0,t2
+         addic. t2,t2,32
+      but then  0>= until
+      sync
+   then
+c;
+defer invalidate-d$-range   ' invalidate-603-d$-range to invalidate-d$-range
+
+code store-603-d$-range  ( adr len -- )
+   mr    t2,tos
+   lwz   t0,0(sp)
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,hid0
+   andi.  t1,t1,h#4000
+   0<>  if
+      add       t0,t0,t2	\ Bias the base so we can increment the index
+      neg.      t2,t2		\ Bias the index
+      ahead begin   
+         dcbst  t0,t2
+         addic. t2,t2,32
+      but then  0>= until
+      sync
+   then
+c;
+defer store-d$-range	' store-603-d$-range to store-d$-range
+
+: stand-sync-cache  ( adr len -- adr )
+   2dup store-d$-range  invalidate-i$-range
+;
+
+defer invalidate-icache  ' noop  to invalidate-icache
+
+: invalidate-603-icache  ( -- )  hid0@ dup  h# 800 or hid0!  hid0!  ;
+: invalidate-604-icache  ( -- )  hid0@      h# 800 or hid0!  ;
+
+headers
+: 603-icache-on  ( -- )
+   \ Bail out if it's already on, to avoid causing inconsistencies
+   \ with L2 caches during invalidation.
+   hid0@  h# 8000 and  if  exit  then
+
+   hid0@
+   sticky-cache-invalidate?  if
+      h#  800 or         dup hid0!      \ Flush
+      h# 8000 or         dup hid0!      \ Turn on
+      h#  800 invert and     hid0!      \ Release flush bit
+      ['] invalidate-603-icache
+   else                                 \ 604
+      h# 8800 or             hid0!      \ turn on and invalidate
+      ['] invalidate-604-icache
+   then
+   to invalidate-icache
+;
+defer icache-on		' 603-icache-on to icache-on
+
+: 603-icache-off  ( -- )
+   hid0@  h#  800 or  h# 8000 invert and  hid0!
+   ['] noop to invalidate-icache
+;
+defer icache-off	' 603-icache-off to icache-off
+
+headerless
+: 603-dcache-on?  ( -- flag )  hid0@  h# 4000 and  0<>  ;
+: 603-icache-on?  ( -- flag )  hid0@  h# 8000 and  0<>  ;
+defer dcache-on?	' 603-dcache-on? to dcache-on?
+defer icache-on?	' 603-icache-on? to icache-on?
+
+headers
+: 603-dcache-on  ( -- )
+   \ Bail out if it's already on, to avoid causing inconsistencies
+   \ with L2 caches during invalidation.
+   dcache-on?  if  exit  then
+
+   hid0@
+   sticky-cache-invalidate?  if
+      h#  400 or         dup hid0!      \ Invalidate
+      h# 4000 or         dup hid0!      \ Turn on
+      h#  400 invert and     hid0!      \ Release flush bit
+   else
+      h# 4400 or             hid0!      \ Invalidate and turn on
+   then
+;
+defer dcache-on		' 603-dcache-on to dcache-on
+
+\ Do this early so that the debugger will work as early as possible
+: stand-init-io   ( -- )   stand-init-io
+   ['] stand-sync-cache to sync-cache
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/cache823.fth
===================================================================
--- cpu/ppc/cache823.fth	                        (rev 0)
+++ cpu/ppc/cache823.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,241 @@
+purpose: Cache driver for 823 PowerPC chip
+\ See license at end of file
+
+headerless
+d# 16 constant /dcache-block
+d# 16 constant /icache-block
+
+code (823-dcache-off)  ( -- )
+   \ Don't do anything if the data cache is already off
+   mfspr   t1,dc-csr
+   andis.  t1,t1,h#8000
+   0=  if
+      next
+   then
+
+   \ Disable data translations before the flush loop: we'll run
+   \ in real mode to make sure there are no mapping problems.
+   mfmsr   t2
+   rlwinm  t1,t2,0,28,26	\ Disable translation by clearing h#10 bit
+   sync isync
+   mtmsr   t1
+   sync isync
+
+   \ Unlock Dcache
+   set     t1,h#0a00.0000
+   sync
+   mtspr   dc-csr,t1
+
+   \ Flush Dcache before turning it off
+   set     t1,h#400             \ Fill Dcache with known addresses
+   begin
+      addic.  t1,t1,-16
+      lwz     r0,0(t1)
+   = until
+
+   set     t1,h#400             \ Size of dcache
+   begin
+      addic.  t1,t1,-16         \ Size of cache line
+      dcbf    r0,t1             \ Flush Dcache line
+   = until
+   sync
+
+   isync
+   mtmsr   t2			\ Restore original MSR
+   set     t1,h#0400.0000
+   sync
+   mtspr   dc-csr,t1		\ Disable Dcache
+   isync
+c;
+headers
+: 823-dcache-off  ( -- )   lock[ (823-dcache-off) ]unlock  ;
+defer dcache-off	' 823-dcache-off to dcache-off
+headerless
+
+\ Warning: it is tempting to subtract one from the length, so that it refers
+\ to the last byte in the range, and then decrement the index inside the loop.
+\ However, that doesn't work because some PowerPC processors (e.g 604), when
+\ in little-endian mode, do not appear to perform the following cache
+\ operations properly when the effective address is unaligned.  This was
+\ determined empirically.
+
+code invalidate-823-i$-range  ( adr len -- )
+   mr    t2,tos			\ len in t2
+   lwz   t3,0(sp)		\ adr in t3
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,ic-csr
+   andis.  t1,t1,h#8000
+   0<>  if
+      \ Expand the range to include all affected cache lines
+      add    t0,t3,t2		\ End of range
+      addi   t0,t0,15		\ Round end address up ..
+      rlwinm t0,t0,0,0,27	\ .. to cache line boundary
+      rlwinm t3,t3,0,0,27	\ Round start address down
+      subf. t2,t0,t3		\ Negative of length of expanded range
+
+      ahead begin   
+         icbi   t0,t2
+         addic. t2,t2,16
+      but then  0>= until
+      sync
+   then
+c;
+defer invalidate-i$-range   ' invalidate-823-i$-range to invalidate-i$-range
+
+code flush-823-d$-range  ( adr len -- )
+   mr    t2,tos			\ len in t2
+   lwz   t3,0(sp)		\ adr in t3
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,dc-csr
+   andis. t1,t1,h#8000
+   0<>  if
+      \ Expand the range to include all affected cache lines
+      add    t0,t3,t2		\ End of range
+      addi   t0,t0,15		\ Round end address up ..
+      rlwinm t0,t0,0,0,27	\ .. to cache line boundary
+      rlwinm t3,t3,0,0,27	\ Round start address down
+      subf. t2,t0,t3		\ Negative of length of expanded range
+
+      ahead begin   
+         dcbf   t0,t2
+         addic. t2,t2,16
+      but then  0>= until
+      sync
+   then
+c;
+headers
+defer flush-d$-range	' flush-823-d$-range to flush-d$-range
+headerless
+
+code invalidate-823-d$-range  ( adr len -- )
+   mr    t2,tos			\ len in t2
+   lwz   t3,0(sp)		\ adr in t3
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,dc-csr
+   andis. t1,t1,h#8000
+   0<>  if
+      \ Expand the range to include all affected cache lines
+      add    t0,t3,t2		\ End of range
+      addi   t0,t0,15		\ Round end address up ..
+      rlwinm t0,t0,0,0,27	\ .. to cache line boundary
+      rlwinm t3,t3,0,0,27	\ Round start address down
+      subf. t2,t0,t3		\ Negative of length of expanded range
+
+      ahead begin   
+         dcbi   t0,t2
+         addic. t2,t2,16
+      but then  0>= until
+      sync
+   then
+c;
+defer invalidate-d$-range   ' invalidate-823-d$-range to invalidate-d$-range
+
+code store-823-d$-range  ( adr len -- )
+   mr    t2,tos			\ len in t2
+   lwz   t3,0(sp)		\ adr in t3
+   lwz   tos,1cell(sp)
+   addi  sp,sp,2cells
+
+   \ Don't touch the cache if it's off
+   mfspr  t1,dc-csr
+   andis. t1,t1,h#8000
+   0<>  if
+      \ Expand the range to include all affected cache lines
+      add    t0,t3,t2		\ End of range
+      addi   t0,t0,15		\ Round end address up ..
+      rlwinm t0,t0,0,0,27	\ .. to cache line boundary
+      rlwinm t3,t3,0,0,27	\ Round start address down
+      subf. t2,t0,t3		\ Negative of length of expanded range
+
+      ahead begin   
+         dcbst  t0,t2
+         addic. t2,t2,16
+      but then  0>= until
+      sync
+   then
+c;
+defer store-d$-range	' store-823-d$-range to store-d$-range
+
+: stand-sync-cache  ( adr len -- adr )
+   2dup store-d$-range  invalidate-i$-range
+;
+
+: invalidate-823-icache  ( -- )
+   h# 0a00.0000 ic-csr!		\ Unlock all
+   h# 0e00.0000 ic-csr!		\ Invalidate all
+;
+defer invalidate-icache  ' noop to invalidate-icache
+
+headerless
+: 823-dcache-on?  ( -- flag )  dc-csr@ h# 8000.0000 and  ;
+: 823-icache-on?  ( -- flag )  ic-csr@ h# 8000.0000 and  ;
+defer dcache-on?	' 823-dcache-on? to dcache-on?
+defer icache-on?	' 823-icache-on? to icache-on?
+
+headers
+: 823-icache-on  ( -- )
+   \ Bail out if it's already on, to avoid causing inconsistencies
+   \ with L2 caches during invalidation.
+   823-icache-on?  if  exit  then
+
+   invalidate-823-icache	\ Unlock and invalidate Icache
+   h# 0200.0000 ic-csr!		\ Enable Icache
+   ['] invalidate-823-icache to invalidate-icache
+;
+defer icache-on		' 823-icache-on to icache-on
+
+: 823-icache-off  ( -- )
+   h# 0400.0000 ic-csr!		\ Disable Icache
+   ['] noop to invalidate-icache
+;
+defer icache-off	' 823-icache-off to icache-off
+
+headers
+: 823-dcache-on  ( -- )
+   \ Bail out if it's already on, to avoid causing inconsistencies
+   \ with L2 caches during invalidation.
+   dcache-on?  if  exit  then
+
+   h# 0a00.0000 dc-csr!		\ Unlock all
+   h# 0c00.0000 dc-csr!		\ Invalidate all
+   h# 0200.0000 dc-csr!		\ Enable Dcache
+;
+defer dcache-on		' 823-dcache-on to dcache-on
+
+\ Do this early so that the debugger will work as early as possible
+: stand-init-io   ( -- )   stand-init-io
+   ['] stand-sync-cache to sync-cache
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/call.fth
===================================================================
--- cpu/ppc/call.fth	                        (rev 0)
+++ cpu/ppc/call.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,55 @@
+purpose: Call C subroutines from Forth
+\ See license at end of file
+
+\ From Forth, call the C subroutine whose address is on the stack
+
+code call  ( [ arg5 .. arg0 ] adr -- [ arg5 .. arg0 ] result )
+   'user saved-sp   stw  sp,*	\ Save for callbacks
+   'user saved-rp   stw  rp,*	\ Save for callbacks
+
+   \ Pass up to 6 arguments
+   lwz  r3,h#00(sp)
+   lwz  r4,h#04(sp)
+   lwz  r5,h#08(sp)
+   lwz  r6,h#0c(sp)
+   lwz  r7,h#10(sp)
+   lwz  r8,h#14(sp)
+
+   mtspr lr,tos
+   bclrl 20,0
+
+   mr    tos,r3		\ Return subroutine result
+   mtspr ctr,up		\ Restore "next" pointer
+c;
+
+headerless
+code r1!  ( adr -- )  mr r1,tos  lwz tos,0(sp)  addi sp,sp,1cell  c;
+
+headers
+: sp-call  ( [ arg5 .. arg0 ] adr sp -- [ arg5 .. arg0 ] result )
+   h# 10 - r1! call
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/catchexc.fth
===================================================================
--- cpu/ppc/catchexc.fth	                        (rev 0)
+++ cpu/ppc/catchexc.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,433 @@
+purpose: Save the processor state after a signal.
+\ See license at end of file
+
+\ This code is entered as a result of a Unix signal.
+\ It saves the processor state, then enters Forth so that the
+\ state may be examined, and possibly re-established later.
+
+\ needs signal signal.f
+
+\ exception-area is a place to store registers during exception handling.
+\ Each cpu gets its own area and uses SPRG0 to point to it.
+h# 40 /l* constant /exception-area
+0 value exception-area
+
+decimal
+
+only forth also hidden also  forth definitions
+
+headers
+0 value virt-phys
+
+headerless
+0 value cpu-state-phys
+
+: enterforth  ( -- )
+   state-valid on
+   my-self to %saved-my-self
+   handle-breakpoint
+;
+
+code (restart  ( -- )
+   \ Restore the Forth stacks.
+
+   \ Establish the Data and Return stacks
+   'user rp0    lwz  rp,*
+   'user sp0    lwz  sp,*
+
+   \ Restore the Forth Data and Return stacks from the save area.
+
+   \ Data Stack
+   'user sp0      lwz  t3,*
+   'user pssave   lwz  t0,*	\ Address of data stack save area
+   ps-size        addi t1,r0,*	\ Size of data stack area
+   add   t0,t0,t1		\ End of save area
+
+   srawi  t1,t1,2		\ Number of longwords
+   mtspr  ctr,t1
+
+   begin
+      lwzu   t2,-4(t0)
+      stwu   t2,-4(t3)
+   bc     16,0,*		\ Decrement and branch if nonzero
+
+   \ Return Stack
+   'user rp0     lwz  t3,*
+   'user rssave  lwz  t0,*	\ Address of return stack save area
+   rs-size       addi t1,r0,*	\ Size of return stack area
+   add   t0,t0,t1		\ End of save area
+
+   srawi  t1,t1,2		\ Number of longwords
+   mtspr  ctr,t1
+
+   begin
+      lwzu   t2,-4(t0)
+      stwu   t2,-4(t3)
+   bc     16,0,*		\ Decrement and branch if nonzero
+
+   or        r0,r0,r0
+
+   \ The following code communicates with the first part of "save-state".
+   \ See the description there.
+   here 4 +  bl  *		\ Get current address
+   mfspr     t0,lr
+   addi      t0,t0,16
+   mfspr     t2,sprg0		\ Get this cpu's exception-area address
+   stw       t0,h#10(t2)	\ Store the address of the next instruction
+				\ so save-state can recognize it
+
+   \ Take another trap, so we can fix up the PC's in the signal handler
+   0 asm,			\ Illegal instruction
+
+end-code
+
+\ This is the second half of the state saving procedure.  It is executed
+\ in normal state (not exception state).
+
+label finish-save
+   \ The base register is already set
+
+   \ Find the user area
+   'body main-task  set  up,*	\ Find the save area
+   lwzx  up,up,base		\ Get user pointer
+
+   \ Establish the Data and Return stacks
+
+   \ Copy the entire Forth Data and Return stacks areas to a save area.
+
+   \ Data Stack
+   'user sp0      lwz  t3,*
+   'user pssave   lwz  t0,*	\ Address of data stack save area
+   ps-size        addi t1,r0,*	\ Size of data stack area
+   add   t0,t0,t1		\ End of save area
+
+   srawi  t1,t1,2		\ Number of longwords
+   mtspr  ctr,t1
+
+   begin
+      lwzu   t2,-4(t3)
+      stwu   t2,-4(t0)
+   bc     16,0,*		\ Decrement and branch if nonzero
+
+   'user sp0    lwz  sp,*
+
+   \ Return Stack
+   'user rp0     lwz  t3,*
+   'user rssave  lwz  t0,*	\ Address of return stack save area
+   rs-size       addi t1,r0,*	\ Size of return stack area
+   add   t0,t0,t1		\ End of save area
+
+   srawi  t1,t1,2		\ Number of longwords
+   mtspr  ctr,t1
+
+   begin
+      lwzu   t2,-4(t3)
+      stwu   t2,-4(t0)
+   bc     16,0,*		\ Decrement and branch if nonzero
+
+   'user rp0     lwz  rp,*
+
+   \ Adjust the stack pointer to account for the top of stack register
+   addi   sp,sp,4
+
+   \ Restart the Forth interpreter.
+
+   \ Set the next pointer
+   mtspr  ctr,up
+
+   \ Execute enterforth
+   'body enterforth 4 -   set  ip,*
+   add   ip,ip,base
+c;
+
+\ This is the first part of the exception handling sequence.  It is
+\ executed in exception state.
+\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area,
+\ r3 points to the address where the exception occured.
+label save-state
+   stw    r3,h#0c(r2)		\ Save exception address
+   lwz    r3,h#08(r2)		\ Restore lr
+   mtspr  lr,r3
+				\ R3 is available
+   stw    base,h#14(r2)		\ A register for us to play with
+   stw    up,h#18(r2)		\ A register for us to play with
+   
+   mfcr   base			\ CR is saved in base
+   
+   \ WARNING: This code is tricky.  The goal is to determine whether or not
+   \ the instruction that caused the exception was the illegal instruction at
+   \ the end of (restart, just above.  It's not safe to access the instruction
+   \ at the saved PC location, because this handler runs with translations
+   \ disabled, but the saved PC is virtual address, so accessing it could
+   \ result in a machine check (which would cause the system to hang) if the
+   \ PC value is not a valid real-mode address.
+   \ Instead, we compare the saved PC with the contents of the cell at
+   \ sprg0+10, depending on the fact that (restart stored the
+   \ address of its illegal instruction there just before executing that
+   \ illegal instruction.
+
+   mfspr  up,srr0		\ Saved PC
+   lwz    r3,h#10(r2)		\ Get magic address
+   cmp    0,0,up,r3		\ Is it the magic address?
+
+   lwz    r3,h#00(r2)		\ Restore r3
+
+   =  if
+      \ This is the second half of (restart, so we restore all the registers
+      \ from the save area.
+
+      lwz  up,h#18(r2)		\ Get UP back
+
+\      'user cpu-state-phys  lwz  r31,*	\ Get cpu-state buffer address
+      lwz  r31,h#38(r2)
+
+      \ Restore floating point registers if they were saved
+      36 /l*  31  lwz r0,*		\ saved msr
+      andi.  r0,r0,h#2000
+      0<> if
+         mfmsr  t0			\ Turn on FP unit
+         ori    t0,t0,h#2000
+         mtmsr  t0
+         isync
+
+         106 /l* 31 lfd  0,*		\ Get back fpscr double word into fr0
+         mtfsf  h#ff,0			\ Move fr0 to fpscr
+	 
+	 \ Assemble 32 "lfd fN,42*4+N*8(r31)" instructions
+         32  0  do
+            i 8 *  42 la+ ( offset ) 31 ( r31 ) i ( reg# )  " lfd *,*" evaluate
+         loop
+      then
+
+      32 /l*  31  lwz  r0,*   mtspr  xer,r0      \ xer
+      33 /l*  31  lwz  r0,*   mtspr  lr,r0       \ lr
+      34 /l*  31  lwz  r0,*   mtspr  ctr,r0      \ ctr
+      35 /l*  31  lwz  r0,*   mtspr  srr0,r0     \ saved pc
+      36 /l*  31  lwz  r0,*   mtspr  srr1,r0     \ saved msr
+      37 /l*  31  lwz  r0,*   mtcrf  h#ff,r0     \ cr
+
+\       108 /l* 31  lwz  r0,*   mtspr  sprg0,r0    \ sprg0
+\       109 /l* 31  lwz  r0,*   mtspr  sprg1,r0    \ sprg1
+\       110 /l* 31  lwz  r0,*   mtspr  sprg2,r0    \ sprg2
+\       111 /l* 31  lwz  r0,*   mtspr  sprg3,r0    \ sprg3
+
+      \ Assemble 32 "lwz rN,N*4(r31)" instructions
+      32  0  do
+         i 4 * ( offset )  31 ( r31 )   i ( reg# )   " lwz *,*" evaluate
+      loop
+\     lmw   r0,0(up)		\ Restore all general registers
+
+      rfi
+   then
+
+   \ This is not the second half of (restart, so we save all the registers
+   \ to the save area.
+   mtcrf  h#ff,base		\ Restore CR
+
+\    \ Set the base register
+\   here  4 +        bl   *	\ Absolute address of next instruction
+\   here  origin -   set  base,*	\ Relative address of this instruction
+\   mfspr  up,lr
+\   subf   base,base,up		\ Base address of Forth kernel
+ 
+\    'body main-task  set  up,*	\ Find the save area
+\    lwzx  up,up,base		\ Get user pointer
+\ 
+\    'user cpu-state-phys  lwz  up,*	\ Get cpu-state buffer address
+
+   lwz    up,h#38(r2)		\ Get address from save area   
+   lwz    base,h#3c(r2)		\ Get address from save area   
+
+\  stmw   r0,0(up)		\ Save all general registers
+   \ Assemble 32 "stw rN,N*4(up)" instructions
+   32  0  do
+      i 4 * ( offset )  27 ( up )   i ( reg# )   " stw *,*" evaluate
+   loop
+
+   lwz    r0,h#14(r2) 26 /l*  27  stw  r0,*   \ base
+   lwz    r0,h#18(r2) 27 /l*  27  stw  r0,*   \ up
+   mfspr  r0,xer      32 /l*  27  stw  r0,*   \ xer
+   lwz    r0,h#08(r2) 33 /l*  27  stw  r0,*   \ lr
+   mfspr  r0,ctr      34 /l*  27  stw  r0,*   \ ctr
+   mfspr  r0,srr0     35 /l*  27  stw  r0,*   \ saved pc
+   mfspr  r0,srr1     36 /l*  27  stw  r0,*   \ saved msr
+   mfcr   r0          37 /l*  27  stw  r0,*   \ cr
+
+   lwz    r0,h#0c(r2)  rlwinm r0,r0,24,24,31
+                      38 /l*  27  stw  r0,*   \ exception#
+   lwz    r2,h#04(r2)  2 /l*  27  stw  r2,*   \ original r2
+
+\    mfspr  r0,sprg0   108 /l*  27  stw  r0,*   \ sprg0
+\    mfspr  r0,sprg1   109 /l*  27  stw  r0,*   \ sprg1
+\    mfspr  r0,sprg2   110 /l*  27  stw  r0,*   \ sprg2
+\    mfspr  r0,sprg3   111 /l*  27  stw  r0,*   \ sprg3
+   
+   \ Save floating point registers if floating point is enabled
+   mfmsr  t0
+   andi.  t0,t0,h#2000
+   0<>  if
+      \ Assemble 32 "stfd fN,42*4+N*8(up)" instructions
+      32  0  do
+         i 8 *  42 la+  ( offset )  27 ( up ) i ( reg# )   " stfd *,*" evaluate
+      loop
+      \ Now that fp regs are saved, we can trounce on them to get the 
+      \ fpscr register
+      mffs   0			\ Move fpscr to fp0[63:32]
+      106 /l*  27  stfd  0,*	\ Move fp0[63:0] to memory
+   then
+
+   \ Now we set the saved PC to point to the rest of the state save
+   \ routine, then return from interrupt.
+
+   'body finish-save  set  up,*
+   add    up,up,base
+   mtspr  srr0,up
+
+   rfi
+end-code
+
+hidden definitions
+
+' (restart is restart
+' (restart is restart-step
+
+string-array exception-name
+( 00 )  ," Reserved exception 0"
+( 01 )  ," System reset"
+( 02 )  ," Machine check"
+( 03 )  ," Data access exception"
+( 04 )  ," Instruction access exception"
+( 05 )  ," External interrupt"
+( 06 )  ," Alignment exception"
+( 07 )  ," Illegal instruction"
+( 08 )  ," Floating point unavailable"
+( 09 )  ," Decrementer interrupt"
+( 0a )  ," I/O controller interface error"
+( 0b )  ," Reserved exception 0b"
+( 0c )  ," System call"
+( 0d )  ," Trace exception"
+( 0e )  ," Floating point assist exception"
+( 0f )  ," Reserved exception 0f"
+( 10 )  ," Instruction translation miss"
+( 11 )  ," Data load translation miss"
+( 12 )  ," Data store translation miss"
+( 13 )  ," Instruction address breakpoint"
+( 14 )  ," System management interrupt"
+end-string-array
+
+: (.exception) ( -- )
+   exception#  dup  h# 20  =  if
+      ." Run mode/trace exception"
+   else
+      dup h# 15 <  if
+         exception-name count type
+      else
+         ." Reserved exception # " .h
+      then
+   then
+   cr
+;
+' (.exception) is .exception
+
+: print-breakpoint
+   .exception  \ norm
+   interactive? 0=  if bye then	\ Restart only if a human is at the controls
+   ??cr quit
+;
+\ ' print-breakpoint is handle-breakpoint
+
+code hwbp  ( adr -- )
+   mtspr  iabr,tos
+   lwz    tos,0(sp)
+   addi   sp,sp,4
+c;
+
+code tbar!  ( adr -- okay? )
+   \ As a side effect of the  mfspr *,pvr  instruction, the simulator
+   \ sets its internal trap base address register (which isn't a real
+   \ part of the PowerPC architecture) to the address contained in the
+   \ destination register.  That instruction was chosen because it
+   \ is not likely to be used in general code, but it is valid on all
+   \ PPC implementations.
+   mfspr  tos,pvr
+c;
+
+forth definitions
+0 value exc-adr
+: exc,  ( instruction -- )  exc-adr instruction!  exc-adr la1+ to exc-adr  ;
+: put-exception  ( exception-handler-addr exception-addr -- )
+   to exc-adr  virt-phys - lwsplit
+   h# 7c51.43a6       exc,   \ mtspr sprg1,r2		protect r2
+   h# 7c50.42a6       exc,   \ mfspr r2,sprg0		set r2 to save area
+   h# 9062.0000       exc,   \ stw   r3,0(r2)		save r3
+   h# 7c71.42a6       exc,   \ mfspr r3,sprg1
+   h# 9062.0004       exc,   \ stw   r3,4(r2)		save r2
+   h# 7c68.02a6       exc,   \ mfspr r3,lr
+   h# 9062.0008       exc,   \ stw   r3,8(r2)		save lr
+   \ h# 80620020 exc, h# 38630001 exc, h# 90620020 exc,
+   h# 3c60.0000 or    exc,   \ set   r3,high address half-word
+   h# 6063.0000 or    exc,   \ set   r3,low address half-word
+   h# 7c68.03a6       exc,   \ mtspr lr,r3		point lr to handler
+   h# 3860.0000 exc-adr h# ff00 and or  exc,   \ addi  r3,r0,exception-addr
+   h# 4e80.0020       exc,   \ bclr 20,0		jump to handler
+;
+d# 12 /l* constant /exc	\ size of entry made by put-exception
+: catch-exception  ( exception# -- )  8 <<  save-state swap put-exception  ;
+
+headers
+: catch-exceptions  ( -- )
+   /save-area alloc-mem is cpu-state		( )
+   clear-save-area				( )
+   pssave drop  rssave drop	\ Force allocation of these buffers
+   /exception-area alloc-mem			( virt )
+   cpu-state virt-phys -  over h# 38 + l!	( virt )
+   origin over h# 3c + l!			( virt )
+   virt-phys - dup is exception-area		( virt' )
+   sprg0!		\ Save this cpu's exception-area address to SPRG0
+
+   
+   2 catch-exception   \ Machine check
+   3 catch-exception   \ Data access
+   4 catch-exception   \ Instruction access
+   6 catch-exception   \ Alignment
+   7 catch-exception   \ Illegal instruction
+   8 catch-exception   \ Floating point unavailable
+;
+: stand-init  ( -- )
+   msr@ h# 40 invert and msr!
+   catch-exceptions
+;
+: sys-init  ( -- )
+   sys-init
+   syscall-vec @  0=  if
+      h# 4000 alloc-mem tbar!  if
+         catch-exceptions
+      then
+   then
+;
+
+only forth also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/centry.fth
===================================================================
--- cpu/ppc/centry.fth	                        (rev 0)
+++ cpu/ppc/centry.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,124 @@
+purpose: Client interface handler code
+\ See license at end of file
+
+d# 108 buffer: cif-reg-save
+
+headerless
+code cif-return  !csp
+   mr     r3,tos
+
+   'user cif-reg-save   lwz  r7,*	\ Address of register save area in r7
+
+   lwz r13,00(r7)   lwz r14,04(r7)   lwz r15,08(r7)   lwz r16,12(r7)
+   lwz r17,16(r7)   lwz r18,20(r7)   lwz r19,24(r7)   lwz r20,28(r7)
+   lwz r21,32(r7)   lwz r22,36(r7)   lwz r23,40(r7)   lwz r24,44(r7)
+   lwz r25,48(r7)   lwz r26,52(r7)   lwz r27,56(r7)   lwz r28,60(r7)
+   lwz r29,64(r7)   lwz r30,68(r7)   lwz r31,72(r7)   lwz r1,76(r7)
+   lwz r2,80(r7)    lwz r4,88(r7)    mtspr hid0,r4    
+   lwz r4,92(r7)    mtspr sprg0,r4   lwz r4,96(r7)    mtspr sprg1,r4
+   lwz r4,100(r7)   mtspr sprg2,r4   lwz r4,104(r7)   mtspr sprg3,r4
+   lwz r4,84(r7)
+
+   mtspr  lr,r4
+   bclr   20,0
+end-code
+
+defer rm-cif-entry  ' noop to rm-cif-entry
+defer rm-cif-exit   ' noop to rm-cif-exit
+
+: cif-exec  ( args ... -- )
+   rm-cif-entry do-cif rm-cif-exit  cif-return
+;
+
+headers
+: cif-caller  ( -- adr )  cif-reg-save  d# 84 +  @  ;
+
+headerless
+label cif-handler
+   \ Registers:
+   \ r3			argument array pointer
+   \ r1,r2,r13-r31	must be preserved
+   \ r0,r4-r12		scratch
+
+   mfspr  r4,lr		\ Save link register for later
+   mr     r5,base	\ Save base register (r26)
+   mr     r6,up		\ Save user area pointer register (r27)
+
+   \ Set the base register
+   here  4 +        bl   *	\ Absolute address of next instruction
+   here  origin -   set  base,*	\ Relative address of this instruction
+   mfspr  up,lr
+   subf   base,base,up		\ Base address of Forth kernel in base
+
+   \ Find the user area
+   'body main-task  set  up,*	\ Find the save area
+   lwzx  up,up,base		\ Get user pointer
+
+   'user cif-reg-save   lwz  r7,*	\ Address of register save area in r7
+
+   stw r13,00(r7)   stw r14,04(r7)   stw r15,08(r7)   stw r16,12(r7)
+   stw r17,16(r7)   stw r18,20(r7)   stw r19,24(r7)   stw r20,28(r7)
+   stw r21,32(r7)   stw r22,36(r7)   stw r23,40(r7)   stw r24,44(r7)
+   stw r25,48(r7)   stw r5,52(r7)    stw r6,56(r7)    stw r28,60(r7)
+   stw r29,64(r7)   stw r30,68(r7)   stw r31,72(r7)   stw r1,76(r7)
+   stw r2,80(r7)    stw r4,84(r7)   mfspr r4,hid0    stw r4,88(r7)
+   mfspr r4,sprg0   stw r4,92(r7)   mfspr r4,sprg1   stw r4,96(r7)
+   mfspr r4,sprg2   stw r4,100(r7)  mfspr r4,sprg3   stw r4,104(r7)
+
+   mr  tos,r3
+   
+   'user rp0   lwz  rp,*
+   'user sp0   lwz  sp,*
+   \ We don't add 4 to account for the top of stack register because
+   \ there is one item - the argument array address - on the stack
+   \ (actually it is in the TOS register; logically it's on the stack)
+
+   'user exception-area   lwz r2,*   mtspr sprg0,r2
+   
+   mtspr  ctr,up			\ Set "next" pointer
+   'body cif-exec 4 -   set  ip,*
+   add   ip,ip,base
+c;
+
+0 value callback-stack
+
+headers
+code callback-call  ( args vector -- )
+   mtspr  lr,tos
+   lwz    r3,0(sp)
+   'user callback-stack   lwz  r1,*
+   lwz    tos,1cell(sp)
+   addi   sp,sp,2cells
+   bclrl  20,0
+   mtspr  ctr,up
+c;
+
+\ Force allocation of buffer
+stand-init: CIF buffers
+   cif-reg-save drop
+   h# 1000 dup alloc-mem + to callback-stack
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/code.fth
===================================================================
--- cpu/ppc/code.fth	                        (rev 0)
+++ cpu/ppc/code.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,104 @@
+purpose: Assembler extensions to create Forth words
+\ See license at end of file
+
+\ These words are specific to the virtual machine implementation
+: assembler  ( -- )  ppc-assembler  ;
+
+only forth also assembler also definitions
+
+\ Forth Virtual Machine registers
+
+also register-names definitions
+decimal
+: t0   20 ;  : t1 21 ;  : t2  22 ;  : t3 23 ;  : t4 24 ;  : t5 25 ;
+: t6   19 ;  : t7 18 ;  : t8  17 ;  : t9 16 ;
+: base 26 ;  : up 27 ;  : tos 28 ;  : ip 29 ;  : rp 30 ;  : sp 31 ;
+: w    t5 ;
+previous definitions
+
+also constant-names definitions
+
+/n          constant  1cell	\ Offsets into the stack
+1cell  -1 * constant -1cell
+1cell   2 * constant  2cells
+1cell   3 * constant  3cells
+1cell   4 * constant  4cells
+
+1cell       constant  /cf	\ Size of a code field (except for "create")
+/cf    -1 * constant -/cf
+
+1cell       constant  /token	\ Size of a compiled word reference
+/token -1 * constant -/token
+
+1cell       constant  /branch	\ Size of a branch offset
+
+/token  2 * constant  /ccf	\ Size of a "create" code field
+
+/cf 1cell + constant  /cf+1cell \ Location of second half of 
+previous definitions
+
+\ The next few words are already in the forth vocabulary;
+\ we want them in the assembler vocabulary too
+alias next  next
+headerless
+: exitcode  ( -- )
+   ['] $interpret-do-undefined is $do-undefined
+   previous
+;
+' exitcode is do-exitcode
+headers
+alias c;  c;
+
+: 'user#  \ name  ( -- user# )
+   '  ( acf-of-user-variable )  >body @
+;
+: 'user  \ name  ( -- user-addressing-mode )
+   [ also ppc-assembler also register-names ]
+   'user#  up    
+   [ previous previous ]
+;
+: 'body  \ name  ( -- variable-apf-offset )
+   '  ( acf-of-user-variable )  >body  origin -
+;
+: 'acf  \ name  ( -- variable-acf-offset )
+   '  ( acf-of-user-variable )  origin -
+;
+
+also forth definitions
+: entercode  ( -- )
+   also assembler
+   false is disassembling?
+   ['] $ppc-assem-do-undefined is $do-undefined   
+;
+' entercode is do-entercode
+
+\ "code" is defined in the kernel
+
+: label  \ name  ( -- )
+   create  !csp  entercode
+;
+only forth also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/cpubpsup.fth
===================================================================
--- cpu/ppc/cpubpsup.fth	                        (rev 0)
+++ cpu/ppc/cpubpsup.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,91 @@
+purpose: Machine-dependent definitions for breakpoints
+\ See license at end of file
+
+headerless
+0 value breakpoint-opcode
+defer breakpoint-trap?
+' true is breakpoint-trap?  \ XXX until arcbpsup is installed...
+
+: op@  ( adr -- op )  l@  ;
+: op!  ( op adr -- )  instruction!  ;
+: bp-address-valid?  ( adr -- flag )  3 and  0=  ;
+: at-breakpoint?  ( adr -- flag )  op@  breakpoint-opcode =  ;
+: put-breakpoint  ( adr -- )  breakpoint-opcode swap op!  ;
+
+headers
+: .instruction  ( -- )
+   %pc   [ also assembler ] pc ! dis1 [ previous ]
+;
+
+headerless
+\ Find the places to set the next breakpoint for single stepping.
+
+\ Flag is true if the branch should be followed - we don't follow branches
+\ if stepping? is false and the instruction modifies the link register.
+: -hop?  ( stepping? pc -- stepping? pc flag )  2dup 1 and 0=  or  ;
+: next-instruction  ( stepping? -- next-adr branch-target|0 )
+   %pc la1+   swap                          ( next-adr stepping? )
+
+   \ If we are hopping (not stepping), then we don't follow subroutine
+   \ calls (branches that have the link bit set).  We needn't bother
+   \ checking whether or not the instruction is a branch, because if
+   \ it isn't, we want to do the same thing as for a branch with link.
+   0=  %pc l@ 1 and  and  if  0 exit  then  ( next-adr )
+
+   %pc                                      ( next-adr pc )
+   bclr?   if  drop %lr    exit  then       ( next-adr pc )
+   bcctr?  if  drop %ctr   exit  then       ( next-adr pc )
+   bc?     if  >bc-target  exit  then       ( next-adr pc )
+   b?      if  >b-target   exit  then       ( next-adr pc )
+   drop 0
+;
+
+: bumppc  ( -- )  %pc la1+ to %pc   ;
+
+alias rpc %pc
+
+code goto  ( adr -- )
+   mtspr  lr,tos
+   lwz    tos,0(sp)
+   addi   sp,sp,4
+   bclr   20,0
+end-code
+
+: return-adr  ( -- adr )  %r1 @ 8 + @  ;
+: leaf-return-adr  ( -- adr )  %lr  ;
+
+: backward-branch?  ( adr -- flag )  \ True if adr points to a backward branch
+   b?   if  dup  >b-target  u>  exit  then   ( adr )
+   bc?  if  dup  >bc-target u>  exit  then   ( adr )
+   drop false
+;
+: loop-exit-adr  ( -- adr )
+   %pc  begin  dup backward-branch? 0=  while  la1+  repeat  la1+
+;
+
+headers
+: set-pc  ( adr -- )  to %pc  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/cpuclass.fth
===================================================================
--- cpu/ppc/cpuclass.fth	                        (rev 0)
+++ cpu/ppc/cpuclass.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,97 @@
+purpose: Classify PowerPC CPUs into various general families
+\ See license at end of file
+
+headerless
+\ At present, PowerPC CPUs can be grouped into several classes.
+\ There are several characteristics that are the same across all
+\ members of a class.  New classes and new class members appear
+\ from time to time.  The 601 is handled elsewhere.
+
+: 603-class?  ( -- flag )
+   \ CPU-version 81 is for the 8240
+   cpu-version  dup 3 =  over 6 = or  over 7 = or  over 8 = or  swap h# 81 = or
+;
+: 604-class?  ( -- flag )
+   cpu-version  dup 4 =  over 9 = or  swap h# a = or
+;
+: 620-class?  ( -- flag )
+   cpu-version  d# 20 =
+;
+: 704-class?  ( -- flag )		\ remove 54 to drop proto support.
+   cpu-version  dup h# 54 =  swap h# 60 = or
+;
+
+: mach-5/pass1?  ( -- flag )
+   pvr@ lwsplit h# a = swap h# 100 = and
+;
+: 823-class?  ( -- flag )
+   cpu-version  h# 50 =
+;
+
+\ According to IBM, MACH-5 (PVR = A) revision 100 has a bug that requires
+\ the BTAC bit be set to 1 in order to disable cacheing of branch addresses.
+\ We set the BTAC disable bit in resetvec, here we turn it off if we are
+\ running on anything other than a mach-5, version 100.
+\ The BTAC bit is bit 30 of HID0. (Well actually, its the 0x00000002 bit
+\ the way we look at it)
+
+: fastest-mode  ( -- )
+   604-class?  if
+      \ Turn on 604 superscalar and dynamic branch prediction modes
+      \ machine checks, and cache parity checking
+      \ Turn off cache locks and bus parity checking
+      hid0@ h# 84 or			( hid0' )
+      mach-5/pass1? 0=  if		( hid0' )
+         h# 02 invert and		( hid0'' )
+      then				( hid0 )
+      h# f008.3000 invert and hid0!	( )
+   then
+[ifdef] exponential
+   \ 704-class? if
+   cpu-version  h# 60 = if			\ non-proto x704
+      \ Turn on 704 superscalar and set POE
+      modes@ h# 3.0000 or modes!
+   then
+[then]
+;
+
+\ Some characteristics of various classes
+
+: software-tlb-miss?  ( -- flag )  603-class? 823-class? or  ;
+: sticky-cache-invalidate?  ( -- flag )  603-class?  ;
+
+d# 64 value #tlb-lines
+: configure-tlb  ( -- )
+   cpu-version  case
+       3 of  d# 32  endof
+       6 of  d# 32  endof
+   h# 50 of  d#  8  endof
+   ( default ) #tlb-lines swap
+   endcase
+   to #tlb-lines
+;
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/cpunode.fth
===================================================================
--- cpu/ppc/cpunode.fth	                        (rev 0)
+++ cpu/ppc/cpunode.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,223 @@
+purpose: CPU node
+\ See license at end of file
+
+0 value l2-cache-node
+defer probe-l2-cache
+' false to probe-l2-cache  ( -- false | #sets #bytes write-back? true )
+
+\ A hook that can be used on a per-platform basis to amend any
+\ information that needs to be changed.
+defer get-cpu-info   ( -- )
+' noop to get-cpu-info
+
+headerless
+\ Interfaces to platform-dependent code to determine the status of
+\ CPUs in an MP system.
+1 value max#cpus
+
+\ keep track of cpu#; may be used by get-cpu-info and probe-l2-cache
+0 value cpu	
+
+defer firmware-cpu#  ( -- cpu# )
+' 0 to firmware-cpu#	
+
+defer cpu-started?  ( cpu# -- flag )
+' 0= to cpu-started?
+
+headers
+d# 100,000,000 value cpu-clock-frequency
+
+' cpu-node  " cpu" chosen-variable
+
+headerless
+0 value cpu-package
+
+headers
+: make-l2-cache-node  ( #sets size write-back? -- )
+   new-device
+      " l2-cache" device-name
+      " cache" device-type
+      0 0 encode-bytes  " cache-unified" property   \ Assumes a unified cache
+
+      drop   ( #sets size )
+      2dup " i-cache-size" integer-property  " i-cache-sets" integer-property
+           " d-cache-size" integer-property  " d-cache-sets" integer-property
+
+      d# 32 " d-cache-block-size" integer-property
+      d# 32 " i-cache-block-size" integer-property
+
+      current-device				( phandle )
+   finish-device
+   dup to l2-cache-node
+   " l2-cache" integer-property
+;
+headerless
+
+: make-cache-props  ( ts tsz d$s d$b d$sz i$s i$b i$sz -- )
+   " i-cache-size"       integer-property
+   dup to /icache-block
+   " i-cache-block-size" integer-property
+   " i-cache-sets"       integer-property
+   " d-cache-size"       integer-property
+   dup to /dcache-block
+   " d-cache-block-size" integer-property
+   " d-cache-sets"       integer-property
+   " tlb-size"           integer-property
+   " tlb-sets"           integer-property
+;
+: start-cpu-node  ( ts tsz d$s d$b d$sz i$s i$b i$sz adr len -- )
+   new-device
+   ( tlb-params cache-params adr len )  device-name
+   " cpu" device-type
+;
+: make-603-node  ( -- )
+   " PowerPC,603" start-cpu-node
+   d# 64  d# 128   d# 128  d# 32  d# 8192  3dup  make-cache-props
+;
+: make-604-node  ( -- )
+   " PowerPC,604" start-cpu-node
+   d# 128  d# 256   d# 128  d# 32  d# 16384   3dup  make-cache-props
+;
+: make-603e-node  ( -- )
+   " PowerPC,603e" start-cpu-node
+   d# 64  d# 128  d# 128  d# 32  d# 16384  3dup  make-cache-props
+;
+: make-603ev-node  ( -- )
+   " PowerPC,603ev" start-cpu-node
+   d# 64  d# 128  d# 128  d# 32  d# 16384  3dup  make-cache-props
+;
+: make-603eva-node  ( -- )
+   " PowerPC,603evARTHUR" start-cpu-node
+   d# 128  d# 256   d# 128  d# 32  d# 32768   3dup  make-cache-props
+;
+: make-604ev-node  ( -- )
+   " PowerPC,604ev" start-cpu-node
+   d# 128  d# 256   d# 256  d# 32  d# 32768   3dup  make-cache-props
+;
+: make-604ev5-node  ( -- )
+   " PowerPC,604ev5" start-cpu-node
+   d# 128  d# 256   d# 256  d# 32  d# 32768   3dup  make-cache-props
+;
+: make-620-node  ( -- )
+   " PowerPC,620" start-cpu-node
+   d# 128  d# 128   d# 64  d# 64  d# 32768   3dup  make-cache-props
+;
+: make-704-node  ( -- )
+   " PowerPC,X704" start-cpu-node
+   d# 32  d# 128   d# 64  d# 32  d# 2048   3dup  make-cache-props
+;
+: make-8240-node  ( -- )
+   " PowerPC,603ev" start-cpu-node
+   d# 64  d# 128  d# 128  d# 32  d# 16384  3dup  make-cache-props
+;
+: make-823-node  ( -- )
+   " PowerPC,MPC823" start-cpu-node
+   d# 32  d# 256   d# 32  d# 16  d# 1024   d# 64  d# 16  d# 2048  make-cache-props
+;
+
+headers
+0 0  " "  " /"  begin-package
+" cpus" device-name
+1 " #address-cells" integer-property
+0 " #size-cells" integer-property
+
+: decode-unit  ( adr len -- phys )  $number  if  0  then  ;
+: encode-unit  ( phys -- adr len )  (u.)  ;
+
+: open  ( -- true )  true  ;
+: close  ( -- )  ;
+end-package
+
+headerless
+
+defer make-cpu-extras	' noop to make-cpu-extras
+
+: make-cpu-node  ( cpu# -- )
+   to cpu
+   " /cpus" find-device
+
+   cpu-version  case
+       3 of  make-603-node    endof
+       4 of  make-604-node    endof
+       6 of  make-603e-node   endof
+       7 of  make-603ev-node  endof
+       8 of  make-603eva-node endof
+       9 of  make-604ev-node  endof
+   h#  a of  make-604ev5-node endof
+   d# 20 of  make-620-node    endof
+   h# 50 of  make-823-node    endof
+   h# 54 of  make-704-node    endof	\ proto... remove!
+   h# 60 of  make-704-node    endof
+   h# 81 of  make-8240-node   endof
+   ( default ) ." make-cpu-node: Unknown CPU Version " dup . cr
+   endcase
+
+   get-cpu-info
+
+   \ ??? cpu-version " arc-key" integer-property
+
+   counts/ms d# 1000 *  " timebase-frequency" integer-property
+
+   cpu firmware-cpu# =  if  current-device to cpu-package  then
+
+   cpu " reg" integer-property
+
+   " clock-frequency"  " /" find-package  drop  get-package-property  0=  if
+      " bus-frequency" property
+   then
+
+   cpu-clock-frequency " clock-frequency" integer-property
+   " : open true ; : close ;" evaluate
+   
+   \ check for in-line (or unshared) cache
+   probe-l2-cache  if
+      make-l2-cache-node
+   else
+      l2-cache-node ?dup if  " l2-cache" integer-property  then
+   then
+
+   make-cpu-extras
+
+   finish-device
+   device-end
+;
+
+: make-cpu-nodes  ( -- )
+   \ check for look-aside cache
+   " /cpus" find-device   -1 to cpu
+      probe-l2-cache  if  make-l2-cache-node  then
+   device-end
+   max#cpus 0  do
+      i cpu-started?  if  i make-cpu-node  then
+   loop
+;
+headers
+
+stand-init: CPU nodes
+   make-cpu-nodes
+   cpu-package  open-phandle  cpu-node !
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/cpustate.fth
===================================================================
--- cpu/ppc/cpustate.fth	                        (rev 0)
+++ cpu/ppc/cpustate.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,40 @@
+purpose: Buffers for saving program state
+\ See license at end of file
+
+headers
+\ A place to save the CPU registers when we take a trap
+0 value cpu-state               \ Pointer to CPU state save area
+
+headerless
+: >state  ( offset -- adr )  cpu-state  +  ;
+
+ps-size  buffer: pssave		\ Forth data stack save area
+rs-size  buffer: rssave		\ Forth return stack save area
+
+headers
+defer .exception		\ Display the exception type
+defer handle-breakpoint		\ What to do after saving the state
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/ctrace.fth
===================================================================
--- cpu/ppc/ctrace.fth	                        (rev 0)
+++ cpu/ppc/ctrace.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,81 @@
+purpose: After a crash, displays a backtrace of C stack frames.
+\ See license at end of file
+
+only forth also hidden also forth definitions
+needs (rstrace rstrace.fth
+needs >saved savedstk.fth
+only forth also hidden also forth definitions
+
+headerless
+: imatch?  ( adr match mask -- adr flag )  2 pick l@ and =  ;
+
+: b?      ( adr -- adr flag )  h# 4800.0000 h# fc00.0000 imatch?  ;
+: bc?     ( adr -- adr flag )  h# 4000.0000 h# fc00.0000 imatch?  ;
+: bclr?   ( adr -- adr flag )  h# 4c00.0020 h# fc00.07fe imatch?  ;
+: bcctr?  ( adr -- adr flag )  h# 4c00.0420 h# fc00.07fe imatch?  ;
+
+: >b-target  ( adr -- target-adr )
+   dup l@  dup  d# 6 <<  d# 6 >>a  3 invert and        ( adr instr bd )
+   swap  2 and  if  nip  else  +  then
+;
+: >bc-target  ( adr -- target-adr )
+   dup l@  dup  d# 16 <<  d# 16 >>a  3 invert and      ( adr instr bd )
+   swap  2 and  if  nip  else  +  then
+;
+: .subroutine  ( call-adr -- )  \ Show subroutine address
+   b?      if  >b-target    9 u.r  exit  then
+   bc?     if  >bc-target   9 u.r  exit  then
+   bclr?   if  drop %lr     9 u.r  exit  then  \ only works in leaf context
+   bcctr?  if  drop %ctr    9 u.r  exit  then  \ only works in leaf context
+   drop  ."    ??????"
+;
+: .args  ( -- )  \ Show C subroutine arguments
+   ."  ("  %r3 9 u.r   %r4 9 u.r   %r5 9 u.r   %r6 9 u.r  ."  ... )"
+;
+: .leaf  ( return-adr -- )
+   4 -
+   base @ >r  hex
+   dup .subroutine  .args  ."  called from "  9 u.r  cr
+   r> base !
+;
+: .subr  ( return-adr -- )
+   4 -
+   base @ >r  hex
+   dup .subroutine  ." ( ???? )"  ."  called from "  9 u.r  cr
+   r> base !
+;
+headers
+: ctrace  ( -- )   \ C stack backtrace
+   ?saved-state
+   ." Last Leaf:" cr   %lr .leaf
+   %r1  if
+      ." On stack:" cr
+      %r1     ( leaf-frame-adr )
+      begin  @ dup  while   ( frame-adr )  dup 8 + @ .subr  repeat
+      drop
+   then
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/debugm.fth
===================================================================
--- cpu/ppc/debugm.fth	                        (rev 0)
+++ cpu/ppc/debugm.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,110 @@
+purpose: CPU-dependent definitions for the source-level debugger
+\ See license at end of file
+
+headerless
+\ \needs at		: at  ( row column -- )  2drop  ;
+\needs kill-line	: kill-line  ( -- )  ;
+
+hex
+
+: low-dictionary-adr  ( -- adr )  origin  init-user-area +  ;
+
+nuser debug-next  \ Pointer to "next"
+vocabulary bug   bug also definitions
+nuser 'debug   \ code field for high level trace
+nuser <ip      \ lower limit of ip
+nuser ip>      \ upper limit of ip
+nuser cnt      \ how many times thru debug next
+
+\ Since we use a shared "next" routine, slow-next and fast-next are no-op's
+alias slow-next 2drop  ( high low -- )
+alias fast-next 2drop  ( high low -- )
+
+: copy-next  ( -- )
+   \ Copy the normal next routine from the user area
+   here  5 /n*  dup  allot   ( adr size )
+   up@ -rot cmove
+;
+
+label normal-next
+   copy-next
+end-code
+
+label debnext
+   'user <ip  lwz  t0,*
+   addi   t2,ip,4
+   cmpl   0,0,t2,t0
+   >= if
+      'user ip>   lwz  t0,*
+      cmpl  0,0,t2,t0
+      < if
+         'user cnt   lwz  t0,*
+         set    t1,2
+         addi   t0,t0,1
+	 'user cnt  stw  t0,*
+	 cmp   0,0,t0,t1
+	 = if
+            set  t0,0
+	    'user cnt  stw  t0,*
+
+            set  t0,h#873d0004	\ lwzu  w,4(ip)
+	    stw  t0,0(up)
+
+	    dcbf r0,up		\ flush cache
+	    icbi r0,up		\ flush cache
+	    isync
+	    
+            \ Machine code for   'debug token@ execute
+            'user 'debug   lwz  w,*
+
+            \ Tail of "NEXT"
+            lwzux   t1,w,base	\ Read the contents of the code field
+            add     t1,t1,base	\ Relocate
+            mtspr   lr,t1
+            bclr    20,0	\ Execute the code
+         then
+      then
+   then
+   copy-next   
+end-code
+
+\ Fix the next routine to use the debug version
+\ XXX This assumes that the user area and the dictionary are within
+\ 16 MBytes of one another.
+: pnext  ( -- )
+   debnext up@ - h# 3ffffff and  h# 48000000 or  up@ instruction!
+;
+
+\ Turn off debugging
+\ h# 873d0004  is  "lwzu  w,4(ip)", the first instruction of "next"
+: unbug  ( -- )   h# 873d0004 up@ instruction!  ;
+
+forth definitions
+syscall-vec @  0=  if
+unbug
+then
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/decompm.fth
===================================================================
--- cpu/ppc/decompm.fth	                        (rev 0)
+++ cpu/ppc/decompm.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,48 @@
+purpose: Machine/implementation-dependent decompiler support
+\ See license at end of file
+
+headerless
+
+only forth also hidden also  definitions
+: dictionary-base  ( -- adr )  origin  ;
+
+\ True if adr is a reasonable value for the interpreter pointer
+: reasonable-ip?  ( adr -- flag )
+   dup  in-dictionary?  if  ( ip )
+      #talign 1- and 0=  \ must be token-aligned
+   else
+      drop false
+   then
+;
+
+\ Decompiler extension for 32-bit literals
+: .llit      ( ip -- ip' )  ta1+ dup l@ n.  la1+  ;  
+: skip-llit  ( ip -- ip' )  ta1+ la1+  ;  
+' (llit)  ' .llit  ' skip-llit  install-decomp
+
+only forth also definitions
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/dectrap.fth
===================================================================
--- cpu/ppc/dectrap.fth	                        (rev 0)
+++ cpu/ppc/dectrap.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,36 @@
+purpose: Ignore decrementer interrupt
+\ See license at end of file
+
+headerless
+label dec-handler
+rfi
+end-code
+
+headers
+stand-init: Decrementer
+   dec-handler l@ h# 900 instruction!
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/disinflt.fth
===================================================================
--- cpu/ppc/disinflt.fth	                        (rev 0)
+++ cpu/ppc/disinflt.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,85 @@
+purpose: Disassemble inflate.bix so it can be re-assembled from Forth
+\ See license at end of file
+
+\ Example use:
+\ ppcforth tools.dic ${BP}/cpu/powerpc/disinflt.fth >inflate.dis
+\
+\ The output may require some amount of manual editing...
+\ To make inflate.bix:  xcftobin <inflate.out >inflate.bix
+
+hex
+
+4000 buffer: buf
+0 value /buf
+reading inflate.bix
+buf 4000 ifd @ fgets to /buf
+ifd @ fclose
+
+: show-relative  ( target -- )
+   [ also assembler ] pc [ previous ]  @  -
+   push-hex
+   ?dup  if  dup  0<  if  ." .-" negate  else  ." .+"  then  ." h#" ul.  then
+   pop-base
+;
+: +u.  ( adr -- adr' )  dup be-l@ 9 u.r  la1+  ;
+: dis0  ( 32b -- )
+   ?dup  if  disasm  else
+      [ also assembler ] pc [ previous ] @
+
+      dup h# 14 +  buf /buf +  u>  if
+         buf /buf +  over  do
+            ." h# "  i be-l@ u.  ." be-l,  "
+         /l +loop   cr
+         bye
+      then
+
+      \ Typically produces:
+      \ Debug:      2041 800b0300        0      49c   inflate
+      \                ^                        ^^^   ^^^^^^^
+      \         0 for leaf                     code    name
+      \          routines                     length          
+
+      cr ." Debug: " la1+  +u.  +u.  +u.  +u.
+      dup wa1+  swap be-w@  2dup  ."    "  type cr
+      + aligned  4 -
+      [ also assembler ] pc [ previous ] !
+   then
+;
+: keep-going  ( adr -- false )  drop false  ;
+also assembler
+true to numeric-conditionals?
+patch dis0 disasm dis1
+patch keep-going @ +dis
+patch keep-going @ +dis
+patch @ keep-going +dis
+' show-relative is showaddr
+previous
+
+no-page
+
+\ buf 20 + dis
+buf dis
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/epic.fth
===================================================================
--- cpu/ppc/epic.fth	                        (rev 0)
+++ cpu/ppc/epic.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,73 @@
+purpose: Driver for Motorola Embedded Programmable Interrupt Controller
+\ See license at end of file
+
+h# fdf0.0000 constant eu-pa
+0 value eu-va
+: map-eu  ( -- )
+   eu-pa h# 78 config-l!
+   eu-pa h# 10.0000 root-map-in to eu-va   
+;
+: +eu  ( offset -- adr )  eu-va +  ;
+: eu!  ( l offset -- )  +eu rl!  ;
+: eu@  ( offset -- l )  +eu rl@  ;
+
+: priority!  ( pri -- )    h# 60080 eu!  ;
+: vector@   ( -- vector )  h# 600a0 eu@  ;
+: eoi  ( -- )  0  h# 600b0 eu!  ;
+: gcr!  ( l -- )  h# 41020 eu!  ;
+: gcr@  ( -- l )  h# 41020 eu@  ;
+
+: pi!  ( l -- )  h# 41090 eu!  ;
+: pi@  ( -- l )  h# 41090 eu@  ;
+
+: spurious!  ( n -- )  h# 410e0 eu!  ;
+: eicr!  ( l -- )  h# 41030 eu!  ;
+: eicr@  ( -- l )  h# 41030 eu@  ;
+
+: >irq  ( channel -- adr )  h# 20 *  h# 50200 +  ;
+: vec/pri!  ( l channel -- )  >irq  eu!  ;
+: vec/pri@  ( channel -- l )  >irq  eu@  ;
+: dest!  ( l channel -- )  >irq h# 10 +  eu!  ;
+: dest@  ( channel -- l )  >irq h# 10 +  eu@  ;
+
+\ Other channels:  I2C - 0x71, DMA0 - 0x72, DMA1 - 0x73, Message unit - 0x76
+
+: reset-epic  ( -- )
+   gcr@  h# a000.0000 or  gcr!
+   h# 2000.0000 gcr!
+   \ XXX should configure it for the correct mode - direct, pass-thru, etc.
+
+   \ Eat any pending interrupts
+   h# 20 0  do
+      vector@  h# ff =  if  unloop exit  then
+      eoi
+   loop
+   ." The EPIC won't stop interrupting" cr
+;
+stand-init: Initializing EPIC
+   map-eu
+   reset-epic
+;
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/fb8-ops.fth
===================================================================
--- cpu/ppc/fb8-ops.fth	                        (rev 0)
+++ cpu/ppc/fb8-ops.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,205 @@
+purpose: Optimized fb8 package support routines
+\ See license at end of file
+
+headerless
+decimal
+
+\ Invert foreground and background colors within a rectangular region
+code fb8-invert  ( adr width height bytes/line fg-color bg-color -- )
+				\ bg-color in tos
+    lwz		t4,0(sp)	\ fg-color in t4
+    lwzu	t0,1cell(sp)	\ bytes/line in scr
+    lwzu	t2,1cell(sp)	\ height in t1 (outer loop index, >0)
+    lwzu	t1,1cell(sp)	\ width in t2 (inner loop index, >0)
+    lwzu	t3,1cell(sp)	\ adr in sc3 (starting address)
+
+    mfspr	t6,ctr		\ Save counter
+    
+    subf	t0,t1,t0	\ Account for inner loop incrementing
+    addi	t3,t3,-1	\ Account for inner loop incrementing
+
+    begin 			\ Outer loop
+        mtspr	ctr,t1		\ Starting width value
+	begin			\ Inner loop
+	    lbzu  t5,1(t3)	\ read byte
+	    cmp   0,0,t5,tos	\ Background?
+	    =  if
+		mr  t5,t4	\ Set to foreground
+	    else
+		cmp  0,0,t5,t4	\ Foreground?
+		= if
+		    mr  t5,tos	\ Set to background
+		then
+	    then
+	    stb	  t5,0(t3)	\ store byte
+	countdown		\ End inner loop when width=0
+
+	addic.	t2,t2,-1	\ decrement height until =0
+	add	t3,t3,t0	\ increment adr to next line
+    = until			\ End outer loop when height=0
+
+    mtspr	ctr,t6		\ Restore counter
+    lwzu	tos,1cell(sp)	\ Clean up stack
+    addi	sp,sp,1cell
+c;
+
+\ Draws a character from a 1-bit-deep font into an 8-bit-deep frame buffer
+\ Assumptions: 	Fontbytes is 2; 0 < width <= 16
+\		Fontadr is divisible by 2
+code fb8-paint
+( fontadr fontbytes width height screenadr bytes/line fg-color bg-color -- )
+    \ tos already there		\ bg-color in tos
+    lwz		t9,0(sp)	\ fg-color in t9
+    lwzu	t2,1cell(sp)	\ Bytes/line - bytes per scan line
+    lwzu	t3,1cell(sp)	\ Screenadr - start address in frame buffer
+    lwzu	t4,1cell(sp)	\ Height - character height in pixels
+    lwzu	t5,1cell(sp)	\ Width - character width in pixels (bytes)
+    lwzu	t6,1cell(sp)	\ Fontbytes - bytes per font line
+    lwzu	t7,1cell(sp)	\ Fontadr - start adr of this char in font table
+ 
+    addi	t3,t3,-1	\ Account for pre-incrementing
+    subf	t2,t5,t2	\ Account for inner loop incrementing
+    mfspr	t8,ctr		\ Save counter
+
+    addi	r0,r0,8		\ Constant 8 (pixels/font-byte), needed below
+
+
+    begin			\ Outer loop - for all scan lines in char
+	lbz	t0,0(t7)	\ Up to 8 font bits into scr  
+	rlwinm	t0,t0,23,1,8	\ Align almost to high part of word so that
+				\ one more shift will affect the sign bit
+
+	mr	t1,t5		\ Reset width counter for the new scan line
+
+	ahead			\ Branch down to end of loop
+	begin
+
+	    cmpi  0,0,t1,8
+	    <  if
+	        mtspr  ctr,t1	\ Set count
+	        subf   t1,t1,t1	\ Width is exhausted
+	    else
+		mtspr  ctr,r0	\ Max inner loop count is 8
+		addi   t1,t1,-8	\ Reduce width by 8
+	    then
+
+	    begin		\ Inner loop - for each pixel in a font byte
+		add.  t0,t0,t0		\ Shift next pixel bit to top position
+		0<  if
+		    stbu  t9,1(t3)	\ Write foreground color to framebuffer
+		else
+		    stbu  tos,1(t3)	\ Write background color to framebuffer
+		then	    	    
+	    countdown               \ Repeat until width count = 0
+
+        but then
+	    cmpi  0,0,t1,0
+        = until
+
+	add	t7,t7,t6	\ Next scan line in font table
+	addic.	t4,t4,-1	\ Decrement height counter
+	add	t3,t3,t2	\ Increment frame buffer addr to next line
+    = until                	\ Repeat until height count = 0
+
+    mtspr	ctr,t8		\ Restore counter
+    lwzu	tos,4(sp)	\ Clean up stack
+    addi	sp,sp,4
+c;
+
+\ Very fast window move, for scrolling
+\ Similar to 'move', but only moves #move/line out of every 'bytes/line' bytes
+\ Assumes bytes/line is divisible by 8 (for double-long load/stores)
+\ Assumes src and dst separated by n*bytes/line
+\ Called with:
+\ src-start dst-start      size      bytes/line #move/line      fb8-move
+\ (break-lo)(cursor-y) (winbot-breaklo)  (")  (emu-bytes/line)
+\ src > dst, so move from start towards end
+
+\ Note that the 601 is a 32-bit implementation.
+\ It would be cool to test here, but the PVR is supervisor-only!
+[ifdef] sixtyfour-bit
+   8 constant fbalign
+[else]
+   4 constant fbalign
+[then]
+
+code fb8-window-move  ( src-start dst-start size bytes/line #move/line -- )
+    				\ tos=#move/line
+    lwz		t0,0(sp)	\ t0=bytes/line
+    lwzu	t1,1cell(sp)	\ t1=size
+    lwzu	t2,1cell(sp)	\ t2=dst-start
+    lwzu	t3,1cell(sp)	\ t3=src-start
+
+    fbalign 1-  addi	t5,r0,*	\ Get fbalign-1 into a register
+
+    \ First, force src and dst to alignment boundary, adjust #move/line
+    and		t4,t3,t5	\ Any extra bytes at start?
+    add		tos,tos,t4	\ Adjust #move/line by that amount
+    andc	t3,t3,t5	\ Lock src to alignment boundary
+    andc	t2,t2,t5	\ Lock dst to alignment boundary
+    add		tos,tos,t5	\ Round #move/line up to next unit
+    andc	tos,tos,t5
+
+    subf	t4,tos,t0	\ Account for inner loop incrementing
+
+    fbalign negate  addi t3,t3,*  \ Account for pre-incrementing
+    fbalign negate  addi t2,t2,*  \ Account for pre-incrementing
+[ifdef] sixtyfour-bit
+    rlwinm	tos,tos,29,3,31
+[else]
+    rlwinm	tos,tos,30,2,31
+[then]
+    mfspr	t7,ctr		\ Save counter
+
+    cmpi	0,0,t1,0
+    ahead			\ Branch to loop end for initial comparison
+    begin			\ Outer loop
+        mtspr   ctr,tos		\ Setup inner loop index
+
+	begin			\ Inner loop
+[ifdef] sixtyfour-bit
+	    ldzu	t6,8(t3)
+	    stdu	t6,8(t2)
+[else]
+	    lwzu	t6,4(t3)
+	    stwu	t6,4(t2)
+[then]
+        countdown
+
+	subf.	t1,t0,t1	\ Decrement size until =0
+	add	t2,t4,t2	\ Increment src
+	add	t3,t4,t3	\ Increment dst
+    but then			\ Target of "ahead" branch
+    <= until			\ End outer loop when size=0
+
+    mtspr	ctr,t7		\ Restore counter
+
+    lwzu	tos,1cell(sp)	\ Clean up stack
+    addi	sp,sp,1cell
+c;
+
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/field.fth
===================================================================
--- cpu/ppc/field.fth	                        (rev 0)
+++ cpu/ppc/field.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,45 @@
+purpose: Structures and fields for PowerPC
+\ See license at end of file
+
+\ field creates words which add their offset within the structure
+\ to the base address of the structure
+
+: struct  ( -- 0 )  0  ;
+
+: field  \ name  ( offset size -- offset+size )
+   create over , +
+
+   \ The high level equivalen of what the following machine code is:
+   \    does> @ file @ + ;
+   \ We write it in code because the metacompiler facilities for
+   \ resolving DOES> clauses are clumsy
+
+   ;code  ( struct-adr -- field-adr )
+      pop-to-t0			\ Get the struct address
+      lwz   tos,0(tos)		\ Get the structure member offset
+      add   tos,tos,t0		\ Return the structure member address
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/filecode.fth
===================================================================
--- cpu/ppc/filecode.fth	                        (rev 0)
+++ cpu/ppc/filecode.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,165 @@
+purpose: File system support code for PowerPC
+\ See license at end of file
+
+headerless
+\ signed mixed mode addition
+code ln+   (s n1 n2 -- n3 )  pop-to-t0   add  tos,tos,t0  c;
+
+\ &ptr is the address of a pointer.  fetch the pointed-to
+\ character and post-increment the pointer
+ 
+code @c at ++ ( &ptr -- char )
+   lwz  t0,0(tos)	\ Fetch the pointer
+   mr   t1,tos		\ Copy of the address
+   lbz  tos,0(t0)	\ Get the byte
+   addi t0,t0,1		\ Increment the pointer   
+   stw  t0,0(t1)	\ Replace the pointer
+c;
+ 
+\ &ptr is the address of a pointer.  store the character into
+\ the pointed-to location and post-increment the pointer
+
+code @c!++ ( char &ptr -- )
+   lwz  t0,0(tos)	\ Fetch the pointer
+   lwz  t1,0(sp)	\ char in t1
+   stb  t1,0(t0)	\ Put the byte
+   addi t0,t0,1		\ Increment the pointer   
+   stw  t0,0(tos)	\ Replace the pointer
+   lwz  tos,1cell(sp)	\ Fixup top of stack
+   addi sp,sp,2cells	\ Adjust stack pointer
+c;
+
+headers
+\ "adr1 len2" is the longest initial substring of the string "adr1 len1"
+\ that does not contain the character "char".  "adr2 len1-len2" is the
+\ trailing substring of "adr1 len1" that is not included in "adr1 len2".
+\ Accordingly, if there are no occurrences of that character in "adr1 len1",
+\ "len2" equals "len1", so the return values are "adr1 len1  adr1+len1 0"
+
+code split-string  ( adr1 len1 char -- adr1 len2  adr1+len2 len1-len2 )
+			\ char in tos
+   lwz  t1,0(sp)	\ len1
+   lwz  t0,1cell(sp)	\ adr1
+
+   cmpi 0,0,t1,0	\ Test length
+   0<> if
+      mfspr  t5,ctr
+      mtspr  ctr,t1
+
+      addi  t0,t0,-1	\ Account for pre-increment
+
+      begin
+         lbzu  t3,1(t0)		\ get the next character
+         cmp   0,0,t3,tos	\ Look for the terminator character
+      bc  0,2,*
+
+      =  if			\ Found terminator?
+         mfspr  tos,ctr		\ len1-len2-1
+         addi   tos,tos,1	\ len1-len2
+         subfc  t1,tos,t1	\ len2	( Use subfc for POWER compatibility)
+         stw    t1,0(sp)	\ store len2 on stack
+
+	 stwu   t0,-1cell(sp)	\ Store adr1+len2 on stack
+         mtspr  ctr,t5
+	 next
+      then
+      mtspr ctr,t5
+   then
+
+   \ The test character is not present in the input string
+
+   stwu  t0,-1cell(sp)		\ Store adr1+len2 on stack
+   addi  tos,r0,0        	\ Return rem-len=0
+c;
+
+headerless
+\ Splits a buffer into two parts around the first line delimiter
+\ sequence.  A line delimiter sequence is either CR, LF, CR followed by LF,
+\ or LF followed by CR.
+\ adr1 len2 is the initial substring before, but not including,
+\ the first line delimiter sequence.
+\ adr2 len3 is the trailing substring after, but not including,
+\ the first line delimiter sequence.
+
+code parse-line  ( adr1 len1 -- adr1 len2  adr2 len3 )
+   mr    t1,tos		\ len1
+   lwz   t0,0(sp)	\ adr1
+
+   set   tos,10		\ Delimiter 1 (linefeed)
+   set   t4,13		\ Delimiter 2 (carriage return)
+
+   cmpi 0,0,t1,0	\ Test length
+   0<> if
+      mfspr  t5,ctr
+      mtspr  ctr,t1
+
+      addi  t0,t0,-1	\ Account for pre-increment
+
+      begin
+         lbzu  t2,1(t0)		\ get the next character
+         cmp   0,0,t2,tos  <> if  cmp  0,0,t2,t4  then  \ Compare to delimiters
+      bc  0,2,*
+
+      =  if			\ Found delimiter?
+         mfspr  t3,ctr		\ len1-len2
+         addi   t3,t3,1
+         addi   t0,t0,1		\ Consume first delimiter
+
+         subfc  t1,t3,t1	\ len2 ( Use subfc for POWER compatibility)
+         stwu   t1,-1cell(sp)	\ store len2 on stack
+
+         addic. t3,t3,-1
+         0<>  if		\ Is there another delimiter?
+            lbz  t6,0(t0)	\ Get the next character
+
+            \ Compare next character to other delimiter
+            cmp 0,0,t2,tos  =  if  cmp 0,0,t6,t4  else  cmp 0,0,t6,tos  then
+
+	    =  if		\ If next character is the other delimiter
+	       addi t0,t0,1	\ ... consume it
+               addi t3,t3,-1
+            then
+         then
+	 stwu  t0,-1cell(sp)	\ Store adr1+len2 on stack
+
+         mr     tos,t3		\ Return len1-len2
+         mtspr  ctr,t5
+	 next
+      then
+      mtspr ctr,t5
+   then
+
+   \ There is no line delimiter in the input string
+
+   stwu  t1,-1cell(sp)		\ Store len2 (=len1) on stack
+   stwu  t0,-1cell(sp)		\ Store adr1+len2 on stack
+   addi  tos,r0,0		\ Return rem-len=0
+c;
+
+headers
+
+nuser delimiter
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/filefld.fth
===================================================================
--- cpu/ppc/filefld.fth	                        (rev 0)
+++ cpu/ppc/filefld.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,50 @@
+purpose: Code words to support the file system interface
+\ See license at end of file
+
+nuser file
+
+:-h struct ( -- 0 )  00  ;-h
+
+\ Run-time action for fields
+code dofield
+   lwz   tos,0(tos)	   \ Get the structure member offset
+   'user file  lwz  t0,*   \ Get the structure base address
+   add   tos,tos,t0	   \ Return the structure member address
+c;
+
+\ Assembles the code field when metacompiling a field
+:-h file-field-cf   ( -- )
+   dodoes token,-t  
+   " dofield" $sfind drop resolution@  token,-t	\ code field
+;-h
+
+\ Metacompiler defining word for creating fields
+:-h file-field  \ name  ( offset size -- offset' )
+   " file-field-cf" header-t	\ name field and code field
+   over ,-t +   ?debug		\ parameter field
+;-h
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/finish.fth
===================================================================
--- cpu/ppc/finish.fth	                        (rev 0)
+++ cpu/ppc/finish.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,41 @@
+purpose: Final cleanup for kernel metacompilation
+\ See license at end of file
+
+' init        is do-init
+' sys-init-io is init-io
+
+also assembler
+'body  cold-code 4 +  cld  8 +  put-branch
+previous
+variable dodoesaddr
+
+assembler dodoes meta   is dodoesaddr
+forth-h
+metaoff
+only forth also definitions
+fix-vocabularies
+' symbols fixall
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/fixvoc.fth
===================================================================
--- cpu/ppc/fixvoc.fth	                        (rev 0)
+++ cpu/ppc/fixvoc.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,52 @@
+purpose: Fixup vocabularies at the end of kernel metacompilation
+\ See license at end of file
+
+only forth meta also forth also definitions
+\ Nasty kludge to resolve the to pointer to the does> clause of vocabulary
+\ within "forth".  The problem is that the code field of "forth" contains
+\ a call instruction to the does> clause of vocabulary.  This call is a 
+\ forward reference which cannot be resolved in the same way as compiled
+\ addresses.
+
+: used-t  ( definer-acf child-acf -- )
+   [ also meta ] token!-t [ previous ]
+;
+
+: fix-vocabularies  ( -- )
+   [""] <vocabulary>  also symbols  find   previous  ( acf true | str false )
+   0= abort" Can't find <vocabulary> in symbols"
+   dup resolution@ >r               ( acf )  ( Return stack: <vocabulary>-adr )
+   dup first-occurrence@                     ( acf occurrence )
+   \ Don't let fixall muck with this entry later
+   0 rot >first-occurrence !		     ( occurrence )
+   begin  another-occurrence?  while         ( occurrence )
+      dup [ meta ] token at -t [ forth ] swap   ( next-occurrence occurrence )
+      \ Calculate the longword offset to the vocabulary does> clause
+      r@ swap used-t
+   repeat
+   r> drop
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/flipdic.fth
===================================================================
--- cpu/ppc/flipdic.fth	                        (rev 0)
+++ cpu/ppc/flipdic.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,71 @@
+purpose: Endian-swap the Forth dictionary for PowerPC
+\ See license at end of file
+
+\needs bittest  fload ${BP}/forth/lib/bitops.fth
+\needs lbflip   \needs lbsplit  fload ${BP}/forth/lib/split.fth
+\needs lbflip   : lbflip  ( l1 -- l2 )  lbsplit swap 2swap swap bljoin  ;
+\needs lbflips  : lbflips  ( a l -- )  bounds  ?do  i l@ lbflip i l! /l +loop ;
+
+0 value header
+h# 20 constant /header
+0 value dict
+0 value /dict
+0 value ua
+0 value /ua
+0 value relmap
+0 value total-size
+
+: ?lbflips  ( adr len -- )
+   3 + 4 /  0  ?do                          ( adr )
+      i relmap bittest  0=  if              ( adr )
+         dup i la+ dup l@ lbflip swap l!    ( adr )
+      then                                  ( adr )
+   loop                                     ( adr )
+   drop
+;
+
+reading fw.dil
+ifd @ fsize to total-size
+total-size alloc-mem  to header
+header  total-size  ifd @ fgets  drop
+ifd @ fclose
+
+header /header +  to dict
+header 1 la+ l@   to /dict
+
+dict /dict + to ua
+header 2 la+ l@   to /ua
+
+ua /ua + to relmap
+
+header /header lbflips
+dict /dict ?lbflips
+ua /ua lbflips
+
+writing fw.dic
+header total-size  ofd @ fputs
+ofd @ fclose
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/flips.fth
===================================================================
--- cpu/ppc/flips.fth	                        (rev 0)
+++ cpu/ppc/flips.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,63 @@
+purpose: Switch to little-endian after the firmware is already running
+\ See license at end of file
+
+code lbflips  ( adr len -- )
+   mfspr  r10,ctr
+
+   mr         r6,tos
+   rlwinm     r6,r6,30,2,31	\ Divide by /l
+   mtspr      ctr,r6
+
+   lwz        r5,0(sp)
+   addi       sp,sp,1cell
+
+   begin
+      lwz     r4,0(r5)
+      stwbrx  r4,r0,r5
+      addi    r5,r5,4
+   countdown
+   mtspr  ctr,r10
+c;
+
+code wbflips  ( adr len -- )
+   mfspr  r10,ctr
+
+   mr         r6,tos
+   rlwinm     r6,r6,31,1,31	\ Divide by /w
+   mtspr      ctr,r6
+
+   lwz        r5,0(sp)
+   addi       sp,sp,1cell
+
+   begin
+      lhz     r4,0(r5)
+      sthbrx  r4,r0,r5
+      addi    r5,r5,2
+   countdown
+   mtspr  ctr,r10
+c;
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/forthint.fth
===================================================================
--- cpu/ppc/forthint.fth	                        (rev 0)
+++ cpu/ppc/forthint.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,258 @@
+purpose: Low-level handler for alarm interrupt 
+\ See license at end of file
+
+headerless
+\ Interfaces to system-dependent routines
+defer init-dispatcher ( -- )  ' noop to init-dispatcher
+defer dispatch-interrupt  ' noop to dispatch-interrupt
+
+h# 400 constant /intstack
+hex
+
+0 value tick-limit
+0 value 'rm-intret
+
+decimal
+
+label rm-interrupt-return  ( -- )
+   mfspr  r2,sprg0		\ physical address of this cpu's exception-area
+   
+   stw  t3,h#0c(r2)		\ Put derived flag in a safe place
+
+   lwz r31,h#9fc(r0)		\ Address of interrupt save area
+
+   \ Now we have to get these guys back into the per-prpcessor
+   \ save area. They were squirreld away here by interrupt-preamble
+   38 /l*  31  lwz  r0,*   stw  r0,0(r2)	\ r3
+   39 /l*  31  lwz  r0,*   stw  r0,4(r2)	\ r2
+   40 /l*  31  lwz  r0,*   stw  r0,8(r2)	\ lr
+
+   32 /l*  31  lwz  r0,*   mtspr  xer,r0      \ xer
+   34 /l*  31  lwz  r0,*   mtspr  ctr,r0      \ ctr
+   35 /l*  31  lwz  r0,*   mtspr  srr0,r0     \ saved pc
+   36 /l*  31  lwz  r0,*   mtspr  srr1,r0     \ saved msr
+
+\ XXX the next line is probably unnecessary, because RFI doesn't change the
+\ ILE bit, and we are careful to preserve it when we enter the high-level
+\ handler.
+   mfmsr r1  rlwimi r1,r0,0,15,15  mtmsr r1   \ Restore MSR ILE bit - RFI won't
+
+   37 /l*  31  lwz  r0,*   stw    r0,h#10(r2) \ Put CR in low memory area
+
+   \ Assemble 32 "lwz rN,N*4(r31)" instructions
+   32  0  do
+      i 4 * ( offset )  31 ( r31 )   i ( reg# )   " lwz *,*" evaluate
+   loop
+
+   mfspr  r2,sprg0
+
+   \ Now the registers and low-memory values are back to the state that
+   \ existed upon entry to the interrupt handler.  We can use only r3 and lr
+   \ in the following code.
+
+   lwz   r3,h#0c(r2)		\ Abort flag
+   cmpi  0,0,r3,0
+   <>  if			\ Abort if non-zero
+      lwz    r3,h#10(r2)	\ Restore CR
+      mtcrf  h#ff,r3
+
+      lwz    r3,h#9f0(r0)	\ Save-state address
+      mtspr  lr,r3
+      addi   r3,r0,-1		\ Indicate an abort
+      stw    r3,h#0c(r2)	\ Exception #
+      bclr   20,0		\ Jump to save-state
+   then
+
+   lwz    r3,h#10(r2)		\ Restore CR
+   mtcrf  h#ff,r3
+
+   lwz    r3,h#08(r2)		\ Restore LR
+   mtspr  lr,r3
+
+   lwz    r3,h#0(r2)		\ Restore r3
+   lwz    r2,h#04(r2)		\ Restore r2
+
+   rfi
+end-code
+
+code interrupt-return  ( -- )
+
+   \ At the first indication of a keyboard abort, we branch to the
+   \ Forth entry trap handler.  We do the actual branch after we have
+   \ restored all the state, so it appears as if Forth were entered
+   \ directly from the program that was running, rather than through
+   \ the interrupt handler.
+
+   addi  t3,r0,0		\ Clear derived abort flag
+   'user aborted?  lwz  t5,*	\ Abort flag
+
+   cmpi  0,0,t5,1
+   =  if
+      \ Don't abort in the middle of the terminal emulator, because
+      \ it's not reentrant.
+
+      'user terminal-locked?   lwz  t4,*
+      cmpi   0,0,t4,0
+      =  if
+
+         \ Increment the abort flag past 1 so that we won't see it again
+         \ until the interpreter has seen and cleared it.
+         addi  t5,t5,1
+         'user aborted?  stw  t5,*
+
+         addi  t3,r0,-1		\ Set derived abort flag
+      then
+   then
+
+   mfmsr t4
+   rlwinm t4,t4,0,28,25		\ Get back into real mode so we won't have
+   mtspr srr1,t4		\ translation faults in the following code.
+
+   'user 'rm-intret  lwz t4,*
+   mtspr srr0,t4
+
+   rfi
+end-code
+
+: interrupt-handler  ( exc-adr -- )
+   h# 900 =  if  check-alarm  else  dispatch-interrupt  then
+   interrupt-return
+;
+
+\ This routine is entered in real mode.
+\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area,
+\ r3 points to the address where the exception occured.
+label interrupt-preamble
+   stw    r3,h#9e8(r0)		\ Save exception address
+   lwz    r3,h#9fc(r0)		\ Physical address of register save area
+
+   \ Save the registers
+
+   \ Assemble 32 "stw rN,N*4(r3)" instructions
+   32  0  do
+      i 4 * ( offset )  3 ( r3 )   i ( reg# )   " stw *,*" evaluate
+   loop
+
+   \ We can't leave these in the sprg save area because they will
+   \ get trounced if we get a DSI in the hi level part of the handler
+   lwz    r0,0(r2)    38 /l*  3  stw  r0,*	\ r3
+   lwz    r0,4(r2)    39 /l*  3  stw  r0,*	\ r2
+   lwz    r0,8(r2)    40 /l*  3  stw  r0,*	\ lr
+
+   mfspr  r0,xer      32 /l*  3  stw  r0,*   \ xer
+   mfspr  r0,ctr      34 /l*  3  stw  r0,*   \ ctr
+   mfspr  r0,srr0     35 /l*  3  stw  r0,*   \ saved pc
+   mfspr  r0,srr1
+
+   \ Save the ILE bit too; it doesn't show up in SRR1, so we get it
+   \ from the LE bit in in the current MSR value, putting it in its
+   \ normal position in the saved value.
+   mfmsr r1    rlwimi r0,r1,16,15,15
+
+   \ Keep a copy for later use in establishing the MSR value for the
+   \ high-level interrupt handler, but turn off the EE bit so that the
+   \ handler can't be re-entered
+   rlwinm  t1,r0,0,17,15
+
+                      36 /l*  3  stw  r0,*   \ saved msr
+   mfcr   r0          37 /l*  3  stw  r0,*   \ cr
+
+   lwz    t0,h#9ec(r0)		\ Virtual address of interrupt stack area
+
+   \ Set up Forth stacks
+   addi   sp,t0,h#200		\ Data stack pointer
+   addi   rp,sp,h#200		\ Return stack pointer
+
+   lwz    t0,h#9f4(r0)		\ Get decrementer initial value
+   mtspr  dec,t0		\ Restart ticker
+
+   here 4 +  bl  *		\ Get address of next instruction into LR
+   here origin -  set   t0,*	\ Relative address of this instruction
+   mfspr  base,lr
+   subf   base,t0,base		\ Base register is now set (physical address)
+
+   'body main-task  set  up,*	\ Relative address of main-task
+   lwzx   up,up,base		\ User pointer is now set
+
+   lwz    base,h#9f8(r0)	\ Virtual address of origin
+   lwz    tos,h#9e8(r0)		\ Stack exception address
+
+   'body interrupt-handler 4 -  set  ip,*
+   add    ip,ip,base
+
+   mtspr  ctr,up		\ Pointer to NEXT routine
+
+   \ Restore old MSR value so normal address translation can occur, but
+   \ don't allow other external interrupts
+   mtspr  srr1,t1		\ Old MSR value
+   mtspr  srr0,up		\ Address of NEXT routine
+   rfi
+end-code
+
+\ code dec!  ( #ticks -- )
+\    mtspr  dec,tos
+\    lwz    tos,0(sp)
+\    addi   sp,sp,1cell
+\ c;
+\ code dec@  ( -- #ticks )
+\    stwu   tos,-1cell(sp)
+\    mfspr  tos,dec
+\ c;
+
+\ The implementations are defined in msr.fth
+' (enable-interrupts) to enable-interrupts
+' (disable-interrupts) to disable-interrupts
+' (lock) to lock[
+' (unlock) to ]unlock
+
+: set-tick-limit  ( #msecs -- )
+   to ms/tick
+   ms/tick counts/ms *  to tick-limit
+   tick-limit dec!
+   tick-limit h# 9f4 !
+;
+: install-alarm  ( -- )
+   \ Put various important parameters in real memory where the
+   \ real-mode part of the interrupt handler can find them.
+
+   /intstack alloc-mem  dup h# 9ec !  >physical h# 9fc !  \ Interrupt stack
+   origin                   h# 9f8 !
+   tick-limit		    h# 9f4 !
+   save-state >physical     h# 9f0 !
+
+   rm-interrupt-return >physical  to 'rm-intret
+
+   disable-interrupts
+      interrupt-preamble  h# 500  put-exception  \ External interrupt
+      interrupt-preamble  h# 900  put-exception  \ Decrementer interrupt
+      init-dispatcher
+      d# 10 set-tick-limit
+   enable-interrupts		\ Turn interrupts on
+;
+
+headers
+hex
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/ftrace.fth
===================================================================
--- cpu/ppc/ftrace.fth	                        (rev 0)
+++ cpu/ppc/ftrace.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,33 @@
+purpose: Display a Forth stack backtrace
+\ See license at end of file
+
+only forth also hidden also  forth definitions
+: ftrace  ( -- )   \ Forth stack
+   ip >saved .traceline
+   rp >saved  rssave-end swap  (rstrace   
+;
+only forth also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/gdb.fth
===================================================================
--- cpu/ppc/gdb.fth	                        (rev 0)
+++ cpu/ppc/gdb.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,67 @@
+purpose: PowerPC-specific words for remote GDB interface
+\ See license at end of file
+
+only forth also hidden also definitions
+headerless
+
+: ppc-read-registers  ( -- )
+  xbuf
+  %r0  gr  %r1  gr  %r2  gr  %r3  gr  %r4  gr  %r5  gr  %r6  gr  %r7  gr 
+  %r8  gr  %r9  gr  %r10 gr  %r11 gr  %r12 gr  %r13 gr  %r14 gr  %r15 gr 
+  %r16 gr  %r17 gr  %r18 gr  %r19 gr  %r20 gr  %r21 gr  %r22 gr  %r23 gr 
+  %r24 gr  %r25 gr  %r26 gr  %r27 gr  %r28 gr  %r29 gr  %r30 gr  %r31 gr 
+
+  %f0  dr  %f1  dr  %f2  dr  %f3  dr  %f4  dr  %f5  dr  %f6  dr  %f7  dr
+  %f8  dr  %f9  dr  %f10 dr  %f11 dr  %f12 dr  %f13 dr  %f14 dr  %f15 dr
+  %f16 dr  %f17 dr  %f18 dr  %f19 dr  %f20 dr  %f21 dr  %f22 dr  %f23 dr
+  %f24 dr  %f25 dr  %f26 dr  %f27 dr  %f28 dr  %f29 dr  %f30 dr  %f31 dr
+
+\  %y gr   %psr gr %wim gr %tbr gr %pc gr  %npc gr %fpsr gr %cpsr gr
+  xbuf tuck - putpkt
+;   
+: ppc-write-registers  ( -- )
+  rbuf 1+
+  v to %r0  v to %r1  v to %r2  v to %r3  v to %r4  v to %r5  v to %r6  v to %r7
+  v to %r8  v to %r9  v to %r10 v to %r11 v to %r12 v to %r13 v to %r14 v to %r15
+  v to %r16 v to %r17 v to %r18 v to %r19 v to %r20 v to %r21 v to %r22 v to %r23
+  v to %r24 v to %r25 v to %r26 v to %r27 v to %r28 v to %r29 v to %r30 v to %r31
+
+  w to %f0  w to %f1  w to %f2  w to %f3  w to %f4  w to %f5  w to %f6  w to %f7
+  w to %f8  w to %f9  w to %f10 w to %f11 w to %f12 w to %f13 w to %f14 w to %f15
+  w to %f16 w to %f17 w to %f18 w to %f19 w to %f20 w to %f21 w to %f22 w to %f23
+  w to %f24 w to %f25 w to %f26 w to %f27 w to %f28 w to %f29 w to %f30 w to %f31
+
+\  v to %y v to %psr v to %wim v to %tbr v to %pc  v to %npc
+\  v to %fpsr v to %cpsr gr
+  drop
+  okay-reply
+;  
+' ppc-read-registers to read-registers
+' ppc-write-registers to write-registers
+
+headers
+only forth also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/getms.fth
===================================================================
--- cpu/ppc/getms.fth	                        (rev 0)
+++ cpu/ppc/getms.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,261 @@
+purpose: Interval timing functions
+\ See license at end of file
+
+headerless
+code 601?  ( -- flag )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,pvr
+   rlwinm tos,tos,16,16,31
+   cmpi   0,0,tos,1
+   =  if
+      set tos,-1
+   else
+      set tos,0
+   then
+c;
+
+\ 604  TB is incremented at 1/4 the speed of the system bus.
+\ at 40Mhz sysclk, there are 10000 counts/ms.
+\ at 50Mhz sysclk, there are 12500 counts/ms.
+\ default: 50Mhz
+\ d#  8250 value counts/ms   \ For a 603 with a 33 MHz bus clock
+\ d# 10000 value counts/ms   \ For a 604 with a 40 MHz bus clock
+\ d# 12500 value counts/ms   \ For a 604 with a 50 MHz bus clock
+\ d# 16500 value counts/ms   \ For a 604 with a 66 MHz bus clock
+
+headers
+d# 8250 value counts/ms   \ For a 603 with a 33 MHz bus clock
+
+headerless
+\ XXX Put in the actual ratios when IBM gets around to documenting
+\ the encoding of the bus ratio field
+\ create 620-ratios  ? c,  ? c,  ? c,  ? c,
+: bus-ratio  ( -- n )
+   620-class?  if
+\      buscsr@ d# 22 2 bits 620-ratios + c@
+      1          \ Temporary value
+   else
+      4
+   then
+;
+headers
+\ We want "microseconds" to have a range of at least 1 second
+\ (1,000,000 microseconds) and as good a precision as possible
+\ given that constraint.  We do this by choosing multiplier and
+\ divisor values accordingly.
+0 value us-multiplier
+0 value us-divisor
+: calibrate-microseconds  ( -- )
+   \ The starting multiplier is counts/ms and the starting divisor is
+   \ 1000 (microseconds/millisecond).  We can eliminate common factors
+   \ without introducing inaccuracy, so we go ahead and do that.  The
+   \ factors of 1000 are 2x2x2x5x5x5.
+
+   d# 1000 counts/ms  ( denominator numerator )
+
+   \ Remove powers of two
+   begin  2dup or  1 and 0=  while  swap 2/ swap 2/  repeat  ( den' num' )
+
+   \ Remove powers of 5
+   begin                                    ( den num )
+      over 5 mod 0=  over 5 mod 0=  and     ( den num flag )
+   while                                    ( den num )
+      swap 5 /  swap 5 /                    ( den' num' )
+   repeat                                   ( den num )
+
+   \ At this point, if the numerator is still too large (unlikely),
+   \ we divide the numerator by the denominator and accept the loss
+   \ in precision.
+   dup d# 4294 >  if                        ( den num )
+      swap /  1 swap                        ( 1 num' )
+   then                
+
+   \ If the numerator is *still* too large, we just live with the
+   \ loss in range.  We could do something like use 64-bit arithmetic
+   \ or loop over several calls to the low-level primitive, but we will
+   \ cross that bridge when we get to it (it won't happen until we see
+   \ a processor with a timebase tick rate of > 4K ticks/microsecond;
+   \ the timebase rate is typically scaled down considerably from the
+   \ instruction rate).
+   to us-multiplier     to us-divisor
+;
+
+\ The 601 increments the RTC register pair and decrements the
+\ decrementer register by 128 counts every 128 nsec, thus their
+\ count values represent nanoseconds.  Other PowerPC processors
+\ count bus clocks, with no absolute calibration.
+: calibrate-ticker  ( -- )
+   601?  if
+      d# 1000000
+   else
+      d# 8250
+
+      \ Current PowerPC processors run the timebase at 1/4 the bus clock
+      " /" find-package  if
+         " clock-frequency" rot  get-package-property 0=  if  ( n adr len )
+            rot drop  get-encoded-int  d# 1000 /                 ( n' )
+	    bus-ratio /
+         then
+      then
+
+   then
+   to counts/ms
+   calibrate-microseconds
+;
+headerless
+
+code get-rtclu  ( -- nsec sec )
+   stwu  tos,-4(sp)
+   begin		\ Loop until we get a consistent sample
+      mfspr t1,rtcu
+      mfspr t0,rtcl
+      mfspr tos,rtcu
+      cmp  0,0,t1,tos
+   = until
+   stwu  t0,-4(sp)
+c;
+code get-tb ( -- ticks.lo ticks.hi )
+   stwu  tos,-4(sp)
+   begin		\ Loop until we get a consistent sample
+      isync
+      mftb  t1,tbu
+      mftb  t0,tb
+      mftb  tos,tbu
+      cmp  0,0,t1,tos
+   = until
+   stwu  t0,-4(sp)
+c;
+: get-msecs-601  ( -- ms )
+   get-rtclu  d# 40000000 mod  d# 1000 *  swap counts/ms / +
+;
+: get-msecs-ppc  ( -- ms )  get-tb  counts/ms um/mod nip  ;
+: (get-msecs)  ( -- ms )  601?  if  get-msecs-601  else  get-msecs-ppc  then  ;
+' (get-msecs) to get-msecs
+
+: ms-601  ( n -- )
+   d# 1000 /mod             ( msec sec )
+   swap counts/ms *  swap   ( nsec sec )
+   get-rtclu                ( nsec sec nsec sec )
+   rot +  -rot  + dup  d# 1000000000 >=  if
+      d# 1000000000 -  swap 1+
+   else
+      swap
+   then                     ( target-nsec target-sec )
+
+   begin
+      get-rtclu             ( target-nsec target-sec nsec sec )
+      2 pick  2dup u>  if  5drop exit  then	( t-n t-s n s t-s )
+      =  if
+         2 pick  ( t-n t-s n t-n )  u>=  if  2drop  exit  then
+      else
+         drop
+      then
+   again
+;
+: ms-ppc  ( n -- )
+   counts/ms um*             ( d.nsec )
+   get-tb d+                ( d.target-ticks )
+
+   begin
+      get-tb                ( d.target-ticks d.ticks )
+      2over d-              ( d.target-ticks d.diff )
+      nip  0>=
+   until
+   2drop
+;
+: (ms)  ( n -- )  601?  if  ms-601  else  ms-ppc  then  ;
+' (ms) to ms
+
+code dec!  ( #ticks -- )	\ Store the decrementer register
+   sync
+   mtspr  dec,tos
+   sync
+   lwz    tos,0(sp)
+   addi   sp,sp,1cell
+c;
+
+code dec@  ( -- #ticks )	\ Read the decrementer rgister
+   stwu   tos,-1cell(sp)
+   sync
+   mfspr  tos,dec
+c;
+code tb@    ( -- ticks.lo )
+   stwu  tos,-4(sp)
+   isync
+   mftb  tos,tb
+c;
+
+
+\ On a 60 MHz 8xx, the fixed overhead of this word is about .5 microseconds,
+\ so the actual time delay is about half a count longer.  On faster processors,
+\ the overhead might be somewhat smaller, although the multiply time, the
+\ time to enable and disable interrupts, and the time to read the time base
+\ register might not quite scale with the clock rate.
+
+\ Delay at least n microseconds.  Interrupts remain enabled.
+code unlocked-microseconds   ( #microseconds --  )
+   'user us-multiplier lwz t0,*	\ Multiplier
+   mullw  tos,t0,tos		\ Counts*125
+   'user us-divisor lwz t0,*	\ Divisor
+   divwu  tos,tos,t0		\ Counts
+   mftb   t0,tb			\ Current time
+   add    tos,tos,t0		\ Target time
+   begin
+      mftb  t0,tb		\ Get time
+      subf. t0,tos,t0		\ Compare to target using circular arithmetic
+   0>= until 			\ Spin until target time reached
+   lwz tos,0(sp)		\ Clean up stack
+   addi sp,sp,4
+c;
+
+\ Delay n microseconds with interrupts disabled.  This gives more precise
+\ timing but keeps the processor from doing other things.
+code microseconds  ( #microseconds --  )
+   mfmsr  t1
+   rlwinm t2,t1,0,17,15		\ Clear interrupt enable bit
+   mtmsr  t2			\ Disable interrupts
+
+   'user us-multiplier lwz t0,*	\ Multiplier
+   mullw  tos,t0,tos		\ Counts*125
+   'user us-divisor lwz t0,*	\ Divisor
+   divwu  tos,tos,t0		\ Counts
+   mftb   t0,tb			\ Current time
+   add    tos,tos,t0		\ Target time
+   begin
+      mftb  t0,tb		\ Get time
+      subf. t0,tos,t0		\ Compare to target using circular arithmetic
+   0>= until 			\ Spin until target time reached
+   lwz tos,0(sp)		\ Clean up stack
+   addi sp,sp,4
+
+   mtmsr  t1			\ Restore interrupts
+c;
+
+headers
+stand-init: Calibrate
+   calibrate-ticker
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/hacks.fth
===================================================================
--- cpu/ppc/hacks.fth	                        (rev 0)
+++ cpu/ppc/hacks.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,43 @@
+purpose: Little code fragments to clip out and paste in real programs as needed
+\ See license at end of file
+
+\ For startup code - displays I and D if caches on, i and d if caches off
+mfspr t0,hid0
+andi. t0,t0,h#4000
+0<> if
+   ascii D ?report
+else
+   ascii d ?report
+then
+
+mfspr t0,hid0
+andi. t0,t0,h#8000
+0<> if
+   ascii I ?report
+else
+   ascii i ?report
+then
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/htabmmu.fth
===================================================================
--- cpu/ppc/htabmmu.fth	                        (rev 0)
+++ cpu/ppc/htabmmu.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,753 @@
+purpose: HTAB paged MMU driver
+\ See license at end of file
+
+also forth definitions
+
+headers
+
+h#    1.0000 value /htab
+/htab value htab
+/htab value htab-phys
+
+headerless
+
+false value mmu64?
+h#        40 value tag-h
+h# 8000.0000 value tag-v
+              8 value /htab-entry
+/htab-entry 8 * value /htab-group
+previous definitions
+
+also
+: invalidate-pte  ( pte-adr -- )  0 swap l!  ;
+
+\ Data in exception vector area:
+\ 4f0: save-state address
+\ 4f4: PTEG roving replacement offset
+\ 4f8: physical base address of "translations" list
+\ 4fc: virtual base address of "translations" list
+
+\ Data in this cpu's exception area (exception-area)
+\  00: save r3
+\  04: save r2
+\  08: save lr
+\  0c: save exception number
+\  10: save cr
+\  14: save base
+\  18: save ip
+\  1c: save lr
+\  20-3c: save registers
+
+\ fault - r4   node - r5   offset - r6   adr - r7   end - r8
+\ Physical address 
+also assembler also register-names definitions
+warning @ warning off
+4 constant fault
+5 constant node
+6 constant offset
+7 constant adr
+8 constant end
+9 constant temp
+warning !
+previous previous definitions
+
+\ get-phys searches the "translations" list, which is the master copy of
+\ the information describing the current set of virtual to physical
+\ address translations.  The input (in r3) is the virtual address.  The
+\ output (in r3) is -1 if there was no mapping for that virtual address,
+\ or the physical word of the PTE, containing the physical page number and
+\ the mode bits, otherwise.
+
+\ Input:    r4 - virtual address of fault
+\ Output:   r3 - physical_PTE_word or -1
+\ Destroys: r4-r8
+label get-phys
+   lwz    node,h#4f8(r0)	\ Physical base address of translation list
+   lwz    offset,h#4fc(r0)	\ Virtual base address of translation list
+   ahead  begin
+      subf node,offset,node	\ Convert node virtual address to physical
+      lwz  adr,1cell(node)	\ Beginning virtual address of range
+      cmpl 0,0,adr,fault	\ Test beginning of range
+      <=  if
+         lwz  end,2cells(node)	\ Length of mapped range
+         add  end,adr,end	\ Ending virtual address of range
+         cmpl 0,0,end,fault	\ Test end of range
+         >  if
+1 L:
+	    \ We found it
+	    rlwinm  temp,fault,0,0,19	\ Zero fault address page offset bits
+	    subf    adr,adr,temp	\ Compute page offset within range
+	    lwz     r3,3cells(node)	\ Physical page#
+	    rlwinm  r3,r3,12,0,19	\ Shift page# into place
+            add     r3,r3,adr		\ physical address portion is complete
+            lwz     adr,4cells(node)	\ WIMG.PP
+	    or      r3,r3,adr		\ PTE physical word is complete
+2 L:
+	    bclr    20,0
+	 then
+
+	 \ If the ending address is 0, it really means 2^32, which is
+	 \ larger than any possible fault address.
+         cmpi 0,0,end,0
+         1 B:  =  brif
+
+      then
+
+   but then
+      lwz  node,0(node)		\ Next node
+      cmpi 0,0,node,0
+   = until
+
+   \ No translation found
+   set  r3,-1
+
+   2 B: again
+end-code
+
+\ r3:phys  r4:fault  r5:vsid  r6:pteg  r7:htab/ctr_save  r8:mask  r9:temp
+
+also assembler also register-names definitions
+warning @ warning off
+5 constant vsid
+6 constant pteg
+7 constant htab
+8 constant mask
+warning !
+previous previous definitions
+
+label find-pte  ( r4: virtual -- r5: vsid r6: 'pte )
+   mfsrin  vsid,fault		\ Get virtual segment ID
+   rlwinm  vsid,vsid,0,13,31	\ Keep the low 19 bits (omit protection bits)
+   rlwinm  pteg,fault,20,16,31	\ Move page index bits into place
+   xor     pteg,vsid,pteg	\ Compute hash value
+
+   mfspr   htab,sdr1		\ Get hash table base address and size mask
+
+mfspr   mask,pvr
+rlwinm  mask,mask,16,16,31
+cmpi    0,0,mask,20
+<> if   \ 32-bit code
+   addi    mask,r0,h#3ff	\ Set low 10 bits of mask
+   rlwimi  mask,htab,10,13,21	\ merge in upper 9 bits
+   rlwinm  mask,mask,6,7,25	\ Move up 6 bits to align with PTEG address
+
+   rlwinm  pteg,pteg,6,7,25	\ Move into place
+   and     pteg,pteg,mask	\ Compute low bits of pte
+
+   rlwinm  htab,htab,0,0,15	\ Eliminate mask bits
+   or      pteg,htab,pteg	\ Insert hash table base into the high bits
+
+   \ Now we have the address of the primary page table entry group in "pteg".
+   \ We also need to preserve "mask" in case we need to find the secondary
+   \ PTEG, and "fault" and "vsid" to generate the first word of the new PTE.
+
+   mfspr   htab,ctr		\ htab is no longer needed so we re-use it
+
+   \ Generate the tag for the first word of the new PTE
+   rlwinm  vsid,vsid,7,1,24
+   rlwimi  vsid,fault,10,26,31	\ Move bits 4-9 to 26-31
+   \ vsid is now the new PTE tag
+
+   \ In little-endian mode, addresses within a PTE are swizzled from the
+   \ viewpoint of code executing on the CPU, which does 32-bit or smaller
+   \ accesses, but not from the viewpoint of the table-search hardware,
+   \ which appears to do 64-bit accesses.  Consequently, in little-endian
+   \ mode, the tag word appears at offset 4 and the physical word at offset 0.
+   mfmsr  temp
+   andi.  temp,temp,1
+   <> if			\ Little-endian
+      addi  pteg,pteg,4		\ Tag is in second longword when in LE mode
+   then
+
+   addi   pteg,pteg,-8
+   set    temp,8
+   mtspr  ctr,temp
+   begin
+      lwzu  temp,8(pteg)
+      cmpi 0,0,temp,0
+      1 F:  >=  brif
+   countdown
+   
+   \ Didn't find room in the primary PTEG - search the secondary PTEG
+   addi   pteg,pteg,h#-38	\ Reset the lower bits
+   xor    pteg,pteg,mask	\ Invert the hash bits - to secondary PTEG
+
+   ori    vsid,vsid,h#40	\ Set the "H" bit in the tag
+
+   addi   pteg,pteg,-8
+   set    temp,8
+   mtspr  ctr,temp
+   begin
+      lwzu  temp,8(pteg)
+      cmpi 0,0,temp,0
+      1 F:  >=  brif
+   countdown
+
+   \ Didn't find room in the secondary PTEG - replace a primary entry.
+   addi   pteg,pteg,h#-38	\ Reset the lower bits
+   xor    pteg,pteg,mask	\ Invert the hash bits - back to primary PTEG
+   rlwinm vsid,vsid,0,26,24	\ Clear the "H" bit in the tag
+
+   \ It might be nice to use the statistics bits to implement a pseudo-LRU
+   \ replacement policy, but that is too complicated for now (especially
+   \ since I don't want to bother with the complexity of a periodic process
+   \ to test the bits), so I'm using a roving replacement pointer instead.
+   \ The performance difference is probably entirely negligeable in this
+   \ environment, and might favor the roving pointer anyway.
+   lwz    temp,h#4f4(r0)	\ Get replacement index
+   add    pteg,temp,pteg	\ Address of PTE to replace
+
+   addi   temp,temp,8		\ Update replacement pointer
+   cmpi   0,0,temp,h#40
+   =  if
+      set  temp,0
+   then
+   stw    temp,h#4f4(r0)
+
+   set    temp,0
+   stw    temp,0(pteg)		\ Invalidate tag word
+else
+   set     mask,h#4.0000	\ Smallest hash table size
+\ TRYME   rldcr   mask,mask,htab,45	\ Shift to actual size
+   rlwnm   mask,mask,htab,0,13	\ Shift to actual size
+   addi    mask,mask,-1         \ Convert to mask
+   rlwinm  mask,mask,0,0,24	\ Clear low 7 bits to align to PTEG base
+
+\ TRYME   rldic   pteg,pteg,7,0	\ Move hash value into place
+   rlwinm  pteg,pteg,7,0,24	\ Move hash value into place
+   and     pteg,pteg,mask	\ Compute low bits of PTE
+
+\ TRYME   rldicr  htab,htab,0,45	\ Eliminate mask bits
+   rlwinm  htab,htab,0,0,13	\ Eliminate mask bits
+   or      pteg,htab,pteg	\ Insert hash table base into the high bits
+
+   \ Now we have the address of the primary page table entry group in "pteg".
+   \ We also need to preserve "mask" in case we need to find the secondary
+   \ PTEG, and "fault" and "vsid" to generate the first word of the new PTE.
+
+   mfspr   htab,ctr		\ htab is no longer needed so we re-use it
+
+   \ Generate the tag for the first word of the new PTE
+\ TRYME  rldicr  vsid,vsid,12,51
+   rlwinm  vsid,vsid,12,0,19
+   rlwimi  vsid,fault,16,20,24	\ Move bits 4-8 to 20-24 (64-bit: okay as-is)
+   \ vsid is now the new PTE tag
+
+\ ZZZ 23/5/96 was 16
+   addi   pteg,pteg,-16   \ Account for pre-increment
+   set    temp,8
+   mtspr  ctr,temp
+   begin
+      ldu  temp,16(pteg)
+      andi. temp,temp,1		\ Test valid bit
+      1 F:  >=  brif
+   countdown
+   
+   \ Didn't find room in the primary PTEG - search the secondary PTEG
+   addi   pteg,pteg,h#-70	\ Reset the lower bits
+   xor    pteg,pteg,mask	\ Invert the hash bits - to secondary PTEG
+
+   ori    vsid,vsid,2	\ Set the "H" bit in the tag
+
+   addi   pteg,pteg,-16
+   set    temp,8
+   mtspr  ctr,temp
+   begin
+      ldu  temp,16(pteg)
+      andi. temp,temp,1		\ Test valid bit
+      1 F:  >=  brif
+   countdown
+
+   \ Didn't find room in the secondary PTEG - replace a primary entry.
+   addi   pteg,pteg,h#-70	\ Reset the lower bits
+   xor    pteg,pteg,mask	\ Invert the hash bits - back to primary PTEG
+   rlwinm vsid,vsid,0,31,29	\ Clear the "H" bit in the tag
+
+   \ It might be nice to use the statistics bits to implement a pseudo-LRU
+   \ replacement policy, but that is too complicated for now (especially
+   \ since I don't want to bother with the complexity of a periodic process
+   \ to test the bits), so I'm using a roving replacement pointer instead.
+   \ The performance difference is probably entirely negligeable in this
+   \ environment, and might favor the roving pointer anyway.
+   lwz    temp,h#4f4(r0)	\ Get replacement index
+   add    pteg,temp,pteg	\ Address of PTE to replace
+
+   addi   temp,temp,16		\ Update replacement pointer
+   cmpi   0,0,temp,h#80
+   =  if
+      set  temp,0
+   then
+   stw    temp,h#4f4(r0)
+
+   set    temp,0
+   std    temp,0(pteg)		\ Invalidate tag word
+
+\ ZZZ AEC 23/5/1996 added ; 620 errata: tlbia does not work
+\   tlbia
+   sync
+then
+
+   sync
+   tlbie  pteg
+   sync
+   tlbsync
+   sync
+
+1 L:
+   mtspr ctr,htab
+   bclr  20,0
+end-code
+
+\ Common code for HTAB ISI and DSI miss handlers.
+\ Input:  r3: virtual address
+\         r2: exception-area
+\ Output: none (returns from interrupt)
+\ Side effects:
+\    If the input virtual address is mapped, adds or replaces an HTAB entry,
+\    clearing the TLB as needed, to reflect that mapping.
+\    If the input virtual address is not mapped, transfers control to the
+\    unexpected exception handler.
+\ Destroys: nothing
+\ Requirements:
+\    The pre-trap value of R3 must be in memory location 0(sprg0)
+\    The pre-trap value of CR must be in memory location h#10(sprg0)
+\    Those register values are restored before returning.
+\ Uses:
+\    Memory location h#0c(sprg0) to store the exception address.
+\    Memory locations h#20-h#34(sprg0) for saving registers.
+
+label htab-miss-handler
+
+   stw r4,h#20(r2)   stw r5,h#24(r2)   stw r6,h#28(r2)	\ Save GPRs
+   stw r7,h#2c(r2)   stw r8,h#30(r2)   stw r9,h#34(r2)
+
+   mr    fault,r3
+
+   \ Determine the physical address, if any, to which the virtual address
+   \ that caused the fault is mapped.
+
+   get-phys  bl *		\ ( virtual -- pte-phys|-1 )
+
+   \ If there is no valid mapping for that virtual address, invoke the
+   \ unexpected exception handler.
+   cmpi    0,0,r3,-1		\ If no 
+   =  if
+      lwz r4,h#20(r2)  lwz r5,h#24(r2)  lwz r6,h#28(r2)	\ Restore GPRs
+      lwz r7,h#2c(r2)  lwz r8,h#30(r2)  lwz r9,h#34(r2)
+
+      \ Restore registers and jump to unexpected exception handler
+      lwz    r3,h#10(r2)   mtcrf  h#80,r3		\ Restore CR
+      lwz    r3,h#4f0(r0)	\ save-state address
+      mtspr  lr,r3
+      lwz    r3,h#0c(r2)	\ Exception address
+      bclr   20,0		\ branch to exception handler
+   then
+
+   find-pte  bl *   ( r4: fault-address -- r6: 'pte )
+
+   mfspr   temp,pvr
+   rlwinm  temp,temp,16,16,31
+   cmpi    0,0,temp,20
+   <> if			\ 32-bit processor
+      \ pteg now points to the tag word of an invalid PTE; replace its value
+      \ See clause 4.12.1 of the PPC architecture spec (hard-back book)
+      \ for an explanation of this sequence.
+      mfmsr  temp
+      andi.  temp,temp,1
+      <> if			\ Little-endian
+         stw    r3,-4(pteg)	\ Replace physical address portion
+      else
+         stw    r3,4(pteg)	\ Replace physical address portion
+      then
+
+      stw    vsid,0(pteg)	\ Replace the tag word with valid bit clear
+      sync
+      oris   vsid,vsid,h#8000	\ Set the valid bit
+      stw    vsid,0(pteg)	\ Replace the tag word with valid bit set
+   else			\ 64-bit processor
+      \ pteg now points to the tag word of an invalid PTE; replace its value
+      \ See clause 4.12.1 of the PPC architecture spec (hard-back book)
+      \ for an explanation of this sequence.
+      std    r3,8(pteg)		\ Replace physical address portion
+      std    vsid,0(pteg)	\ Replace the tag word with valid bit clear
+      sync
+      ori    vsid,vsid,1	\ Set the valid bit
+      std    vsid,0(pteg)	\ Replace the tag word with valid bit set
+   then
+   
+   \ Restore registers used herein
+
+   lwz r4,h#20(r2)  lwz r5,h#24(r2)  lwz r6,h#28(r2)	\ Restore GPRs
+   lwz r7,h#2c(r2)  lwz r8,h#30(r2)  lwz r9,h#34(r2)
+
+   \ Restore registers used by the generic trap preamble
+   lwz    r3,h#10(r2)   mtcrf  h#80,r3		\ Restore CR
+   lwz    r3,h#08(r2)   mtspr  lr,r3		\ Restore LR
+   lwz    r3,h#00(r2)				\ Restore r3
+   lwz    r2,h#04(r2)				\ Restore r2
+
+   \ Return from interrupt
+   rfi
+end-code
+
+\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area,
+\ r3 points to the address where the exception occured.
+label htab-isi-handler
+   stw    r3,h#0c(r2)		\ Save exception number
+   mfcr   r3
+   stw    r3,h#10(r2)		\ Save CR
+
+   \ Determine the fault type
+   mfspr   r3,srr1		\ Fault type is in SRR1 for I faults
+   rlwinm. r3,r3,0,1,1		\ Test bit 1
+   0=  if			\ Not a translation fault
+      \ Restore registers and jump to unexpected exception handler
+      lwz    r3,h#10(r2)   mtcrf  h#80,r3		\ Restore CR
+      lwz    r3,h#4f0(r0)	\ save-state address
+      mtspr  lr,r3
+      lwz    r3,h#0c(r2)	\ Exception address
+      bclr   20,0		\ branch to exception handler
+   then
+
+   mfspr  r3,srr0		\ Get fault address
+
+   htab-miss-handler  b *	\ Jump to common code
+end-code
+
+\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area,
+\ r3 points to the address where the exception occured.
+label htab-dsi-handler
+   stw    r3,h#0c(r2)		\ Save exception number
+   mfcr   r3
+   stw    r3,h#10(r2)		\ Save CR
+
+   \ Determine the fault type
+   mfspr   r3,dsisr		\ SPR18
+   rlwinm. r3,r3,0,1,1		\ Test bit 1
+   0=  if			\ Not a translation fault
+      \ Restore registers and jump to unexpected exception handler
+      lwz    r3,h#10(r2)   mtcrf  h#80,r3		\ Restore CR
+      lwz    r3,h#4f0(r0)	\ save-state address
+      mtspr  lr,r3
+      lwz    r3,h#0c(r2)	\ Exception address
+      bclr   20,0		\ branch to exception handler
+   then
+
+   mfspr  r3,dar		\ Get fault address
+
+   htab-miss-handler  b *	\ Jump to common code
+end-code
+
+previous
+
+headers
+\ sdr1@ and sdr1! are okay for 64-bit implementations if the physical
+\ address of the page table is in the lower 4GB of memory, which is a
+\ fairly safe assumption.
+code sdr1!  ( n -- )
+   mtspr  sdr1,tos
+   lwz    tos,0(sp)
+   addi   sp,sp,1cell
+c;
+code sdr1@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,sdr1
+c;
+
+headerless
+\ We could use "fill" for this, but it is slightly faster to do it this way,
+\ because we only have to touch every other word.
+code invalidate-htab-64  ( -- )
+   mfspr  t3,sdr1
+   rlwinm t3,t3,0,27,31		\ Compute hash table size from shift count
+   set    t4,h#4.0000		\ Shift count 0 means 256K
+   rlwnm  t3,t4,t3,0,31
+
+   'user htab  lwz  t0,*	\ Virtual address of hash table
+
+   \ Hardware accesses PTEs as doublewords, so address swizzling doesn't occur.
+   addi   t0,t0,-16		\ Account for pre-increment
+
+   rlwinm t3,t3,28,4,31		\ Divide by 16; we'll touch each PTE once
+   set    t2,0
+   mtspr  ctr,t3		\ Set loop count
+   begin
+      stdu t2,16(t0)		\ Clear the tag word of each PTE
+   countdown
+   mtspr  ctr,up		\ Restore CTR register
+c;
+
+\ We could use "fill" for this, but it is slightly faster to do it this way,
+\ because we only have to touch every other word.
+code invalidate-htab-32  ( -- )
+   mfspr  t3,sdr1
+   rlwinm t3,t3,16,7,15		\ Compute hash table size from mask bits
+   ori    t3,t3,h#ffff		\ MAX(hashbits,64k-1)
+   addi   t3,t3,1
+
+   'user htab  lwz  t0,*	\ Virtual address of hash table
+
+   \ Hardware accesses PTEs as doublewords, so address swizzling doesn't occur.
+   \ Consequently, when accessing a PTE from the processor, we must undo
+   \ its swizzling.
+   mfmsr  t4
+   andi.  t4,t4,1		\ Test little-endian bit
+   <> if			\ Little endian
+      addi   t0,t0,-4		\ Account for pre-increment and endianness
+   else
+      addi   t0,t0,-8		\ Account for pre-increment
+   then
+
+   rlwinm t3,t3,29,3,31		\ Divide by 8; we'll touch each PTE once
+   set    t2,0
+   mtspr  ctr,t3		\ Set loop count
+   begin
+      stwu t2,8(t0)		\ Clear the tag word of each PTE
+   countdown
+   mtspr  ctr,up		\ Restore CTR register
+c;
+
+: set-mmu  ( -- )
+   cpu-version d# 20 =  if
+      true to mmu64?
+      h#    4.0000 to /htab
+                 2 to tag-h
+                 1 to tag-v
+      d#        16 to /htab-entry
+      h#        80 to /htab-group
+   then
+;
+
+: get-htab  ( -- phys size )
+   sdr1@ dup
+   mmu64?  if
+      h# 3.ffff invert and   h# 4.0000  rot h# 1f and  lshift
+   else
+      h# ffff invert and  swap h# 1ff and  1+  d# 16 lshift
+   then
+;
+: set-htab  ( phys size -- )
+   mmu64?  if
+      log2 d# 18 -       ( phys size-code )
+   else
+      1- d# 16 rshift    ( phys size-mask )
+   then
+   or sdr1!
+;
+: init-paged-mmu  ( -- )
+   htab /htab 0  mem-claim  drop
+
+   \ We don't use invalidate-htab here because we want the HTAB to start
+   \ out completely clean, and invalidate-htab clears only the tag words.
+   htab  /htab  erase
+
+   htab-phys  /htab set-htab
+[ifdef] invalidate-tlb
+   invalidate-tlb
+[then]
+;
+
+[ifdef] shootdown-range
+\ RFE: map? should report BAT mappings and VSID too
+\ RFE: MMU driver should account for BAT mappings too
+
+: >htab-adr  ( padr -- vadr )
+   htab-phys - htab +
+   mmu64?  if  la1+  then
+   in-little-endian?  4 and xor
+;
+: htab-@  ( padr -- l )  >htab-adr l@  ;
+: htab-!  ( l padr -- )  >htab-adr l!  ;
+
+\ HTAB display tools
+
+: break-pte  ( phys-stuff tag -- false | rc.wimg.pp phys api vsid h true )
+   \ Check valid bit
+   dup tag-v and  0=  if  2drop false exit  then     ( phys-stuff tag )
+
+   \ Extract physical address and type field
+   over 9 lowbits  rot h# fff invert and   ( tags rc.wimg.pp phys )
+   rot                                     ( rc.wimg.pp phys tags )
+
+   \ Extract tag information
+   mmu64?  if
+      d# 7 5 bits  d# 23 lshift swap        ( rc.wimg.pp phys api tags )
+      \ XXX we should extract more vsid bits from the 64-bit tag
+      dup d# 12  d# 25 bits  swap           ( rc.wimg.pp phys api vsid tags )
+      1 1 bits                              ( rc.wimg.pp phys api vsid h )
+   else
+      dup h# 7f and d# 22 lshift  swap      ( rc.wimg.pp phys api tags )
+      dup 7 d# 19 bits  swap                ( rc.wimg.pp phys api vsid tags )
+      6 1 bits                              ( rc.wimg.pp phys api vsid h )
+   then
+   true
+;
+headers
+: pte@  ( adr -- phys-stuff tag )
+   dup /htab-entry 2/ +  htab-@   swap htab-@
+;
+headerless
+: hold.  ( -- )  ascii . hold  ;
+: .mode  ( mode -- )
+   push-binary
+   ."  RC.WIMG.PP: "  <# u# u# hold. 2/ u# u# u# u# hold. u# u# u#> type
+   pop-base
+;
+: .phys  ( phys -- )   push-hex ." Physical: " u. pop-base  ;
+: .pte  ( tags phys-stuff -- )
+   break-pte  if
+      push-hex
+      ." H: " .
+      ."  Virtual: " <# u# ascii , hold u#s u#> type	( rc.wimg.pp phys api )
+      d# 20 >>  (.2) type ." X.Xxxx"			( rc.wimg.pp phys )
+      pop-base
+      ."   "  .phys  .mode
+   else
+      ." Invalid"
+   then
+   cr
+;
+
+\ See, for example, figure 7-24 in the 603 manual
+\ >vsid is valid on 64-bit implementations only if the implementation
+\ also supports mtsr and mfsr, as does the 620.
+: >vsid  ( virtual -- sr )
+   d# 28 4 bits sr@  mmu64?  if  d# 24 lowbits  then
+;
+: virtual>hash  ( virtual -- tag hash )
+   dup
+   mmu64?  if
+      d# 23  5                            ( virtual bit# #bits )
+   else
+      d# 22  6                            ( virtual bit# #bits )
+   then
+   bits                                   ( virtual api )
+   mmu64?  if  7 lshift  then             ( virtual api' )
+   over >vsid  tuck                       ( virtual vsid api vsid )
+   mmu64?  if  d# 12  else  7  then       ( virtual vsid api vsid bit# )
+   lshift or  tag-v or                    ( virtual vsid tag )
+   rot d# 12 d# 16 bits                   ( vsid tag page-index )
+   rot                                    ( tag page-index vsid )
+   \ 39 or 19 bit hash codes
+   mmu64?  0=  if  h# 7ffff and  then     ( tag page-index vsid' )
+   xor                                    ( tag hash )
+;
+: hash>ptegs  ( hash -- 'pteg1 'pteg2 )
+   /htab-group *              ( hash<< )
+   get-htab 1-                ( hash<< base size-mask )
+   /htab-group 1- invert and  ( hash<< base size-mask' )
+
+   rot over and               ( base size-mask masked-hash )
+   rot or  tuck xor           ( 'pteg1 'pteg2 )
+;
+: virtual>pteg  ( virtual -- tag 'pteg1 'pteg2 )  virtual>hash hash>ptegs  ;
+
+: virtual>pte  ( virtual -- false | pte-adr true )
+   virtual>pteg  -rot                 ( 'pteg2 tag 'pteg1 )
+   /htab-group bounds  do             ( 'pteg2 tag )
+      dup i htab-@  =  if             ( 'pteg2 tag )
+         2drop i true  unloop  exit
+      then                            ( 'pteg2 tag )
+   /htab-entry +loop                  ( 'pteg2 tag )
+   tag-h or  swap                     ( tag' pteg2 )
+   /htab-group bounds  do             ( tag )
+      dup i htab-@  =  if             ( tag )
+         drop i true  unloop  exit
+      then                            ( tag )
+   /htab-entry +loop                  ( tag )
+   drop  false
+;
+: .pteg  ( 'pteg -- )  d# 64 bounds  ?do  i pte@ .pte  8 +loop  ;
+headers
+: pteg?  ( virtual -- )
+   virtual>pteg                       ( tag 'pteg1 'pteg2 )
+   swap ." Primary PTEG" cr  .pteg    ( tag 'pgeg2 )
+   ." Secondary PTEG" cr  .pteg       ( tag )
+   drop
+;
+: pte?  ( virtual -- )
+   virtual>pte  if  pte@ .pte else  ." Not in HTAB" cr  then
+;
+
+headerless
+: (shootdown-range)  ( virtual len -- )
+   \ If we have to shootdown more than about 8 pages,
+   \ it's faster to blow away the whole thing; searching
+   \ for matching PTEs is pretty time-consuming.
+   dup h# 8000 u>  if                          ( virtual len )
+      2drop
+      mmu64?  if  invalidate-htab-64  else  invalidate-htab-32  then
+      invalidate-tlb   ( )
+      exit
+   then                                        ( virtual len )
+   bounds  ?do                                 ( )
+      i virtual>pte  if  0 swap htab-!  i invalidate-tlb-entry  then
+   pagesize +loop
+;
+' (shootdown-range) to shootdown-range
+
+: (map-mode)  ( phys.. mode -- mode' )
+   >r  memory?  r>                    ( memory? mode )
+   dup -2 -1 between if               ( memory? -1 )
+      drop  if			      ( )
+         h# 12	 \ For memory, WIMG.x.PP is 0010.0.10, i.e. M=1, PP=10
+      else			      ( )
+         h# 3a	 \ For I/O, WIMG.x.PP is 0111.0.10, i.e. I=1,M=1,G=1, PP=10
+      then			      ( mode' )
+   else                               ( memory? mode )
+      nip			      ( mode )
+   then				      ( mode' )
+;
+' (map-mode) to map-mode
+
+headers
+[ifdef] NOTYET
+\ : init  ( -- )  ;
+
+\ finish-device
+
+warning @  warning off
+only forth also definitions
+: stand-init  ( -- )
+   stand-init
+   " /mmu" open-dev mmu-node !
+;
+warning !
+[then]
+
+: map?  ( virtual -- )
+[ifdef] NOTYET
+   " translate" mmu-node @ $call-method  if
+[else]
+   translate  if
+[then]
+      >r .phys r> .mode
+   else
+      ." Not mapped" cr
+   then
+;
+[then]
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/inflate.fth
===================================================================
--- cpu/ppc/inflate.fth	                        (rev 0)
+++ cpu/ppc/inflate.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,1396 @@
+purpose: Inflater - source code in Forth-assembler format
+\ See license at end of file
+
+\ The following code uses only non-privileged instructions, and knows
+\ nothing about the "operating environment" portion of the PowerPC
+\ architecture.  Please keep it that way!
+\ For use in the firmware environment, this code is typically called
+\ from a routine that handles operating-environment details, such as
+\ setting up memory mappings, turning on caches, etc.
+
+\ The body of the code below was created by disassembling the stripped
+\ output of GCC.  The script that runs the disassembler is in
+\ cpu/ppc/disinflt.fth
+
+fload ${BP}/cpu/ppc/asmtools.fth
+
+: number,  ( -- )
+   safe-parse-word                ( adr len )
+   push-hex  $number abort" Invalid argument to debug:"  pop-base  ( n )
+   be-l,
+;
+: debug:
+   0 be-l,  number, number, number, number,
+   safe-parse-word dup wbsplit c, c,           ( adr len )
+   here over allot                             ( adr len here )
+   swap move align
+   postpone \
+;
+
+start-assembling
+
+\ The following routines use Power/Open C calling conventions:
+\ e.g. arguments in r3, r4, ...
+\ r1 must point to a stack area.  r2 is ostensibly the TOC pointer,
+\ but the C code and compilation flags were carefully set up so that
+\ the generated code does not use a data segment or external linkage,
+\ so there are no references to r2 in the code below.
+
+label inflate  ( r3: &compressed-image  r4: &destination  r5: &scratch -- ... )
+               ( ... -- r3: length-of-uncompressed-image )
+    mfspr   r0,lr
+    stw     r21,h#-2c(r1)
+    stw     r22,h#-28(r1)
+    stw     r23,h#-24(r1)
+    stw     r24,h#-20(r1)
+    stw     r25,h#-1c(r1)
+    stw     r26,h#-18(r1)
+    stw     r27,h#-14(r1)
+    stw     r28,h#-10(r1)
+    stw     r29,h#-c(r1)
+    stw     r30,-8(r1)
+    stw     r31,-4(r1)
+    stw     r0,8(r1)
+    stwu    r1,h#-568(r1)
+    or      r21,r4,r4
+    or      r27,r21,r21
+    or      r30,r5,r5
+    addi    r0,r30,h#80
+    stw     r0,h#7c(r30)
+    or      r4,r30,r30
+    bl      .+h#46c 
+    addi    r0,r0,0
+    addic   r0,r0,1
+    lwz     r11,8(r30)
+    cmpi    crf1,0,r0,2
+    addi    r9,r11,1
+    stw     r9,8(r30)
+    bc      4,5,.-h#14 
+    addi    r0,r9,1
+    stw     r0,8(r30)
+    addi    r0,r0,0
+    lbz     r10,1(r11)
+    addic   r0,r0,1
+    lwz     r11,8(r30)
+    cmpi    crf1,0,r0,5
+    addi    r9,r11,1
+    stw     r9,8(r30)
+    bc      4,5,.-h#14 
+    andi.   r0,r10,8
+    bc      12,2,.+h#30 
+    addi    r0,r9,1
+    stw     r0,8(r30)
+    lbz     r0,1(r11)
+    cmpi    crf1,0,r0,0
+    bc      12,6,.+h#1c 
+    lwz     r9,8(r30)
+    addi    r0,r9,1
+    stw     r0,8(r30)
+    lbz     r0,0(r9)
+    cmpi    crf1,0,r0,0
+    bc      4,6,.-h#14 
+    addi    r26,r0,1
+    addi    r3,r0,1
+    lwz     r4,0(r30)
+    or      r5,r30,r30
+    bl      .+h#7a0 
+    or      r4,r3,r3
+    rlwinm  r25,r4,0,31,31
+    addi    r3,r0,2
+    rlwinm  r4,r4,31,1,31
+    lwz     r0,4(r30)
+    or      r5,r30,r30
+    addic   r0,r0,-1
+    stw     r0,4(r30)
+    bl      .+h#77c 
+    or      r4,r3,r3
+    rlwinm  r9,r4,0,30,31
+    rlwinm  r4,r4,30,2,31
+    cmpi    crf1,0,r9,0
+    lwz     r0,4(r30)
+    stw     r4,0(r30)
+    addic   r0,r0,-2
+    stw     r0,4(r30)
+    bc      4,6,.+h#b8 
+    addi    r3,r0,h#10
+    lwz     r0,4(r30)
+    or      r5,r30,r30
+    rlwinm  r31,r0,0,29,31
+    subf    r0,r31,r0
+    stw     r0,4(r30)
+    srw     r4,r4,r31
+    bl      .+h#738 
+    or      r4,r3,r3
+    rlwinm  r31,r4,0,16,31
+    addi    r3,r0,h#10
+    rlwinm  r4,r4,16,16,31
+    lwz     r0,4(r30)
+    or      r5,r30,r30
+    addic   r0,r0,h#-10
+    stw     r0,4(r30)
+    bl      .+h#714 
+    or      r4,r3,r3
+    nor     r0,r4,r4
+    rlwinm  r9,r0,0,16,31
+    cmp     crf1,0,r31,r9
+    bc      4,6,.+h#bc 
+    rlwinm  r4,r4,16,16,31
+    lwz     r0,4(r30)
+    cmpi    crf1,0,r9,0
+    addi    r31,r31,-1
+    addic   r0,r0,h#-10
+    stw     r0,4(r30)
+    bc      12,6,.+h#3c 
+    addi    r3,r0,8
+    or      r5,r30,r30
+    bl      .+h#6d8 
+    or      r4,r3,r3
+    stb     r4,0(r27)
+    addi    r27,r27,1
+    rlwinm  r4,r4,24,8,31
+    or      r9,r31,r31
+    lwz     r0,4(r30)
+    cmpi    crf1,0,r9,0
+    addi    r31,r31,-1
+    addic   r0,r0,-8
+    stw     r0,4(r30)
+    bc      4,6,.-h#34 
+    stw     r4,0(r30)
+    b       .+h#27c 
+    cmpi    crf1,0,r9,1
+    bc      4,6,.+h#30 
+    or      r3,r22,r22
+    addi    r4,r1,h#528
+    addi    r5,r1,h#52c
+    addi    r6,r1,h#530
+    addi    r7,r1,h#534
+    addi    r8,r1,h#38
+    or      r9,r30,r30
+    bl      .+h#d20 
+    cmpi    crf1,0,r3,0
+    bc      4,6,.+h#30 
+    b       .+h#34 
+    or      r3,r22,r22
+    addi    r4,r1,h#528
+    addi    r5,r1,h#52c
+    addi    r6,r1,h#530
+    addi    r7,r1,h#534
+    addi    r8,r1,h#38
+    or      r9,r30,r30
+    bl      .+h#e54 
+    cmpi    crf1,0,r3,0
+    bc      12,6,.+h#c 
+    addi    r25,r0,1
+    b       .+h#218 
+    lwz     r9,h#530(r1)
+    lwz     r10,0(r30)
+    lwz     r0,h#534(r1)
+    slw     r9,r26,r9
+    addi    r23,r9,-1
+    slw     r0,r26,r0
+    addic   r24,r0,-1
+    or      r4,r10,r10
+    lwz     r3,h#530(r1)
+    or      r5,r30,r30
+    bl      .+h#614 
+    or      r10,r3,r3
+    and     r9,r10,r23
+    lwz     r11,h#528(r1)
+    rlwinm  r9,r9,3,0,28
+    lbzx    r31,r9,r11
+    cmpli   crf1,0,r31,h#10
+    add     r29,r9,r11
+    bc      4,5,.+h#58 
+    cmpi    crf1,0,r31,h#63
+    bc      12,6,.+h#1c4 
+    addi    r31,r31,h#-10
+    or      r3,r31,r31
+    lbz     r4,1(r29)
+    lwz     r0,4(r30)
+    or      r5,r30,r30
+    subf    r0,r4,r0
+    stw     r0,4(r30)
+    srw     r4,r10,r4
+    bl      .+h#5c8 
+    or      r10,r3,r3
+    slw     r9,r26,r31
+    addi    r9,r9,-1
+    and     r9,r10,r9
+    lwz     r11,4(r29)
+    rlwinm  r9,r9,3,0,28
+    lbzx    r31,r9,r11
+    cmpli   crf1,0,r31,h#10
+    add     r29,r9,r11
+    bc      12,5,.-h#50 
+    cmpi    crf1,0,r31,h#10
+    lbz     r9,1(r29)
+    lwz     r0,4(r30)
+    srw     r10,r10,r9
+    subf    r0,r9,r0
+    stw     r0,4(r30)
+    bc      4,6,.+h#14 
+    lhz     r0,2(r29)
+    stb     r0,0(r27)
+    addi    r27,r27,1
+    b       .-h#ac 
+    cmpi    crf1,0,r31,h#f
+    bc      12,6,.+h#138 
+    or      r3,r31,r31
+    or      r4,r10,r10
+    or      r5,r30,r30
+    bl      .+h#55c 
+    or      r10,r3,r3
+    srw     r4,r10,r31
+    or      r5,r30,r30
+    slw     r0,r26,r31
+    addic   r0,r0,-1
+    and     r0,r10,r0
+    lwz     r3,h#534(r1)
+    lhz     r11,2(r29)
+    lwz     r9,4(r30)
+    add     r28,r11,r0
+    subf    r9,r31,r9
+    stw     r9,4(r30)
+    bl      .+h#528 
+    or      r10,r3,r3
+    and     r9,r10,r24
+    lwz     r11,h#52c(r1)
+    rlwinm  r9,r9,3,0,28
+    lbzx    r31,r9,r11
+    cmpli   crf1,0,r31,h#10
+    add     r29,r9,r11
+    bc      4,5,.+h#58 
+    cmpi    crf1,0,r31,h#63
+    bc      12,6,.+h#d8 
+    addi    r31,r31,h#-10
+    or      r3,r31,r31
+    lbz     r4,1(r29)
+    lwz     r0,4(r30)
+    or      r5,r30,r30
+    subf    r0,r4,r0
+    stw     r0,4(r30)
+    srw     r4,r10,r4
+    bl      .+h#4dc 
+    or      r10,r3,r3
+    slw     r9,r26,r31
+    addi    r9,r9,-1
+    and     r9,r10,r9
+    lwz     r11,4(r29)
+    rlwinm  r9,r9,3,0,28
+    lbzx    r31,r9,r11
+    cmpli   crf1,0,r31,h#10
+    add     r29,r9,r11
+    bc      12,5,.-h#50 
+    or      r3,r31,r31
+    lbz     r4,1(r29)
+    lwz     r0,4(r30)
+    or      r5,r30,r30
+    subf    r0,r4,r0
+    stw     r0,4(r30)
+    srw     r4,r10,r4
+    bl      .+h#494 
+    or      r10,r3,r3
+    slw     r9,r26,r31
+    addi    r9,r9,-1
+    and     r9,r10,r9
+    srw     r10,r10,r31
+    or      r11,r28,r28
+    addi    r28,r28,-1
+    cmpi    crf1,0,r11,0
+    lwz     r0,4(r30)
+    lhz     r11,2(r29)
+    subf    r0,r31,r0
+    stw     r0,4(r30)
+    add     r11,r11,r9
+    bc      12,6,.-h#1c4 
+    subf    r9,r11,r27
+    or      r0,r28,r28
+    lbz     r9,0(r9)
+    cmpi    crf1,0,r0,0
+    addi    r28,r28,-1
+    stb     r9,0(r27)
+    addi    r27,r27,1
+    bc      4,6,.-h#1c 
+    b       .-h#1e8 
+    lwz     r0,h#20(r30)
+    stw     r10,0(r30)
+    stw     r0,h#7c(r30)
+    cmpi    crf1,0,r25,0
+    bc      12,6,.-h#388 
+    subf    r3,r21,r27
+    addi    r1,r1,h#568
+    lwz     r0,8(r1)
+    mtspr   lr,r0
+    lwz     r21,h#-2c(r1)
+    lwz     r22,h#-28(r1)
+    lwz     r23,h#-24(r1)
+    lwz     r24,h#-20(r1)
+    lwz     r25,h#-1c(r1)
+    lwz     r26,h#-18(r1)
+    lwz     r27,h#-14(r1)
+    lwz     r28,h#-10(r1)
+    lwz     r29,h#-c(r1)
+    lwz     r30,-8(r1)
+    lwz     r31,-4(r1)
+    bclr    20,0
+
+    Debug:      2041 800b0300        0      49c   inflate
+
+    addi    r11,r0,0
+    stw     r11,0(r4)
+    stw     r11,4(r4)
+    stw     r3,8(r4)
+    addi    r8,r0,0
+    addi    r10,r0,3
+    lwz     r9,h#7c(r4)
+    lwz     r0,h#7c(r4)
+    stw     r9,h#c(r4)
+    addic   r0,r0,h#4c
+    stw     r0,h#7c(r4)
+    lwz     r9,h#c(r4)
+    addi    r0,r0,h#10
+    stw     r0,0(r9)
+    addi    r0,r0,h#11
+    stwu    r0,4(r9)
+    addi    r0,r0,h#12
+    stwu    r0,4(r9)
+    stwu    r11,4(r9)
+    addi    r0,r0,8
+    stwu    r0,4(r9)
+    addi    r0,r0,7
+    stwu    r0,4(r9)
+    addi    r0,r0,9
+    stwu    r0,4(r9)
+    addi    r0,r0,6
+    stwu    r0,4(r9)
+    addi    r0,r0,h#a
+    stwu    r0,4(r9)
+    addi    r0,r0,5
+    stwu    r0,4(r9)
+    addi    r0,r0,h#b
+    stwu    r0,4(r9)
+    addi    r0,r0,4
+    stwu    r0,4(r9)
+    addi    r0,r0,h#c
+    stwu    r0,4(r9)
+    addi    r0,r0,3
+    stwu    r0,4(r9)
+    addi    r0,r0,h#d
+    stwu    r0,4(r9)
+    addi    r0,r0,2
+    stwu    r0,4(r9)
+    addi    r0,r0,h#e
+    stwu    r0,4(r9)
+    addi    r0,r0,1
+    stwu    r0,4(r9)
+    addi    r0,r0,h#f
+    stw     r0,4(r9)
+    lwz     r9,h#7c(r4)
+    lwz     r0,h#7c(r4)
+    stw     r9,h#10(r4)
+    addic   r0,r0,h#40
+    stw     r0,h#7c(r4)
+    lwz     r9,h#10(r4)
+    addi    r0,r0,3
+    sth     r0,0(r9)
+    addi    r0,r0,4
+    sthu    r0,2(r9)
+    addi    r0,r0,5
+    sthu    r0,2(r9)
+    addi    r0,r0,6
+    sthu    r0,2(r9)
+    addi    r0,r0,7
+    sthu    r0,2(r9)
+    addi    r0,r0,8
+    sthu    r0,2(r9)
+    addi    r0,r0,9
+    sthu    r0,2(r9)
+    addi    r0,r0,h#a
+    sthu    r0,2(r9)
+    addi    r0,r0,h#b
+    sthu    r0,2(r9)
+    addi    r0,r0,h#d
+    sthu    r0,2(r9)
+    addi    r0,r0,h#f
+    sthu    r0,2(r9)
+    addi    r0,r0,h#11
+    sthu    r0,2(r9)
+    addi    r0,r0,h#13
+    sthu    r0,2(r9)
+    addi    r0,r0,h#17
+    sthu    r0,2(r9)
+    addi    r0,r0,h#1b
+    sthu    r0,2(r9)
+    addi    r0,r0,h#1f
+    sthu    r0,2(r9)
+    addi    r0,r0,h#23
+    sthu    r0,2(r9)
+    addi    r0,r0,h#2b
+    sthu    r0,2(r9)
+    addi    r0,r0,h#33
+    sthu    r0,2(r9)
+    addi    r0,r0,h#3b
+    sthu    r0,2(r9)
+    addi    r0,r0,h#43
+    sthu    r0,2(r9)
+    addi    r0,r0,h#53
+    sthu    r0,2(r9)
+    addi    r0,r0,h#63
+    sthu    r0,2(r9)
+    addi    r0,r0,h#73
+    sthu    r0,2(r9)
+    addi    r0,r0,h#83
+    sthu    r0,2(r9)
+    addi    r0,r0,h#a3
+    sthu    r0,2(r9)
+    addi    r0,r0,h#c3
+    sthu    r0,2(r9)
+    addi    r0,r0,h#e3
+    sthu    r0,2(r9)
+    addi    r0,r0,h#102
+    sthu    r0,2(r9)
+    addi    r0,r0,0
+    sthu    r0,2(r9)
+    addi    r9,r9,2
+    sth     r0,0(r9)
+    lwz     r9,h#7c(r4)
+    lwz     r0,h#7c(r4)
+    stw     r9,h#14(r4)
+    addic   r0,r0,h#40
+    stw     r0,h#7c(r4)
+    lwz     r9,h#14(r4)
+    addic.  r10,r10,-1
+    sth     r8,0(r9)
+    addi    r9,r9,2
+    bc      4,0,.-h#c 
+    addi    r10,r0,4
+    addi    r0,r10,-1
+    srawi   r0,r0,2
+    addze   r0,r0
+    sth     r0,0(r9)
+    sthu    r0,2(r9)
+    addi    r10,r10,4
+    cmpi    crf1,0,r10,h#1b
+    sthu    r0,2(r9)
+    sthu    r0,2(r9)
+    addi    r9,r9,2
+    bc      4,5,.-h#28 
+    addi    r11,r0,0
+    sth     r11,0(r9)
+    addi    r0,r0,h#63
+    sthu    r0,2(r9)
+    sth     r0,2(r9)
+    lwz     r9,h#7c(r4)
+    lwz     r0,h#7c(r4)
+    stw     r9,h#18(r4)
+    addic   r0,r0,h#40
+    stw     r0,h#7c(r4)
+    lwz     r9,h#18(r4)
+    addi    r0,r0,1
+    sth     r0,0(r9)
+    addi    r0,r0,2
+    sthu    r0,2(r9)
+    addi    r0,r0,3
+    sthu    r0,2(r9)
+    addi    r0,r0,4
+    sthu    r0,2(r9)
+    addi    r0,r0,5
+    sthu    r0,2(r9)
+    addi    r0,r0,7
+    sthu    r0,2(r9)
+    addi    r0,r0,9
+    sthu    r0,2(r9)
+    addi    r0,r0,h#d
+    sthu    r0,2(r9)
+    addi    r0,r0,h#11
+    sthu    r0,2(r9)
+    addi    r0,r0,h#19
+    sthu    r0,2(r9)
+    addi    r0,r0,h#21
+    sthu    r0,2(r9)
+    addi    r0,r0,h#31
+    sthu    r0,2(r9)
+    addi    r0,r0,h#41
+    sthu    r0,2(r9)
+    addi    r0,r0,h#61
+    sthu    r0,2(r9)
+    addi    r0,r0,h#81
+    sthu    r0,2(r9)
+    addi    r0,r0,h#c1
+    sthu    r0,2(r9)
+    addi    r0,r0,h#101
+    sthu    r0,2(r9)
+    addi    r0,r0,h#181
+    sthu    r0,2(r9)
+    addi    r0,r0,h#201
+    sthu    r0,2(r9)
+    addi    r0,r0,h#301
+    sthu    r0,2(r9)
+    addi    r0,r0,h#401
+    sthu    r0,2(r9)
+    addi    r0,r0,h#601
+    sthu    r0,2(r9)
+    addi    r0,r0,h#801
+    sthu    r0,2(r9)
+    addi    r0,r0,h#c01
+    sthu    r0,2(r9)
+    addi    r0,r0,h#1001
+    sthu    r0,2(r9)
+    addi    r0,r0,h#1801
+    sthu    r0,2(r9)
+    addi    r0,r0,h#2001
+    sthu    r0,2(r9)
+    addi    r0,r0,h#3001
+    sthu    r0,2(r9)
+    addi    r0,r0,h#4001
+    sthu    r0,2(r9)
+    addi    r0,r0,h#6001
+    sth     r0,2(r9)
+    lwz     r0,h#7c(r4)
+    addi    r10,r0,2
+    stw     r0,h#1c(r4)
+    lwz     r0,h#7c(r4)
+    lwz     r9,h#1c(r4)
+    addic   r0,r0,h#40
+    stw     r0,h#7c(r4)
+    sth     r11,0(r9)
+    sthu    r11,2(r9)
+    addi    r9,r9,2
+    addi    r0,r10,-1
+    srawi   r0,r0,1
+    addze   r0,r0
+    addi    r10,r10,2
+    cmpi    crf1,0,r10,h#1d
+    sth     r0,0(r9)
+    sthu    r0,2(r9)
+    addi    r9,r9,2
+    bc      4,5,.-h#20 
+    lwz     r0,h#7c(r4)
+    stw     r0,h#20(r4)
+    bclr    20,0
+
+    Debug:      2040      200        0      3a0   init_var
+
+    lwz     r0,4(r5)
+    or      r8,r3,r3
+    cmpl    crf1,0,r0,r8
+    or      r3,r4,r4
+    bclr    4,4
+    lwz     r11,8(r5)
+    lwz     r10,4(r5)
+    addi    r0,r11,1
+    stw     r0,8(r5)
+    addi    r9,r10,8
+    cmpl    crf1,0,r9,r8
+    lbz     r0,0(r11)
+    stw     r9,4(r5)
+    slw     r0,r0,r10
+    or      r3,r3,r0
+    bc      12,4,.-h#28 
+    bclr    20,0
+
+    Debug:      2040      300        0       44   NEEDBITS
+
+    cmpi    crf1,0,r5,0
+    addi    r5,r5,-1
+    bclr    12,6
+    lbz     r0,0(r4)
+    addi    r4,r4,1
+    cmpi    crf1,0,r5,0
+    addi    r5,r5,-1
+    stb     r0,0(r3)
+    addi    r3,r3,1
+    bc      4,6,.-h#18 
+    bclr    20,0
+
+    Debug:      2040      300        0       2c   memcpy
+
+    mfspr   r0,lr
+    stw     r13,h#-4c(r1)
+    stw     r14,h#-48(r1)
+    stw     r15,h#-44(r1)
+    stw     r16,h#-40(r1)
+    stw     r17,h#-3c(r1)
+    stw     r18,h#-38(r1)
+    stw     r19,h#-34(r1)
+    stw     r20,h#-30(r1)
+    stw     r21,h#-2c(r1)
+    stw     r22,h#-28(r1)
+    stw     r23,h#-24(r1)
+    stw     r24,h#-20(r1)
+    stw     r25,h#-1c(r1)
+    stw     r26,h#-18(r1)
+    stw     r27,h#-14(r1)
+    stw     r28,h#-10(r1)
+    stw     r29,h#-c(r1)
+    stw     r30,-8(r1)
+    stw     r31,-4(r1)
+    stw     r0,8(r1)
+    stwu    r1,h#-5f8(r1)
+    stw     r4,h#588(r1)
+    or      r13,r5,r5
+    stw     r6,h#58c(r1)
+    stw     r7,h#590(r1)
+    or      r7,r8,r8
+    or      r8,r9,r9
+    or      r6,r10,r10
+    addi    r9,r1,h#38
+    addi    r11,r0,0
+    addi    r0,r0,0
+    stwx    r11,r9,r0
+    addic   r0,r0,4
+    cmpli   crf1,0,r0,h#40
+    bc      4,5,.-h#c 
+    or      r24,r3,r3
+    addi    r11,r1,h#38
+    lwz     r28,h#588(r1)
+    lwz     r9,0(r24)
+    rlwinm  r9,r9,2,0,29
+    lwzx    r0,r9,r11
+    addi    r24,r24,4
+    addic   r0,r0,1
+    stwx    r0,r9,r11
+    addic.  r28,r28,-1
+    bc      12,2,.+h#8 
+    b       .-h#20 
+    lwz     r0,h#38(r1)
+    lwz     r12,h#588(r1)
+    cmp     crf1,0,r0,r12
+    bc      4,6,.+h#14 
+    stw     r28,0(r7)
+    stw     r28,0(r8)
+    addi    r3,r0,0
+    b       .+h#4a0 
+    addi    r30,r0,1
+    addi    r11,r1,h#38
+    addi    r9,r0,4
+    lwz     r22,0(r8)
+    lwzx    r0,r9,r11
+    cmpi    crf1,0,r0,0
+    bc      4,6,.+h#14 
+    addi    r30,r30,1
+    cmpli   crf1,0,r30,h#10
+    addi    r9,r9,4
+    bc      4,5,.-h#18 
+    or      r19,r30,r30
+    subfc   r9,r19,r22
+    subfe   r9,r9,r9
+    nand    r9,r9,r9
+    nor     r0,r9,r9
+    and     r0,r0,r19
+    and     r9,r22,r9
+    or      r22,r9,r0
+    addi    r28,r0,h#10
+    addi    r11,r1,h#38
+    addi    r9,r0,h#40
+    lwzx    r0,r9,r11
+    cmpi    crf1,0,r0,0
+    bc      4,6,.+h#14 
+    addi    r9,r9,-4
+    addic.  r28,r28,-1
+    bc      12,2,.+h#8 
+    b       .-h#18 
+    or      r14,r28,r28
+    subfc   r9,r22,r14
+    subfe   r9,r9,r9
+    nand    r9,r9,r9
+    nor     r0,r9,r9
+    and     r0,r0,r14
+    and     r9,r22,r9
+    or      r22,r9,r0
+    cmpl    crf1,0,r30,r14
+    stw     r22,0(r8)
+    addi    r0,r0,1
+    slw     r18,r0,r30
+    bc      4,4,.+h#2c 
+    addi    r11,r1,h#38
+    rlwinm  r9,r30,2,0,29
+    lwzx    r0,r9,r11
+    subf.   r18,r0,r18
+    bc      12,0,.+h#2c 
+    addi    r30,r30,1
+    cmpl    crf1,0,r30,r28
+    addi    r9,r9,4
+    rlwinm  r18,r18,1,0,30
+    bc      12,4,.-h#1c 
+    rlwinm  r11,r28,2,0,29
+    addi    r9,r1,h#38
+    lwzx    r0,r11,r9
+    subf.   r18,r0,r18
+    bc      4,0,.+h#c 
+    addi    r3,r0,2
+    b       .+h#3b4 
+    add     r0,r18,r0
+    stwx    r0,r11,r9
+    addi    r30,r0,0
+    stw     r30,h#548(r1)
+    addi    r24,r1,h#3c
+    addi    r9,r1,h#54c
+    addic.  r28,r28,-1
+    bc      4,2,.+h#8 
+    b       .+h#24 
+    lwz     r0,0(r24)
+    addi    r24,r24,4
+    add     r30,r30,r0
+    stw     r30,0(r9)
+    addi    r9,r9,4
+    addic.  r28,r28,-1
+    bc      12,2,.+h#8 
+    b       .-h#1c 
+    or      r24,r3,r3
+    addi    r28,r0,0
+    addi    r10,r1,h#38
+    lwz     r30,0(r24)
+    cmpi    crf1,0,r30,0
+    addi    r24,r24,4
+    bc      12,6,.+h#24 
+    rlwinm  r9,r30,2,0,29
+    add     r9,r9,r10
+    lwz     r11,h#50c(r9)
+    addi    r0,r11,1
+    stw     r0,h#50c(r9)
+    rlwinm  r11,r11,2,0,29
+    add     r11,r11,r10
+    stw     r28,h#8c(r11)
+    lwz     r12,h#588(r1)
+    addi    r28,r28,1
+    cmpl    crf1,0,r28,r12
+    bc      12,4,.-h#3c 
+    addi    r28,r0,0
+    stw     r28,h#544(r1)
+    addi    r24,r1,h#c4
+    addi    r20,r0,-1
+    neg     r27,r22
+    cmp     crf1,0,r19,r14
+    stw     r28,h#84(r1)
+    addi    r26,r0,0
+    addi    r25,r0,0
+    bc      12,5,.+h#2c0 
+    addi    r17,r1,h#38
+    addi    r16,r0,1
+    addi    r12,r1,h#80
+    stw     r12,h#598(r1)
+    rlwinm  r15,r19,2,0,29
+    lwzx    r21,r15,r17
+    or      r0,r21,r21
+    cmpi    crf1,0,r0,0
+    addi    r21,r21,-1
+    bc      12,6,.+h#288 
+    stw     r15,h#594(r1)
+    add     r9,r27,r22
+    cmp     crf1,0,r19,r9
+    bc      4,5,.+h#120 
+    rlwinm  r0,r20,2,0,29
+    add     r29,r0,r17
+    or      r23,r0,r0
+    addi    r29,r29,4
+    addi    r23,r23,4
+    addi    r20,r20,1
+    or      r27,r9,r9
+    subf    r25,r27,r14
+    subfc   r9,r25,r22
+    subfe   r9,r9,r9
+    nand    r9,r9,r9
+    nor     r11,r9,r9
+    subf    r30,r27,r19
+    slw     r31,r16,r30
+    addi    r0,r21,1
+    cmpl    crf1,0,r31,r0
+    and     r11,r11,r22
+    and     r9,r25,r9
+    or      r25,r9,r11
+    bc      4,5,.+h#40 
+    addi    r30,r30,1
+    addi    r0,r31,-1
+    cmpl    crf1,0,r30,r25
+    lwz     r12,h#594(r1)
+    subf    r31,r21,r0
+    add     r9,r17,r12
+    bc      4,4,.+h#24 
+    lwzu    r0,4(r9)
+    rlwinm  r31,r31,1,0,30
+    cmpl    crf1,0,r31,r0
+    bc      4,5,.+h#14 
+    addi    r30,r30,1
+    cmpl    crf1,0,r30,r25
+    subf    r31,r0,r31
+    bc      12,4,.-h#1c 
+    slw     r25,r16,r30
+    addi    r0,r25,1
+    rlwinm  r0,r0,3,0,28
+    lwz     r26,h#7c(r6)
+    cmpi    crf1,0,r20,0
+    add     r0,r0,r26
+    stw     r0,h#7c(r6)
+    addi    r9,r26,8
+    stw     r9,0(r7)
+    addi    r7,r26,4
+    addi    r0,r0,0
+    stw     r0,4(r26)
+    or      r26,r9,r9
+    stw     r26,h#4c(r29)
+    bc      12,6,.+h#4c 
+    stw     r28,h#50c(r29)
+    stb     r22,h#7d(r1)
+    addi    r0,r30,h#10
+    stb     r0,h#7c(r1)
+    stw     r26,h#80(r1)
+    subf    r0,r22,r27
+    srw     r30,r28,r0
+    addi    r4,r1,h#7c
+    addi    r5,r0,8
+    lwz     r12,h#598(r1)
+    rlwinm  r3,r30,3,0,28
+    lwzx    r0,r23,r12
+    stw     r6,h#59c(r1)
+    stw     r7,h#5a0(r1)
+    add     r3,r3,r0
+    bl      .-h#408 
+    lwz     r6,h#59c(r1)
+    lwz     r7,h#5a0(r1)
+    add     r9,r27,r22
+    cmp     crf1,0,r19,r9
+    bc      12,5,.-h#10c 
+    lwz     r12,h#588(r1)
+    addi    r0,r1,h#c4
+    rlwinm  r9,r12,2,0,29
+    add     r0,r0,r9
+    cmpl    crf1,0,r24,r0
+    subf    r0,r27,r19
+    stb     r0,h#7d(r1)
+    bc      12,4,.+h#10 
+    addi    r0,r0,h#63
+    stb     r0,h#7c(r1)
+    b       .+h#64 
+    lwz     r0,0(r24)
+    cmpl    crf1,0,r0,r13
+    bc      4,4,.+h#28 
+    subfic  r0,r0,h#ff
+    subfe   r0,r0,r0
+    rlwinm  r9,r0,0,28,31
+    nor     r0,r0,r0
+    rlwinm  r0,r0,0,27,27
+    or      r9,r9,r0
+    stb     r9,h#7c(r1)
+    lwz     r0,0(r24)
+    b       .+h#2c 
+    subf    r0,r13,r0
+    lwz     r12,h#590(r1)
+    rlwinm  r0,r0,1,0,30
+    lhzx    r0,r12,r0
+    stb     r0,h#7c(r1)
+    lwz     r0,0(r24)
+    lwz     r12,h#58c(r1)
+    subf    r0,r13,r0
+    rlwinm  r0,r0,1,0,30
+    lhzx    r0,r12,r0
+    addi    r24,r24,4
+    sth     r0,h#7e(r1)
+    srw     r30,r28,r27
+    cmpl    crf1,0,r30,r25
+    subf    r0,r27,r19
+    slw     r31,r16,r0
+    bc      4,4,.+h#40 
+    rlwinm  r0,r30,3,0,28
+    add     r29,r0,r26
+    or      r3,r29,r29
+    addi    r4,r1,h#7c
+    addi    r5,r0,8
+    stw     r6,h#59c(r1)
+    stw     r7,h#5a0(r1)
+    bl      .-h#4dc 
+    add     r30,r30,r31
+    cmpl    crf1,0,r30,r25
+    rlwinm  r0,r31,3,0,28
+    add     r29,r29,r0
+    lwz     r6,h#59c(r1)
+    lwz     r7,h#5a0(r1)
+    bc      12,4,.-h#30 
+    addi    r0,r19,-1
+    slw     r30,r16,r0
+    and.    r0,r28,r30
+    bc      12,2,.+h#14 
+    xor     r28,r28,r30
+    rlwinm  r30,r30,31,1,31
+    and.    r0,r28,r30
+    bc      4,2,.-h#c 
+    xor     r28,r28,r30
+    slw     r0,r16,r27
+    addic   r0,r0,-1
+    rlwinm  r9,r20,2,0,29
+    add     r11,r9,r17
+    lwz     r9,h#50c(r11)
+    and     r0,r28,r0
+    cmp     crf1,0,r0,r9
+    bc      12,6,.+h#2c 
+    addi    r10,r0,1
+    addi    r11,r11,-4
+    subf    r27,r22,r27
+    slw     r0,r10,r27
+    addic   r0,r0,-1
+    lwz     r9,h#50c(r11)
+    and     r0,r28,r0
+    cmp     crf1,0,r0,r9
+    addi    r20,r20,-1
+    bc      4,6,.-h#20 
+    or      r0,r21,r21
+    cmpi    crf1,0,r0,0
+    addi    r21,r21,-1
+    bc      4,6,.-h#27c 
+    addi    r19,r19,1
+    cmp     crf1,0,r19,r14
+    addi    r15,r15,4
+    bc      4,5,.-h#2a4 
+    neg     r0,r18
+    and     r0,r0,r18
+    cntlzw  r0,r0
+    subfic  r0,r0,h#20
+    neg     r0,r0
+    rlwinm  r0,r0,1,31,31
+    xori    r3,r14,1
+    neg     r12,r3
+    and     r12,r12,r3
+    cntlzw  r12,r12
+    subfic  r12,r12,h#20
+    or      r3,r12,r12
+    neg     r3,r3
+    rlwinm  r3,r3,1,31,31
+    and     r3,r0,r3
+    addi    r1,r1,h#5f8
+    lwz     r0,8(r1)
+    mtspr   lr,r0
+    lwz     r13,h#-4c(r1)
+    lwz     r14,h#-48(r1)
+    lwz     r15,h#-44(r1)
+    lwz     r16,h#-40(r1)
+    lwz     r17,h#-3c(r1)
+    lwz     r18,h#-38(r1)
+    lwz     r19,h#-34(r1)
+    lwz     r20,h#-30(r1)
+    lwz     r21,h#-2c(r1)
+    lwz     r22,h#-28(r1)
+    lwz     r23,h#-24(r1)
+    lwz     r24,h#-20(r1)
+    lwz     r25,h#-1c(r1)
+    lwz     r26,h#-18(r1)
+    lwz     r27,h#-14(r1)
+    lwz     r28,h#-10(r1)
+    lwz     r29,h#-c(r1)
+    lwz     r30,-8(r1)
+    lwz     r31,-4(r1)
+    bclr    20,0
+
+    Debug:      2041 80130800        0      5d8   huft_build
+
+    mfspr   r0,lr
+    stw     r28,h#-10(r1)
+    stw     r29,h#-c(r1)
+    stw     r30,-8(r1)
+    stw     r31,-4(r1)
+    stw     r0,8(r1)
+    stwu    r1,h#-48(r1)
+    or      r11,r4,r4
+    or      r28,r5,r5
+    or      r29,r7,r7
+    or      r31,r8,r8
+    or      r30,r9,r9
+    addi    r9,r0,8
+    addi    r0,r0,h#23c
+    stwx    r9,r31,r0
+    addic.  r0,r0,-4
+    bc      4,0,.-h#8 
+    addi    r3,r0,h#90
+    addi    r9,r0,9
+    addi    r0,r0,h#240
+    addi    r3,r3,1
+    cmpi    crf1,0,r3,h#ff
+    stwx    r9,r31,r0
+    addic   r0,r0,4
+    bc      4,5,.-h#10 
+    cmpi    crf1,0,r3,h#117
+    bc      12,5,.+h#20 
+    addi    r9,r0,7
+    rlwinm  r0,r3,2,0,29
+    addi    r3,r3,1
+    cmpi    crf1,0,r3,h#117
+    stwx    r9,r31,r0
+    addic   r0,r0,4
+    bc      4,5,.-h#10 
+    cmpi    crf1,0,r3,h#11f
+    bc      12,5,.+h#1c 
+    addi    r0,r0,8
+    rlwinm  r3,r3,2,0,29
+    stwx    r0,r3,r31
+    addi    r3,r3,4
+    cmpi    crf1,0,r3,h#47c
+    bc      4,5,.-h#c 
+    addi    r0,r0,7
+    stw     r0,0(r6)
+    or      r3,r31,r31
+    addi    r4,r0,h#120
+    addi    r5,r0,h#101
+    or      r8,r11,r11
+    or      r9,r6,r6
+    lwz     r6,h#10(r30)
+    lwz     r7,h#14(r30)
+    or      r10,r30,r30
+    bl      .-h#6c8 
+    or.     r3,r3,r3
+    bc      4,2,.+h#48 
+    addi    r9,r0,5
+    addi    r0,r0,0
+    stwx    r9,r31,r0
+    addic   r0,r0,4
+    cmpi    crf1,0,r0,h#74
+    bc      4,5,.-h#c 
+    addi    r0,r0,5
+    stw     r0,0(r29)
+    or      r3,r31,r31
+    addi    r4,r0,h#1e
+    addi    r5,r0,0
+    or      r8,r28,r28
+    or      r9,r29,r29
+    lwz     r6,h#18(r30)
+    lwz     r7,h#1c(r30)
+    or      r10,r30,r30
+    bl      .-h#714 
+    addi    r1,r1,h#48
+    lwz     r0,8(r1)
+    mtspr   lr,r0
+    lwz     r28,h#-10(r1)
+    lwz     r29,h#-c(r1)
+    lwz     r30,-8(r1)
+    lwz     r31,-4(r1)
+    bclr    20,0
+
+    Debug:      2041 80040700        0      140   huft_fixed
+
+    mfspr   r0,lr
+    stw     r16,h#-40(r1)
+    stw     r17,h#-3c(r1)
+    stw     r18,h#-38(r1)
+    stw     r19,h#-34(r1)
+    stw     r20,h#-30(r1)
+    stw     r21,h#-2c(r1)
+    stw     r22,h#-28(r1)
+    stw     r23,h#-24(r1)
+    stw     r24,h#-20(r1)
+    stw     r25,h#-1c(r1)
+    stw     r26,h#-18(r1)
+    stw     r27,h#-14(r1)
+    stw     r28,h#-10(r1)
+    stw     r29,h#-c(r1)
+    stw     r30,-8(r1)
+    stw     r31,-4(r1)
+    stw     r0,8(r1)
+    stwu    r1,h#-78(r1)
+    or      r20,r4,r4
+    or      r21,r5,r5
+    or      r23,r6,r6
+    or      r16,r7,r7
+    or      r25,r8,r8
+    or      r28,r9,r9
+    addi    r3,r0,5
+    lwz     r4,0(r28)
+    or      r5,r28,r28
+    bl      .-h#874 
+    or      r30,r3,r3
+    addi    r3,r0,5
+    rlwinm  r4,r30,27,5,31
+    lwz     r0,4(r28)
+    or      r5,r28,r28
+    addic   r0,r0,-5
+    stw     r0,4(r28)
+    rlwinm  r0,r30,0,27,31
+    addic   r19,r0,h#101
+    bl      .-h#89c 
+    or      r30,r3,r3
+    addi    r3,r0,4
+    rlwinm  r4,r30,27,5,31
+    lwz     r0,4(r28)
+    or      r5,r28,r28
+    addic   r0,r0,-5
+    stw     r0,4(r28)
+    rlwinm  r0,r30,0,27,31
+    addic   r18,r0,1
+    bl      .-h#8c4 
+    or      r30,r3,r3
+    rlwinm  r10,r30,0,28,31
+    rlwinm  r30,r30,28,4,31
+    subfic  r11,r19,h#11e
+    subfe   r11,r11,r11
+    neg     r11,r11
+    subfic  r9,r18,h#1e
+    subfe   r9,r9,r9
+    neg     r9,r9
+    or.     r8,r11,r9
+    lwz     r0,4(r28)
+    addi    r29,r10,4
+    addic   r0,r0,-4
+    stw     r0,4(r28)
+    bc      4,2,.+h#2fc 
+    addi    r31,r0,0
+    cmpl    crf1,0,r31,r29
+    bc      4,4,.+h#4c 
+    addi    r3,r0,3
+    or      r4,r30,r30
+    or      r5,r28,r28
+    bl      .-h#91c 
+    or      r30,r3,r3
+    rlwinm  r9,r31,2,0,29
+    addi    r31,r31,1
+    lwz     r11,h#c(r28)
+    rlwinm  r0,r30,0,29,31
+    lwzx    r9,r9,r11
+    cmpl    crf1,0,r31,r29
+    rlwinm  r9,r9,2,0,29
+    stwx    r0,r9,r25
+    lwz     r0,4(r28)
+    rlwinm  r30,r30,29,3,31
+    addic   r0,r0,-3
+    stw     r0,4(r28)
+    bc      12,4,.-h#44 
+    cmpli   crf1,0,r31,h#12
+    bc      12,5,.+h#28 
+    addi    r10,r0,0
+    rlwinm  r11,r31,2,0,29
+    addi    r31,r31,1
+    lwz     r9,h#c(r28)
+    cmpli   crf1,0,r31,h#12
+    lwzx    r0,r11,r9
+    rlwinm  r0,r0,2,0,29
+    stwx    r10,r25,r0
+    bc      4,5,.-h#1c 
+    addi    r0,r0,7
+    stw     r0,0(r23)
+    or      r3,r25,r25
+    addi    r4,r0,h#13
+    addi    r5,r0,h#13
+    addi    r6,r0,0
+    addi    r7,r0,0
+    or      r8,r20,r20
+    or      r9,r23,r23
+    or      r10,r28,r28
+    bl      .-h#900 
+    or.     r29,r3,r3
+    bc      12,2,.+h#c 
+    cmpi    crf1,0,r29,1
+    bc      12,6,.+h#240 
+    addi    r26,r0,0
+    addi    r29,r0,0
+    add     r24,r19,r18
+    lwz     r0,0(r23)
+    cmpl    crf1,0,r29,r24
+    addi    r9,r0,1
+    slw     r9,r9,r0
+    addi    r17,r9,-1
+    bc      4,4,.+h#1d4 
+    addi    r22,r0,0
+    addi    r27,r0,0
+    or      r4,r30,r30
+    lwz     r3,0(r23)
+    or      r5,r28,r28
+    bl      .-h#9f8 
+    or      r30,r3,r3
+    and     r9,r30,r17
+    lwz     r0,0(r20)
+    rlwinm  r9,r9,3,0,28
+    add     r9,r9,r0
+    stw     r9,0(r21)
+    lbz     r31,1(r9)
+    lwz     r0,4(r28)
+    subf    r0,r31,r0
+    stw     r0,4(r28)
+    lwz     r9,0(r21)
+    srw     r30,r30,r31
+    lhz     r31,2(r9)
+    cmpli   crf1,0,r31,h#f
+    bc      12,5,.+h#18 
+    or      r26,r31,r31
+    stwx    r26,r27,r25
+    addi    r27,r27,4
+    addi    r29,r29,1
+    b       .+h#164 
+    cmpi    crf1,0,r31,h#10
+    bc      4,6,.+h#74 
+    addi    r3,r0,2
+    or      r4,r30,r30
+    or      r5,r28,r28
+    bl      .-h#a60 
+    or      r30,r3,r3
+    rlwinm  r11,r30,0,30,31
+    addi    r31,r11,3
+    add     r9,r29,r31
+    lwz     r0,4(r28)
+    cmpl    crf1,0,r9,r24
+    rlwinm  r30,r30,30,2,31
+    addic   r0,r0,-2
+    stw     r0,4(r28)
+    bc      12,5,.+h#174 
+    or      r0,r31,r31
+    cmpi    crf1,0,r0,0
+    addi    r31,r11,2
+    bc      12,6,.+h#114 
+    rlwinm  r9,r29,2,0,29
+    stwx    r26,r9,r25
+    addi    r9,r9,4
+    or      r0,r31,r31
+    cmpi    crf1,0,r0,0
+    addi    r27,r27,4
+    addi    r29,r29,1
+    addi    r31,r31,-1
+    bc      4,6,.-h#1c 
+    b       .+h#ec 
+    cmpi    crf1,0,r31,h#11
+    bc      4,6,.+h#74 
+    addi    r3,r0,3
+    or      r4,r30,r30
+    or      r5,r28,r28
+    bl      .-h#ad8 
+    or      r30,r3,r3
+    rlwinm  r11,r30,0,29,31
+    addi    r31,r11,3
+    add     r9,r29,r31
+    lwz     r0,4(r28)
+    cmpl    crf1,0,r9,r24
+    rlwinm  r30,r30,29,3,31
+    addic   r0,r0,-3
+    stw     r0,4(r28)
+    bc      12,5,.+h#fc 
+    or      r0,r31,r31
+    cmpi    crf1,0,r0,0
+    addi    r31,r11,2
+    bc      12,6,.+h#98 
+    rlwinm  r9,r29,2,0,29
+    stwx    r22,r9,r25
+    addi    r9,r9,4
+    or      r0,r31,r31
+    cmpi    crf1,0,r0,0
+    addi    r27,r27,4
+    addi    r29,r29,1
+    addi    r31,r31,-1
+    bc      4,6,.-h#1c 
+    b       .+h#70 
+    addi    r3,r0,7
+    or      r4,r30,r30
+    or      r5,r28,r28
+    bl      .-h#b48 
+    or      r30,r3,r3
+    rlwinm  r11,r30,0,25,31
+    addi    r31,r11,h#b
+    add     r9,r29,r31
+    lwz     r0,4(r28)
+    cmpl    crf1,0,r9,r24
+    rlwinm  r30,r30,25,7,31
+    addic   r0,r0,-7
+    stw     r0,4(r28)
+    bc      12,5,.+h#8c 
+    or      r0,r31,r31
+    cmpi    crf1,0,r0,0
+    addi    r31,r11,h#a
+    bc      12,6,.+h#28 
+    rlwinm  r9,r29,2,0,29
+    stwx    r22,r9,r25
+    addi    r9,r9,4
+    or      r0,r31,r31
+    cmpi    crf1,0,r0,0
+    addi    r27,r27,4
+    addi    r29,r29,1
+    addi    r31,r31,-1
+    bc      4,6,.-h#1c 
+    addi    r26,r0,0
+    cmpl    crf1,0,r29,r24
+    bc      12,4,.-h#1c4 
+    stw     r30,0(r28)
+    or      r3,r25,r25
+    or      r4,r19,r19
+    addi    r5,r0,h#101
+    or      r8,r20,r20
+    lwz     r0,h#20(r28)
+    or      r9,r23,r23
+    stw     r0,h#7c(r28)
+    addi    r0,r0,9
+    stw     r0,0(r9)
+    lwz     r6,h#10(r28)
+    lwz     r7,h#14(r28)
+    or      r10,r28,r28
+    bl      .-h#b3c 
+    or.     r29,r3,r3
+    bc      12,2,.+h#14 
+    or      r3,r29,r29
+    b       .+h#48 
+    addi    r3,r0,1
+    b       .+h#40 
+    addi    r0,r0,6
+    stw     r0,0(r16)
+    rlwinm  r3,r19,2,0,29
+    add     r3,r25,r3
+    or      r4,r18,r18
+    addi    r5,r0,0
+    or      r8,r21,r21
+    or      r9,r16,r16
+    lwz     r6,h#18(r28)
+    lwz     r7,h#1c(r28)
+    or      r10,r28,r28
+    bl      .-h#b84 
+    or.     r29,r3,r3
+    bc      12,2,.+h#8 
+    or      r3,r29,r29
+    addi    r1,r1,h#78
+    lwz     r0,8(r1)
+    mtspr   lr,r0
+    lwz     r16,h#-40(r1)
+    lwz     r17,h#-3c(r1)
+    lwz     r18,h#-38(r1)
+    lwz     r19,h#-34(r1)
+    lwz     r20,h#-30(r1)
+    lwz     r21,h#-2c(r1)
+    lwz     r22,h#-28(r1)
+    lwz     r23,h#-24(r1)
+    lwz     r24,h#-20(r1)
+    lwz     r25,h#-1c(r1)
+    lwz     r26,h#-18(r1)
+    lwz     r27,h#-14(r1)
+    lwz     r28,h#-10(r1)
+    lwz     r29,h#-c(r1)
+    lwz     r30,-8(r1)
+    lwz     r31,-4(r1)
+    bclr    20,0
+
+    Debug:      2041 80100700        0      48c   huft_dynamic
+
+\ I'm not sure what this is; perhaps part of the TOC, or something like that
+\ The code above doesn't appear to depend on it.
+    h# 0 be-l,  h# 153c be-l,  h# 0 be-l,  
+
+end-code
+
+end-assembling
+
+writing inflate.bin
+asm-base  here over -  ofd @ fputs
+ofd @ fclose
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/initpgm.fth
===================================================================
--- cpu/ppc/initpgm.fth	                        (rev 0)
+++ cpu/ppc/initpgm.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,50 @@
+purpose: Generic tools for load image handlers
+\ See license at end of file
+
+: +base  ( n -- adr )  load-base +  ;
+
+: (init-program)  ( pc sp -- )
+   clear-save-area  state-valid on
+   \ PowerPC calling conventions store the link register at SP+8,
+   \ so we start with r1 a little below the top of the allocated region
+   h# 20 - to %r1  to %pc
+   cif-handler to %r5
+
+   msr@  interrupt-enable-bit invert and  to %msr
+
+   restartable? on
+   true to already-go?
+;
+
+dev /client-services
+: chain  ( len args entry size virt -- )
+   release                                       ( len args entry )
+   h# 8000 alloc-mem h# 8000 +  (init-program)   ( len args )
+   to %r6  to %r7
+   go
+;
+device-end
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/kerncode.fth
===================================================================
--- cpu/ppc/kerncode.fth	                        (rev 0)
+++ cpu/ppc/kerncode.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,1479 @@
+purpose: Kernel code words
+\ See license at end of file
+
+\ In the portions of the code than are used while incrementally compiling on
+\ the host system, we use "subfc" instead of "subf" instructions, because the
+\ POWER, as opposed to PowerPC, instruction set architecture does not have
+\ "subf".  This allows us to compile on POWER-based RS6000 systems.
+\ In code that is only used in a target firmware environment, we can use "subf"
+\ "subf" may execute somewhat faster than "subfc", because the carry bit
+\ represents an interaction between the integer unit and the branch unit,
+\ but the difference is likely to be insignificant in the Forth environment.
+\ However, there are cases in interrupt handlers where "subfc" modification
+\ of the carry bit represents an undesireable change to the value of the
+\ XER register, complicating the process of restoring the state of the
+\ interrupted code.
+
+meta
+hex
+
+\ Allocate and clear the initial user area image
+mlabel init-user-area
+setup-user-area
+
+extend-meta-assembler
+
+\ ---- Assembler macros that reside in the host environment
+\ and assemble code for the target environment
+
+\ Forth Virtual Machine registers
+
+\ Note that the Forth Stack Pointer (r31) is NOT the same register that
+\ C uses for the stack frame pointer (r1).
+
+register-names definitions
+
+decimal
+:-h t0   20 ;-h  :-h t1 21 ;-h  :-h t2  22 ;-h  :-h t3 23 ;-h
+:-h t4   24 ;-h  :-h t5 25 ;-h
+:-h base 26 ;-h  :-h up 27 ;-h  :-h tos 28 ;-h  :-h ip 29 ;-h
+:-h rp   30 ;-h  :-h sp 31 ;-h
+:-h w    t5 ;-h
+:-h t6   19 ;-h
+hex
+
+
+\ Constants defining virtual machine implementation parameters
+
+constant-names definitions
+
+also meta  /n-t  previous   ( /n-t )
+            constant-h  1cell	\ Offsets into the stack
+1cell  -1 * constant-h -1cell
+1cell   2 * constant-h  2cells
+1cell   3 * constant-h  3cells
+1cell   4 * constant-h  4cells
+1cell   5 * constant-h  5cells
+
+1cell       constant-h  /cf	\ Size of a code field (except for "create")
+/cf    -1 * constant-h -/cf
+
+1cell       constant-h  /token	\ Size of a compiled word reference
+/token -1 * constant-h -/token
+
+1cell       constant-h  /branch	\ Size of a branch offset
+
+/token  2 * constant-h  /ccf	\ Size of a "create" code field
+
+/cf 1cell + constant-h  /cf+1cell \ Location of second half of 
+
+previous previous definitions
+
+\ assembler macros for common sequences
+extend-meta-assembler
+
+:-h next-tail1      " add t1,t1,base  mtspr lr,t1  bclr 20,0"  evaluate  ;-h
+:-h next-tail       " lwzux t1,w,base  next-tail1"             evaluate  ;-h
+:-h push-tos        " stwu tos,-1cell(sp)"                     evaluate  ;-h
+:-h push-t0         " stwu t0,-1cell(sp)"                      evaluate  ;-h
+:-h pop-tos         " lwz  tos,0(sp)      addi sp,sp,1cell"    evaluate  ;-h
+:-h pop1            " lwz  tos,1cell(sp)  addi sp,sp,2cells"   evaluate  ;-h
+:-h pop2            " lwz  tos,2cells(sp) addi sp,sp,3cells"   evaluate  ;-h
+:-h second-to-t0    " lwz  t0,0(sp)"                           evaluate  ;-h
+:-h pop-to-t0       " second-to-t0        addi sp,sp,1cell"    evaluate  ;-h
+:-h double-tos      " add  tos,tos,tos"                        evaluate  ;-h
+:-h third-to-t1     " lwz  t1,1cell(sp)"                       evaluate  ;-h
+:-h user#-to-t0     " lwz  t0,/cf(w)"                          evaluate  ;-h
+:-h take-branch     " lwz  t0,/branch(ip)  add ip,ip,t0"       evaluate  ;-h
+:-h skip-branch     " addi ip,ip,/branch"                      evaluate  ;-h
+:-h literal-to-tos  " lwzu tos,/token(ip)"                     evaluate  ;-h
+:-h literal-to-t0   " lwzu t0,/token(ip)"                      evaluate  ;-h
+:-h rdrop           " addi rp,rp,1cell"                        evaluate  ;-h
+:-h rdrop3          " addi rp,rp,3cells"                       evaluate  ;-h
+
+\ We create the shared code for the "next" routine so that:
+\ a) It will be in RAM for speed (ROM is often slow)
+\ b) We can use the user pointer as its base address, for quick jumping
+
+also forth
+compilation-base  here-t			\ Save meta dictionary pointer
+0 dp-t !  userarea-t is compilation-base	\ Point it to user area
+previous
+
+mlabel (next)   \ Shared code for next; will be copied into user area
+   lwzu    w,/token(ip)
+   next-tail
+end-code
+
+also forth
+dp-t !  is compilation-base  previous		\ Restore meta dict. pointer
+
+d# 32 equ #user-init		\ Leaves space for the shared "next"
+
+only forth also labels also meta also assembler definitions
+
+\ assembler macro to assemble next
+:-h next   " bcctr   20,0"  evaluate  ;-h
+
+:-h c;  next end-code  ;-h
+
+previous definitions
+
+code-field: docolon
+   stwu  ip,-1cell(rp)	\ Push the ip register on the return stack
+   mr    ip,w		\ Set ip to apf of the colon definition
+c;
+
+code-field: dovariable
+   push-tos
+   addi  tos,w,/cf	\ Put pfa in top-of-stack register
+c;
+
+code-field: dolabel
+
+   push-tos
+   addi  tos,w,/cf	\ Put pfa in top-of-stack register
+c;
+
+code-field: douser
+   push-tos
+   user#-to-t0
+   add   tos,t0,up	\ Add the base address of the user area
+c;
+
+code-field: dovalue
+   push-tos
+   user#-to-t0
+   lwzx  tos,t0,up	\ Get the contents of the user area location
+c;
+
+code-field: dodefer
+   user#-to-t0
+   lwzx  w,t0,up	\ Get the acf stored in that user location
+   next-tail
+end-code
+
+code-field: doconstant
+   push-tos
+   lwz   tos,/cf(w)	\ Get the constant's value
+c;
+
+code-field: do2constant
+   push-tos
+   lwzu  tos,/cf(w)	\ Get the constant's value
+   push-tos		\ Put it on the memory stack
+   lwz   tos,1cell(w)	\ Get the top constant's value
+c;
+
+code-field: dodoes
+   \ The child word's code field contains the token of dodoes, followed
+   \ by the token of the does clause.
+
+   push-tos
+   addi  tos,w,/ccf		\ Put pfa in top-of-stack register
+   lwz   w,/cf(w)		\ Set w to acf of the definition
+   next-tail
+end-code
+
+:-h code-cf        ( -- )  here /token + aligned  token,-t  align-t  ;-h
+:-h label-cf       ( -- )  dolabel    token,-t  align-t  ;-h
+:-h colon-cf       ( -- )  docolon    token,-t  ;-h
+:-h constant-cf    ( -- )  doconstant token,-t  ;-h
+:-h variable-cf    ( -- )  dovariable token,-t  ;-h
+:-h user-cf        ( -- )  douser     token,-t  ;-h
+:-h value-cf       ( -- )  dovalue    token,-t  ;-h
+:-h defer-cf       ( -- )  dodefer    token,-t  ;-h
+:-h startdoes      ( -- )  colon-cf             ;-h
+:-h start;code     ( -- )  code-cf		;-h
+:-h create-cf      ( -- )  dodoes     token,-t  compile-t noop  ;-h
+:-h vocabulary-cf  ( -- )  dodoes     token,-t  compile-t <vocabulary>  ;-h
+
+meta definitions
+
+\ dovariable constant dovariable
+\ dodoes     constant dodoes
+
+code (lit)  (s -- n )
+   push-tos
+   literal-to-tos
+c;
+code (wlit)  (s -- n )
+   push-tos
+   literal-to-tos
+c;
+
+\ Execute a Forth word given a code field address
+code execute   (s acf -- )
+   mr      w,tos
+   pop-tos
+   lwz     t1,0(w)	\ Read the contents of the code field
+   next-tail1
+end-code
+
+\ High level branch. The branch offset is compiled in-line.
+code branch (s -- )
+mlabel bran1
+   take-branch
+c;
+
+\ High level conditional branch.
+code ?branch (s f -- )  \ Takes the branch if the flag is false
+   cmpi    0,0,tos,0
+   pop-tos
+
+   bran1   0= brif
+
+   skip-branch
+c;
+
+\ Run time word for loop
+code (loop)  (s -- )
+   lwz     t0,0(rp)
+   addic.  t1,t0,1	\ Increment index
+   stw     t1,0(rp)	\ Write back the loop index
+   bran1   0>=  brif	\ Result still positive; continue looping
+   cmpi    0,0,t0,0	\ Result negative, so check operand
+   bran1   0<   brif	\ If operand is negative too, continue looping
+
+   \ The internal "i" value went from positive to negative, so the loop ends
+   rdrop3		\ remove loop params from stack
+   skip-branch
+c;
+
+\ Run time word for +loop
+code (+loop) (s increment -- )
+   lwz     t0,0(rp)
+   add     t1,t0,tos	\ increment loop index
+   stw     t1,0(rp)	\ Write back the loop index
+   xor.    t3,t0,tos	\ Compare operand signs
+   pop-tos
+   bran1   0<  brif	\ Operand signs different
+
+   xor.    t2,t1,t0	\ Compare result with an operand
+   bran1   0>=  brif	\ Result has same sign as operand; continue looping
+
+   \ The result sign differs from the operand signs; so the loop ends
+   rdrop3		\ remove loop params from stack
+   skip-branch
+c;
+
+\ Run time word for do
+code (do)  (s l i -- )
+   mr      t1,tos		\ i in t1 
+   second-to-t0			\ l in t0
+   pop1				\ Finish popping stack
+mlabel pd0 ( -- r: loop-end-offset l+0x8000 i-l-0x8000 )
+   stwu    ip,-1cell(rp)	\ remember the do offset address
+   addi    ip,ip,/branch	\ Skip the do offset
+   addis   t0,t0,h#-8000	\ Bias by h#8000.0000
+   stwu    t0,-1cell(rp)	\ Push biased limit on return stack
+   subfc   t1,t0,t1		\ ( Use subfc for POWER compatibility)
+   stwu    t1,-1cell(rp)	\ Push biased index on return stack
+c;
+meta
+
+\ Run time word for ?do
+code (?do)  (s l i -- )
+   second-to-t0			\ l in t0
+   mr      t1,tos		\ i in t1
+   pop1				\ Finish popping stack
+   cmp     0,0,t0,t1
+   pd0     <>  brif
+
+   take-branch
+c;
+
+\ Loop index for current do loop
+code i  (s -- n )
+   push-tos
+   lwz     tos,0(rp)
+   lwz     t0,1cell(rp)
+   add     tos,tos,t0
+c;
+
+\ Loop index for next enclosing do loop
+code j   (s -- n )
+   push-tos
+   lwz     tos,12(rp)
+   lwz     t0,16(rp)
+   add     tos,tos,t0
+c;
+
+code (leave)  (s -- )
+mlabel pleave
+   lwz     ip,2cells(rp)	\ Get the address of the ending offset
+   rdrop3			\ get rid of the loop indices
+
+   take-branch
+c;
+
+code (?leave)  (s f -- )
+   cmpi    0,0,tos,0
+   pop-tos
+   pleave  0<>  brif
+c;
+
+code unloop  ( -- )  rdrop3  c;  \ Discard the loop indices
+
+code (of)  ( selector test -- [ selector ] )
+   pop-to-t0		\ Test in tos, Selector in t0
+   cmp     0,0,t0,tos
+   mr      tos,t0	\ Copy selector to tos
+   =  if
+      pop-tos		\ Overwrite tos if selector matches
+      skip-branch
+      next
+   then
+
+   take-branch
+c;
+
+\ (endof) is the same as branch, and (endcase) is the same as drop,
+\ but redefining them this way makes the decompiler much easier.
+code (endof)    (s -- )
+   take-branch
+c;
+code (endcase)  (s n -- )
+   pop-tos
+c;
+
+assembler
+mlabel dofalse
+   addi    tos,r0,0
+   next
+meta
+
+\ Convert a character to a digit according to the current base
+code digit  (s char base -- digit true | char false )
+   mr      t0,tos		\ base in t0
+   lwz     tos,0(sp)		\ char in tos
+   addic.  tos,tos,h#-30	\ convert to number \  30 is ascii 0
+   dofalse 0<  brif		\ Anything less than ascii 0 isn't a digit
+   cmpi    0,0,tos,10		\ Test for >= 10
+   0>=  if			\ Try for a letter representing a digit
+      ascii A ascii 0 -  cmpi    0,0,tos,*
+      dofalse <  brif		\ bad if > '9' and < 'A'
+      ascii a ascii 0 -  cmpi    0,0,tos,*  \ >= 'a'
+      >=  if
+         ascii a ascii 0 -  d# 10 -  negate  addi  tos,tos,*
+      else
+         ascii A ascii 0 -  d# 10 -  negate  addi  tos,tos,*
+      then
+   then
+   cmp     0,0,tos,t0		\ Compare digit to base
+   dofalse 0>= brif		\ Error if digit is bigger than base
+   stw     tos,0(sp)		\ Replace the char on the stack with the digit
+   addi    tos,r0,-1		\ True to indicate success
+c;
+
+\ Copy cnt characters starting at from-addr to to-addr.  Copying is done
+\ strictly from low to high addresses, so be careful of overlap between the
+\ two buffers.
+
+code cmove  ( src dst cnt -- )  \ Copy from bottom to top
+   second-to-t0		\ Dst into t0
+   third-to-t1		\ Src into t1
+
+   cmpi  0,0,tos,0
+   0<> if
+      addi  t0,t0,-1    \ Account for pre-incrementing
+      addi  t1,t1,-1    \ Account for pre-incrementing
+      mfspr t2,ctr	\ Save count register
+      mtspr ctr,tos	\ Count in count register
+      begin
+         lbzu  t3,1(t1)	\ Load byte
+	 stbu  t3,1(t0)	\ Store byte
+      countdown		\ Decrement & Branch if nonzero
+      mtspr ctr,t2	\ Restore count register
+   then
+
+   pop2
+c;
+
+code cmove>  ( src dst cnt -- )  \ Copy from top to bottom
+   second-to-t0		\ Dst into t0
+   third-to-t1		\ Src into t1
+
+   cmpi  0,0,tos,0
+   0<> if
+      add   t0,t0,tos	\ Top of dst range
+      add   t1,t1,tos	\ Top of src range
+      mfspr t2,ctr	\ Save count register
+      mtspr ctr,tos	\ Count in count register
+      begin
+         lbzu t3,-1(t1)	\ Load byte
+	 stbu t3,-1(t0)	\ Store byte
+      countdown		\ Decrement & Branch if nonzero
+      mtspr ctr,t2	\ Restore count register
+   then
+
+   pop2
+c;
+
+code lshift  (s n1 cnt -- n2 )  pop-to-t0   slw  tos,t0,tos  c;
+code rshift  (s n1 cnt -- n2 )  pop-to-t0   srw  tos,t0,tos  c;
+code <<      (s n1 cnt -- n2 )  pop-to-t0   slw  tos,t0,tos  c;
+code >>      (s n1 cnt -- n2 )  pop-to-t0   srw  tos,t0,tos  c;
+code >>a     (s n1 cnt -- n2 )  pop-to-t0   sraw tos,t0,tos  c;
+
+code and  (s n1 n2 -- n3 )   pop-to-t0   and  tos,tos,t0  c;
+code or   (s n1 n2 -- n3 )   pop-to-t0   or   tos,tos,t0  c;
+code xor  (s n1 n2 -- n3 )   pop-to-t0   xor  tos,tos,t0  c;
+
+code +    (s n1 n2 -- n3 )   pop-to-t0   add   tos,tos,t0  c;
+
+\ ( Use subfc for POWER compatibility)
+code -    (s n1 n2 -- n3 )   pop-to-t0   subfc tos,tos,t0  c;
+
+code min   (s n1 n2 -- n3 )
+   pop-to-t0   cmp  0,0,t0,tos   < if   mr tos,t0   then
+c;
+code max   (s n1 n2 -- n3 )
+   pop-to-t0   cmp  0,0,t0,tos   > if   mr tos,t0   then
+c;
+code umin   (s n1 n2 -- n3 )
+   pop-to-t0   cmpl  0,0,t0,tos   < if   mr tos,t0   then
+c;
+code umax   (s n1 n2 -- n3 )
+   pop-to-t0   cmpl  0,0,t0,tos   > if   mr tos,t0   then
+c;
+
+code invert  (s n1 -- n2 )   nor tos,tos,tos  c;
+code negate  (s n1 -- n2 )   neg tos,tos  c;
+code abs   (s n1 -- n2 )   cmpi  0,0,tos,0   0< if  neg tos,tos  then  c;
+
+code up@  (s -- addr )  push-tos  mr tos,up  c;
+code sp@  (s -- addr )  push-tos  mr tos,sp  c;
+code rp@  (s -- addr )  push-tos  mr tos,rp  c;
+code up!  (s addr -- )  mr up,tos  pop-tos  c;
+code sp!  (s addr -- )  mr sp,tos  pop-tos  c;
+code rp!  (s addr -- )  mr rp,tos  pop-tos  c;
+
+code >r   (s n -- )  stwu tos,-1cell(rp)  pop-tos  c;
+code r>   (s -- n )  push-tos  lwz tos,0(rp)  rdrop  c;
+code r@   (s -- n )  push-tos  lwz tos,0(rp)  c;
+
+code 2>r  (s n1 n2 -- )
+   second-to-t0  stwu t0,-1cell(rp)  stwu tos,-1cell(rp)  pop1
+c;
+code 2r>  (s -- n1 n2 )
+   push-tos  lwz tos,1cell(rp)  push-tos  lwz tos,0(rp)  addi rp,rp,2cells
+c;
+code 2r@  (s -- n1 n2 )
+   push-tos  lwz tos,1cell(rp)  push-tos  lwz tos,0(rp)
+c;
+
+code ip>  (s -- n )  push-tos  lwz tos,0(rp)  rdrop  addi tos,tos,/token  c;
+code ip@  (s -- n )  push-tos  lwz tos,0(rp)         addi tos,tos,/token  c;
+code >ip  (s n -- )  addi tos,tos,-/token  stwu tos,-1cell(rp)  pop-tos  c;
+code ip>token  ( ip -- token-adr )  c;
+
+code exit   (s -- )  lwz ip,0(rp)  rdrop  c;
+code unnest (s -- )  lwz ip,0(rp)  rdrop  c;
+
+code tuck  (s n1 n2 -- n2 n1 n2 )  second-to-t0  push-t0  stw tos,1cell(sp)  c;
+code nip   (s n1 n2 -- n2 )  addi  sp,sp,1cell  c;
+code flip  (s w1 -- w2 )  \ byte swap
+   rlwinm   t0,tos,24,24,31	\ high half to low half
+   rlwimi   t0,tos,8,16,23	\ low to high and insert
+   mr       tos,t0
+c;
+
+assembler definitions
+
+\ macro to assemble code to leave a flag on the stack
+:-h leaveflag  (s condition -- )
+  " if  addi tos,r0,-1  else  addi tos,r0,0  then" evaluate
+;-h
+
+:-h compare   " pop-to-t0  cmp  0,0,t0,tos" evaluate  ;-h
+:-h compareu  " pop-to-t0  cmpl 0,0,t0,tos" evaluate  ;-h
+:-h compare0  "            cmpi 0,0,tos,0"  evaluate  ;-h
+
+meta definitions
+code 0<   (s n -- f )      compare0  0<  leaveflag  c;
+code 0>   (s n -- f )      compare0  0>  leaveflag  c;
+code 0<=  (s n -- f )      compare0  0<= leaveflag  c;
+code 0>=  (s n -- f )      compare0  0>= leaveflag  c;
+code 0=   (s n -- f )      compare0  0=  leaveflag  c;
+code 0<>  (s n -- f )      compare0  0<> leaveflag  c;
+
+code =    (s n1 n2 -- f )  compare   =   leaveflag  c;
+code <>   (s n1 n2 -- f )  compare   <>  leaveflag  c;
+
+code <    (s n1 n2 -- f )  compare   <   leaveflag  c;
+code >=   (s n1 n2 -- f )  compare   >=  leaveflag  c;
+code >    (s n1 n2 -- f )  compare   >   leaveflag  c;
+code <=   (s n1 n2 -- f )  compare   <=  leaveflag  c;
+code u<   (s n1 n2 -- f )  compareu  <   leaveflag  c;
+code u>=  (s n1 n2 -- f )  compareu  >=  leaveflag  c;
+code u>   (s n1 n2 -- f )  compareu  >   leaveflag  c;
+code u<=  (s n1 n2 -- f )  compareu  <=  leaveflag  c;
+
+code drop  (s n -- )      pop-tos    c;
+code dup   (s n -- n n )  push-tos   c;
+code over  (s n1 n2 -- n1 n2 n1 )  push-tos  lwz tos,1cell(sp)  c;
+code swap  (s n1 n2 -- n2 n1 )  second-to-t0  stw tos,0(sp)  mr tos,t0  c;
+code rot  (s n1 n2 n3 -- n2 n3 n1 )
+   second-to-t0
+   third-to-t1
+   stw  t0,1cell(sp)
+   stw  tos,0(sp)
+   mr   tos,t1
+c;
+code -rot  (s n1 n2 n3 -- n3 n1 n2 )
+   second-to-t0
+   third-to-t1
+   stw  tos,1cell(sp)
+   stw  t1,0(sp)
+   mr   tos,t0
+c;
+code 2drop  (s d -- )   pop1  c;
+code 2dup   (s d -- d d )  second-to-t0  push-tos  push-t0  c;
+code 2over  (s d1 d2 -- d1 d2 d1 )
+   push-tos
+   lwz  tos,12(sp)
+   push-tos
+   lwz  tos,12(sp)
+c;
+code 2swap  (s d1 d2 -- d2 d1 )
+   lwz  t2,2cells(sp)
+   third-to-t1
+   second-to-t0
+   stw  t0,2cells(sp)
+   stw  tos,1cell(sp)
+   stw  t2,0(sp)
+   mr   tos,t1
+c;
+code 3drop  (s n1 n2 n3 -- )  pop2  c;
+code 3dup   (s n1 n2 n3 -- n1 n2 n3 n1 n2 n3 )
+   third-to-t1
+   second-to-t0
+   push-tos
+   stwu t1,-1cell(sp)
+   push-t0
+c;
+code 4drop  (s n1 n2 n3 n4 -- )
+   lwz  tos,3cells(sp)   addi sp,sp,4cells
+c;
+code 5drop  (s n1 n2 n3 n4 n5 -- )
+   lwz  tos,4cells(sp)   addi sp,sp,5cells
+c;
+
+code pick   (s nm ... n1 n0 k -- nm ... n2 n0 nk )
+   add   tos,tos,tos
+   add   tos,tos,tos  \ Multiply by /n
+   lwzx  tos,tos,sp
+c;  
+ 
+code 1+  (s n1 -- n2 )  addi  tos,tos,1   c;
+code 2+  (s n1 -- n2 )  addi  tos,tos,2   c;
+code 1-  (s n1 -- n2 )  addi  tos,tos,-1  c;
+code 2-  (s n1 -- n2 )  addi  tos,tos,-2  c;
+
+code 2/  (s n1 -- n2 )  srawi tos,tos,1   c;
+code u2/ (s n1 -- n2 )  rlwinm tos,tos,31,1,31  c;
+code 4/  (s n1 -- n2 )  srawi tos,tos,2   c;
+code 2*  (s n1 -- n2 )  rlwinm tos,tos,1,0,30  c;
+code 4*  (s n1 -- n2 )  rlwinm tos,tos,2,0,29  c;
+code 8*  (s n1 -- n2 )  rlwinm tos,tos,3,0,28  c;
+
+code on  (s addr -- )  addi t0,r0,-1  stw t0,0(tos)  pop-tos  c;
+code off (s addr -- )  addi t0,r0,0   stw t0,0(tos)  pop-tos  c;
+
+code +!  (s n addr -- )
+   second-to-t0
+   lwz  t1,0(tos)
+   add  t1,t1,t0
+   stw  t1,0(tos)
+   pop1
+c;
+
+code @    (s adr -- n )  lwz tos,0(tos)  c; \ longword aligned
+code l@   (s adr -- l )  lwz tos,0(tos)  c; \ longword aligned
+code w@   (s adr -- w )  lhz tos,0(tos)  c; \ 16-bit word aligned
+code <w@  (s adr -- w )  lha tos,0(tos)  c; \ with sign extension
+code c@   (s adr -- c )  lbz tos,0(tos)  c;
+code be-w@   ( a -- w )
+   lbz t0,0(tos)
+   lbz tos,1(tos)
+   rlwimi tos,t0,8,16,23
+c;
+code le-w@   ( a -- w )
+   lbz t0,1(tos)
+   lbz tos,0(tos)
+   rlwimi tos,t0,8,16,23
+c;
+
+code !   (s n adr -- )  second-to-t0  stw t0,0(tos)  pop1  c;
+code l!  (s n adr -- )  second-to-t0  stw t0,0(tos)  pop1  c;
+code w!  (s w adr -- )  second-to-t0  sth t0,0(tos)  pop1  c;
+code c!  (s c adr -- )  second-to-t0  stb t0,0(tos)  pop1  c;
+code be-w!   ( w a -- )
+   second-to-t0
+   rlwinm  t1,t0,24,24,31	\ high byte
+   stb t1,0(tos)
+   stb t0,1(tos)
+   pop1
+c;
+code le-w!   ( w a -- )
+   second-to-t0
+   rlwinm  t1,t0,24,24,31	\ high byte
+   stb t1,1(tos)
+   stb t0,0(tos)
+   pop1
+c;
+
+[ifdef] 64bit-hardware
+[else]
+\ XXX Use 64-bit oper
+: d@  (s adr -- low high )  dup na1+ @  swap @  ;
+: d!  (s low high adr -- )  tuck !  na1+ !  ;
+[then]
+
+: instruction!  (s n adr -- )  tuck !  /l sync-cache  ;
+
+code 2@  (s adr -- d )  lwz t0,1cell(tos)  push-t0  lwz tos,0(tos)  c;
+code 2!  (s d adr -- )
+   second-to-t0
+   stw  t0,0(tos)
+   lwz  t0,1cell(sp)
+   stw  t0,1cell(tos)
+   pop2
+c;
+
+code fill (s start-adr count char -- )
+			\ char in tos
+   second-to-t0	\ count in t0
+   third-to-t1	\ dst in t1
+    
+   cmpli  0,0,t0,h#1000	\ Optimize only if the count is large
+   >=  if
+      or    r0,t1,t0	\ Collect low bits of count and address
+      andi. r0,r0,3	\ Optimize only if the address and count are aligned
+      0=  if
+         addi  t1,t1,-1cell		\ Account for pre-increment
+         rlwinm  t0,t0,30,2,31		\ Divide count by 4
+         rlwimi  tos,tos,8,16,23	\ Replicate low byte into low halfword
+         rlwimi  tos,tos,16,0,15	\ Replicate low halfword into word
+         mfspr t2,ctr	\ Save CTR
+         mtspr ctr,t0
+         begin
+            stwu tos,1cell(t1)
+         countdown
+         mtspr ctr,t2
+
+         pop2 next
+      then
+
+   then
+
+   cmpi 0,0,t0,0
+   0<> if
+      addi  t1,t1,-1	\ Account for pre-increment
+      mfspr t2,ctr	\ Save CTR
+      mtspr ctr,t0
+      begin
+         stbu tos,1(t1)	\ Store byte
+      countdown		\ Decrement and Branch if nonzero
+      mtspr ctr,t2
+   then
+
+   pop2
+c;
+
+code noop (s -- )  c;
+
+code lowbyte   (s n -- low )   andi. tos,tos,h#ff  c;
+
+code wbsplit   (s w -- b.low b.high )   \ split a word into two bytes
+   andi. t0,tos,h#ff
+   push-t0
+   rlwinm  tos,tos,24,24,31
+c;
+code bwjoin   (s b.low b.high -- w )
+   pop-to-t0
+   andi. t0,t0,h#ff
+   rlwimi t0,tos,8,16,23
+   mr     tos,t0
+c;
+code lwsplit   (s l -- w.low w.high )  \ split a long into two words
+   andi. t0,tos,h#ffff
+   push-t0
+   rlwinm  tos,tos,16,16,31
+c;
+code wljoin   (s w.low w.high -- l )
+   pop-to-t0
+   rlwimi t0,tos,16,0,15
+   mr     tos,t0
+c;
+
+1 constant /c
+2 constant /w
+4 constant /l
+/l constant /n
+
+code ca+  (s addr index -- addr+index*/c )
+   pop-to-t0
+   add  tos,tos,t0
+c;
+code wa+  (s addr index -- addr+index*/w )
+   pop-to-t0
+   add  tos,tos,tos
+   add  tos,tos,t0
+c;
+code la+  (s addr index -- addr+index*/l )
+   pop-to-t0
+   add  tos,tos,tos
+   add  tos,tos,tos
+   add  tos,tos,t0
+c;
+code na+  (s addr index -- addr+index*/n )
+   pop-to-t0
+   add  tos,tos,tos
+   add  tos,tos,tos
+   add  tos,tos,t0
+c;
+code ta+  (s addr index -- addr+index*/t )
+   pop-to-t0
+   add  tos,tos,tos
+   add  tos,tos,tos
+   add  tos,tos,t0
+c;
+
+code ca1+  (s addr -- addr+/w )      addi tos,tos,1       c;
+code char+ (s addr -- addr+/w )      addi tos,tos,1       c;
+code wa1+  (s addr -- addr+/w )      addi tos,tos,2       c;
+code la1+  (s addr -- addr+/l )      addi tos,tos,4       c;
+code na1+  (s addr -- addr+/n )      addi tos,tos,1cell   c;
+code cell+ (s addr -- addr+/n )      addi tos,tos,1cell   c;
+code ta1+  (s addr -- addr+/token )  addi tos,tos,/token  c;
+
+code /c*   (s n -- n*/c )  c;
+code chars (s n -- n*/c )  c;
+code /w*   (s n -- n*/w )  add  tos,tos,tos  c;
+code /l*   (s n -- n*/l )  add  tos,tos,tos  add  tos,tos,tos  c;
+code /n*   (s n -- n*/n )  add  tos,tos,tos  add  tos,tos,tos  c;
+code cells (s n -- n*/n )  add  tos,tos,tos  add  tos,tos,tos  c;
+
+code upc   (s char -- upper-case-char )
+   ascii a   cmpi 0,0,tos,*  >= if
+      ascii z   cmpi 0,0,tos,*  <= if
+	 addi tos,tos,h#-20
+      then
+   then
+c;
+code lcc   (s char -- upper-case-char )
+   ascii A   cmpi 0,0,tos,*  >= if
+      ascii Z   cmpi 0,0,tos,*  <= if
+	 addi tos,tos,h#20
+      then
+   then
+c;
+
+code c at +  (s adr -- adr' char )  addi t0,tos,1  push-t0  lbz tos,0(tos)  c;
+
+code comp  ( addr1 addr2 len -- -1 | 0 | 1 )
+   second-to-t0		\ addr2
+   third-to-t1		\ addr1
+   addi sp,sp,2cells
+   mr t2,tos		\ len
+   set tos,0		\ default result
+   
+   addi  t0,t0,-1    \ Account for pre-incrementing
+   addi  t1,t1,-1    \ Account for pre-incrementing
+   begin
+      cmpi  0,0,t2,0   0<> while
+      addi  t2,t2,-1
+      lbzu  t3,1(t0)	\ Load byte
+      lbzu  t4,1(t1)	\ Load byte
+      cmp  0,0,t3,t4  <> if	\ mismatch
+	 < if  addi tos,tos,1  else  addi tos,tos,-1  then
+	 next
+      then
+    repeat
+c;
+
+: caps-comp  (s addr1 addr2 len -- -1 | 0 | 1 )
+\ XXX optimize me
+   rot 0 swap  2swap    ( 0 addr1 addr2 len )
+   bounds  ?do                                            ( 0 addr1' )
+      c at + lcc  i c@ lcc  <>  if                           ( 0 addr1' )
+         nip  dup 1- c@ lcc  i c@ lcc  <
+         if  -1  else  1  then                            ( addr1' flag )
+	 swap leave                                       ( flag addr1' )
+      then                                                ( 0 addr1' )
+   loop
+   drop
+;
+
+code pack  ( str-adr len dest -- dest )
+   second-to-t0		\ len
+   third-to-t1		\ str-adr
+   addi  sp,sp,2cells
+   mr  t2,tos		\ dest
+   stb  t0,0(tos)	\ requires length < 256
+   
+   cmpi  0,0,t0,0
+   0<> if
+      addi  t1,t1,-1	\ Account for pre-incrementing
+      mfspr t4,ctr	\ Save count register
+      mtspr ctr,t0	\ Count in count register
+      begin
+         lbzu  t3,1(t1)	\ Load byte
+	 stbu  t3,1(t2)	\ Store byte
+      countdown		\ Decrement & Branch if nonzero
+      set   t3,0
+      stbu  t3,1(t2)	\ Store a null byte at the end
+      mtspr ctr,t4	\ Restore count register
+   then
+c;
+
+code (')  (s -- acf )  push-tos  literal-to-tos  add tos,tos,base  c;
+
+\ Modifies caller's ip to skip over an in-line string
+code skipstr (s -- adr len)
+   push-tos
+   lwz   t0,0(rp)	\ Get string address in t0
+   lbzu  tos,/token(t0)	\ Get length byte in tos
+   addi  t0,t0,1	\ Address of data bytes
+   push-t0	\ Push adr
+
+   \ Now we have to skip the string
+   add   t0,t0,tos	\ Scr now points past the last data byte
+
+\ ! We don't want to add 4 because IP is pre-incremented inside NEXT
+\  addi  t0,t0,4	\ Round up to token boundary + null byte (4= #align)
+
+   rlwinm t0,t0,0,0,29	\ Round down to token boundary
+   stw   t0,0(rp)	\ Put the modified ip back
+c;
+
+code (")  (s -- adr len)
+   push-tos
+   lbzu  tos,/token(ip)	\ Get length byte in tos
+   addi  ip,ip,1	\ Address of data bytes
+   stwu  ip,-1cell(sp)	\ Push adr
+
+   \ Now we have to skip the string
+   add   ip,ip,tos	\ ip now points past the last data byte
+
+\ ! We don't want to add 4 because IP is pre-incremented inside NEXT
+\  addi  ip,ip,4	\ Round up to a token boundary, plus null byte (#talign
+
+   rlwinm ip,ip,0,0,29
+c;
+
+code count  (s adr -- adr+1 len )
+   addi  tos,tos,1
+   lbz   t0,-1(tos)
+   push-tos
+   mr    tos,t0
+c;
+
+code origin  (s -- addr )  push-tos  mr tos,base  c;
+
+code origin+  (s n -- adr )  add  tos,base,tos  c;
+code origin-  (s n -- adr )  subf tos,base,tos  c;
+
+: acf-align  (s -- )
+   begin  here #acf-align 1- and  while  0 c,  repeat
+   here 'lastacf token!
+;
+
+headerless
+
+\ Place the "standard" code field
+
+: set-cf  (s action-adr -- )  acf-align  origin+  token,  ;
+
+headers
+\ : place-cf  (s action-adr -- )  acf-align  token,  ;
+\ This is only used in action: .  We define it as a no-op so that
+\ "doaction" can do all the work.
+: place-cf  (s -- )  ;
+
+\ Create code field for code word
+: code-cf  (s -- )  acf-align  here ta1+  aligned token,  align  ;
+
+: >code  ( acf-of-code-word -- address-of-start-of-machine-code )  token@  ;
+: code?  ( acf -- f )  \ True if the acf is for a code word
+   dup token@  swap >body =
+;
+
+\ Assemble "next" routine at the end of a code definition.
+\ This is not needed for the kernel to run; it is used later
+\ after the resident assembler has been loaded
+
+: next  (s -- )
+   here  /l allot  h# 4e800420 swap instruction!	( "bcctr 20,0" )
+;
+
+: create-cf    (s -- )  [ dodoes ]     literal set-cf  ['] noop token,  ;
+: variable-cf  (s -- )  [ dovariable ] literal set-cf  ;
+
+: place-;code  (s -- )  code-cf  ;
+: place-does   (s -- )  [ docolon ]    literal set-cf  ;
+
+\ Ip is assumed to point to (;code .  flag is true if
+\ the code at ip is a does> clause as opposed to a ;code clause.
+: does-ip?  ( ip -- ip' flag )
+   dup token@  ['] (does>) =  ( ip flag )  swap ta1+ ta1+  swap
+;
+
+: put-cf  (s action-clause-adr where -- )  token!  ;   
+
+\ uses  sets the code field of the indicated word so that
+\ it will execute the code at action-clause-adr
+: uses  (s action-clause-adr xt -- )
+   tuck /token + put-cf
+   [ dodoes ] literal  origin+  swap put-cf
+;
+
+\ used  sets the code field of the most-recently-defined word so that
+\ it executes the word at action-clause-adr
+: used  (s action-clause-adr -- )  lastacf uses  ;
+
+: colon-cf?  ( possible-acf -- flag )
+   dup  token@  [ docolon ] literal origin+ =  if
+      /token - token@
+      dup  ['] branch   <>
+      over ['] ?branch  <> and
+      over ['] (of)     <> and
+      over ['] (leave)  <> and
+      over ['] (?leave) <> and
+      over ['] (do)     <> and
+      over ['] (?do)    <> and
+      swap ['] (lit)    <> and
+   else
+      drop false
+   then
+;
+: colon-cf      (s -- )  [ docolon ]     literal set-cf  ;
+: user-cf       (s -- )  [ douser ]      literal set-cf  ;
+: value-cf      (s -- )  [ dovalue ]     literal set-cf  ;
+: constant-cf   (s -- )  [ doconstant ]  literal set-cf  ;
+: defer-cf      (s -- )  [ dodefer ]     literal set-cf  ;
+: 2constant-cf  (s -- )  [ do2constant ] literal set-cf  ;
+
+4 constant /branch
+: branch,  ( offset -- )  ,  ;
+: branch!  ( offset where -- )  !  ;
+
+: branch@  ( where -- offset )  @  ;
+\ >target depends on the way that branches are compiled
+: >target  ( ip-of-branch-instruction -- target )  ta1+ dup branch@ +  ;
+headerless
+
+/a constant /a
+
+headers
+
+code a@  ( adr -- adr' )
+   lwz  tos,0(tos)
+   add  tos,tos,base
+c;
+
+\ R : a!  ( adr1 adr2 -- )  set-relocation-bit  l!  ;
+code a!  ( adr1 adr2 -- )
+   pop-to-t0
+   subfc t0,base,t0	\ ( Use subfc for POWER compatibility)
+   stw  t0,0(tos)
+   pop-tos
+c;
+: a,  ( adr -- )  here  /a allot  a!  ;
+
+/token constant /token
+code token@ (s adr -- cfa )  lwz tos,0(tos)  add tos,tos,base  c;
+\ R : token! (s cfa adr -- )  set-relocation-bit l!  ;
+code token! (s cfa addr -- )
+   second-to-t0
+   subfc t0,base,t0	\ ( Use subfc for POWER compatibility)
+   stw  t0,0(tos)
+   pop1
+c;
+
+
+: token, (s cfa -- )  here  /token allot  token!  ;
+
+: null  ( -- token )  origin  ;
+: !null-link   ( adr -- )  null swap link!  ;
+: !null-token  ( adr -- )  null swap token!  ;
+: non-null?  ( link -- false | link true )
+   dup origin =  if  drop false  else  true  then
+;
+\ code non-null?  ( link -- false | link true )
+\    tos  base    cmp
+\    <>  if
+\    false t0  mr       \ Delay slot
+\ 
+\       push-tos
+\       true t0 mr
+\    then
+\    t0  tos  mr
+\ c;
+: get-token?     ( adr -- false | acf  true )  token@ non-null?  ;
+: another-link?  ( adr -- false | link true )  link@  non-null?  ;
+
+\ The "word type" is a number which distinguishes one type of word
+\ from another.  This is highly implementation-dependent.
+
+\ For the PowerPC implementation, the magic number returned by word-type
+\ is the absolute address of the action code.
+
+: long-cf?  (s acf -- flag )  token@ origin-  [ dodoes ] literal  =  ;
+
+: word-type  (s acf -- word-type )  dup long-cf?  if  ta1+  then  token@  ;
+
+: body>  (s apfa -- acf )
+   /token -   dup /token -  long-cf?  if  /token -  then
+;
+: >body  (s acf -- apf )  dup long-cf?  if  ta1+  then   ta1+  ;
+
+4 constant /user#
+
+\ Move to a machine alignment boundary.
+
+: aligned  (s adr -- adr' )  /n round-up  ;
+
+code acf-aligned  (s adr -- adr' )
+   addi  tos,tos,3
+\   addi  t0,r0,-4
+\   and   tos,tos,t0
+   rlwinm tos,tos,0,0,29
+c;
+
+\ Floored division is prescribed by the Forth 83 standard.
+\ The quotient is rounded toward negative infinity, and the
+\ remainder has the same sign as the divisor.
+
+: /mod  (s dividend divisor -- remainder quotient )
+  \ Check if either factor is negative
+    2dup               ( n1 n2 n1 n2)
+    or 0< if           ( n1 n2)
+    
+        \ Both factors not non-negative; do division by:
+        \ Take absolute value and do unsigned division
+        \ Convert to truncated signed divide by:
+        \  if dividend is negative then negate the remainder
+        \  if dividend and divisor have opposite signs then negate the quotient
+        \ Then convert to floored signed divide by:
+        \  if quotient is negative and remainder is non-zero
+        \    add divisor to remainder and decrement quotient
+
+        2dup swap abs swap abs  ( n1 n2 u1 u2)     \ Absolute values
+
+        u/mod              ( n1 n2 urem uqout)     \ Unsigned divide
+        >r >r              ( n1 n2) ( uquot urem)
+
+        over 0< if         ( n1 n2) ( uquot urem)  
+            r> negate >r                 \ Negative dividend; negate remainder
+        then               ( n1 n2) ( uquot trem)
+   
+        swap over          ( n2 n1 n2) ( uquot trem)
+        xor 0< if          ( n2) ( uquot trem)
+            r> r>
+            negate         ( n2 trem tquot)  \ Opposite signs; negate quotient
+           -rot            ( tquot n2 trem)
+            dup 0<> if 
+                +          ( tquot rem) \ Negative quotient & non-zero remainder
+                swap 1-    ( rem quot)  \ add divisor to rem. & decrement  quot.
+            else
+                nip swap   ( rem quot)
+            then
+        else
+            drop r> r>     ( rem quot)
+        then
+
+    else   \ Both factors non-negative
+
+        u/mod          ( rem quot)
+    then
+;
+
+\ 64-bit addition and subtraction
+: dabs  ( d# -- d# )  dup 0<  if  dnegate  then  ;
+: dmax  ( d1 d2 -- d3 )  2over 2over  d-  nip 0<  if  2swap  then  2drop  ;
+
+code d+  ( d1 d2 -- d3 )
+   lwz    t1,0(sp)	\ d2.low
+   lwz    t3,2cells(sp)	\ d1.low
+   lwz    t2,1cell(sp)	\ d1.high
+   addi   sp,sp,2cells	\ Pop args
+   addc   t1,t1,t3	\ d3.low
+   adde   tos,tos,t2	\ d3.high
+   stw    t1,0(sp)	\ Push result (d3.high already in tos)
+c;
+code d-  ( d1 d2 -- d3 )
+   lwz    t1,0(sp)	\ x2.low
+   lwz    t2,1cell(sp)	\ x1.high
+   lwz    t3,2cells(sp)	\ x1.low
+   addi   sp,sp,2cells	\ Pop args
+   subfc  t1,t1,t3	\ x3.low
+   subfe  tos,tos,t2	\ x3.high
+   stw    t1,0(sp)	\ Push result (x3.high already in tos)
+c;
+code s>d  ( n -- d )  push-tos  srawi tos,tos,31  c;
+code dnegate  ( d -- -d )
+   second-to-t0
+   subfic t0,t0,0
+   stw    t0,0(sp)
+   subfze tos,tos
+c;
+
+only forth also labels also meta also assembler definitions
+
+:-h 'user#  \ name  ( -- user# )
+    [ meta ]-h  '  ( acf-of-user-variable )  >body-t
+    @-t
+;-h
+:-h 'user  \ name  ( -- user-addressing-mode )
+    [ also assembler also register-names ]-h   'user#  up 
+    [ previous previous ]-h
+;-h
+:-h 'body  \ name  ( -- variable-apf )
+    [ meta ]-h  '  ( acf-of-user-variable )  >body-t
+;-h
+:-h 'acf  \ name  ( -- variable-apf )
+    [ meta ]-h  '  ( acf-of-user-variable )  >body-t
+;-h
+ 
+only forth also labels also meta also definitions
+
+: m+    ( d1|ud1 n -- )  s>d  d+  ;
+
+fload ${BP}/forth/kernel/dmuldiv.fth
+
+: m/mod   (s l.dividend n.divisor -- n.remainder n.quotient )    fm/mod  ;
+
+code *  ( n1 n2 -- n3 )  pop-to-t0  mullw tos,t0,tos  c;
+
+: ul*    (s un1 un2 -- lproduct )  *  ;
+: u*     (s un1 un2 -- uproduct )  *  ;
+
+
+\ PowerPC version is dynamically relocated, so we don't need a bitmap
+: clear-relocation-bits  ( adr len -- )  2drop  ;
+
+: move  ( src dst cnt -- )
+   >r 2dup u<  if  r> cmove>  else  r> cmove  then
+;
+
+init-user-area constant init-user-area
+
+code (llit)  (s -- l )  push-tos  literal-to-tos  c;
+code (dlit)  (s -- d )  push-tos  literal-to-tos  literal-to-t0  push-t0  c;
+
+\ Select a vocabulary thread by hashing the lookup name.
+\ Hashing function:  Use the lower bits of the first character in the
+\ name to select one of #threads threads in the array pointed-to by
+\ the user number in the parameter field of voc-acf.
+code hash  (s str-addr voc-acf -- thread )
+   \ The next 2 lines are equivalent to ">threads", which in this
+   \ implementation happens to be the same as ">body >user"
+   lwz  tos,/ccf(tos)	\ Get the user number
+   add  tos,tos,up	\ Find the address of the threads
+
+   pop-to-t0	\ str-adr in t0
+   lbz  t0,1(t0)	\ First byte of string
+   #threads-t 1-  andi. t0,t0,*	\ Extract low bits
+   add  t0,t0,t0
+   add  t0,t0,t0	\ Convert index to longword offset
+   add  tos,tos,t0
+c;
+
+\ Search a vocabulary thread (link) for a name matching string.
+\ If found, return its code field address and -1 if immediate, 1 if not
+\ immediate.  If not found, return the string and 0.
+
+\ Name field:
+\     name: forth-style packed string, no tag bits
+\     flag: 40 bit is immediate bit
+\ Padding is optionally inserted between the name and the flags
+\ so that the byte after the flag byte is on an even boundary.
+
+[ifdef] notdef
+code (find)  (s string link origin -- acf -1  |  acf 1  |  string 0 )
+   pop-tos	\ link in tos
+
+\ Registers:
+\ tos    alf of word being tested
+\ t0    string
+\ t1    name being tested
+\ t2    # of characters left to test
+\ string is kept on the top of the external stack
+
+\   1 F: always brif		\ Branch to test at end of list
+\   begin
+    begin   cmp   0,0,tos,base <> while  
+      addi  t1,tos,/token	\ Get name address of word to test
+      second-to-t0	   	\ Get string address
+      lbz   t2,0(t0)		\ get the name field length
+      addi  t0,t0,-1		\ Account for pre-increment
+      addi  t1,t1,-1		\ Account for pre-increment
+      begin
+         lbzu  t3,1(t0)		\ Compare 2 characters
+         lbzu  t4,1(t1)
+      cmp 0,0,t3,t4  = while	\ Keep looking as long as characters match
+         addic. t2,t2,-1	\ Decrement byte counter
+         0< if			\ If we've tested all chars, the names match.
+            lbzu  tos,1(t1)	\ Get flags byte into tos register
+
+            addi  t1,t1,/cf	\ Now find the code field by
+\           addi  t2,r0,-/cf
+\           and   t1,t1,t2	\ aligning to the next 4 byte boundary
+	    rlwinm t1,t1,0,0,29
+
+	    andi. t2,tos,h#20	\ Test the alias flag
+	    0<> if
+	       lwz  t1,0(t1)	\ Get acf
+               add  t1,t1,base	\ Relocate
+            then
+
+            stw   t1,0(sp)	\ Replace string on stack with acf
+	    andi. t2,tos,h#40	\ Test the immediate flag
+	    0<> if
+	       addi tos,r0,1	\ Immediate
+	    else
+               addi tos,r0,-1	\ Not immediate
+	    then
+	    next
+         then
+      repeat
+
+      \ The names did not match, so check the next name in the list
+      lwz  tos,0(tos)		\ Fetch next link  ( next acf )
+      add  tos,tos,base		\ Relocate
+1 L:
+\      cmp   0,0,tos,base
+\   = until
+repeat
+
+   \ If we get here, we've checked all the names with no luck
+   addi  tos,r0,0
+c;
+[then]
+
+code ($find-next)  (s adr len link -- adr len alf true  |  adr len false )
+\ Registers:
+\ tos    alf of word being tested
+\ t0     string
+\ t1     anf of word being tested
+\ t2     saves ctr register value
+\ t3    character from string
+\ t4    character from name
+\ t5    string length
+\ string is kept on the top of the external stack
+
+   lwz   t0,1cell(sp)		\ Get string address
+   lwz   t5,0(sp)		\ get the name field length
+   addi  t0,t0,-1		\ Account for pre-increment
+
+   mfspr  t2,ctr		\ Save CTR register
+
+   ahead
+   begin
+      addi   tos,tos,-/token	\ >link
+      addi   t1,tos,-2		\ t1 points before count byte at string *end*
+      subfc  t1,t5,t1		\ t1 points to beginning of string
+				\ ( Use subfc for POWER compatibility)
+      mr     t6,t0
+      
+      mtspr  ctr,t5		\ Set starting loop index
+      begin
+         lbzu  t4,1(t1)		\ Get character from name field
+         lbzu  t3,1(t6)		\ Get character from search string
+         cmp   0,0,t3,t4	\ Compare 2 characters
+      bc 8,2,*			\ Branch while characters match and count non0
+
+      = if			\ If we've tested all name chars, we
+         lbzu  t4,1(t1)		\ may have a match; check the count byte
+         andi. t4,t4,h#1f
+         cmp   0,0,t4,t5	\ Compare count bytes
+         = if
+            push-tos		\ Push alf above pstr
+            addi   tos,r0,-1	\ True on top of stack means "found"
+            mtspr  ctr,t2	\ Restore CTR register
+            next
+         then
+      then
+
+   but then
+      \ The names did not match, so check the next name in the list
+      lwz   tos,0(tos)		\ Fetch next link  ( next acf )
+      add   tos,tos,base	\ Relocate
+      cmp   0,0,tos,base
+   = until
+
+   \ If we get here, we've checked all the names with no luck
+   addi   tos,r0,0
+   mtspr  ctr,t2		\ Restore CTR register
+c;
+
+: ?negate  (s n1 n2 -- n3 )  if  negate  then  ;
+
+code wflip (s l1 -- l2 )  \ word swap
+   rlwinm  t0,tos,16,16,31	\ high half to low half
+   rlwimi  t0,tos,16,0,15	\ low to high and insert
+   mr      tos,t0
+c;
+
+code lwflip  ( l -- l' )
+   rlwinm t0,tos,16,0,15
+   rlwimi t0,tos,16,16,31
+   mr     tos,t0
+c;
+
+code lbflip  ( l -- l' )
+   rlwinm t0,tos,24,0,7
+   rlwimi t0,tos,8,8,15
+   rlwimi t0,tos,24,16,23
+   rlwimi t0,tos,8,24,31
+   mr     tos,t0
+c;
+
+code wbflip  ( w -- w' )
+   rlwinm t0,tos,8,16,23
+   rlwimi t0,tos,24,24,31
+   mr     tos,t0
+c;
+
+code lwflips  ( adr len -- )
+   lwz     t0,0(sp)	\ adr in t0, len in tos
+
+   addi    tos,tos,3		\ Round up to longword boundary
+   rlwinm. tos,tos,30,2,31	\ Divide by 4
+
+   0<>  if
+      addi    t0,t0,-4		\ Account for pre-increment
+      addi    r0,r0,0
+
+      mtspr   ctr,tos
+
+      begin
+         lwzu   t1,4(t0)		\ Load one way
+         rlwinm t2,t1,16,0,15
+	 rlwimi t2,t1,16,16,31
+         stw    t2,0(t0)		\ Store the other
+      countdown
+
+      mtspr   ctr,up
+   then
+
+   lwz     tos,1cell(sp)
+   addi    sp,sp,2cells
+c;
+
+code lbflips  ( adr len -- )
+   lwz     t0,0(sp)	\ adr in t0, len in tos
+
+   addi    tos,tos,3		\ Round up to longword boundary
+   rlwinm. tos,tos,30,2,31	\ Divide by 4
+
+   0<>  if
+      addi    t0,t0,-4		\ Account for pre-increment
+      addi    r0,r0,0
+
+      mtspr   ctr,tos
+
+      begin
+         lwzu   t1,4(t0)		\ Load one way
+         stwbrx t1,r0,t0		\ Store the other
+      countdown
+
+      mtspr   ctr,up
+   then
+
+   lwz     tos,1cell(sp)
+   addi    sp,sp,2cells
+c;
+
+code wbflips  ( adr len -- )
+   lwz     t0,0(sp)		\ adr in t0, len in tos
+
+   addi    tos,tos,1		\ Round up to longword boundary
+   rlwinm. tos,tos,31,1,31	\ Divide by 4
+
+   0<>  if
+      addi    t0,t0,-2		\ Account for pre-increment
+      addi    r0,r0,0
+
+      mtspr   ctr,tos
+
+      begin
+         lhzu   t1,2(t0)	\ Load one way
+         sthbrx t1,r0,t0	\ Store the other
+      countdown
+
+      mtspr   ctr,up
+   then
+
+   lwz     tos,1cell(sp)
+   addi    sp,sp,2cells
+c;
+
+\ these are not used. remove?
+: cset     (s byte-mask adr -- )  tuck c@ or swap c!  ;
+: creset   (s byte-mask adr -- )  swap invert over c@ and swap c!  ;
+: ctoggle  (s byte-mask adr -- )  tuck c@ xor swap c!  ;
+: toggle   (s adr byte-mask -- )  swap ctoggle  ;
+
+
+code s->l  (s n.signed -- l )   c;
+code n->l  (s n.unsigned -- l )  c;
+code n->a  (s n -- a )  c;
+code l->n  (s l -- n )  c;
+code l->w  (s l -- w )  andi.  tos,tos,h#ffff  c;
+code n->w  (s n -- w )  andi.  tos,tos,h#ffff  c;
+code w->l  (s w -- l )
+   andi.  t0,tos,h#8000   0<> if
+      set  t1,h#ffff.0000
+      or   tos,tos,t1
+   then
+c;
+
+
+code l>r   (s l -- )    stwu  tos,-1cell(rp)  pop-tos  c;
+code lr>   (s -- l )    push-tos  lwz tos,0(rp)  rdrop  c;
+code lr@   (s -- l )    push-tos  lwz tos,0(rp)  c;
+
+code /t* (s n -- n*/t )  add  tos,tos,tos   add  tos,tos,tos   c;
+
+[ifdef] oldmeta
+: >name   ( acf -- anf )
+   1- begin  1-  dup c@  bl >  until	\ Find the end of the name
+   /token 1- invert and			\ Move to token boundary
+   begin  dup c@  bl >=  while  /token -  repeat
+;
+[then]
+#align-t     constant #align
+#acf-align-t constant #acf-align
+#talign-t    constant #talign
+
+: align  (s -- )  #align (align)  ;
+: taligned  (s adr -- adr' )  #talign round-up  ;
+: talign  (s -- )  #talign (align)  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/kernel.bth
===================================================================
--- cpu/ppc/kernel.bth	                        (rev 0)
+++ cpu/ppc/kernel.bth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,107 @@
+purpose: Load file for PowerPC Forth kernel
+\ See license at end of file
+
+command: &builder &this
+build-now
+
+\ ' $report-name is include-hook        ' noop is include-exit-hook
+  ' noop is include-hook                ' noop is include-exit-hook
+
+
+\ Don't accept ',' as numeric punctuation because doing so makes
+\ the forward referencing mechanism think that "c," is a number!
+ascii . ascii , npatch numdelim?
+
+warning off	\ Turn OFF the warning messages
+
+alias constant-h constant
+
+fload ${BP}/forth/kernel/conft32.fth
+fload ${BP}/forth/kernel/meta1.fth
+
+only forth also meta also definitions
+: sx .s cr ;
+\needs ppc-assembler fload ${BP}/cpu/ppc/assem.fth
+
+only forth also meta definitions
+: assembler  ( -- )  ppc-assembler  ;
+
+only forth also meta also assembler definitions
+\needs L: fload ${BP}/forth/lib/loclabel.fth
+init-labels
+
+only forth also definitions
+
+fload ${BP}/forth/kernel/swapmap.fth
+\ : : : lastacf .name cr ;
+fload ${BP}/cpu/ppc/target.fth
+fload ${BP}/forth/kernel/forward.fth
+fload ${BP}/cpu/ppc/fixvoc.fth
+fload ${BP}/forth/kernel/metacompile.fth
+
+only forth meta also forth also definitions
+sometimes-headers
+only forth also definitions
+
+fload ${BP}/cpu/ppc/metainit.fth
+
+\ Comment out the following line(s) when debugging
+-1  threshold  !	\ Turn OFF ALL debugging messages
+warning-t  off  	\ Turn OFF target warning messages
+
+\ Uncomment the following line(s) for more debug output
+\ show? on  1 granularity !  1 threshold !
+\ warning-t on
+
+fload ${BP}/cpu/ppc/kerncode.fth
+
+fload ${BP}/forth/kernel/uservars.fth
+fload ${BP}/forth/kernel/double.fth
+
+fload ${BP}/forth/lib/bitops.fth
+fload ${BP}/cpu/ppc/kernrel.fth
+
+fload ${BP}/forth/lib/struct.fth
+
+fload ${BP}/cpu/ppc/unalign.fth
+
+fload ${BP}/forth/kernel/kernel.fth
+
+fload ${BP}/forth/kernel/sysio.fth
+fload ${BP}/forth/lib/dumballo.fth
+fload ${BP}/cpu/ppc/syscall.fth
+
+fload ${BP}/cpu/ppc/filecode.fth
+
+fload ${BP}/cpu/ppc/boot.fth
+fload ${BP}/forth/kernel/init.fth
+fload ${BP}/cpu/ppc/finish.fth
+
+fload ${BP}/cpu/ppc/savemeta.fth
+
+.( --- Saving kernel.dic ---)  "" kernel.dic save-meta
+cr
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2006 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: cpu/ppc/kernrel.fth
===================================================================
--- cpu/ppc/kernrel.fth	                        (rev 0)
+++ cpu/ppc/kernrel.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,69 @@
+purpose: Maintain a byte swap table for the Forth dictionary
+\ See license at end of file
+
+decimal
+
+0 value swap-map
+
+\ The swap map has one bit for every 32-bit word, since we assume
+\ that relocated longwords must start on a 32-bit boundary
+d# 32 constant bits/swapbit
+
+\ Number of bytes in bitmap
+: >swap-map-size  ( end-adr -- )
+   origin -  bits/swapbit /mod  swap  if  1+  then
+; 
+: /swap-map  ( -- n )  memtop @  >swap-map-size  ;
+
+defer set-swap-bit
+: (set-swap-bit)  ( addr -- )
+   origin -  2 >>           ( lword-index )
+   dup  3 >> /swap-map u<  if  swap-map bitset  else  drop  then
+;
+
+\ The upper endpoint must be aligned in case the lower endpoint
+\ is unaligned and the lower endpoint straddles an alignment boundary.
+\ In that case, if we didn't align the upper endpoint, the last
+\ word of the range would not be marked.
+: note-string  ( adr len -- adr len )
+   2dup  over + aligned swap  ?do  i set-swap-bit  /n +loop
+;
+
+defer init-swap-map
+: (init-swap-map)  ( -- )
+   /swap-map alloc-mem  is swap-map
+   swap-map /swap-map erase
+   \ Copy in old swap map
+   here user-size +  swap-map  here >swap-map-size  move
+   ['] (set-swap-bit) is set-swap-bit
+;
+' (init-swap-map) is init-swap-map
+
+\ Plug this into init-swap-map to turn off swap-map management
+: no-swap-map  ( -- )  ['] drop is set-swap-bit  ;
+
+: init  ( -- )  init  init-swap-map  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/loadmach.fth
===================================================================
--- cpu/ppc/loadmach.fth	                        (rev 0)
+++ cpu/ppc/loadmach.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,73 @@
+purpose: Load file for machine-dependent Forth tools
+\ See license at end of file
+
+assembler? [if]
+fload ${BP}/cpu/ppc/assem.fth
+fload ${BP}/cpu/ppc/code.fth
+fload ${BP}/forth/lib/loclabel.fth
+[else]
+transient  fload ${BP}/cpu/ppc/assem.fth  resident
+fload ${BP}/cpu/ppc/code.fth
+transient  fload ${BP}/forth/lib/loclabel.fth     resident
+[then]
+
+fload ${BP}/cpu/ppc/decompm.fth
+
+: be-l,  ( l -- )  here 4 note-string  allot  be-l!  ;
+
+[ifndef] partial-no-heads	transient  [then]
+fload ${BP}/forth/lib/binhdr.fth
+fload ${BP}/cpu/ppc/savefort.fth
+\ alias save-forth save-forth
+[ifndef] partial-no-heads	resident  [then]
+
+fload ${BP}/forth/lib/instdis.fth
+
+fload ${BP}/cpu/ppc/objsup.fth
+fload ${BP}/forth/lib/objects.fth
+
+fload ${BP}/cpu/ppc/call.fth		\ C subroutine calls
+
+fload ${BP}/cpu/ppc/cpustate.fth
+fload ${BP}/cpu/ppc/register.fth
+
+fload ${BP}/forth/lib/savedstk.fth
+fload ${BP}/forth/lib/rstrace.fth
+fload ${BP}/cpu/ppc/ftrace.fth
+fload ${BP}/cpu/ppc/ctrace.fth
+
+fload ${BP}/cpu/ppc/debugm.fth		\ Forth debugger support
+fload ${BP}/forth/lib/debug.fth		\ Forth debugger
+
+start-module				\ Breakpointing
+fload ${BP}/cpu/ppc/cpubpsup.fth	\ Breakpoint support
+fload ${BP}/forth/lib/breakpt.fth
+end-module
+
+fload ${BP}/cpu/ppc/msr.fth		\ Stuff in the Machine State Register
+fload ${BP}/cpu/ppc/spr.fth		\ Various special registers
+fload ${BP}/cpu/ppc/catchexc.fth
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/loadvmem.fth
===================================================================
--- cpu/ppc/loadvmem.fth	                        (rev 0)
+++ cpu/ppc/loadvmem.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,63 @@
+purpose: Load file for virtual memory node
+\ See license at end of file
+
+headers
+false value use-real-mode?
+true value in-real-mode?
+0 value /rm-tlbmiss
+
+fload ${BP}/ofw/core/allocmor.fth	\ S Allow alloc-mem to use more memory
+
+dev /
+new-device
+" mmu" device-name
+fload ${BP}/ofw/core/virtlist.fth	\ Virtual memory allocator
+fload ${BP}/ofw/core/maplist.fth	\ Manage translation list 
+fload ${BP}/ofw/core/clntmap.fth	\ OS callbacks for address translation
+\ fload ${BP}/arch/prep/memcb.fth		\ Memory allocation callback
+
+fload ${BP}/cpu/ppc/tlb.fth
+fload ${BP}/cpu/ppc/tlbmiss.fth
+fload ${BP}/cpu/ppc/htabmmu.fth
+fload ${BP}/cpu/ppc/batfault.fth
+fload ${BP}/cpu/ppc/batmap.fth
+[ifdef] exponential
+fload ${BP}/cpu/ppc/exptlb.fth
+[then]
+
+: .t   translations translation-node .list  ;
+
+fload ${BP}/cpu/ppc/testmmu.fth
+
+' 2drop is ?splice
+
+finish-device
+device-end
+
+: map?  ( virtual -- )  " map?" mmu-node @ $call-method  ;
+: .t    ( -- )		" .t"   mmu-node @ $call-method  ;
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/metainit.fth
===================================================================
--- cpu/ppc/metainit.fth	                        (rev 0)
+++ cpu/ppc/metainit.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,70 @@
+purpose: Metacompiler initialization
+\ See license at end of file
+
+\ Debugging aids
+
+0 #words ! h# 480 threshold ! 10 granularity !
+
+warning off
+
+metaon
+meta definitions
+
+\ We want the kernel to be romable, so we put variables in the user area
+:-h variable  ( -- )  nuser  ;-h
+alias \m  \
+
+initmeta
+
+th 11000 alloc-mem  target-image  \ Allocate space for the target image
+
+\ org sets the lowest address that is used by Forth kernel.
+hex
+
+0.0000 org  0.0000
+   voc-link-t token-t!
+
+200 equ ps-size
+
+assembler
+
+\ This is at the first location in the Forth image.
+
+\ init-forth is the initialization entry point.  It should be called
+\ exactly once, with arguments (dictionary_start, dictionary_size).
+\ init-forth sets up some global variables which allow Forth to locate
+\ its RAM areas, including the data stack, return stack, user area,
+\ cpu-state save area, and dictionary.
+
+hex
+mlabel cld
+   b	0	\ The address will be fixed later.
+   nop		\ Delay slot
+   nop
+   nop
+
+meta
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/metarel.fth
===================================================================
--- cpu/ppc/metarel.fth	                        (rev 0)
+++ cpu/ppc/metarel.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,50 @@
+purpose: Maintain a byte swap table for the Forth kernel during metacompilation
+\ See license at end of file
+
+decimal
+
+only forth also meta also definitions
+h# 10000 constant max-kernel-t
+
+\ The swap map has one bit for every 32-bit word, since we assume
+\ that relocated longwords must start on a 32-bit boundary
+d# 32 constant bits/swapbit-t
+
+\ Number of bytes in bitmap
+: >swap-map-size-t  ( end-adr -- )
+   origin-t -  bits/swapbit-t /mod  swap  if  1+  then
+;
+
+max-kernel-t >swap-map-size-t constant /swap-map-t  \ Number of bytes in bitmap
+/swap-map-t buffer: swap-map-t
+
+: set-swap-bit-t  ( addr -- )  origin-t -  2 >>  swap-map-t bitset  ;
+: note-string-t  ( adr len -- adr len )
+   2dup bounds  ?do  i set-swap-bit-t  /n +loop
+;
+
+: init-swap-t  ( -- )  swap-map-t /swap-map-t erase  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/minifth.fth
===================================================================
--- cpu/ppc/minifth.fth	                        (rev 0)
+++ cpu/ppc/minifth.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,986 @@
+purpose: Forth-like peek/poke/memory-test monitor using only registers
+\ See license at end of file
+
+\ Requires the following external definitions:
+\ isa-io-pa  ( -- n )	     \ Returns the base address of IO space
+\ init-serial  ( -- )        \ May destroy r3-r7
+\ getchar  ( -- r3: char )   \ May destroy r3-r7
+\ putchar  ( r3: char -- )   \ May destroy r3-r7
+
+\ The following code must run entirely from registers.  The following
+\ register allocation conventions are used:
+\  r3-r7	Argument passing and return, scratch registers for subroutines
+\  r8		Return address for level 1 routines, scratch use for level 2+
+\  r9		Return address for level 2 routines, scratch use for level 3+
+\  r10-r11	Used as needed within higher-level subroutines
+\  r12		Global state flags
+\  r13		As-yet unassigned
+\  r14-r17	4-element stack
+\  r18		script pointer
+
+\ Send a space character to the output device.
+label putspace  ( -- )  \ Level 0, destroys: r3-r7 (because it calls putchar)
+   set  r3,h#20
+   putchar b *
+end-code
+
+\ Send a newline sequence (CR-LF) to the output device.
+label putcr  ( -- )  \ Level 1, destroys: r3-r8 (because it calls putchar)
+   mfspr r8,lr
+   set  r3,h#0d   putchar bl *
+   set  r3,h#0a   putchar bl *
+   mtspr lr,r8
+   bclr 20,0
+end-code
+
+\ Send ": " to the output device.
+label putcolon  ( -- )  \ Level 1, destroys: r3-r8
+   mfspr  r8,lr
+   char : set  r3,*  putchar bl *
+   putspace bl *
+   mtspr  lr,r8
+   bclr   20,0
+end-code
+
+\ Accept input characters, packing up to 8 of them into the register pair
+\ r3,r4.  The first character is placed in the least-significant byte of
+\ r4, and for each subsequent character, the contents of r3,r4 are shifted
+\ left by 8 bits to make room for the new character (shifting the most-
+\ significant byte of r4 into the least-significant byte of r3).
+\ A backspace character causes r3,r4 to be shifted right, discarding the
+\ previous character.
+\ The process terminates when a space or carriage return is seen.  The
+\ terminating character is not stored in r3,r4.  Any unused character
+\ positions in r3,r4 contain binary 0 bytes.
+label getword  ( -- r3,r4 )  \ Level 4, destroys r3-r11
+   mfspr  r9,lr
+   set  r10,0		\ Clear high temporary holding register
+   set  r11,0		\ Clear low temporary holding register
+
+   begin
+      andi.  r3,r12,4  0<>  if
+         lbz   r3,0(r18)
+         addi  r18,r18,1
+         \ Translate linefeed to carriage return in script mode
+         cmpi  0,0,r3,h#0a  =  if  set r3,h#0d  then
+      else
+         getchar bl *  ( char in r3 )
+      then
+
+      cmpi  0,0,r3,h#0d  = if		\ carriage return
+         andi.  r0,r12,8  0=  if	\ Check no-echo flag
+            putcr bl *			\ Echo CR-LF
+         then
+         mr r3,r10  mr r4,r11		\ Return packed word in r3,r4
+         mtspr lr,r9
+         bclr 20,0			\ Return
+      then
+
+      control h  cmpi  0,0,r3,*  <>  if \ backspace
+         cmpi  0,0,r3,h#20  =  if	\ white space
+            andi. r0,r12,8  0=  if	\ Check no-echo flag
+               \ In quiet mode, echo the input character; otherwise echo CR-LF
+               andi. r0,r12,2  0<>  if  putchar bl *  else  putcr bl *   then
+            then
+            mr r3,r10  mr r4,r11	\ Return packed word in r3,r4
+            mtspr lr,r9
+            bclr 20,0			\ Return
+         then
+      then
+
+      mr  r8,r3				\ Save character
+      andi. r0,r12,8  0=  if		\ Check no-echo flag
+         putchar bl *			\ Echo the character
+      then
+
+      control h cmpi  0,0,r8,*  = if
+         \ Double-shift right one byte
+         rlwinm  r11,r11,24,8,31
+         rlwimi  r11,r10,24,0,7
+         rlwinm  r10,r10,24,0,23
+      else
+         \ Double-shift left one byte and merge in the new character
+         rlwinm  r10,r10,8,0,23
+         rlwimi  r10,r11,8,24,31
+         rlwinm  r11,r11,8,0,23
+         or      r11,r11,r8
+      then
+   again
+end-code
+
+\ Convert the ASCII hexadecimal characters packed into r3,r4 into a
+\ 32-bit binary number, returning the result in r3 and non-zero in r4
+\ if the operation succeeded.
+\ If the operation failed (because of the presence of non-hex characters),
+\ return 0 in r4, and an undefined value in r3.
+
+\ Level 1, destroys: r3-r8
+label convert-number  ( r3,r4: ascii -- r3: binary r4: okay? )
+   mr r8,r3		\ Move high 4 ASCII characters away from r3
+   set r3,0		\ Accumulator for output
+
+   set r6,8		\ Loop counter - convert 8 nibbles
+   mtspr ctr,r6
+   begin
+      \ Shift r8,r4 left one byte, putting result in r6
+      rlwinm  r6,r8,8,24,31		\ High byte in r6
+      rlwinm  r8,r8,8,0,23		\ Shift high word
+      rlwimi  r8,r4,8,24,31		\ Merge from low word to high word
+      rlwinm  r4,r4,8,0,23		\ Shift low word
+
+      cmpi    0,0,r6,0  <>  if
+
+         char 0  cmpi   0,0,r6,*
+         <  if
+            set  r4,0
+            bclr 20,0			\ Exit if < '0'
+         then
+
+         char 9  cmpi  0,0,r6,*  <=  if	\ Good digit from 0-9
+            char 0 negate  addi r6,r6,*
+         else
+            char A  cmpi   0,0,r6,*
+            <  if
+               set  r4,0
+               bclr 20,0		\ Exit if < 'A'
+            then
+
+            char F  cmpi  0,0,r6,*  <=  if
+               char A d# 10 - negate  addi  r6,r6,*
+            else
+               char a  cmpi  0,0,r6,*   \ possibly lower case hex digit
+               <  if
+                  set  r4,0
+                  bclr 20,0		\ Exit if < 'a'
+               then
+
+               char f  cmpi  0,0,r6,*
+               >  if
+                  set  r4,0
+                  bclr 20,0		\ Exit if > 'f'
+               then
+
+               char a d# 10 -  negate  addi  r6,r6,*
+            then
+         then
+         rlwinm  r3,r3,4,0,27
+         or      r3,r3,r6
+      then
+   countdown
+
+   set r4,-1
+
+   bclr 20,0
+end-code
+
+\ Display the number in r3 as an 8-digit unsigned hexadecimal number
+label dot  ( r3 -- )  \ Level 3, destroys: r3-r10
+   mfspr r8,lr
+   set r9,8
+   mtspr ctr,r9
+   mr r9,r3
+   begin
+      rlwinm r9,r9,4,0,31
+      andi. r3,r9,h#f
+      cmpi 0,0,r3,10
+      >=  if
+         char a d# 10 -  addi  r3,r3,*
+      else
+         char 0          addi  r3,r3,*
+      then
+      putchar bl *
+   countdown
+
+   set r3,h#20  putchar bl *
+
+   mtspr lr,r8
+   bclr  20,0
+end-code
+
+transient
+\ Macros for managing the mini-stack
+: pop1  ( -- )
+   " mr r14,r15  mr r15,r16  mr r16,r17"  evaluate
+;
+: pop2  ( -- )
+   " mr r14,r16  mr r15,r17  mr r16,r17"  evaluate
+;
+: pop3  ( -- )
+   " mr r14,r17  mr r15,r17  mr r16,r17"  evaluate
+;
+: push1  ( -- )
+   " mr r17,r16  mr r16,r15  mr r15,r15"  evaluate
+;
+: spush  ( -- )
+   " mr r17,r16  mr r16,r15  mr r15,r14  mr r14,r3"  evaluate
+;
+
+\ Macros to assemble code to begin and end command definitions
+8 buffer: name-buf
+
+\ Start a command definition
+: t:  ( "name" -- cond )
+   \ Get a name from the input stream at compile time and pack it
+   \ into a buffer in the same form it will appear in the register
+   \ pair when the mini-interpreter is executed at run-time
+   name-buf 8 erase                       ( )
+   parse-word                             ( adr len )
+   dup 8 -  0 max  /string                ( adr' len' )  \ Keep last 8
+   8 min  8 over - name-buf +  swap move  ( )
+
+   \ Assemble code to compare the register-pair contents against the name.
+   name-buf     be-l@  " set r6,*  cmp 0,0,r3,r6  =  if"  evaluate
+   name-buf 4 + be-l@  " set r6,*  cmp 0,0,r4,r6  then  =  if"  evaluate
+;
+
+\ End a command definition by:
+\ a) Assembling code to jump back to the beginning of the loop after the
+\    current definition has executed ("over again")
+\ b) Resolve the "if" (conditional branch) that skips the current definition
+\    if the name the user has entered does not match this definition.
+
+: t;  ( loop-begin-adr if-adr --- loop-begin-adr )
+   " over again  then" evaluate
+;
+resident
+
+label minifth  ( -- <does not return> )  \ Level 5
+   init-serial bl *
+
+[ifdef] notdef
+set r10,0
+begin
+   mr r3,r10
+   dot bl *
+   putcr bl *
+   addi r10,r10,1
+again
+[then]
+
+   set r14,0  set r15,0  set r16,0  set r17,0	\ Init stack
+   set r12,0					\ Init loop flag
+
+   begin                      ( loop-begin-adr )
+      andi. r0,r12,6  0=  if     \ Display stack if neither silent nor scripting
+  \      mr r3,r17  dot bl *
+         mr r3,r16  dot bl *
+         mr r3,r15  dot bl *
+         mr r3,r14  dot bl *
+         char o  set r3,*  putchar bl *
+         char k  set r3,*  putchar bl *
+         putspace bl *
+      then
+
+      getword bl *	\ Result in r3 and r4
+
+      \ If the word is null (i.e. a bare space or return), do nothing
+      cmpi 0,0,r3,0  =  if  cmpi 0,0,r4,0  then
+      yet <> until		\ Branch back to the "begin" if r3,r4 = 0
+
+      t: showstack  ( -- )
+         rlwinm  r12,r12,0,31,29  \ Clear the 2 bit
+      t;
+
+      t: quiet  ( -- )
+         or r12,r12,2
+      t;
+
+      t: clear  ( ?? -- )
+         set r14,0  set r15,0  set r16,0  set r17,0	 \ Init stack
+      t;
+
+      t: @  ( adr -- n )
+         andi. r0,r12,1  <>  if
+            begin  lwz r3,0(r14)  again
+         then
+         lwz r14,0(r14)
+      t;
+
+      t: !  ( n adr -- )
+         andi. r0,r12,1  <>  if
+            begin  stw r15,0(r14)  again
+         then
+         stw r15,0(r14)
+         pop2
+      t;
+
+      t: l@  ( adr -- l )
+         andi. r0,r12,1  <>  if
+            begin  lwz r3,0(r14)  again
+         then
+         lwz r14,0(r14)
+      t;
+
+      t: l!  ( l adr -- )
+         andi. r0,r12,1  <>  if
+            begin  stw r15,0(r14)  again
+         then
+         stw r15,0(r14)
+         pop2
+      t;
+
+      t: c@  ( adr -- b )
+         andi. r0,r12,1  <>  if
+            begin  lbz r3,0(r14)  again
+         then
+         lbz r14,0(r14)
+      t;
+
+      t: c!  ( b adr -- )
+         andi. r0,r12,1  <>  if
+            begin  stb r15,0(r14)  again
+         then
+         stb r15,0(r14)
+         pop2
+      t;
+
+      t: w@  ( adr -- w )
+         andi. r0,r12,1  <>  if
+            begin  lhz r3,0(r14)  again
+         then
+         lhz r14,0(r14)
+      t;
+
+      t: w!  ( w adr -- )
+         andi. r0,r12,1  <>  if
+            begin  sth r15,0(r14)  again
+         then
+         sth r15,0(r14)
+         pop2
+      t;
+
+      t: pc@  ( port# -- b )
+         isa-io-pa set r3,*
+         andi. r0,r12,1  <>  if
+            begin  lbzx r4,r14,r3  again
+         then
+
+         lbzx r14,r14,r3
+      t;
+
+      t: pc!  ( b port# -- )
+         isa-io-pa set r3,*
+         andi. r0,r12,1  <>  if
+            begin  stbx r15,r14,r3  again
+         then
+         stbx r15,r14,r3
+         pop2
+      t;
+
+      t: pw@  ( port# -- w )
+         isa-io-pa set r3,*
+         andi. r0,r12,1  <>  if
+            begin  lhzx r4,r14,r3  again
+         then
+         lhzx r14,r14,r3
+      t;
+
+      t: pw!  ( w port# -- )
+         isa-io-pa set r3,*
+         andi. r0,r12,1  <>  if
+            begin  sthx r15,r14,r3  again
+         then
+         sthx r15,r14,r3
+         pop2
+      t;
+
+      t: pl@  ( port# -- l )
+         isa-io-pa set r3,*
+         andi. r0,r12,1  <>  if
+            begin  lwzx r4,r14,r3  again
+         then
+         lwzx r14,r14,r3
+      t;
+
+      t: pl!  ( l port# -- )
+         isa-io-pa set r3,*
+         andi. r0,r12,1  <>  if
+            begin  stwx r15,r14,r3  again
+         then
+         stwx r15,r14,r3
+         pop2
+      t;
+
+      t: config-l!  ( l config-adr -- )
+         set     r3,h#8000.0000
+         or      r14,r14,r3		\ Set access enable bit
+         config-addr set r3,*
+         stwbrx  r14,0,r3		\ Set address
+         sync
+         config-data set r3,*
+         andi. r0,r12,1  <>  if
+            begin  stwbrx r15,0,r3  sync  again
+         then
+         stwbrx r15,0,r3  sync
+         pop2
+      t;
+
+      t: cl!  ( l config-adr -- )	\ Shorter name
+         set     r3,h#8000.0000
+         or      r14,r14,r3		\ Set access enable bit
+         config-addr set r3,*
+         stwbrx  r14,0,r3		\ Set address
+         sync
+         config-data set r3,*
+         andi. r0,r12,1  <>  if
+            begin  stwbrx r15,0,r3  sync  again
+         then
+         stwbrx r15,0,r3  sync
+         pop2
+      t;
+
+      t: config-l@  ( config-adr -- l )
+         set     r3,h#8000.0000
+         or      r14,r14,r3		\ Set access enable bit
+         config-addr set r3,*
+         stwbrx  r14,0,r3		\ Set address
+         sync
+         config-data set r3,*
+         andi. r0,r12,1  <>  if
+            begin  lwbrx r14,0,r3  sync  again
+         then
+         lwbrx r14,0,r3  sync
+      t;
+
+      t: cl@  ( config-adr -- l )	\ Shorter name
+         set     r3,h#8000.0000
+         or      r14,r14,r3		\ Set access enable bit
+         config-addr set r3,*
+         stwbrx  r14,0,r3		\ Set address
+         sync
+         config-data set r3,*
+         andi. r0,r12,1  <>  if
+            begin  lwbrx r14,0,r3  sync  again
+         then
+         lwbrx r14,0,r3  sync
+      t;
+
+      t: +  ( n1 n2 -- n1+n2 )
+         add r14,r15,r14  mr r15,r16  mr r16,r17
+      t;
+
+      t: -  ( n1 n2 -- n1-n2 )
+         subf r14,r14,r15  mr r15,r16  mr r16,r17
+      t;
+
+      t: and  ( n1 n2 -- n1&n2 )
+         and r14,r15,r14  mr r15,r16  mr r16,r17
+      t;
+
+      t: or  ( n1 n2 -- n1|n2 )
+         or r14,r15,r14  mr r15,r16  mr r16,r17
+      t;
+
+      t: xor  ( n1 n2 -- n1^n2 )
+         xor r14,r15,r14  mr r15,r16  mr r16,r17
+      t;
+
+      t: lshift  ( n1 n2 -- n1<<n2 )
+         slw r14,r14,r15  mr r15,r16  mr r16,r17
+      t;
+
+      t: rshift  ( n1 n2 -- n1>>n2 )
+         srw r14,r14,r15  mr r15,r16  mr r16,r17
+      t;
+
+      t: invert  ( n -- ~n )
+         nor r14,r14,r14
+      t;
+
+      t: negate  ( n -- -n )
+         neg r14,r14
+      t;
+
+      t: spin  ( -- )  \ Modifies next @/!-class command to loop forever
+         set r12,1
+      t;
+
+      t: *  ( n1 n2 -- n1*n2 )
+         mullw r14,r15,r14
+      t;
+
+      t: .  ( n -- )
+         mr r3,r14
+         dot bl *
+         putcr bl *
+         pop1
+      t;
+
+      t: move  ( src dst len -- )
+         cmpi   0,0,r14,0
+         <>  if
+            cmpl 0,0,r15,r16
+            <  if
+               begin
+                  lbz     r3,0(r16)
+                  addi    r16,r16,1
+                  stb     r3,0(r15)
+                  addi    r15,r15,1
+                  addic.  r14,r14,-1
+               0= until
+            else
+               begin
+                  addic.  r14,r14,-1
+                  lbzx    r3,r16,r14
+                  stbx    r3,r15,r14
+               0= until
+            then
+         then
+         pop3
+      t;
+
+      t: compare  ( adr1 adr2 len -- -1 | offset )
+         mr           r4,r14		\ Save len for later
+         set          r3,-1             \ -1 - provisional return value
+         addi         r14,r14,1
+         begin
+            addic.    r14,r14,-1
+         0> while
+            lbz       r5,0(r15)
+            lbz       r6,0(r16)
+            cmp       0,0,r5,r6
+            <>  if  subf.  r3,r14,r4  then
+         <> until
+         then
+         pop3
+         push1
+         mr r14,r3
+      t;
+
+      t: fill  ( adr len b -- )
+         cmpi 0,0,r15,0  <>  if
+            addi  r16,r16,-1
+            mtspr ctr,r15
+            begin
+               stbu r14,1(r16)
+            countdown
+         then
+         pop3
+      t;
+
+      t: lfill  ( adr len l -- )
+         cmpi 0,0,r15,0  <>  if
+            addi r16,r16,-4
+\            rlwinm r15,r15,2,0,29
+            rlwinm r15,r15,30,2,31
+            mtspr ctr,r15
+            begin
+               stwu  r14,4(r16)
+            countdown
+         then
+         pop3
+      t;
+
+      t: afill  ( adr len -- )
+         cmpi 0,0,r14,0  <>  if
+\            rlwinm r14,r14,2,0,29
+            rlwinm r14,r14,30,2,31
+            mtspr ctr,r14
+            begin
+               stw   r15,(r15)
+               addi  r15,r15,4
+            countdown
+         then
+         pop2
+      t;
+
+      t: check  ( adr len b -- )
+         addi   r16,r16,-1
+         begin
+            addic. r15,r15,-1
+         >= while
+            lbzu   r11,1(r16)
+            cmp    0,0,r11,r14
+            <>  if
+               mr    r3,r16          dot bl *
+               putcolon bl *
+               mr    r3,r11          dot bl *
+               putcr bl *
+            then
+         repeat
+
+         pop3
+      t;
+
+      t: lcheck  ( adr len l -- )
+         addi  r16,r16,-4
+         begin
+            addic. r15,r15,-4
+         >= while
+            lwzu   r11,4(r16)
+            cmp    0,0,r11,r14
+            <>  if
+               mr    r3,r16          dot bl *
+               putcolon bl *
+               mr    r3,r11           dot bl *
+               putcr bl *
+            then
+         repeat
+         pop3
+      t;
+
+      t: acheck  ( adr len -- )
+         addi      r15,r15,-4
+         begin
+            addic. r14,r14,-4
+         >= while
+            lwzu   r11,4(r15)
+            cmp    0,0,r11,r15
+            <>  if
+               mr    r3,r15          dot bl *
+               putcolon bl *
+               mr    r3,r11          dot bl *
+               putcr bl *
+            then
+         repeat
+         pop2
+      t;
+
+      t: erase  ( adr len -- )
+         set r3,0
+         cmpi  0,0,r14,0  <> if
+            addi r15,r15,-1
+            begin
+               stbu r3,1(r15)
+            countdown
+         then
+         pop2
+      t;
+
+      t: dump  ( adr len -- )
+         begin
+            addic. r14,r14,-1
+         >= while
+            mr    r3,r15           dot bl *
+            putcolon bl *
+            lbz   r3,0(r15)        dot bl *
+            putcr bl *
+            addi  r15,r15,1
+         repeat
+         pop2
+      t;
+
+      t: ldump  ( adr len -- )
+         begin
+            addic.  r14,r14,-4
+         >= while
+            mr    r3,r15         dot bl *
+            putcolon bl *
+            lwz   r3,0(r15)      dot bl *
+             putcr bl *
+            addi  r15,r15,4
+         repeat
+         pop2
+      t;
+
+      t: dup  ( n -- n n )
+         mr r17,r16  mr r16,r15  mr r15,r14
+      t;
+
+      t: drop  ( n -- )
+         mr r14,r15  mr r15,r16  mr r16,r17
+      t;
+
+      t: swap  ( n1 n2 -- n2 n1 )
+         mr r3,r15  mr r15,r14  mr r14,r3
+      t;
+
+      t: over  ( n1 n2 -- n1 n2 n1 )
+         mr r17,r16  mr r16,r15  mr r15,r14  mr r14,r16
+      t;
+
+      t: rot  ( n1 n2 n3 -- n2 n3 n1 )
+         mr r3,r16  mr r16,r15  mr r15,r14  mr r14,r3
+      t;
+
+      t: -rot  ( n1 n2 n3 -- n3 n1 n2 )
+         mr r3,r16  mr r16,r14  mr r14,r15  mr r15,r3
+      t;
+
+      t: script  ( address -- )
+         mr      r18,r14
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+         pop1
+      t;
+
+      t: rom-script  ( offset -- )
+         rom-pa  set    r10,*
+         add     r18,r14,r10
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+         pop1
+      t;
+
+      t: fexit  ( -- )
+         rlwinm   r12,r12,0,30,27	\ Clear script and no-echo flags (h#0c)
+      t;
+
+      t: scripts  ( -- )
+         set    r10,0
+         rom-pa h# 10000 + 1-  set     r11,*
+         begin
+            lbzu     r0,1(r11)
+            ascii \   cmpi  0,0,r0,*	\ If the script aread begings
+            =  if			\ with a comment character
+					\ display "s#: "
+               ascii s   set    r3,*       putchar bl *
+               ascii 0   addi   r3,r10,*   putchar bl *
+               ascii :   set    r3,*       putchar bl *
+               putspace bl *
+               begin			\ display the first comment line
+                  lbzu    r3,1(r11)	\ Get comment byte
+                  cmpi    0,0,r3,h#0d	\ Carriage return?
+                  <>  if  cmpi  0,0,r3,h#0a  then	\ Line feed?
+               <> while
+                  putchar bl *
+               repeat
+               putcr bl *
+            then
+            rlwinm  r11,r11,0,0,19		\ Clear 12 low bits
+            addi    r11,r11,h#fff		\ Advance to next script
+            addi    r10,r10,1
+            cmpi    0,0,r10,10
+         = until
+      t;
+
+      t: s0  ( -- )
+         rom-pa h# 10000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s1  ( -- )
+         rom-pa h# 11000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s2  ( -- )
+         rom-pa h# 12000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s3  ( -- )
+         rom-pa h# 13000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s4  ( -- )
+         rom-pa h# 14000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s5  ( -- )
+         rom-pa h# 15000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s6  ( -- )
+         rom-pa h# 16000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s7  ( -- )
+         rom-pa h# 17000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s8  ( -- )
+         rom-pa h# 18000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      t: s9  ( -- )
+         rom-pa h# 19000 + 1-   set     r18,*
+         ori     r12,r12,h#c		\ Set script and no-echo flags
+      t;
+
+      \ The original intention of "no-echo" and its inverse "echo" was
+      \ to create a capability like "dl" whereby one could download a
+      \ script over the serial line, but without requiring the use of
+      \ memory.  However, this has the serious problem that there is
+      \ no flow control, so commands that can take a long time (like
+      \ memory tests) potentially cause input overrun.  Consequently,
+      \ it's better to use quiet mode.  However, quiet mode has its own
+      \ problem: few if any terminal programs support its character-echo
+      \ flow control technique.  Character-echo flow control is not
+      \ particularly great anyway - it can be fooled by generated output
+      \ that happens to contain the next input character.
+      t: no-echo  ( -- )
+         ori     r12,r12,h#8		\ Set no-echo flag
+      t;
+
+      t: echo  ( -- )
+         rlwinm    r12,r12,0,29,27	\ Clear no-echo flag
+      t;
+
+      t: cr  ( -- )
+         putcr bl *
+      t;
+
+      t: key  ( -- char )
+         getchar bl *
+         push1  mr r14,r3
+      t;
+
+      t: emit  ( char -- )
+         mr     r3,r14
+	 putchar bl *
+         pop1
+      t;
+
+      \ This is useful for diagnostics in script mode, but essentially
+      \ useless otherwise.
+      t: .( ( "string" -- )
+         begin
+            andi.  r3,r12,4  0<>  if		\ Script mode
+               lbz  r3,0(r18)
+               addi r18,r18,1
+            else				\ Normal mode
+               getchar bl *   ( char in r3 )
+            then
+            char )  cmpi  0,0,r3,*
+         <> while
+            putchar bl *
+         repeat
+      t;
+
+      \ This is useful for commentary in script mode, but essentially
+      \ useless otherwise.
+      t: \ ( "rest-of-line" -- )
+         begin
+            andi.  r3,r12,4  0<>  if		\ Script mode
+               lbz r3,0(r18)
+            else			\ Normal mode
+               getchar bl *   ( char in r3 )
+            then
+            cmpi   0,0,r3,h#0a
+            <>  if  cmpi  0,0,r3,h#0d  then
+         = until
+      t;
+
+      t: goto  ( address -- )
+         mr     r3,r11  mr r4,r12  mr r5,r13
+         mtspr  lr,r15
+         bclr   20,0
+      t;
+
+      t: gettext  ( address -- length )
+          addi   r8,r14,-1
+          begin
+             getchar bl *
+             cmpi    0,0,r3,4	\ Control-D (ASCII EOT)
+          <> while
+             stbu    r0,1(r8)
+          repeat
+
+          addi  r8,r8,1
+          subf  r14,r14,r8
+      t;
+
+      t: getbytes  ( address length -- )
+          begin
+             addic.  r14,r14,-1
+          0>=  while
+             getchar bl *
+             stb     r3,0(r15)
+             addi    r15,r15,1
+          repeat
+          pop2
+      t;
+
+[ifdef] rom-pa
+      t: rom   ( -- adr )
+         push1  rom-pa set r14,*
+      t;
+[then]
+
+[ifdef] isa-io-pa
+      t: io   ( -- adr )
+         push1  isa-io-pa set r14,*
+      t;
+[then]
+
+[ifdef] mem0-pa
+      t: mem0   ( -- adr )
+         push1  mem0-pa set r14,*
+      t;
+[then]
+
+[ifdef] mem1-pa
+      t: mem1   ( -- adr )
+         push1  mem1-pa set r14,*
+      t;
+[then]
+
+[ifdef] mem2-pa
+      t: mem2   ( -- adr )
+         push1  mem2-pa set r14,*
+      t;
+[then]
+
+[ifdef] mem3-pa
+      t: mem3   ( -- adr )
+         push1  mem3-pa set r14,*
+      t;
+[then]
+
+      t: 1m  ( -- n )
+         push1  set r14,h#100000
+      t;
+
+      t: 2m  ( -- n )
+         push1  set r14,h#200000
+      t;
+
+      t: 4m  ( -- n )
+         push1  set r14,h#400000
+      t;
+
+      t: 8m  ( -- n )
+         push1  set r14,h#800000
+      t;
+
+      t: 16m  ( -- n )
+         push1  set r14,h#1000000
+      t;
+
+      t: 32m  ( -- n )
+         push1  set r14,h#2000000
+      t;
+
+[ifdef] load-nano-extras  load-nano-extras  [then]
+
+      \ The word was not recognized; parse it as a number or complain
+      convert-number bl *  cmpi 0,0,r4,0  <>  if  \ Number in r3
+         \ Push the number
+         spush      ( -- n )
+      else
+         \ The word was neither recognized nor numeric; complain
+         char ?  set r3,*  putchar bl *   putcr bl *
+      then
+
+   again
+
+end-code
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/msr.fth
===================================================================
--- cpu/ppc/msr.fth	                        (rev 0)
+++ cpu/ppc/msr.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,65 @@
+purpose: Machine Status Register access
+\ See license at end of file
+
+code msr@  ( -- n )
+   stwu   tos,-4(sp)
+   mfmsr  tos
+c;
+code msr!  ( n -- )
+   sync  isync
+   mtmsr  tos
+   sync  isync
+   lwz    tos,0(sp)
+   addi   sp,sp,4
+c;
+
+h# 8000 constant interrupt-enable-bit
+: interrupt-enable@   ( -- n )  msr@ interrupt-enable-bit and  ;
+: interrupt-enable!   ( n -- )
+   msr@ interrupt-enable-bit invert and  or  msr!
+;
+
+headerless
+: (enable-interrupts)   ( -- )  msr@  interrupt-enable-bit or  msr!  ;
+: (disable-interrupts)  ( -- )  msr@  interrupt-enable-bit invert and  msr!  ;
+: interrupts-enabled?  ( -- yes? )  interrupt-enable@  ;
+
+code (lock)  ( -- )  ( R: -- oldMSR )
+   mfmsr  t0
+   stwu   t0,-1cell(rp)
+   rlwinm t0,t0,0,17,15		\ Clear EE bit
+   mtmsr  t0
+c;
+code (unlock)  ( -- )  ( R: oldMSR -- )
+   lwz    t0,0(rp)
+   mtmsr  t0
+   addi   rp,rp,1cell
+c;
+
+: mapping-on   ( -- )  msr@ h# 30 or          msr!  ;
+: mapping-off  ( -- )  msr@ h# 30 invert and  msr!  ;
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/ntctrace.fth
===================================================================
--- cpu/ppc/ntctrace.fth	                        (rev 0)
+++ cpu/ppc/ntctrace.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,85 @@
+purpose: Stack backtrace for Microsoft/Motorola compiler
+\ See license at end of file
+
+headerless
+\ Search forward for a "bclr" instruction, then search backward for
+\ "lwz r0,XXX(r1), then get the contents of that effective address.
+: pc>caller  ( fp pc -- call-point-adr )
+   \ XXX we need to determine where we are in the function - if we are
+   \ before the place where the frame pointer is updated, or after the
+   \ place where it is restored, we must treat the function as a leaf
+   \ routine and get the caller address directly from LR.  It is probably
+   \ a good idea to first check to see if the function is a pure leaf
+   \ routine, by searching for a "stwu r1,XX(r1)" instruction between
+   \ the beginning and the bclr.  Hmmm...  I wonder if the beginning
+   \ address of a leaf routine can be determined?  It might not begin
+   \ with a "mfspr r0,lr".
+
+   begin  dup l@ h# 4e800020 <>  while  la1+  repeat  ( fp end-adr )
+   begin  -1 la+  dup l@  d# 16 >>  h# 8001 =  until  ( fp lwz-adr )
+   l@ h# ffff and  + l@ -1 la+
+;
+\ Search forward for an "mfspr r0,lr" instruction
+: pc>function  ( pc -- entry-adr )
+   begin  dup l@  h# 7c0802a6 <> while  -1 la+  repeat  ( mfspr-r0,lr-adr )
+;
+
+\ Determine the stack frame size of the function containing the given PC
+\ by finding the first "stwu r1,XXX(r1)" instruction in the function.
+: pc>framesize  ( pc -- /frame )
+   pc>function
+   begin  dup l@ d# 16 >>  h# 9421 <>  while  la1+  repeat   ( stwu-adr )
+
+   \ The offset is negative, so merge in the sign bits and negate it
+   l@ h# ffff invert or  negate
+;
+
+: .adr  base @ >r hex 9 u.r r> base !  ;
+
+: .call  ( fp caller function -- )
+   .adr  ." ()  called from" .adr ."   FP: " .x cr
+;
+
+\ This must agree with the stack initialization jointly established by
+\ init-pe-program and (init-program).
+: pe-stack-top  ( -- adr )  pe-image-base h# 20 -  ;
+
+headers
+\ XXX show TOC too
+: ms-ctrace  ( -- )
+   ?saved-state
+   %r1  %pc                                     ( frame-ptr pc )
+   begin                                        ( frame-ptr pc )
+      over  pe-stack-top <>                     ( frame-ptr pc )
+   while                                        ( frame-ptr pc )
+      dup pc>function >r                        ( frame-ptr pc )
+      2dup pc>caller  >r  over r> r> .call      ( frame-ptr pc )
+      2dup pc>caller -rot pc>framesize +  swap  ( frame-ptr' pc' )
+      exit?  if  2drop exit  then               ( frame-ptr' pc' )
+   repeat                                       ( frame-ptr' pc' )
+   2drop 0 pe-image-base .call                  ( )
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/objects.fth
===================================================================
--- cpu/ppc/objects.fth	                        (rev 0)
+++ cpu/ppc/objects.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,214 @@
+purpose: Action definition for multiple-code-field words.
+\ See license at end of file
+
+\ Data structures:
+\   nth-action-does-clause   acfs  unnest
+\   n-1th-action-does-clause acfs  unnest
+\   ...
+\   1th-action-does-clause acfs  unnest
+\   nth-adr
+\   n-1th-adr
+\   ...
+\   1th-adr
+\   n
+\   0th-action-does-clause acfs  unnest
+\   object-header  build-acfs
+\   (') 0th-adr uses
+
+needs doaction objsup.fth	\ Machine-dependent support routines
+
+decimal
+headerless
+
+0 value action#
+0 value #actions
+0 value action-adr
+headers
+: actions  ( #actions -- )
+   is #actions
+   #actions 1- /token * na1+ allot    ( #actions )   \ Make the jump table
+   \ The default action is a code field, which must be aligned
+   align acf-align  here is action-adr
+   0 is action#
+   #actions  action-adr /n -  n!
+;
+headerless
+\ Sets the address entry in the action table
+: set-action  ( -- )
+   action#  #actions  > abort" Too many actions defined"
+   lastacf  action-adr  action# /token * -  /n -  token!
+;
+headers
+: action:  ( -- )
+   action# if   \ Not the default action
+      doaction  set-action
+   else \ The default action, like does>
+      place-does
+   then
+
+   action# 1+ is action#
+   !csp
+   ]
+;
+: action-code  ( -- )
+   action#  if   \ Not the default action
+      acf-align start-code set-action
+   else          \ The default action, like ;code
+      start-;code
+   then
+
+   \ For the default action, the apf of the child word is found in
+   \ the same way as with ;code words.
+
+   action# 1+ is action#
+   do-entercode
+;
+: use-actions  ( -- )
+   state @  if
+      compile (')  action-adr  token,  compile used
+   else
+      action-adr  used
+   then
+; immediate
+
+headerless
+: .object-error
+   ( object-acf action-adr false  |  acf action# #actions true -- ... )
+   ( ... -- object-acf action-adr )
+   if
+      ." Unimplemented action # " swap .d  ." on object " swap .name
+      ." , whose maximum action # is " 1- .d cr
+      abort
+   then
+;
+
+headers
+
+\ Run-time code for "to".  This is important enough to deserve special
+\ optimization.
+code to  ( -- )
+   lwzu  t0,4(ip)	\ Object acf in t0
+   add   t0,t0,base	\ Relocate
+
+   stwu  tos,-4(sp)	\ Save the top-of-stack register on memory stack
+   addi  tos,t0,8	\ Put pfa in top-of-stack register
+
+   lwz   t1,4(t0)	\ Token of default action 
+   add   t1,t1,base	\ Relocate
+   lwz   w,-8(t1)	\ Token of "to" action clause
+
+   \ Tail of "NEXT"
+   lwzux t1,w,base	\ Read the contents of the code field
+   add   t1,t1,base	\ Relocate
+   mtspr lr,t1
+   bclr	 20,0		\ Execute the code
+end-code
+
+code dispatch-action  ( acf action-adr -- )
+			\ action-adr in tos
+   lwz   t0,0(sp)	\ Object acf in t0
+   addi  sp,sp,4
+
+   move  w,tos		\ Token of action clause
+
+   addi  tos,t0,8	\ Put pfa in top-of-stack register
+
+   lwz   t1,0(w)	\ Read the contents of the code field
+   \ next-tail1
+   add   t1,t1,base	\ Relocate
+   mtspr lr,t1
+   bclr	 20,0		\ Execute the code
+end-code
+
+\ Executes the numbered action of the indicated object
+\ It might be worthwhile to implement perform-action entirely in code.
+: perform-action  ( object-acf action# -- )
+   dup if
+      >action-adr .object-error  ( object-acf action-adr )
+      dispatch-action
+   else
+      drop execute
+   then
+;
+
+: action-name  \ name  ( action-offset-adr -- )
+   create   1+ /token * negate ,
+   ;code
+
+   lwzu  t0,4(ip)	\ Object acf in t0
+   add   t0,t0,base	\ Relocate
+
+   lwz   t1,4(t0)	\ Token of default action 
+   add   t1,t1,base	\ Relocate
+   lwz   tos,0(tos)	\ Get action offset
+   lwzx  w,tos,t1	\ Token of indicated action clause
+
+   addi  tos,t0,8	\ Put pfa in top-of-stack register
+
+   \ Tail of "NEXT"
+   lwzux t1,w,base	\ Read the contents of the code field
+   add   t1,t1,base	\ Relocate
+   mtspr lr,t1
+   bclr	 20,0		\ Execute the code
+end-code
+
+\ 1 action-name to
+2 action-name addr
+
+: action-compiler:  \ name  ( -- )
+   bl word  dup find  0=  ?missing   \ pstr acf
+   swap "create  token,  immediate
+   does>     ( apf )
+     +level  ( apf )	\ Enter temporary compile state if necessary
+     token@ (compile)	\ Compile run-time action-name word
+     ' (compile)	\ Compile object acf
+     -level		\ Exit temporary compile state, perhaps run word
+;
+\ action-compiler: to
+action-compiler: addr
+
+
+\ Makes "is" and "to" synonymous.  "is" first checks to see if the
+\ object is of one of the kernel object types (which don't have multiple
+\ code fields), and if so, compiles or executes the "(is) <token>" form.
+\ If the object is not of one of the kernel object types, "is" calls
+\ "to-hook" to handle the object as a multiple-code field type object.
+
+: (to)  ( [data] acf -- )  +level  compile to  (compile) -level  ;
+' (to) is to-hook
+alias to is
+
+\ 3 actions
+\ action:  @  ;
+\ action:  !  ; ( is )
+\ action:     ; ( addr )
+\ : value  \ name  ( initial-value -- )
+\    create ,
+\    use-actions
+\ ;
+
+\ Need inheritance
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/objsup.fth
===================================================================
--- cpu/ppc/objsup.fth	                        (rev 0)
+++ cpu/ppc/objsup.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,102 @@
+purpose: Machine dependent support routines for multiple-code-field "objects"
+\ See license at end of file
+
+\ These words know intimate details about the Forth virtual machine
+\ implementation.
+
+\ Assembles the common code executed by actions.  That code
+\ extracts the next token (which is the acf of the object) from the
+\ code stream and leaves the corresponding apf on the stack.
+
+headerless
+
+: start-code  ( -- )  code-cf  !csp  ;
+
+\ Assembles code to begin a ;code clause
+: start-;code  ( -- )  start-code  ;
+
+\ Code field for an object action.
+: doaction  ( -- )  acf-align colon-cf  ;
+
+\ Returns the address of the code executed by the word whose code field
+\ address is acf
+: >code-adr  ( acf -- code-adr )  token@  ;
+
+code >action-adr  ( object-acf action# -- )
+  ( ... -- object-acf action# #actions true | object-apf action-adr false )
+				\ action# in tos
+   lwz  t0,0(sp)		\ object-acf in t0 
+   lwz  t1,1cell(t0)		\ code offset in t1
+   add  t1,t1,base		\ Relocate; code address in t1
+   lwz  t2,-1cell(t1)		\ #actions in t2 
+   cmp  0,0,t2,tos		\ Test action number
+   <= if			\ "true" branch is error
+      stwu  tos,-1cell(sp)	\ Push action#
+      stwu  t2,-1cell(sp)	\ Push #actions
+      addi  tos,r0,-1		\ Return true for error
+   else
+      addi  t0,t0,/cf+1cell	\ Compute object-apf from object-acf
+      stw   t0,0(sp)		\ Put action-apf on stack
+
+      rlwinm tos,tos,2,0,29	\ Convert index to byte offset
+      subfc t1,tos,t1		\ Skip back #actions tokens
+				\ ( Use subfc for POWER compatibility)
+      lwz   t1,-1cell(t1)	\ Get token, accounting for action# field
+      add   t1,t1,base		\ Relocate
+      stwu  t1,-1cell(sp)	\ Push action-adr
+      addi  tos,r0,0		\ Return false for no error
+   then
+c;
+
+headers
+: action-name  \ name  ( action# -- )
+   create  ,		\ Store action number in data field
+   ;code               ( -- object-pfa )
+      lwz    t0,0(tos)		\ Action# in t0 
+
+      lwzu   t1,/token(ip)	\ Object acf in t1 
+      add    t1,t1,base		\ Relocate
+
+      addi   tos,t1,/cf+1cell	\ Compute and push object-apf
+
+      lwz    t1,1cell(t1)	\ relative version of ..
+      add    t1,t1,base		\ default action code address
+   
+      rlwinm t0,t0,2,0,29	\ Convert index to byte offset
+      subfc  t1,t0,t1		\ Skip back action# tokens
+				\ ( Use subfc for POWER compatibility)
+
+      lwz    w,-1cell(t1)	\ Get token, accounting for action# field
+
+      lwzux  t1,w,base		\ next-tail ...
+      add    t1,t1,base
+      mtspr  lr,t1
+      bclr   20,0
+end-code
+
+: >action#  ( apf -- action# )  @  ;
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/occhksum.fth
===================================================================
--- cpu/ppc/occhksum.fth	                        (rev 0)
+++ cpu/ppc/occhksum.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,102 @@
+purpose: Internet checksum (one's complement of 16-bit words) primitive
+\ See license at end of file
+
+\ The complete checksum calculation consists of:
+\ a) add together all the 16-bit big-endian words in the buffer, with
+\    wrap-around carry (i.e. a carry out of the high bit is added back
+\    in at the low bit).
+\ b) Take the one's complement of the result, preserving only the
+\    least-significant 16 bits.
+\ c) If the result is 0, change it to ffff.
+
+\ The process of computing a checksum for UDP packets involves the
+\ creation of a "pseudo header" containing selected information
+\ from the IP header, and checksumming the combination of that pseudo
+\ header and the UDP packet.  To do so, it is convenient to perform
+\ step (a) of the calculation separately on the two pieces (pseudo header
+\ and UDP packet).  Thus we factor the checksum calculation code with
+\ a separate primitive "(oc-checksum)" that performs step (a).  That
+\ primitive is worth optimizing; steps (b) and (c) are typically not.
+
+headerless
+\ This algorithm depends on the assumption that the buffer is
+\ short enough so that we never have a carry out of the high
+\ 16 bit word.  Assuming worst case data (all bytes ff), the
+\ buffer would have to be 128K + 3 bytes long for this to happen.
+\ The maximum length of an IP packet is 64K bytes, so we are safe.
+\ This allows us to accumulate the end-around carries in the high
+\ 16-bit word and add them in one operation at the end.
+
+code (oc-checksum)  ( accum adr len -- checksum )
+   mr     t1,tos		\ t1: len
+   lwz    t0,0(sp)		\ t0: adr
+   lwz    tos,4(sp)		\ tos: accum
+   addi   sp,sp,8		\ clean up stack
+
+   mr     t2,t1			\ t2: copy of len
+   cmpi   0,0,t1,2		\ Are there any complete words to do?
+   >=  if
+
+      mfspr  t5,ctr			\ Save counter
+
+      rlwinm t1,t1,31,1,31		\ Convert to word count
+      mtspr  ctr,t1
+
+      'user in-little-endian?  lwz  t3,*	\ Which endian
+      0=  if				\ If BE, use word accesses
+         addi    t0,t0,-2		\ Account for pre-increment
+
+         begin
+            lhzu  t3,2(t0)		\ Read word and increment pointer
+            add   tos,tos,t3		\ Update checksum
+         countdown
+
+         addi    t0,t0,2		\ Point to next byte
+      else				\ If LE, use byte accesses
+         addi    t0,t0,-1		\ Account for pre-increment
+
+         begin
+            lbzu   t4,1(t0)		\ Read high byte and increment pointer
+            lbzu   t3,1(t0)		\ Read low byte and increment pointer
+            rlwimi t3,t4,8,16,23	\ Merge high and low bytes into t3
+            add    tos,tos,t3		\ Update checksum
+         countdown
+
+         addi    t0,t0,1		\ Point to next byte
+      then
+
+      mtspr   ctr,t5			\ Restore counter
+   then
+
+   andi.   r0,t2,1		\ Is there a leftover byte?
+   0<>  if
+      lbz    t3,0(t0)		\ Get the byte      
+      rlwinm t3,t3,8,16,23	\ Move it to the correct position in the word
+      add    tos,tos,t3		\ Update checksum
+   then
+
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/devalias.fth
===================================================================
--- cpu/ppc/olpc/devalias.fth	                        (rev 0)
+++ cpu/ppc/olpc/devalias.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,40 @@
+purpose: Platform-specific device aliases
+\ See license at end of file
+
+devalias net /pci/ethernet at e
+
+.( XXX olpc/devalias.fth) cr
+devalias disk0 /pci/disk at 0,0:1
+devalias disk1 /pci/scsi at c/disk at 1,0:1
+devalias disk2 /pci/scsi at c/disk at 2,0:1
+devalias cdrom /pci/scsi at c/disk at 5,0
+
+devalias c /pci/scsi at c/disk at 0,0
+
+devalias disk  /pci/scsi at c/disk at 0,0:1
+
+devalias com1 /serial at f1012000
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/elf.fth
===================================================================
--- cpu/ppc/olpc/elf.fth	                        (rev 0)
+++ cpu/ppc/olpc/elf.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,126 @@
+purpose: Load image handler for ELF (Extended Linker Format)
+\ See license at end of file
+
+hex
+
+headerless
+: elf?  ( -- flag )  0 +base 4  " "(7f)ELF" $=  ;
+: elf-le?  ( -- flag )  5 +base c@  1 =  ;
+: elfl@  ( adr -- n )  elf-le?  if   le-l@  else  be-l@  then  ;
+: elfw@  ( adr -- w )  elf-le?  if   le-w@  else  be-w@  then  ;
+
+: eh-l@  ( offset -- l )  +base elfl@  ;
+: eh-w@  ( offset -- w )  +base elfw@  ;
+
+: +elfl@  ( adr offset -- n )  + elfl@  ;
+
+\ XXX the following code assumes that the value of load-base is such that
+\ the copying of program sections to their correct locations does not
+\ overwrite portions of other sections that have not yet been copied.
+
+\ One sufficient condition is that the program sections are stored in the
+\ ELF file in ascending order of their execution addresses (vaddr fields)
+\ and that load-base is large enough that the sections must be moved to
+\ lower addresses.
+
+0 value high-water
+0 value low-water
+: record-extent  ( adr len -- )
+   bounds  low-water umin to low-water   high-water umax to high-water 
+;   
+
+: prepare-elf-program  ( -- entry-point )
+   0  to high-water
+   -1 to low-water
+
+   \ Copy all pheaders to allocated memory to protect them from being
+   \ overwritten when we copy the programs to their final destinations.
+
+   \ e_entry       e_phentsize      e_phnum  
+   h# 18 eh-l@  h# 2a eh-w@ dup  h# 2c eh-w@ *   ( entry phentsize phsize)
+   dup alloc-mem  swap                       ( entry phentsize pbbuf phsize )
+
+   \     e_phoff
+   2dup  1c eh-l@ +base   -rot move          ( entry phentsize phbuf phsize )
+
+   \ Scan the program sections and determine how much memory is needed
+   2dup bounds  ?do	( entry phentsize phbuf phsize ) \ throughout loop
+      \ p_type  PT_LOAD
+      i 0 +elfl@  1 =  if
+	 \ p_vaddr       p_memsz
+         i 8 +elfl@  i h# 14 +elfl@  record-extent
+      then
+   2 pick +loop		( entry phentsize phbuf phsize )
+
+   \ XXX Ultimatelty we need to allocate physical memory and map
+   \ it appropriately, but for now we just claim the virtual address
+   \ space, assuming that it is already mapped.
+
+   low-water 0   high-water low-water -  0  mem-claim drop  ( adr )
+   low-water <> abort" Couldn't claim the program's memory"
+
+   2dup bounds  ?do	( entry phentsize phbuf phsize ) \ throughout loop
+      \ p_type  PT_LOAD
+      i 0 +elfl@  1 =  if
+
+         \ XXX we need to acquire and map the memory first!
+
+	 \ Move it into the correct vaddr.
+         \ p_offset          p_vaddr      p_filesz
+	 i 4 +elfl@ +base   i 8 +elfl@  i h# 10 +elfl@   ( src dst len )
+         2dup 2>r  move  2r> sync-cache
+
+         \ Zero any bytes that are not stored in the file
+	 \ p_vaddr       p_memsz        p_filesz
+         i 8 +elfl@  i h# 14 +elfl@  i h# 10 +elfl@  /string  erase
+      then
+   2 pick +loop		( entry phentsize phbuf phsize )
+   free-mem  drop       ( entry )
+;
+
+defer verify-machine-type
+: (verify-machine-type)   ( -- )
+   h# 10 eh-w@  2  <>  abort" The loaded file is not executable"
+   h# 12 eh-w@  dup d# 17 <>  swap d# 20 <>  and
+   abort" The loaded file is not a PowerPC program"
+;
+' (verify-machine-type) to verify-machine-type
+
+: init-elf-program   ( -- )
+   verify-machine-type
+
+   prepare-elf-program           ( pc )
+
+   h# 8000 alloc-mem  h# 8000 +  ( pc sp )
+
+   (init-program)
+;
+
+headers
+warning @ warning off
+: init-program  ( -- )  elf?  if  init-elf-program  else  init-program  then  ;
+warning !
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/flash.fth
===================================================================
--- cpu/ppc/olpc/flash.fth	                        (rev 0)
+++ cpu/ppc/olpc/flash.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,65 @@
+purpose: Setup for Flash ROM access
+\ See license at end of file
+
+h# 8.0000 to /flash
+h# fff0.0000 constant rom0-pa
+h# fff8.0000 constant rom1-pa
+rom0-pa value rom-pa
+0 value rom0
+
+0 value flashbase
+
+: ?swizzle  ( adr -- adr' )  in-little-endian?  if  7 xor  then  ;
+: (fctl!)   ( n a -- )  flashbase +  ?swizzle  c!  ;  ' (fctl!)  to fctl!
+: (fdata!)  ( n a -- )  flashbase +  ?swizzle  c!  ;  ' (fdata!) to fdata!
+: (fc@)     ( a -- n )  flashbase +  ?swizzle  c@  ;  ' (fc@)    to fc@
+
+
+: open-flash  ( -- )
+   flashbase 0=  if
+      rom-pa /flash  root-map-in  to flashbase
+   then
+   h# a8 config-l@  h# 00001000 or  h# a8 config-l!
+;
+: close-flash  ( -- )
+   flashbase /flash  root-map-out  0 to flashbase
+   h# a8 config-l@  h# 00001000 invert and  h# a8 config-l!
+;
+' open-flash to enable-flash-writes
+
+: (use-rom)  ( adr -- )  flashbase  if  close-flash  then  to rom-pa  ;
+: use-rom1  ( -- )  rom1-pa (use-rom)  ;
+: use-rom0  ( -- )  rom0-pa (use-rom)  ;
+
+\ Copy ROM0 to ROM1
+
+\ (flash) is a forward reference.
+: copy-rom  ( -- )
+   rom-pa >r
+   " rom0" $read-file  use-rom1 " (flash)" evaluate
+   r> (use-rom)
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/fw.bth
===================================================================
--- cpu/ppc/olpc/fw.bth	                        (rev 0)
+++ cpu/ppc/olpc/fw.bth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,300 @@
+purpose: Load file for fw.dic for OLPC School Server
+\ See license at end of file
+
+dictionary: ${BP}/cpu/ppc/build/basefw.dic
+command: &ppcforth &dictionary &this
+build-now
+
+\ Configuration defines
+create bailout-early
+true to stand-init-debug?
+true constant real-mode?
+
+\ ' $report-name is include-hook
+
+headerless
+h# 1000 to pagesize
+d# 12   to pageshift
+
+headers
+true value chrp?	\ Change as needed
+
+dev /
+1 encode-int  " #address-cells"  property
+device-end
+
+\ Memory management services
+fload ${BP}/ofw/core/clntmem1.fth	\ client services for memory
+fload ${BP}/ofw/core/memlist.fth     \ Resource list common routines
+fload ${BP}/ofw/core/showlist.fth	\ Linked list display tool
+fload ${BP}/ofw/core/allocph1.fth	\ S Physical memory allocator
+fload ${BP}/ofw/core/availpm.fth	\ Available memory list
+
+headerless
+: (memory?)  ( phys -- flag )  h# 8000.0000  u<  ;   \ The CHRP boundary is 0x4000.0000
+' (memory?) to memory?
+
+headers
+\ Handy tools to mark device nodes with the "built-in" property
+: mark-builtin  ( -- false )
+   0 package(  0 0 encode-bytes  " built-in" property  )package
+   false
+;
+: mark-builtin-all  ( -- )
+   ['] mark-builtin ['] search-preorder catch  2drop
+;
+
+\ Load file format handlers
+
+fload ${BP}/cpu/ppc/initpgm.fth		\ Basic boot handler
+fload ${BP}/cpu/ppc/olpc/elf.fth	\ handler for ELF booting
+fload ${BP}/ofw/inet/loadtcp.fth	\ TCP extensions
+
+\ Reboot and re-entry code
+fload ${BP}/cpu/ppc/reboot.fth		\ Restart the client program
+fload ${BP}/cpu/ppc/reenter.fth		\ Various entries into Forth
+
+\ Miscellaneous hardware interface words
+fload ${BP}/cpu/ppc/cache603.fth	\ Cache synchronization
+fload ${BP}/cpu/ppc/segreg.fth		\ Segment register access
+fload ${BP}/cpu/ppc/bat.fth		\ BAT mapping register access
+fload ${BP}/cpu/ppc/scrub.fth		\ Fast memory scrubbing using "dcbz"
+
+hex
+warning on
+
+h#  40.0000 ' load-base set-config-int-default
+
+headerless
+: (initial-heap)  ( -- adr len )  sp0 @ ps-size -  limit  tuck -  ;
+' (initial-heap) is initial-heap
+headers
+
+" /openprom" find-device
+   " FirmWorks,3.0" encode-string " model" property
+device-end
+
+\ XXX this may need to change for L2 cache support
+warning @ warning off
+\ We can't turn on the dcache until we have set up BAT mapping
+stand-init: Instruction cache on
+   icache-on? 0=  if  icache-on  then
+;
+warning !
+
+fload ${BP}/cpu/ppc/dectrap.fth		\ Null decrementer handler
+stand-init: Enable machine check exceptions
+   msr@  h# 1000 or  msr!
+;
+
+headerless
+defer set-memory-map  ' noop to set-memory-map
+
+headers
+stand-init: Set Memory Map
+   set-memory-map
+;
+
+headerless
+h# 6000.0000 value fw-virt-base			\ 32 megs of mapping space
+h# 0200.0000 value fw-virt-size
+
+headers
+0 value memsize
+
+fload ${BP}/cpu/ppc/loadvmem.fth		\ /mmu node
+stand-init: MMU
+   " /mmu" open-dev mmu-node !
+;
+
+fload ${BP}/cpu/ppc/realcif.fth		\ Real-mode client interface fixups
+
+fload ${BP}/cpu/ppc/rootnode.fth	\ Methods for root node
+stand-init: Root node
+   " /"  " init"  execute-device-method drop
+;
+stand-init: Data cache on
+   msr@ h# 10 and  dcache-on? 0=  and  if  dcache-on  then
+;
+stand-init: Fast CPU mode
+   fastest-mode
+;
+
+0 0  " "  " /"  begin-package
+fload ${BP}/cpu/ppc/olpc/mappci.fth	\ PCI-to-root-node address translation
+fload ${BP}/dev/pcibus.fth		\ Generic PCI bus package
+end-package
+stand-init: PCI host bridge
+   " /pci" " init" execute-device-method drop
+;
+
+fload ${BP}/dev/pciprobe.fth
+defer probe-all  ' probe-pci to probe-all
+
+fload ${BP}/cpu/ppc/cpunode.fth
+
+fload ${BP}/ofw/core/bailout.fth
+
+fload ${BP}/cpu/ppc/olpc/reset.fth	 \ Reset via "92" register
+
+fload ${BP}/ofw/core/countdwn.fth	 \ Startup countdown
+fload ${BP}/cpu/ppc/banner.fth		 \ Startup banner
+
+fload ${BP}/forth/lib/pattern.fth	\ Text string pattern matching
+fload ${BP}/ofw/core/filecmds.fth	\ File commands: dir, del, ren, etc.
+
+\ fload ${BP}/pkg/flash/flash.fth
+\ fload ${BP}/dev/amd29fxx.fth
+
+\ fload ${BP}/cpu/ppc/ntctrace.fth
+
+fload ${BP}/ofw/core/startup.fth
+
+warning on
+
+h#   4.0000 constant initial-heap-size
+
+\ fload builton.fth  \ Automatic version stamp
+\ dev /openprom
+\    built-date-int encode-int " built-on" property
+\    0 0 encode-bytes  " arc-interrupt-level=vector" property
+\ device-end
+
+\ fload ${BP}/arch/prep/loadcvar.fth	\ PREP NVRAM layout
+
+\ fload ${BP}/arch/prep/ultra/fixednv.fth	\ Offsets of fixed regions of NVRAM 
+
+h# f100.0000 constant mv64660-base   \ Needs to be mapped to a VA
+
+: mv-b@  ( offset -- byte )  mv64660-base + rb@  ;
+: mv-b!  ( byte offset -- )  mv64660-base + rb!  ;
+: mv-w@  ( offset -- byte )  mv64660-base + rw@  ;
+: mv-w!  ( byte offset -- )  mv64660-base + rw!  ;
+: mv-l@  ( offset -- byte )  mv64660-base + rl@  ;
+: mv-l!  ( byte offset -- )  mv64660-base + rl!  ;
+: uart@  ( reg# -- byte )  /l*  h# 1.2000 +  mv-b@  ;
+: uart!  ( byte reg# -- )  /l*  h# 1.2000 +  mv-b!  ;
+fload ${BP}/dev/diaguart.fth		\ Diagnostic driver for PC-compatible serial port
+
+fload ${BP}/forth/lib/sysuart.fth	\ Plug UART routines into key and emit
+' ukey is diag-key			\ Feed UART input to "dl"
+
+fload ${BP}/cpu/ppc/olpc/reports.fth	\ Low-level character output routines
+
+fload ${BP}/cpu/ppc/olpc/pciconfig.fth	\ Configuration space access
+\ fload ${BP}/arch/prep/eagle.fth	\ Eagle configuration registers
+fload ${BP}/cpu/ppc/ppcboot.fth		\ Forth startup code
+
+[ifdef] bailout-early
+: startup quit ;
+
+install-rom-cold
+
+.( --- Saving fw.dic ---) cr  p" fw.dic" save-forth
+bye
+[then]
+
+fload ${BP}/cpu/ppc/olpc/rootnode.fth	\ Methods for root node
+
+fload ${BP}/cpu/ppc/olpc/pcinode.fth	\ System-specific words for PCI
+
+" "  dup config-string pci-probe-list
+
+6 buffer: 'system-mac-address
+: get-mac-address  ( -- )
+   " /ethernet" find-package if
+      " local-mac-address" rot get-package-property 0= if   ( a 6 )
+	 'system-mac-address swap move  exit
+      then
+   then
+   " 123456" 'system-mac-address swap move	\ better than nothing?
+;
+: (system-mac-address)  ( -- addr len )  'system-mac-address 6  ;
+' (system-mac-address) is system-mac-address
+
+: (probe-all)  ( -- )
+   " probe-" do-drop-in
+   probe-pci ( probe-pci-e  probe-pci-x )  get-mac-address
+   " probe+" do-drop-in
+;
+' (probe-all) to probe-all
+
+[ifdef] notyet
+0 0  " ????????"  " /" begin-package		\ Real-time clock node
+fload ${BP}/dev/ds1385r.fth
+end-package
+stand-init: RTC
+   " /rtc" open-dev  clock-node !
+;
+
+0 0  " i74"  " /pci/isa" begin-package		\ NVRAM node
+fload ${BP}/dev/ds1385n.fth
+
+" ds1385-nvram"  encode-string
+" pnpPNP,8"      encode-string encode+
+" compatible" property
+
+env-end-offset to /nvram
+end-package
+stand-init: NVRAM
+   " /nvram" open-dev  to nvram-node
+    init-config-vars
+;
+[endif]
+
+\ fload ${BP}/dev/isa/irq.fth
+
+stand-init:  Keyboard overrides
+   ?bailout
+;
+
+\ fload ${BP}/cpu/ppc/olpc/cpunode.fth		\ CPU node additions
+
+fload ${BP}/cpu/ppc/olpc/probemem.fth		\ Memory probing
+
+fload ${BP}/cpu/ppc/olpc/devalias.fth	\ Device aliases
+
+0 0 " fff00000" " /" begin-package
+   " flash" device-name
+   h# 8.0000 constant /device
+   my-address my-space /device reg
+   fload ${BP}/cpu/x86/pc/flashpkg.fth
+end-package
+
+devalias rom  /flash at fff00000
+
+fload ${BP}/cpu/ppc/olpc/flash.fth		\ Low-level FLASH access
+
+fload ${BP}/pkg/flash/saveflsh.fth		\ FLASH to disk and back
+
+\ ' false to interrupt-auto-boot?	\ Don't do countdown
+
+patch noop fw-title rom-cold	\ Superseded by banner
+
+install-rom-cold
+
+.( --- Saving subset.dic ---) cr  p" subset.dic" save-forth
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/fwuboot.bth
===================================================================
--- cpu/ppc/olpc/fwuboot.bth	                        (rev 0)
+++ cpu/ppc/olpc/fwuboot.bth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,71 @@
+purpose: Create a Uboot-format image
+\ See license at end of file
+
+command: &builder &this
+in: ${BP}/cpu/ppc/olpc/build/fw.dic
+build-now
+
+create uboot-header
+  h# 27051956 be-l,
+  0           be-l,  \ Header CRC, set later
+  0           be-l,  \ Timestamp
+  0           be-l,  \ Data size
+  h# 0f000000 be-l,  \ Load address
+  h# 0f000000 be-l,  \ Entry address
+  0           be-l,  \ Data CRC, set later
+  5              c,  \ OS type - Linux 
+  7              c,  \ CPU type - PowerPC
+  1              c,  \ Image type - standalone (kernel is 2)
+  0              c,  \ Compression type - none
+
+  here h# 20 blank
+  " Open Firmware" here swap move
+  h# 20 allot
+
+here uboot-header -  constant /uboot-header
+
+fload ${BP}/forth/lib/crc32.fth
+
+reading fw.dic
+ifd @ fsize constant /image
+/image buffer: filebuf
+filebuf /image ifd @ fgets  /image <>  abort" Can't read image"
+ifd @ fclose
+
+/image uboot-header 3 la+ be-l!
+
+\ Compute the image CRC and store it in the uboot header
+-1 crctab  filebuf /image  ($crc)  invert  uboot-header 6 la+ be-l!
+
+\ Compute the header CRC and store it in the uboot header
+-1 crctab  uboot-header /uboot-header  ($crc)  invert  uboot-header 1 la+ be-l!
+
+.( --- Saving as fwuboot.rom) cr
+writing fwuboot.rom
+uboot-header /uboot-header ofd @ fputs
+filebuf      /image        ofd @ fputs
+ofd @ fclose
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/mappci.fth
===================================================================
--- cpu/ppc/olpc/mappci.fth	                        (rev 0)
+++ cpu/ppc/olpc/mappci.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,38 @@
+purpose: PCI physical address mapping to root node
+\ See license at end of file
+
+headerless
+: map-pci-phys  ( paddr io? phys.hi size -- vaddr )
+   >r  drop                    ( paddr io? R: size )
+   if  h# c800.0000  else  h# a000.0000  then  ( paddr R: size )
+   or  r>  " map-in" $call-parent
+;
+: >pci-devaddr  ( root-devaddr -- pci-devaddr )
+   chrp?  0=  if  h# 8000.0000  +  then
+;
+: pci-devaddr>  ( pci-devaddr -- root-devaddr )   ;
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/pciconfig.fth
===================================================================
--- cpu/ppc/olpc/pciconfig.fth	                        (rev 0)
+++ cpu/ppc/olpc/pciconfig.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,47 @@
+purpose: PCI configuration space access for Marvell MV64660
+\ See license at end of file
+
+\ Ostensibly this applies to the PCI bus and thus should be in the PCI node.
+\ However, many of the host bridge registers are accessed via this mechanism,
+\ so it is convenient to make the configuration access words globally-visible.
+\ This mechanism works for several different PCI host bridges.
+
+headerless
+
+: config-map  ( config-adr -- port )
+   dup  3 invert and  h# 8000.0000 or  h# 3.0c78 mv-l!  ( config-adr )
+   3 and  h# 3.0c7c or
+;
+
+headers
+
+: config-l@  ( config-addr -- l )  config-map mv-l@  ;
+: config-l!  ( l config-addr -- )  config-map mv-l!  ;
+: config-w@  ( config-addr -- w )  config-map mv-w@  ;
+: config-w!  ( w config-addr -- )  config-map mv-w!  ;
+: config-b@  ( config-addr -- c )  config-map mv-b@  ;
+: config-b!  ( c config-addr -- )  config-map mv-b!  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/pcinode.fth
===================================================================
--- cpu/ppc/olpc/pcinode.fth	                        (rev 0)
+++ cpu/ppc/olpc/pcinode.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,109 @@
+purpose: System-specific portions of PCI bus package
+\ See license at end of file
+
+dev /pci
+
+d# 66,666,666 encode-int " clock-frequency"  property
+
+headers
+
+\ These package methods use the global versions of the configuration
+\ access words.  This is appropriate only for single-PCI-bus systems.
+
+: config-l@  ( config-addr -- l )  config-l@  ;
+: config-l!  ( l config-addr -- )  config-l!  ;
+: config-w@  ( config-addr -- w )  config-w@  ;
+: config-w!  ( w config-addr -- )  config-w!  ;
+: config-b@  ( config-addr -- c )  config-b@  ;
+: config-b!  ( c config-addr -- )  config-b!  ;
+
+\  ------PCI Address-------  ---Host Address--  -- size --
+\ phys.hi    .mid      .low   phys.hi   .lo     .hi    .lo
+
+.( XXX - ranges properties for PCI node) cr
+0 0 encode-bytes
+0100.0000 +i  0+i         0+i  c800.0000 +i     0+i 0800.0000 +i  \ PCI I/O
+0200.0000 +i  0+i         0+i  a000.0000 +i     0+i 2000.0000 +i  \ PCI Mem
+   " ranges" property
+
+headers
+
+: init  ( -- )
+   \ Could do interrupt routing here
+;
+
+[ifdef] notyet
+headerless
+
+\ Determine the parent interrupt information (the "interrupt line" in PCI
+\ parlance) from the child's "interrupt pin" and the child's address,
+\ returning "int-line true" if the child's interrupt line register should
+\ be set or "false" otherwise.
+
+\ This table describes the wiring of PCI interrupt pins at the PCI slots
+\ to PIRQ inputs on the 82378zb chip.  The wiring varies from slot to slot.
+
+create slot-map
+
+\  Pin A  Pin B  Pin C  Pin D     Dev#
+
+    2 c,  ff c,  ff c,  ff c,   \  c SCSI
+   ff c,  ff c,  ff c,  ff c,   \  d nothing
+    0 c,  ff c,  ff c,  ff c,   \  e Ethernet
+    3 c,  ff c,  ff c,  ff c,   \  f Display
+    0 c,   1 c,   2 c,   2 c,   \ 10 Slot 1  (the riser connects INTC and INTD)
+    1 c,   2 c,   2 c,   0 c,   \ 11 Slot 2  (the riser connects INTC and INTD)
+    2 c,   2 c,   0 c,   1 c,   \ 12 Slot 3  (the riser connects INTC and INTD)
+
+: pin,dev>pirq  ( pin# dev# -- true | pirq# false )
+   dup  c 12 between 0=  if  2drop true exit  then   ( int-pin dev# )
+
+   c - 4 * +  slot-map + c@			     ( pirq#|ff )
+   dup h# ff  =  if  drop true  else  false  then
+;
+
+headers
+
+: assign-int-line  ( phys.hi.func int-pin -- false | int-line true )
+   dup 0=  if  2drop false  exit  then               ( phys.hi.func int-pin# )
+   1-  swap d# 11 rshift  h# 1f and                  ( int-pin0 dev# )
+
+   \ Bail out for non-existent device IDs
+   pin,dev>pirq  if  false exit  then                ( pirq# )
+
+   pirq>irq                                          ( irq# )
+
+   true
+;
+
+h# 700 encode-int				\ Mask of implemented slots
+" PCI 1" encode-string encode+
+" PCI 2" encode-string encode+
+" PCI 3" encode-string encode+  " slot-names" property
+[then]
+
+device-end
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/probemem.fth
===================================================================
--- cpu/ppc/olpc/probemem.fth	                        (rev 0)
+++ cpu/ppc/olpc/probemem.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,52 @@
+purpose: Memory probing
+\ See license at end of file
+
+" /memory" find-device
+
+\ This assumes, without checking, that bottom and top are each aligned on
+\ a cache block boundary
+: scrub&release  ( bottom top -- )
+   2dup =  if  2drop exit  then
+   over -  2dup  berase
+   release
+;
+
+: probe  ( -- )
+   0 memsize  reg       \ Put all memory in the "reg" property value
+
+   h# 4000        origin pagesize round-down  scrub&release
+
+   memtop @       memsize                     scrub&release
+;
+
+device-end
+
+also forth definitions
+stand-init: Probing memory
+   " probe" memory-node @ $call-method
+;
+previous definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/reports.fth
===================================================================
--- cpu/ppc/olpc/reports.fth	                        (rev 0)
+++ cpu/ppc/olpc/reports.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,132 @@
+purpose: Simple serial output routines for debugging startup code
+\ See license at end of file
+
+transient
+\ Assembler macro to assemble code to set the location "isa-adr" in
+\ ISA I/O space to the value "data".  Assumes that r1 is already set
+\ to the base addess of ISA I/O space.
+: isa-c!  ( data isa-adr -- )
+   swap " set r3,*" evaluate  1 " eieio  stb r3,*" evaluate
+;
+
+resident
+
+h# f101.2000 constant uart-base
+
+label putbyte  ( r3: byte -- )  \ Destroys r0-r1
+   uart-base  set  r1,*
+   begin   lbz r0,h#14(r1)   andi. r0,r0,h#20   0<> until
+   eieio   stb r3,h#0(r1)
+   begin   lbz r0,h#14(r1)   andi. r0,r0,h#20   0<> until   
+   bclr 20,0
+end-code
+
+\ destroys: r0-r4
+label putdigit  ( r3: nibble -- )  \ print 4-bit value in r3
+   mfspr r4,lr
+   andi. r3,r3,h#0f   cmpi 0,0,r3,9   > if  addi r3,r3,h#27  then
+   addi r3,r3,h#30
+   putbyte bl *
+   mtspr lr,r4
+   bclr 20,0
+end-code
+
+transient
+: be-report  ( char -- )  " set r3,* be-putbyte bl *" evaluate  ;
+resident
+
+\ destroys: r0-r6
+label dot   ( r3: n -- )	\ print 32-bit value in r3
+   mfspr r5,lr
+   mr    r6,r3
+
+   set r3,h#20  putbyte bl *
+
+   rlwinm r3,r6,04,28,31   putdigit bl *
+   rlwinm r3,r6,08,28,31   putdigit bl *
+   rlwinm r3,r6,12,28,31   putdigit bl *
+   rlwinm r3,r6,16,28,31   putdigit bl *
+   rlwinm r3,r6,20,28,31   putdigit bl *
+   rlwinm r3,r6,24,28,31   putdigit bl *
+   rlwinm r3,r6,28,28,31   putdigit bl *
+   rlwinm r3,r6,00,28,31   putdigit bl *
+
+   set r3,h#20  putbyte bl *
+   mtspr lr,r5
+   bclr 20,0
+end-code
+
+\ destroys: r0-r4
+label dcr  ( -- )
+   mfspr r4,lr
+   carret   set r3,*   putbyte bl *
+   linefeed set r3,*   putbyte bl *
+   mtspr lr,r4
+   bclr 20,0
+end-code
+
+[ifdef] pc@
+stand-init-debug?  [if]
+: putc  ( char -- )
+   begin  5 uart@  h# 20 and  until
+   0 uart!
+   begin  5 uart@  h# 20 and  until
+;
+: ?putc  ( "char" -- )  postpone [char]  postpone putc  ; immediate
+[else]
+transient
+: ?putc  ( "char" -- )  safe-parse-word 2drop  ; immediate
+resident
+[then]
+[then]
+
+[ifdef] notdef
+: digits  " 0123456789abcdef" drop ;
+: xx.  0  d# 28  do  dup i >> h# f and  digits + c@ emit  -4 +loop space  drop ;
+[then]
+
+headers
+transient
+: .r3  ( -- )  " dot bl *" evaluate  ;
+
+[ifdef] stand-init-debug?
+: ?report  ( char -- )
+   stand-init-debug?  if
+      " set r3,*  putbyte bl *" evaluate
+   else
+      drop
+   then
+;
+[else]
+: ?report  ( char -- )  " set r3,*  putbyte bl *" evaluate  ;
+[then]
+
+resident
+
+transient
+: spins  ( n -- )  " set r0,*  mtspr ctr,r0  begin countdown" evaluate  ;
+resident
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/reset.fth
===================================================================
--- cpu/ppc/olpc/reset.fth	                        (rev 0)
+++ cpu/ppc/olpc/reset.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,35 @@
+purpose: Reset system - this version works on many PR*P systems
+\ See license at end of file
+
+headerless
+.( XXX: cpu/ppc/olpc/reset.fth - Implement reset-all ) cr
+: (reset-all)  ( -- )
+   icache-off dcache-off
+
+;
+' (reset-all) to reset-all
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/olpc/rootnode.fth
===================================================================
--- cpu/ppc/olpc/rootnode.fth	                        (rev 0)
+++ cpu/ppc/olpc/rootnode.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,35 @@
+purpose: Properties and Methods for root node
+\ See license at end of file
+
+dev /
+
+" olpc,School Server 1" " model" string-property
+
+.( XXX - clock-frequency of root node) cr
+d# 666,666,666 " clock-frequency" integer-property  \ For root bus
+
+device-end
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/pause.fth
===================================================================
--- cpu/ppc/pause.fth	                        (rev 0)
+++ cpu/ppc/pause.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,60 @@
+purpose: Code words for multitasking
+\ See license at end of file
+
+code (pause  (s -- )   \ go see if anybody else wants service
+   stwu  tos,-4(sp)
+   
+   'user saved-ip  stw  ip,*
+   'user saved-rp  stw  rp,*
+   'user saved-sp  stw  sp,*
+
+   'user link      lwz  up,*	\ get up for new task
+   add	 up,up,base		\ Relocate it
+   'user entry     lwz	t0,*	\ get pc for new task
+   add    t0,t0,base
+   mtspr  lr,t0
+   bclr   20,0
+end-code
+
+label to-next-task  (s -- address-of-"next-task"-code )
+   'user link      lwz  up,*	\ get up for new task
+   add	 up,up,base		\ Relocate it
+   'user entry     lwz	t0,*	\ get pc for new task
+   add    t0,t0,base
+   mtspr  lr,t0
+   bclr   20,0
+end-code
+
+\ Called with up set to the user area address of the task to run
+label task-resume (s -- )	\ start a task
+   stwu   tos,-4(sp)
+   'user saved-ip  lwz  ip,*
+   'user saved-rp  lwz  rp,*
+   'user saved-sp  lwz  sp,*
+   lwz    tos,0(sp)
+   addi   sp,sp,4
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/ppcboot.fth
===================================================================
--- cpu/ppc/ppcboot.fth	                        (rev 0)
+++ cpu/ppc/ppcboot.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,377 @@
+purpose: PowerPC Forth startup code
+\ See license at end of file
+
+hex
+
+\ Boot code (cold and warm start).  The cold start code is executed
+\ when Forth is initially started.  Its job is to initialize the Forth
+\ virtual machine registers.  The warm start code is executed when Forth
+\ is re-entered, perhaps as a result of an exception.
+
+hex
+
+warning @ warning off
+: stand-init-io  ( -- )
+   stand-init-io
+
+\  inituarts		\ Already done in startup code
+   install-uart-io
+
+   ['] noop        to mark-error
+   ['] noop        to show-error
+   ['] reset-all   to bye
+   ['] crlf-pstr   to newline-pstring
+   ['] no-swap-map to init-swap-map
+
+   real-mode? to use-real-mode?
+;
+warning !
+
+headerless
+defer rom-init-io
+headers	\ Debugging is difficult if rom-init-environment is headerless
+defer rom-init-environment
+headerless
+defer rom-cold-hook
+
+: rom-cold  (s -- )
+   hex
+\   ?putc $
+   rom-init-io				  \ Memory allocator and character I/O
+\   ?putc #
+   do-init				  \ Kernel
+\   ?putc %
+   stand-init-debug?  if
+      cr ." Type 'i' to interrupt stand-init sequence" cr 
+      d# 200 ms
+      key?  if  key drop  ." Interacting" cr  interact  then
+   then
+   ['] rom-init-environment guarded	  \ Environmental dependencies
+   ['] rom-cold-hook        guarded	  \ Open Firmware final startup
+
+   fw-title
+   quit
+;
+
+[ifndef] ,64bit?
+: ,64bit?  ( -- )
+   " mfspr r0,pvr  rlwinm r0,r0,16,16,31  cmpi 0,0,r0,20  =" evaluate
+;
+[then]
+
+label synchronize-caches  ( scratch: r0 r3 r4 )
+
+   \ Flush Dcache if it's on
+
+   mfspr   r3,hid0
+   andi.   r3,r3,h#4000
+   0<>  if
+      ,64bit?  if
+         h# 10000 64 /  set r4,*	\ #cache-lines
+         mtspr  ctr,r4
+         set    r4,64			\ /cache-line
+      else
+         h# 10000 32 /  set r4,*	\ #cache-lines
+         mtspr  ctr,r4
+         set    r4,32			\ /cache-line
+      then
+
+      neg    r3,r4		\ Begin at 0 - /cache-line
+
+      begin
+         lbzux   r0,r3,r4	\ Touch each cache block
+      countdown			\ from [0 to 64K) (0x800 * 0x20)
+
+      neg        r4,r4		\ Prepare to count down
+      begin
+         dcbf    r0,r3		\ Flush each block
+         add.    r3,r3,r4	\ on the way back down to 0
+      0<> until
+   then
+
+   \ Invalidate Icache if it's on
+
+   mfspr   r3,hid0
+   andi.   r3,r3,h#8000
+   0<>  if
+      mfspr  r3,hid0
+      ori    r0,r3,h#800
+      sync isync
+      mtspr  hid0,r0	\ Set the invalidate bit
+      sync isync
+      mtspr  hid0,r3	\ Clear the invalidate bit for 603
+      sync isync
+   then
+
+   bclr 20,0
+end-code
+
+[ifndef] nv-adr-low
+h# 74 constant nv-adr-low
+h# 75 constant nv-adr-high
+h# 77 constant nv-data
+[then]
+
+create force-big-endian
+\ \needs read-le-flag  fload ${BP}/arch/prep/leflag.fth
+
+label memcpy  ( r3: dst r4: src r5: n -- r3: dst )
+   mtspr  ctr,r5
+   mr     r6,r3
+
+   addi   r3,r3,-1	\ Account for pre-decrement
+   addi   r4,r4,-1	\ Account for pre-decrement
+   begin
+      lbzu r5,1(r4)
+      stbu r5,1(r3)
+   countdown
+
+   mr    r3,r6		\ Return dst
+   bclr  20,0
+end-code
+
+[ifdef] switcheroo
+label ?switch-endian
+   mfspr   r30,lr
+
+   switcheroo origin - set r4,*
+   add     r4,r4,base		\ Absolute address of switcheroo code
+   set     r3,h#1000	 	\ Temporary RAM location for switcheroo code
+   /switcheroo  set  r5,*
+   memcpy  bl *
+
+   bla     h#1000		\ Execute the RAM copy of switcheroo
+
+   nop nop nop nop		\ Endian-independent landing pad
+
+   mtspr  lr,r30
+   bclr   20,0
+end-code
+[else]
+
+label move-user-area
+\ move-user-area copies the initial user area image to its final RAM location
+
+\ In:  r13: header-adr   r14: little-endian?   r15: allocation pointer
+\ Destroys: r20-r24
+\ Out: up: final user area address   r15: updated allocation pointer
+
+\ Find the user area size from the header
+   lwz   r21,4(r13)		\ Text size = offset to start of data
+   lwz   r20,8(r13)		\ Data size = user area size in r20 
+
+\ Allocate high memory for the stacks and stuff, starting at memtop and
+\ allocating downwards.  r15 is the allocation pointer.
+
+\ Allocate the RAM copy of the User Area
+   subf    r15,r20,r15
+   rlwinm  r15,r15,0,0,28	\ doubleword-align by clearing 3 low bits 
+   mr      up,r15		\ Set user pointer
+
+   \ Copy the initial User Area image to the RAM copy
+   add    r23,r21,base		\ Init-up pointer in r23 
+   mr     r22,up		\ Destination pointer
+
+   srawi  r20,r20,2
+   mtspr  ctr,r20
+   addi   r23,r23,-4		\ Account for pre-incrementing
+   addi   r22,r22,-4		\ Account for pre-incrementing
+   begin			\ Copy without byte swapping
+      lwzu  r20,4(r23)
+      stwu  r20,4(r22)
+   countdown
+
+   bclr   20,0
+   nop
+
+end-code
+[then]
+
+create uboot-entry
+label rom-cold-code  ( r3:fw-RAM-base r4:fw-RAM-size -- )
+
+[ifdef] uboot-entry
+   set r13,h#0f000000		\ Firmware memory base address in r13
+   set r11,h#00200000		\ Firmware memory size in r11
+[else]
+   mr  r13,r3			\ Firmware memory base address in r13
+   mr  r11,r4			\ Firmware memory size in r11
+[then]
+
+   lwz r12,0(r0)		\ Get memsize from low memory
+
+   add r15,r13,r11		\ r15 is the allocation pointer
+
+carret ?report
+linefeed ?report
+ascii A ?report
+
+[ifdef] force-big-endian
+   set r14,0
+[else]
+   read-le-flag  bl *
+   mr r14,r3
+[then]
+
+   \ Allocate HTAB
+   ,64bit?  if			\ 64-bit CPUs
+      set r22,h#40000		\ /htab-64
+   else				\ 32-bit CPUs
+      set   r22,h#10000		\ /htab-32
+   then
+   rlwinm   r2,base,0,0,19	\ Round base down to page boundary
+
+   subf     r15,r22,r15
+   mr       r6,r15
+
+ascii B ?report
+\ Find the base address
+   here 4 +   bl   *		\ Absolute address of next instruction
+   here origin - set base,*	\ Relative address of this instruction
+   mfspr   r0,lr
+   subf    base,base,r0		\ Base address of Forth kernel
+
+[ifdef] ?switch-endian
+   ?switch-endian  bl *
+
+" ppcboot.fth: Do we need to sync caches after endian switch?" ?reminder
+\ set r3,h#1f0.0000 set r4,h#10.0000  sync-cache bl *
+\ mr  r3,up   user-size set r4,*  sync-cache bl *
+[else]
+\   mr r3,r13 .r3
+\   lwz r3,4(r13) .r3
+   lwz r3,8(r13) .r3
+
+   move-user-area  bl *
+[then]
+
+ascii Q ?report
+[ifdef] ?enter-virtual-mode
+   mr    r3,r13			\ Firmware memory base address
+   mr    r4,r11			\ Firmware memory size
+
+   ?enter-virtual-mode  bl *	\ Returns virt minus phys offset
+   mr    r16,r3
+[else]
+    set   r16,0			\ Set virtual-physical offset to 0
+[then]
+
+ascii R ?report
+   add   r15,r15,r16		\ Convert allocation pointer to virtual
+   add   up,up,r16		\ Convert user pointer to virtual
+
+   \ This must be done after we switch modes because longwords may be
+   \ exchanged in the RAM copy of the user area prior to the mode switch.
+   'user in-little-endian?  stw  r14,*  \ Assert mode for Forth code
+   'user virt-phys          stw  r16,*  \ Assert mode for Forth code
+
+   'user htab-phys  stw  r6,*	\ Allocated address of hash table
+   add   r2,r2,r16		\ Convert htab address to virtual
+   'user htab       stw  r6,*	\ Allocated address of hash table
+
+ascii J ?report
+
+\ Find the base address
+   here 4 +   bl   *		\ Absolute address of next instruction
+   here origin -  set  base,*	\ Relative address of this instruction
+   mfspr   r22,lr
+   subf    base,base,r22	\ Base address of Forth kernel
+
+\ Now the user area has been copied to the proper place, so we can set
+\ some important user variables whose inital values are determined at
+\ run time.
+
+   'body main-task   set  r22,*	\ Allow the exception handler to find the
+        			\ user area by storing the address of the
+   stwx  up,base,r22		\ main user area in the "constant" main-task
+
+   set  r0,-1
+   'user powerpc?  stw  r0,*
+
+\ Top of memory and dictionary limit
+   add   r0,r11,r13		\ Compute memtop
+   'user memtop  stw  r0,*
+   'user memsize stw  r12,*
+
+\ Set the up0 user variable
+   'user up0  stw  up,*
+
+\ Establish the return stack and set the rp0 user variable
+   mr    rp,r15			\ Set rp
+   'user rp0  stw  rp,*
+   rs-size negate  addi  r15,r15,*	\ allocate space for the return stack
+
+ascii K ?report
+\ Establish the Parameter Stack
+   'user sp0   stw  r15,*
+   addi   sp,r15,4		\ account for the top of stack register
+
+   ps-size negate  addi  r15,r15,*	\ Allocate the stuff on the stack
+
+   initial-heap-size  set  r22,* \ Reserve some space for the heap
+   subf    r15,r22,r15
+   'user limit   stw  r15,*	\ Top of dictionary growth area
+
+\ Set the dictionary pointer
+   add   r21,r21,base		\ Base + text size
+   'user dp   stw   r21,*	\ Set dp
+
+ascii L ?report
+\ Save the address of the system call table in the user variable syscall-vec
+   set r0,0
+   'user syscall-vec  stw  r0,*
+
+\ Set the value of #args and args
+   'user #args   stw  r0,*
+   'user args    stw  r0,*
+
+   synchronize-caches  bl *
+
+ascii M ?report
+\ Set the next pointer
+   mtspr  ctr,up
+
+ascii N ?report
+\ Enter Forth
+   'body rom-cold 4 -   set  ip,*
+   add   ip,ip,base
+\ ctr:np w:r25, base:r26, up:r27, tos:r28, ip:r29, rp:r30, sp: r31
+h# 20 ?report
+mfspr r3,ctr .r3  mr r3,base .r3  mr r3,up .r3   mr r3,ip .r3  mr r3,rp .r3  mr r3,sp .r3  
+lwz r3,0(ip) .r3
+carret ?report
+c;
+
+: install-rom-cold  ( -- )
+   " stand-init-io"  $find-name is rom-init-io
+   " stand-init"     $find-name is rom-init-environment
+   " startup"        $find-name is rom-cold-hook
+
+   rom-cold-code origin put-branch
+;
+
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/ppcsim/ppcsim.c
===================================================================
--- cpu/ppc/ppcsim/ppcsim.c	                        (rev 0)
+++ cpu/ppc/ppcsim/ppcsim.c	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,2092 @@
+// See license at end of file
+/*
+ * PowerPC instruction set simulator for Forth
+ */
+
+#include <stdio.h>
+
+#define BI_ENDIAN
+
+extern long s_bye();
+extern long c_key();
+
+typedef	unsigned char	u_char;
+typedef	unsigned short	u_short;
+typedef	unsigned int	u_int;
+typedef	unsigned long	u_long;
+
+#define MAXMEM 0x80000
+
+union {
+    u_long all;
+    struct {
+        u_long SO :1;
+        u_long OV :1;
+        u_long CA :1;
+        u_long res:13;
+    } bits;
+} XER;
+
+union {
+    u_long all;
+    struct {
+        u_long LTGTEQ :3;
+        u_long SO :1;
+        u_long res:12;
+    } bits;
+} CR;
+
+
+#define ILLEGAL goto illegal
+
+#ifdef TRACE
+#define INSTR(a)	trace(a, instruction, pc)
+#else
+#define INSTR(a)
+#endif
+
+#define CMP(a,b)	((a < b) ? 4 : ((a > b) ? 2 : 1 ))
+
+#define DO_UPDATE_SO  CR.bits.SO = XER.bits.SO
+#define DO_UPDATE_SO_CRFD(crfd)  {  \
+        CR.all &= ~(1 << ((7-crfd)<<2)); \
+	CR.all |= (XER.bits.SO << ((7-crfd)<<2));\
+    }
+
+#define DO_UPDATE_OV(dest,src1,src2) \
+	   if (OE) { \
+	       XER.bits.SO |= \
+	           (XER.bits.OV = \
+		       ((((long)(dest))^((long)(src1))) <  0) && \
+		       ((((long)(src1))^((long)(src2))) >= 0));  \
+	   }
+
+#ifdef OVERFLOWS
+#define UPDATE_SO  DO_UPDATE_SO
+#define UPDATE_SO_CRFD(crfd)  DO_UPDATE_SO_CRFD(crfd)
+#define UPDATE_OV(a,b,c)  DO_UPDATE_OV(a,b,c)
+#else
+#define UPDATE_SO
+#define UPDATE_SO_CRFD(a)
+#define UPDATE_OV(a,b,c)
+#endif
+
+#define UPDATE_CA(res,op)  XER.bits.CA = ((u_long)res < (u_long)op)
+
+#define DO_UPDATE_CRFD(dest,src,crfd) \
+	   { \
+               CR.all &= ~(0xe << ((7-crfd)<<2)); \
+	       CR.all |= (CMP(dest, src) << (((7-crfd)<<2)+1)); \
+	       UPDATE_SO_CRFD(crfd); \
+	   }
+
+#ifdef notdef
+#define DO_UPDATE_CR(dest,src) \
+	   { \
+	       CR.bits.LTGTEQ = CMP(dest, src); \
+	       UPDATE_SO; \
+	   }
+#else
+#define DO_UPDATE_CR(dest,src) DO_UPDATE_CRFD(dest,src,0)
+#endif
+
+#define UPDATE_CR(dest) \
+	   if (RC) { \
+		DO_UPDATE_CR((long)dest, 0); \
+	   }
+
+/* Add/subtract with carry */
+#define ADDC(b,a) \
+	   temp = (b)+(a); \
+	   UPDATE_OV(temp,(b),(a)); \
+	   UPDATE_CA((temp),(a)); \
+	   UPDATE_CR(temp); \
+	   RD = temp;
+
+#define SUBC(b,a) \
+	   temp = (b)-(a); \
+	   UPDATE_OV(temp,(b),(a)); \
+	   XER.bits.CA = (b) >= (a); \
+	   UPDATE_CR(temp); \
+	   RD = temp;
+
+/* Add/subtract without carry */
+#define ADD(b,a) \
+	   temp = (b)+(a);  \
+	   UPDATE_OV(temp,(b), (a)); \
+	   UPDATE_CR(temp); \
+	   RD = temp; \
+	   break;
+
+/* logical operations - and, or, shifts, etc */
+#define LOGIC(expr) \
+	   RA = expr; \
+	   UPDATE_CR(RA); \
+	   break;
+
+/* Condition/counter evaluation for bcXXX */
+#define CONDITION \
+	   /* \
+	    * If (BO&0x10), don't test condition. \
+	    * Otherwise the CR[BI] and the 0x8 bit of BO must be the same. \
+	    */ \
+	   cond_ok =  ((BO & 0x10) \
+	           || ((long)((CR.all << BI) ^ (BO << 28)) >= 0)); \
+	   if ((BO & 4) == 0) {  /* Update and test counter */ \
+		CTR -= 1; \
+		cond_ok &= ((CTR != 0) ^ ((BO >> 1) & 1)); \
+	   } \
+	   if (LK) \
+		LR = CIA+4;
+
+
+#define UFIELD(lbit,nbits)  ((instruction << lbit) >> (32 - nbits))
+#define SFIELD(lbit,nbits)  ((long)(instruction << lbit) >> (32 - nbits))
+
+#define OPCD (instruction >> 26)
+#define OP2  UFIELD(21,10)
+
+/* These bits are never used as indices; only as flags */
+#define LK   (instruction & 1)
+#define RC   (instruction & 1)
+#define AA   (instruction & 2)
+#define SHD  (instruction & 2)
+
+#define LI   SFIELD( 6,24)
+
+#define RD   reg[UFIELD( 6, 5)]
+#define RS   reg[UFIELD( 6, 5)]
+#define FRD  reg[UFIELD( 6, 5)]
+#define FRS  reg[UFIELD( 6, 5)]
+#define BO       UFIELD( 6, 5)
+#define CRBD     UFIELD( 6, 5)
+
+#define RA   reg[UFIELD(11, 5)]
+#define FRA  reg[UFIELD(11, 5)]
+#define BI       UFIELD(11, 5)
+#define CRBA     UFIELD(11, 5)
+#define TO       UFIELD(11, 5)
+#define RA0	 (UFIELD(11, 5) ? RA : 0)
+
+#define RB   reg[UFIELD(16, 5)]
+#define FRB  reg[UFIELD(16, 5)]
+#define CRBB     UFIELD(16, 5)
+#define NB       UFIELD(16, 5)
+#define SH       UFIELD(16, 5)
+
+#define FRC  reg[UFIELD(21, 5)]
+#define MB       UFIELD(21, 5)
+
+#define ME       UFIELD(26, 5)
+
+#define BD       SFIELD(16,14)
+#define DS       SFIELD(16,14)
+
+#define D        SFIELD(16,16)
+#define SIMM     SFIELD(16,16)
+#define UIMM     UFIELD(16,16)
+
+#define CRFD     UFIELD( 6, 3)
+#define FM       UFIELD( 7, 8)
+#define L        UFIELD(10, 1)
+#define CRFS     UFIELD(11, 3)
+#define SPR      (UFIELD(11,5) | (UFIELD(16,5) << 5))
+#define TBR      UFIELD(11,10)
+#define CRM      UFIELD(12, 8)
+#define SR   seg[UFIELD(12, 4)]
+#define IMM      UFIELD(16, 4)
+#define XO       UFIELD(21,10)
+#define OE       UFIELD(21, 1)
+
+#define MASK  ((MB <= ME) ?   (u_long)(-1L << (31-ME+MB)) >>  MB \
+	                  :   (u_long)(-1L << (31-ME)) | ((u_long)-1L >> MB))
+
+#define ROTATE(val, cnt) (((val) >> (32-(cnt))) | ((val) << (cnt)))
+
+u_long TBAR;
+
+#ifdef MMU
+
+/*
+ * This is not an accurate simulation of the PowerPC MMU behavior
+ * a) BATs aren't implemented.
+ * b) the simulated TLB is much much larger than a real one
+ * c) segment register values are limited to the range 0..f
+ */
+u_long mmutab[0x100000];
+void
+init_tlb()
+{
+	int i;
+	for (i = 0; i < 0x100000; i++)
+		mmutab[i] = 0xffffffff;
+}
+u_long
+tlb_miss(vaddr)
+	register u_long vaddr;
+{
+	/* References: 603 manual, sections 7.6.1.4 and 7.6.3.1 */
+	register u_long temp, vsid, mask;
+	vsid = seg[vaddr >> 28];
+	temp = ((vaddr >> 12) & 0xffff) | vsid;
+	mask = ((((SDR1 & 0x1ff) << 10) | 0x3ff) << 6;
+	DMISS = IMISS = vaddr;
+	HASH1 = (SDR1 & 0xffff0000) | ((temp << 6) & mask);
+	HASH2 = HASH1 ^ mask;
+	DCMP = ICMP = 0x80000000 | (vsid << 7) | ((vaddr >> 22) & 0x3f);
+}
+tlbie(vaddr)
+	register u_long vaddr;
+{
+	mmutab[vaddr >> 12] = 0xffffffff;
+}
+u_long
+MAP(vaddr)
+	register u_long vaddr;
+{
+	register u_long phys;
+	register u_long pageno;
+	pageno = (seg[vaddr >> 28] << 16) | ((vaddr >> 12) & 0xffff);
+
+	if ((phys = mmutab[pageno]) == 0xffffffff)
+		mmutab[pageno] = phys = tlb_miss(vaddr);
+	return (phys | (vaddr & 0xfff));
+}
+#else
+#ifdef SIMNT
+/*
+ * Most PPC kernel stuff wants to run in what used to be kseg0 (long
+ * long ago in a galaxy far far away). This little deal maps virtual
+ * to physical.
+ */
+u_long
+MAP(vaddr)
+	u_long vaddr;
+{
+	if (vaddr > 0x80000000 && vaddr < 0xf0000000)
+		vaddr &= ~0x80000000;
+	return(vaddr < 0x10000 ? vaddr + 0x50000 : vaddr);
+}
+#else
+#ifdef TRACE
+#ifndef SIMROM
+/* This can't be a macro because of side effects of operand evaluation */
+u_long
+MAP(vaddr)
+	register u_long vaddr;
+{
+	return ((vaddr < 0x1000) ? (vaddr + TBAR) : vaddr);
+}
+#else
+#define MAP(vaddr)   (vaddr)
+#endif
+#else
+#define MAP(vaddr)   (vaddr)
+#endif
+#endif
+#endif
+
+#ifdef NOTDEF
+#define CIA  ((u_char *)MAP(pc) - mem)
+#else
+#define CIA  ((u_long)MAP(pc))
+#endif
+#define UNIMP(str)  { opname = str;  goto unimplemented; }
+#define POWER(str)  { opname = str;  goto power; }
+
+#ifdef BI_ENDIAN
+#define MEM(type, size, adr)   *(type *)(&mem[MAP((adr) ^ size)])
+#else
+#define MEM(type, size, adr)   *(type *)(&mem[MAP(adr)])
+#endif
+
+u_long greg[32];
+u_long seg[16];
+
+#ifdef TRACE
+u_long instruction;
+u_long pc;
+u_long CTR;
+u_long LR;
+#endif
+
+u_long IABR;
+u_long HID0;
+u_long DEC, SRR0, SRR1, SPRG0, SPRG1, SPRG2, SPRG3, MSR;
+
+u_char *xmem;
+
+void
+simulate(mem, start, arg0, arg1, arg2, arg3, arg4, arg5)
+        register u_char *mem;
+	u_long start;
+	u_long arg0, arg1, arg2, arg3, arg4, arg5;
+{
+	register u_long *reg = &greg[0];
+#ifndef TRACE
+	register u_long instruction;
+	register u_long pc;
+	register u_long CTR;
+	register u_long LR;
+#endif
+#ifdef BI_ENDIAN
+	register u_long BYTE = 0;	/* 7 for little-endian */
+	register u_long WORD = 0;	/* 6 for little-endian */
+	register u_long LONG = 0;	/* 4 for little-endian */
+#endif
+
+
+	register int cond_ok;
+	register u_long temp;
+	u_long	scratch;
+	char *msg;
+	char *opname;
+
+	xmem = mem;
+
+	reg[3] = arg0;
+
+	/*
+	 * Pass 0 as the system call vector to let the kernel know it's
+	 * running on the simulator.
+	 */
+	reg[4] = 0;	/* Was	reg[4] = arg1; */ 
+	reg[5] = arg2;
+	reg[6] = arg3;
+	reg[7] = arg4;
+	reg[8] = arg5;
+
+#ifdef TRACE
+	catch_signals();
+#endif
+
+	for (pc = start; ; pc += 4) {
+
+#ifdef TRACE
+ 		if (DEC-- == 0 && (MSR & 0x8000) && TBAR) {
+			SRR0 = CIA;
+			SRR1 = MSR;
+			pc = TBAR + 0x900 - 4;
+			continue;
+		}
+#endif
+
+		instruction = MEM(u_long , LONG, pc);
+
+switch(OPCD) {
+
+case    0: ILLEGAL;
+case    1: ILLEGAL;
+case    2: ILLEGAL;
+case    3: /* UNIMP("twi"); */
+/* Hack to speed-up Forth dictionary searches */
+	RA = (u_long) xfindnext((u_char *)reg[3], (long)reg[4], (long)reg[5],
+			       (u_long)reg[6], (u_long *)reg[7]);
+	break;
+case    4: ILLEGAL;
+case    5: ILLEGAL;
+case    6: ILLEGAL;
+case    7: INSTR("mulli");       RD = RA * SIMM;         break;
+
+case    8: INSTR("subfic");  
+	   RD = SIMM - RA;
+	   UPDATE_CA(RD,SIMM);
+           break;
+
+case    9: POWER("dozi");
+
+case   10: INSTR("cmpli");  
+/*DEBUG*/  if (L)    UNIMP("cmpli - 64-bit");
+           if (CRFD)
+               DO_UPDATE_CRFD(RA, UIMM, CRFD)
+           else
+	       DO_UPDATE_CR(RA, UIMM)
+           break;
+
+case   11: INSTR("cmpi");  
+/*DEBUG*/  if (L)    UNIMP("cmpi - 64-bit");
+           if (CRFD)
+               DO_UPDATE_CRFD((long)RA, SIMM, CRFD)
+           else
+	       DO_UPDATE_CR((long)RA, SIMM)
+           break;
+
+case   12: INSTR("addic");  
+	   RD = RA + SIMM;
+	   UPDATE_CA(RD,SIMM);
+           break;
+
+case   13: INSTR("addic.");  
+	   RD = RA + SIMM;
+	   UPDATE_CA(RD,SIMM);
+	   DO_UPDATE_CR((long)RD, 0);
+           break;
+
+case   14: INSTR("addi");     RD = RA0 + SIMM;           break;
+case   15: INSTR("addis");    RD = RA0 + (SIMM << 16);   break;
+
+case   16: INSTR("bcX");  
+	   CONDITION
+	   if ( cond_ok )
+		pc = (BD << 2) + (AA ? 0 : CIA) - 4;
+           break;
+
+case   17: UNIMP("sc");
+
+case   18: INSTR("bX");  
+	   if (LK)
+		LR = CIA+4;
+	   pc = (LI << 2) + (AA ? 0 : CIA) - 4;
+           break;
+
+case   19:
+	   switch(OP2) {
+		case  16: INSTR("bclr");
+			  CONDITION
+/* XXX Possible problem with updating the link register before using it */
+			  if ( cond_ok )
+				pc = LR - 4;
+			  break;
+		case  50: INSTR("rfi");
+			  MSR = SRR1;
+			  pc = SRR0 - 4;
+			  break;
+		case 150: INSTR("isync");			  break;
+		case 528: INSTR("bcctr");
+#ifdef SIMNEXT
+#define W    reg[25]
+#define BASE reg[26]
+#define UP   reg[27]
+#define IP   reg[29]
+#define RP   reg[30]
+#define DOCOLON 0x10
+#define UNNEST 0x848
+		  if (instruction == 0x4e800420 && CTR == UP
+/*
+ * If the first instruction of next is a branch, the Forth source
+ * debugger is active, in which case we don't want to do the fast
+ * next simulation.
+ */
+		      && (MEM(u_long, LONG, CTR) >> 26) != 18) {
+
+		      next:
+
+		      /* Recognize unnest from the unrelocated token value */
+                      IP += sizeof(u_long);
+		      while ((temp = *(u_long *)IP) == UNNEST) {
+                          IP += sizeof(u_long);
+			  IP = *(u_long *)RP;
+                          RP += sizeof(u_long);
+                      }
+
+		      /* Recognize docolon from the unrelocated code field */
+		      if ((temp = *(u_long *)(W = temp + BASE)) == DOCOLON) {
+		          RP -= sizeof(u_long);
+		          *(u_long *)RP = IP;
+			  IP = W;
+			  goto next;
+		      }
+
+		      /* -4 is an artifact of the simulator implementation */
+		      pc = temp + BASE - 4;
+		      break;
+		  }
+#endif
+			  CONDITION
+			  if ( cond_ok )
+				pc = CTR - 4;
+			  break;
+		default:  UNIMP("CR logical ops");
+	   }
+           break;
+case   20: INSTR("rlwimi"); RA = (RA & ~MASK) | (ROTATE(RS,SH) & MASK);
+			    UPDATE_CR(RA); break;
+case   21: INSTR("rlwinm"); RA = ROTATE(RS,SH) & MASK; UPDATE_CR(RA); break;
+case   22: POWER("rlmi");
+case   23: INSTR("rlwnm");  RA = ROTATE(RS,RB) & MASK; UPDATE_CR(RA); break;
+case   24: INSTR("ori");    RA = RS |  UIMM;           break;
+case   25: INSTR("oris");   RA = RS | (UIMM << 16);    break;
+case   26: INSTR("xori");   RA = RS ^  UIMM;           break;
+case   27: INSTR("xoris");  RA = RS ^ (UIMM << 16);    break;
+case   28: INSTR("andi.");  RA = RS &  UIMM;
+			    DO_UPDATE_CR((long)RA, 0); break;
+case   29: INSTR("andis."); RA = RS & (UIMM << 16);
+			    DO_UPDATE_CR((long)RA, 0); break;
+case   30: ILLEGAL;
+/* case 31 is at the end */
+case   32: INSTR("lwz");   RD = MEM(u_long , LONG,       RA0+ D );      break;
+case   33: INSTR("lwzu");  RD = MEM(u_long , LONG, RA = (RA + D));      break;
+case   34: INSTR("lbz");   RD = MEM(u_char , BYTE,       RA0+ D );      break;
+case   35: INSTR("lbzu");  RD = MEM(u_char , BYTE, RA = (RA + D));      break;
+case   36: INSTR("stw");        MEM(u_long , LONG,       RA0+ D ) = RS; break;
+case   37: INSTR("stwu");       MEM(u_long , LONG, RA = (RA + D)) = RS; break;
+case   38: INSTR("stb");        MEM(u_char , BYTE,       RA0+ D ) = RS; break;
+case   39: INSTR("stbu");       MEM(u_char , BYTE, RA = (RA + D)) = RS; break;
+case   40: INSTR("lhz");   RD = MEM(u_short, WORD,       RA0+ D );      break;
+case   41: INSTR("lhzu");  RD = MEM(u_short, WORD, RA = (RA + D));      break;
+case   42: INSTR("lha");   RD = MEM(  short, WORD,       RA0+ D );      break;
+case   43: INSTR("lhau");  RD = MEM(  short, WORD, RA = (RA + D));      break;
+case   44: INSTR("sth");        MEM(u_short, WORD,       RA0+ D ) = RS; break;
+case   45: INSTR("sthu");       MEM(u_short, WORD, RA = (RA + D)) = RS; break;
+case   46: INSTR("lmw");  {
+				u_long *src, *dst;
+#ifdef BI_ENDIAN
+				if (LONG)
+					goto illegal;
+					/* Should be an alignment exception */
+#endif
+				dst = &(RD);
+				src = (u_long  *)(&mem[MAP(RA0+D)]);
+				while (dst < &reg[32])
+				    *dst++ = *src++;
+			  }
+			break;
+case   47: INSTR("stmw"); {
+				u_long *src, *dst;
+#ifdef BI_ENDIAN
+				if (LONG)
+					goto illegal;
+					/* Should be an alignment exception */
+#endif
+				dst = (u_long  *)(&mem[MAP(RA0+D)]);
+				src = &(RS);
+				while (src < &reg[32])
+					*dst++ = *src++;
+			  }
+			break;
+case   48: UNIMP("lfs");
+case   49: UNIMP("lfsu");
+case   50: UNIMP("lfd");
+case   51: UNIMP("lfdu");
+case   52: UNIMP("stfs");
+case   53: UNIMP("stfsu");
+case   54: UNIMP("stfd");
+case   55: UNIMP("stfdu");
+case   56: ILLEGAL;
+case   57: ILLEGAL;
+case   58: ILLEGAL;
+case   59: UNIMP("Single Floating Point");
+case   60: ILLEGAL;
+case   61: ILLEGAL;
+case   62: ILLEGAL;
+case   63: UNIMP("Double Floating Point");
+case   31:
+
+switch(OP2) {
+case    0: INSTR("cmp");  
+/*DEBUG*/  if (L)    UNIMP("cmp - 64-bit");
+           if (CRFD)
+               DO_UPDATE_CRFD((long)RA, (long)RB, CRFD)
+           else
+	       DO_UPDATE_CR((long)RA, (long)RB)
+	   
+           break;
+case    1: ILLEGAL;
+case    2: ILLEGAL;
+case    3: ILLEGAL;
+case    4: 
+#ifdef notdef
+	   UNIMP("tw");
+#else
+	   /* tw */
+	   /* Handle Forth wrapper calls - the call# is in RA */
+	   reg[3] = (*(long (*) ())(*(long *)(arg1 + RA)))
+		    (reg[3],reg[4],reg[5],reg[6],reg[7], reg[8]);
+	   break;
+#endif
+case    5: ILLEGAL;
+case    6: ILLEGAL;
+case    7: ILLEGAL;
+case    8: INSTR("subfc");  SUBC(RB,RA); break;
+case    9: ILLEGAL;
+case   10: INSTR("addc");   ADDC(RB,RA); break;
+case   11: INSTR("mulhwu");
+	   umtimes((u_long *)&RD, (u_long *)&scratch, RA, RB);  UPDATE_CR(RD);  break;
+case   12: ILLEGAL;
+case   13: ILLEGAL;
+case   14: ILLEGAL;
+case   15: ILLEGAL;
+case   16: ILLEGAL;
+case   17: ILLEGAL;
+case   18: ILLEGAL;
+case   19: INSTR("mfcr");  RD = CR.all;  break;
+case   20: UNIMP("lwarx");
+case   21: ILLEGAL;
+case   22: ILLEGAL;
+case   23: INSTR("lwzx");  RD = MEM(u_long , LONG, RA0 + RB);  break;
+case   24: INSTR("slw");  LOGIC( (RB & 0x20 ? 0 : RS << (RB & 0x1f)) ); break;
+case   25: ILLEGAL;
+case   26: INSTR("cntlzw");
+	   temp = RS;
+	   for(scratch = 0;
+	       scratch < 32 && ((temp & 0x80000000) == 0);
+	       scratch++) {
+		   temp <<= 1;
+	   }
+	   UPDATE_CR(scratch);
+	   RA = scratch;
+	   break;
+case   27: ILLEGAL;
+case   28: INSTR("and");  LOGIC( RS & RB );
+case   29: POWER("maskg");
+case   30: ILLEGAL;
+case   31: ILLEGAL;
+case   32: INSTR("cmpl");  
+/*DEBUG*/  if (L)    UNIMP("cmpl - 64-bit");
+           if (CRFD)
+               DO_UPDATE_CRFD(RA, RB, CRFD)
+           else
+	       DO_UPDATE_CR(RA, RB)
+           break;
+case   33: ILLEGAL;
+case   34: ILLEGAL;
+case   35: ILLEGAL;
+case   36: ILLEGAL;
+case   37: ILLEGAL;
+case   38: ILLEGAL;
+case   39: ILLEGAL;
+case   40: INSTR("subf");  ADD(RB,-RA);
+case   41: ILLEGAL;
+case   42: ILLEGAL;
+case   43: ILLEGAL;
+case   44: ILLEGAL;
+case   45: ILLEGAL;
+case   46: ILLEGAL;
+case   47: ILLEGAL;
+case   48: ILLEGAL;
+case   49: ILLEGAL;
+case   50: ILLEGAL;
+case   51: ILLEGAL;
+case   52: ILLEGAL;
+case   53: ILLEGAL;
+case   54: INSTR("dcbst");  break;
+case   55: INSTR("lwzux");  RD = MEM(u_long , LONG, RA = (RA + RB));   break;
+case   56: ILLEGAL;
+case   57: ILLEGAL;
+case   58: ILLEGAL;
+case   59: ILLEGAL;
+case   60: INSTR("andc");	LOGIC( RS & ~RB );
+case   61: ILLEGAL;
+case   62: ILLEGAL;
+case   63: ILLEGAL;
+case   64: ILLEGAL;
+case   65: ILLEGAL;
+case   66: ILLEGAL;
+case   67: ILLEGAL;
+case   68: ILLEGAL;
+case   69: ILLEGAL;
+case   70: ILLEGAL;
+case   71: ILLEGAL;
+case   72: ILLEGAL;
+case   73: ILLEGAL;
+case   74: ILLEGAL;
+case   75: INSTR("mulhw");
+       {
+          int negative = ((long)(RA ^ RB)) < 0;
+	  long highres;
+          long op1  = ((long)RA < 0) ? -(long)RA : RA;
+          long op2  = ((long)RB < 0) ? -(long)RB : RB;
+    	  umtimes((u_long *)&highres, (u_long *)&scratch, op1, op2);
+          RD = negative ? (~highres) + (scratch==0) : highres;
+          UPDATE_CR(RD);
+          break;
+       }
+
+case   76: ILLEGAL;
+case   77: ILLEGAL;
+case   78: ILLEGAL;
+case   79: ILLEGAL;
+case   80: ILLEGAL;
+case   81: ILLEGAL;
+case   82: ILLEGAL;
+case   83: INSTR("mfmsr"); RD = MSR;  break;
+case   84: ILLEGAL;
+case   85: ILLEGAL;
+case   86: INSTR("dcbf");  break;
+case   87: INSTR("lbzx");  RD = MEM(u_char , BYTE, RA0 + RB);     break;
+case   88: ILLEGAL;
+case   89: ILLEGAL;
+case   90: ILLEGAL;
+case   91: ILLEGAL;
+case   92: ILLEGAL;
+case   93: ILLEGAL;
+case   94: ILLEGAL;
+case   95: ILLEGAL;
+case   96: ILLEGAL;
+case   97: ILLEGAL;
+case   98: ILLEGAL;
+case   99: ILLEGAL;
+case  100: ILLEGAL;
+case  101: ILLEGAL;
+case  102: ILLEGAL;
+case  103: ILLEGAL;
+case  104: INSTR("neg");  ADD(0,-RA);
+case  105: ILLEGAL;
+case  106: ILLEGAL;
+case  107: POWER("mul");
+case  108: ILLEGAL;
+case  109: ILLEGAL;
+case  110: ILLEGAL;
+case  111: ILLEGAL;
+case  112: ILLEGAL;
+case  113: ILLEGAL;
+case  114: ILLEGAL;
+case  115: ILLEGAL;
+case  116: ILLEGAL;
+case  117: ILLEGAL;
+case  118: ILLEGAL;
+case  119: INSTR("lbzux");  RD = MEM(u_char , BYTE, RA = (RA + RB));  break;
+case  120: ILLEGAL;
+case  121: ILLEGAL;
+case  122: ILLEGAL;
+case  123: ILLEGAL;
+case  124: INSTR("nor");  LOGIC( ~(RS | RB) );
+case  125: ILLEGAL;
+case  126: ILLEGAL;
+case  127: ILLEGAL;
+case  128: ILLEGAL;
+case  129: ILLEGAL;
+case  130: ILLEGAL;
+case  131: ILLEGAL;
+case  132: ILLEGAL;
+case  133: ILLEGAL;
+case  134: ILLEGAL;
+case  135: ILLEGAL;
+case  136: INSTR("subfe");  
+	   if (XER.bits.CA) {
+	       SUBC(RB,RA);
+	   } else {
+	       ADDC(RB,~RA);
+	   }
+           break;
+case  137: ILLEGAL;
+case  138: INSTR("adde");  
+/* printf("adde: XER.bits.CA=%d RB %x -~RA %x\n", XER.bits.CA, RB, -(~RA)); */
+	   if (XER.bits.CA) {
+	       ADDC(RB,-(~RA));
+	   } else {
+	       ADDC(RB,RA);
+	   }
+           break;
+case  139: ILLEGAL;
+case  140: ILLEGAL;
+case  141: ILLEGAL;
+case  142: ILLEGAL;
+case  143: ILLEGAL;
+case  144: INSTR("mtcrf");  CR.all = RS;  break; /* XXX Ignores field mask */
+case  145: ILLEGAL;
+case  146: INSTR("mtmsr");  MSR = RD;	break;
+case  147: ILLEGAL;
+case  148: ILLEGAL;
+case  149: ILLEGAL;
+case  150: UNIMP("stwcx");
+case  151: INSTR("stwx");  MEM(u_long , LONG, RA0 + RB) = RS;   break;
+case  152: POWER("slq");
+case  153: POWER("sle");
+case  154: ILLEGAL;
+case  155: ILLEGAL;
+case  156: ILLEGAL;
+case  157: ILLEGAL;
+case  158: ILLEGAL;
+case  159: ILLEGAL;
+case  160: ILLEGAL;
+case  161: ILLEGAL;
+case  162: ILLEGAL;
+case  163: ILLEGAL;
+case  164: ILLEGAL;
+case  165: ILLEGAL;
+case  166: ILLEGAL;
+case  167: ILLEGAL;
+case  168: ILLEGAL;
+case  169: ILLEGAL;
+case  170: ILLEGAL;
+case  171: ILLEGAL;
+case  172: ILLEGAL;
+case  173: ILLEGAL;
+case  174: ILLEGAL;
+case  175: ILLEGAL;
+case  176: ILLEGAL;
+case  177: ILLEGAL;
+case  178: ILLEGAL;
+case  179: ILLEGAL;
+case  180: ILLEGAL;
+case  181: ILLEGAL;
+case  182: ILLEGAL;
+case  183: INSTR("stwux");  MEM(u_long , LONG, RA = (RA + RB)) = RS;   break;
+case  184: POWER("sliq");
+case  185: ILLEGAL;
+case  186: ILLEGAL;
+case  187: ILLEGAL;
+case  188: ILLEGAL;
+case  189: ILLEGAL;
+case  190: ILLEGAL;
+case  191: ILLEGAL;
+case  192: ILLEGAL;
+case  193: ILLEGAL;
+case  194: ILLEGAL;
+case  195: ILLEGAL;
+case  196: ILLEGAL;
+case  197: ILLEGAL;
+case  198: ILLEGAL;
+case  199: ILLEGAL;
+case  200: INSTR("subfze");  ADDC(~RA,XER.bits.CA); break;
+case  201: ILLEGAL;
+case  202: INSTR("addze");   ADDC(RA,XER.bits.CA); break;
+case  203: ILLEGAL;
+case  204: ILLEGAL;
+case  205: ILLEGAL;
+case  206: ILLEGAL;
+case  207: ILLEGAL;
+case  208: ILLEGAL;
+case  209: ILLEGAL;
+case  210:
+#ifdef MMU
+	INSTR("mtsr");  SR = RS;  break;
+#else
+	UNIMP("mtsr");
+#endif
+case  211: ILLEGAL;
+case  212: ILLEGAL;
+case  213: ILLEGAL;
+case  214: ILLEGAL;
+case  215: INSTR("stbx");   MEM(u_char , BYTE, RA0 + RB) = RS;    break;
+case  216: POWER("sllq");
+case  217: POWER("sleq");
+case  218: ILLEGAL;
+case  219: ILLEGAL;
+case  220: ILLEGAL;
+case  221: ILLEGAL;
+case  222: ILLEGAL;
+case  223: ILLEGAL;
+case  224: ILLEGAL;
+case  225: ILLEGAL;
+case  226: ILLEGAL;
+case  227: ILLEGAL;
+case  228: ILLEGAL;
+case  229: ILLEGAL;
+case  230: ILLEGAL;
+case  231: ILLEGAL;
+case  232: UNIMP("subfme");
+case  233: ILLEGAL;
+case  234: UNIMP("addme");
+case  235: INSTR("mullw");  
+	   umtimes((u_long *)&scratch, (u_long *)&RD, RA, RB);
+#ifdef OVERFLOWS
+	   if (OE) {
+	       XER.bits.SO |= (XER.bits.OV = (scratch != 0));
+	   }
+#endif
+	   UPDATE_CR(RD);
+           break;
+case  236: ILLEGAL;
+case  237: ILLEGAL;
+case  238: ILLEGAL;
+case  239: ILLEGAL;
+case  240: ILLEGAL;
+case  241: ILLEGAL;
+case  242:
+#ifdef MMU
+	INSTR("mtsrin");  seg[RB] = RS;  break;
+#else
+	UNIMP("mtsrin");
+#endif
+case  243: ILLEGAL;
+case  244: ILLEGAL;
+case  245: ILLEGAL;
+case  246: INSTR("dcbtst");  break;
+case  247: INSTR("stbux");  MEM(u_char , BYTE, RA = (RA + RB)) = RS;   break;
+case  248: POWER("slliq");
+case  249: ILLEGAL;
+case  250: ILLEGAL;
+case  251: ILLEGAL;
+case  252: ILLEGAL;
+case  253: ILLEGAL;
+case  254: ILLEGAL;
+case  255: ILLEGAL;
+case  256: ILLEGAL;
+case  257: ILLEGAL;
+case  258: ILLEGAL;
+case  259: ILLEGAL;
+case  260: ILLEGAL;
+case  261: ILLEGAL;
+case  262: ILLEGAL;
+case  263: ILLEGAL;
+case  264: POWER("doz");
+case  265: ILLEGAL;
+case  266: INSTR("add");
+	   temp = RB + RA;
+	   UPDATE_OV(temp,RB,RA);
+	   UPDATE_CR(temp);
+	   RD = temp;
+           break;
+case  267: ILLEGAL;
+case  268: ILLEGAL;
+case  269: ILLEGAL;
+case  270: ILLEGAL;
+case  271: ILLEGAL;
+case  272: ILLEGAL;
+case  273: ILLEGAL;
+case  274: ILLEGAL;
+case  275: ILLEGAL;
+case  276: ILLEGAL;
+case  277: POWER("lscbx");
+case  278: INSTR("dcbt");  break;
+case  279: INSTR("lhzx");   RD = MEM(u_short, WORD, RA0 + RB);   break;
+case  280: ILLEGAL;
+case  281: ILLEGAL;
+case  282: ILLEGAL;
+case  283: ILLEGAL;
+case  284: INSTR("eqv");    LOGIC( ~(RS ^ RB) );
+case  285: ILLEGAL;
+case  286: ILLEGAL;
+case  287: ILLEGAL;
+case  288: ILLEGAL;
+case  289: ILLEGAL;
+case  290: ILLEGAL;
+case  291: ILLEGAL;
+case  292: ILLEGAL;
+case  293: ILLEGAL;
+case  294: ILLEGAL;
+case  295: ILLEGAL;
+case  296: ILLEGAL;
+case  297: ILLEGAL;
+case  298: ILLEGAL;
+case  299: ILLEGAL;
+case  300: ILLEGAL;
+case  301: ILLEGAL;
+case  302: ILLEGAL;
+case  303: ILLEGAL;
+case  304: ILLEGAL;
+case  305: ILLEGAL;
+case  306:
+#ifdef MMU
+		INSTR("tlbie"); tlbie(RB); break;
+#else
+		UNIMP("tlbie");
+#endif
+case  307: ILLEGAL;
+case  308: ILLEGAL;
+case  309: ILLEGAL;
+case  310: UNIMP("eciwx");  /* uses RA0 */
+case  311: INSTR("lhzux");  RD = MEM(u_short, WORD, RA = (RA + RB));   break;
+case  312: ILLEGAL;
+case  313: ILLEGAL;
+case  314: ILLEGAL;
+case  315: ILLEGAL;
+case  316: INSTR("xor");    LOGIC( RS ^ RB );
+case  317: ILLEGAL;
+case  318: ILLEGAL;
+case  319: ILLEGAL;
+case  320: ILLEGAL;
+case  321: ILLEGAL;
+case  322: ILLEGAL;
+case  323: ILLEGAL;
+case  324: ILLEGAL;
+case  325: ILLEGAL;
+case  326: ILLEGAL;
+case  327: ILLEGAL;
+case  328: ILLEGAL;
+case  329: ILLEGAL;
+case  330: ILLEGAL;
+case  331: POWER("div");
+case  332: ILLEGAL;
+case  333: ILLEGAL;
+case  334: ILLEGAL;
+case  335: ILLEGAL;
+case  336: ILLEGAL;
+case  337: ILLEGAL;
+case  338: ILLEGAL;
+case  339: INSTR("mfspr");  
+	   switch(SPR) {
+	       case    1: RD = XER.all;  break;
+	       case    8: RD = LR;       break;
+	       case    9: RD = CTR;      break;
+	       case   22: RD = DEC;      break;
+#ifdef MMU
+	       case   25: SDR1  = RD;    break;
+#endif
+	       case   26: RD = SRR0;     break;
+	       case   27: RD = SRR1;     break;
+	       case  272: RD = SPRG0;    break;
+	       case  273: RD = SPRG1;    break;
+	       case  274: RD = SPRG2;    break;
+	       case  275: RD = SPRG3;    break;
+	       /*
+		* Special simulator reg.  The return value indicates
+		* whether or not page-zero addressing is supported.
+		*/
+#ifdef TRACE
+	       case  287: TBAR = RD;  RD = 1;  break;
+#else
+	       case  287: TBAR = RD;  RD = 0;  break;
+#endif
+	       case 1008: RD = HID0;	 break;
+	       case 1010: RD = IABR;	 break;
+	       case 1023: RD = 0;	 break;
+	       default: UNIMP("mfspr - bad SPR");
+	   }
+           break;
+case  340: ILLEGAL;
+case  341: ILLEGAL;
+case  342: ILLEGAL;
+case  343: INSTR("lhax");   RD = MEM(short  , WORD, RA0 + RB);   break;
+case  344: ILLEGAL;
+case  345: ILLEGAL;
+case  346: ILLEGAL;
+case  347: ILLEGAL;
+case  348: ILLEGAL;
+case  349: ILLEGAL;
+case  350: ILLEGAL;
+case  351: ILLEGAL;
+case  352: ILLEGAL;
+case  353: ILLEGAL;
+case  354: ILLEGAL;
+case  355: ILLEGAL;
+case  356: ILLEGAL;
+case  357: ILLEGAL;
+case  358: ILLEGAL;
+case  359: ILLEGAL;
+case  360: POWER("abs");
+case  361: ILLEGAL;
+case  362: ILLEGAL;
+case  363: POWER("divs");
+case  364: ILLEGAL;
+case  365: ILLEGAL;
+case  366: ILLEGAL;
+case  367: ILLEGAL;
+case  368: ILLEGAL;
+case  369: ILLEGAL;
+case  370: ILLEGAL;
+case  371: INSTR("mftb");
+	   {
+		extern void gettime();
+
+	        switch(SPR) {
+		    case 268:  gettime((long *)0, (long *)&RD);  break;
+		    case 269:  gettime((long *)&RD, (long *)0);  break;
+		    default:   UNIMP("mftbf - bad TBR");
+		}
+	   }
+	   break;
+
+case  372: ILLEGAL;
+case  373: ILLEGAL;
+case  374: ILLEGAL;
+case  375: INSTR("lhaux");   RD = MEM(short  , WORD, RA = (RA + RB));   break;
+case  376: ILLEGAL;
+case  377: ILLEGAL;
+case  378: ILLEGAL;
+case  379: ILLEGAL;
+case  380: ILLEGAL;
+case  381: ILLEGAL;
+case  382: ILLEGAL;
+case  383: ILLEGAL;
+case  384: ILLEGAL;
+case  385: ILLEGAL;
+case  386: ILLEGAL;
+case  387: ILLEGAL;
+case  388: ILLEGAL;
+case  389: ILLEGAL;
+case  390: ILLEGAL;
+case  391: ILLEGAL;
+case  392: ILLEGAL;
+case  393: ILLEGAL;
+case  394: ILLEGAL;
+case  395: ILLEGAL;
+case  396: ILLEGAL;
+case  397: ILLEGAL;
+case  398: ILLEGAL;
+case  399: ILLEGAL;
+case  400: ILLEGAL;
+case  401: ILLEGAL;
+case  402: ILLEGAL;
+case  403: ILLEGAL;
+case  404: ILLEGAL;
+case  405: ILLEGAL;
+case  406: ILLEGAL;
+case  407: INSTR("sthx");   MEM(u_short, WORD, RA0 + RB) = RS;   break;
+case  408: ILLEGAL;
+case  409: ILLEGAL;
+case  410: ILLEGAL;
+case  411: ILLEGAL;
+case  412: INSTR("orc");  LOGIC( RS | ~RB);
+case  413: ILLEGAL;
+case  414: ILLEGAL;
+case  415: ILLEGAL;
+case  416: ILLEGAL;
+case  417: ILLEGAL;
+case  418: ILLEGAL;
+case  419: ILLEGAL;
+case  420: ILLEGAL;
+case  421: ILLEGAL;
+case  422: ILLEGAL;
+case  423: ILLEGAL;
+case  424: ILLEGAL;
+case  425: ILLEGAL;
+case  426: ILLEGAL;
+case  427: ILLEGAL;
+case  428: ILLEGAL;
+case  429: ILLEGAL;
+case  430: ILLEGAL;
+case  431: ILLEGAL;
+case  432: ILLEGAL;
+case  433: ILLEGAL;
+case  434: ILLEGAL;
+case  435: ILLEGAL;
+case  436: ILLEGAL;
+case  437: ILLEGAL;
+case  438: UNIMP("ecowx");  /* uses RA0 */
+case  439: INSTR("sthux");   MEM(u_short, WORD, RA = (RA + RB)) = RS;   break;
+case  440: ILLEGAL;
+case  441: ILLEGAL;
+case  442: ILLEGAL;
+case  443: ILLEGAL;
+case  444: INSTR("or");    LOGIC( RS | RB );
+case  445: ILLEGAL;
+case  446: ILLEGAL;
+case  447: ILLEGAL;
+case  448: ILLEGAL;
+case  449: ILLEGAL;
+case  450: ILLEGAL;
+case  451: ILLEGAL;
+case  452: ILLEGAL;
+case  453: ILLEGAL;
+case  454: ILLEGAL;
+case  455: ILLEGAL;
+case  456: ILLEGAL;
+case  457: ILLEGAL;
+case  458: ILLEGAL;
+case  459: INSTR("divwu"); RD = (u_long)RA / (u_long)RB; UPDATE_CR(RD);  break;
+	   /* XXX Overflow is not handled */
+case  460: ILLEGAL;
+case  461: ILLEGAL;
+case  462: ILLEGAL;
+case  463: ILLEGAL;
+case  464: ILLEGAL;
+case  465: ILLEGAL;
+case  466: ILLEGAL;
+case  467: INSTR("mtspr");  
+	   switch (SPR) {
+	       case    1: XER.all = RD;  break;
+	       case    8: LR    = RD;	 break;
+	       case    9: CTR   = RD;	 break;
+	       case   22: DEC   = RD;    break;
+#ifdef MMU
+	       case   25: SDR1  = RD;    break;
+#endif
+	       case   26: SRR0  = RD;	 break;
+	       case   27: SRR1  = RD;	 break;
+	       case  272: SPRG0 = RD;    break;
+	       case  273: SPRG1 = RD;    break;
+	       case  274: SPRG2 = RD;    break;
+	       case  275: SPRG3 = RD;    break;
+	       case 1008: HID0  = RD;
+#ifdef BI_ENDIAN
+					if (HID0 & 8) {
+						LONG = 4; WORD = 6; BYTE = 7;
+					} else {
+						LONG = 0; WORD = 0; BYTE = 0;
+					}
+#endif
+					 break;
+	       case 1010: IABR  = RD;	 break;
+	       default: UNIMP("mtspr - bad SPR");
+	   }
+           break;
+case  468: ILLEGAL;
+case  469: ILLEGAL;
+case  470: INSTR("dcbi");  break;
+case  471: ILLEGAL;
+case  472: ILLEGAL;
+case  473: ILLEGAL;
+case  474: ILLEGAL;
+case  475: ILLEGAL;
+case  476: INSTR("nand");  LOGIC( ~(RS & RB) );
+case  477: ILLEGAL;
+case  478: ILLEGAL;
+case  479: ILLEGAL;
+case  480: ILLEGAL;
+case  481: ILLEGAL;
+case  482: ILLEGAL;
+case  483: ILLEGAL;
+case  484: ILLEGAL;
+case  485: ILLEGAL;
+case  486: ILLEGAL;
+case  487: ILLEGAL;
+case  488: POWER("nabs");
+case  489: ILLEGAL;
+case  490: ILLEGAL;
+case  491: INSTR("divw");  RD = RA / RB;  UPDATE_CR(RD);  break;
+	   /* XXX Overflow is not handled */
+case  492: ILLEGAL;
+case  493: ILLEGAL;
+case  494: ILLEGAL;
+case  495: ILLEGAL;
+case  496: ILLEGAL;
+case  497: ILLEGAL;
+case  498: ILLEGAL;
+case  499: ILLEGAL;
+case  500: ILLEGAL;
+case  501: ILLEGAL;
+case  502: ILLEGAL;
+case  503: ILLEGAL;
+case  504: ILLEGAL;
+case  505: ILLEGAL;
+case  506: ILLEGAL;
+case  507: ILLEGAL;
+case  508: ILLEGAL;
+case  509: ILLEGAL;
+case  510: ILLEGAL;
+case  511: ILLEGAL;
+case  512: UNIMP("mcrxr");
+case  513: ILLEGAL;
+case  514: ILLEGAL;
+case  515: ILLEGAL;
+case  516: ILLEGAL;
+case  517: ILLEGAL;
+case  518: ILLEGAL;
+case  519: ILLEGAL;
+case  520: ILLEGAL;
+case  521: ILLEGAL;
+case  522: ILLEGAL;
+case  523: ILLEGAL;
+case  524: ILLEGAL;
+case  525: ILLEGAL;
+case  526: ILLEGAL;
+case  527: ILLEGAL;
+case  528: ILLEGAL;
+case  529: ILLEGAL;
+case  530: ILLEGAL;
+case  531: POWER("clcs");
+case  532: ILLEGAL;
+case  533: UNIMP("lswx");
+case  534: INSTR("lwbrx");  
+	   temp = MEM(u_long , LONG, RA0 + RB);
+	   RD = ((temp << 24) & 0xff000000) |
+		((temp <<  8) & 0x00ff0000) |
+		((temp >>  8) & 0x0000ff00) |
+		((temp >> 24) & 0x000000ff);
+           break;
+case  535: UNIMP("lfsx");
+/* XXX is it bit 16 or bit 26? */
+case  536: INSTR("srw");  LOGIC( (RB & 0x10020 ? 0 : RS >> (RB & 0x1f)) ); break;
+case  537: POWER("rrib");
+case  538: ILLEGAL;
+case  539: ILLEGAL;
+case  540: ILLEGAL;
+case  541: POWER("maskir");
+case  542: ILLEGAL;
+case  543: ILLEGAL;
+case  544: ILLEGAL;
+case  545: ILLEGAL;
+case  546: ILLEGAL;
+case  547: ILLEGAL;
+case  548: ILLEGAL;
+case  549: ILLEGAL;
+case  550: ILLEGAL;
+case  551: ILLEGAL;
+case  552: ILLEGAL;
+case  553: ILLEGAL;
+case  554: ILLEGAL;
+case  555: ILLEGAL;
+case  556: ILLEGAL;
+case  557: ILLEGAL;
+case  558: ILLEGAL;
+case  559: ILLEGAL;
+case  560: ILLEGAL;
+case  561: ILLEGAL;
+case  562: ILLEGAL;
+case  563: ILLEGAL;
+case  564: ILLEGAL;
+case  565: ILLEGAL;
+case  566:
+#ifdef MMU
+	INSTR("tlbsync"); break;
+#else
+	UNIMP("tlbsync");
+#endif
+case  567: UNIMP("lfsux");
+case  568: ILLEGAL;
+case  569: ILLEGAL;
+case  570: ILLEGAL;
+case  571: ILLEGAL;
+case  572: ILLEGAL;
+case  573: ILLEGAL;
+case  574: ILLEGAL;
+case  575: ILLEGAL;
+case  576: ILLEGAL;
+case  577: ILLEGAL;
+case  578: ILLEGAL;
+case  579: ILLEGAL;
+case  580: ILLEGAL;
+case  581: ILLEGAL;
+case  582: ILLEGAL;
+case  583: ILLEGAL;
+case  584: ILLEGAL;
+case  585: ILLEGAL;
+case  586: ILLEGAL;
+case  587: ILLEGAL;
+case  588: ILLEGAL;
+case  589: ILLEGAL;
+case  590: ILLEGAL;
+case  591: ILLEGAL;
+case  592: ILLEGAL;
+case  593: ILLEGAL;
+case  594: ILLEGAL;
+case  595:
+#ifdef MMU
+	INSTR("mfsr");  RD = SR;  break;
+#else
+	UNIMP("mfsr");
+#endif
+case  596: ILLEGAL;
+case  597: UNIMP("lswi");
+case  598: INSTR("sync");   break;
+case  599: UNIMP("lfdx");
+case  600: ILLEGAL;
+case  601: ILLEGAL;
+case  602: ILLEGAL;
+case  603: ILLEGAL;
+case  604: ILLEGAL;
+case  605: ILLEGAL;
+case  606: ILLEGAL;
+case  607: ILLEGAL;
+case  608: ILLEGAL;
+case  609: ILLEGAL;
+case  610: ILLEGAL;
+case  611: ILLEGAL;
+case  612: ILLEGAL;
+case  613: ILLEGAL;
+case  614: ILLEGAL;
+case  615: ILLEGAL;
+case  616: ILLEGAL;
+case  617: ILLEGAL;
+case  618: ILLEGAL;
+case  619: ILLEGAL;
+case  620: ILLEGAL;
+case  621: ILLEGAL;
+case  622: ILLEGAL;
+case  623: ILLEGAL;
+case  624: ILLEGAL;
+case  625: ILLEGAL;
+case  626: ILLEGAL;
+case  627: ILLEGAL;
+case  628: ILLEGAL;
+case  629: ILLEGAL;
+case  630: ILLEGAL;
+case  631: UNIMP("lfdux");
+case  632: ILLEGAL;
+case  633: ILLEGAL;
+case  634: ILLEGAL;
+case  635: ILLEGAL;
+case  636: ILLEGAL;
+case  637: ILLEGAL;
+case  638: ILLEGAL;
+case  639: ILLEGAL;
+case  640: ILLEGAL;
+case  641: ILLEGAL;
+case  642: ILLEGAL;
+case  643: ILLEGAL;
+case  644: ILLEGAL;
+case  645: ILLEGAL;
+case  646: ILLEGAL;
+case  647: ILLEGAL;
+case  648: ILLEGAL;
+case  649: ILLEGAL;
+case  650: ILLEGAL;
+case  651: ILLEGAL;
+case  652: ILLEGAL;
+case  653: ILLEGAL;
+case  654: ILLEGAL;
+case  655: ILLEGAL;
+case  656: ILLEGAL;
+case  657: ILLEGAL;
+case  658: ILLEGAL;
+case  659:
+#ifdef MMU
+	INSTR("mfsrin");  RD = seg[RB];  break;
+#else
+	UNIMP("mfsrin");
+#endif
+case  660: ILLEGAL;
+case  661: UNIMP("stswx");
+case  662: INSTR("stwbrx");  
+	   temp = RS;
+	   MEM(u_long , LONG, RA0 + RB) =
+	        ((temp << 24) & 0xff000000) |
+		((temp <<  8) & 0x00ff0000) |
+		((temp >>  8) & 0x0000ff00) |
+		((temp >> 24) & 0x000000ff);
+           break;
+case  663: UNIMP("stfsx");
+case  664: POWER("srq");
+case  665: POWER("sre");
+case  666: ILLEGAL;
+case  667: ILLEGAL;
+case  668: ILLEGAL;
+case  669: ILLEGAL;
+case  670: ILLEGAL;
+case  671: ILLEGAL;
+case  672: ILLEGAL;
+case  673: ILLEGAL;
+case  674: ILLEGAL;
+case  675: ILLEGAL;
+case  676: ILLEGAL;
+case  677: ILLEGAL;
+case  678: ILLEGAL;
+case  679: ILLEGAL;
+case  680: ILLEGAL;
+case  681: ILLEGAL;
+case  682: ILLEGAL;
+case  683: ILLEGAL;
+case  684: ILLEGAL;
+case  685: ILLEGAL;
+case  686: ILLEGAL;
+case  687: ILLEGAL;
+case  688: ILLEGAL;
+case  689: ILLEGAL;
+case  690: ILLEGAL;
+case  691: ILLEGAL;
+case  692: ILLEGAL;
+case  693: ILLEGAL;
+case  694: ILLEGAL;
+case  695: UNIMP("stfsux");
+case  696: POWER("sriq");
+case  697: ILLEGAL;
+case  698: ILLEGAL;
+case  699: ILLEGAL;
+case  700: ILLEGAL;
+case  701: ILLEGAL;
+case  702: ILLEGAL;
+case  703: ILLEGAL;
+case  704: ILLEGAL;
+case  705: ILLEGAL;
+case  706: ILLEGAL;
+case  707: ILLEGAL;
+case  708: ILLEGAL;
+case  709: ILLEGAL;
+case  710: ILLEGAL;
+case  711: ILLEGAL;
+case  712: ILLEGAL;
+case  713: ILLEGAL;
+case  714: ILLEGAL;
+case  715: ILLEGAL;
+case  716: ILLEGAL;
+case  717: ILLEGAL;
+case  718: ILLEGAL;
+case  719: ILLEGAL;
+case  720: ILLEGAL;
+case  721: ILLEGAL;
+case  722: ILLEGAL;
+case  723: ILLEGAL;
+case  724: ILLEGAL;
+case  725: UNIMP("stswi");
+case  726: ILLEGAL;
+case  727: UNIMP("stfdx");
+case  728: POWER("srlq");
+case  729: POWER("sreq");
+case  730: ILLEGAL;
+case  731: ILLEGAL;
+case  732: ILLEGAL;
+case  733: ILLEGAL;
+case  734: ILLEGAL;
+case  735: ILLEGAL;
+case  736: ILLEGAL;
+case  737: ILLEGAL;
+case  738: ILLEGAL;
+case  739: ILLEGAL;
+case  740: ILLEGAL;
+case  741: ILLEGAL;
+case  742: ILLEGAL;
+case  743: ILLEGAL;
+case  744: ILLEGAL;
+case  745: ILLEGAL;
+case  746: ILLEGAL;
+case  747: ILLEGAL;
+case  748: ILLEGAL;
+case  749: ILLEGAL;
+case  750: ILLEGAL;
+case  751: ILLEGAL;
+case  752: ILLEGAL;
+case  753: ILLEGAL;
+case  754: ILLEGAL;
+case  755: ILLEGAL;
+case  756: ILLEGAL;
+case  757: ILLEGAL;
+case  758: ILLEGAL;
+case  759: UNIMP("stfdux");
+case  760: POWER("srliq");
+case  761: ILLEGAL;
+case  762: ILLEGAL;
+case  763: ILLEGAL;
+case  764: ILLEGAL;
+case  765: ILLEGAL;
+case  766: ILLEGAL;
+case  767: ILLEGAL;
+case  768: ILLEGAL;
+case  769: ILLEGAL;
+case  770: ILLEGAL;
+case  771: ILLEGAL;
+case  772: ILLEGAL;
+case  773: ILLEGAL;
+case  774: ILLEGAL;
+case  775: ILLEGAL;
+case  776: ILLEGAL;
+case  777: ILLEGAL;
+case  778: ILLEGAL;
+case  779: ILLEGAL;
+case  780: ILLEGAL;
+case  781: ILLEGAL;
+case  782: ILLEGAL;
+case  783: ILLEGAL;
+case  784: ILLEGAL;
+case  785: ILLEGAL;
+case  786: ILLEGAL;
+case  787: ILLEGAL;
+case  788: ILLEGAL;
+case  789: ILLEGAL;
+case  790: INSTR("lhbrx");  
+	   temp = MEM(u_short, WORD, RA0 + RB);
+	   RD = ((temp & 0xff) << 8 ) | (temp >> 8);
+           break;
+case  791: ILLEGAL;
+case  792: INSTR("sraw");
+	   LOGIC( (RB & 0x20 ? (long)RS >> 31 : (long)RS >> (RB & 0x1f)) );
+	   break;
+	   /* XXX handle XER.bits.CA */
+case  793: ILLEGAL;
+case  794: ILLEGAL;
+case  795: ILLEGAL;
+case  796: ILLEGAL;
+case  797: ILLEGAL;
+case  798: ILLEGAL;
+case  799: ILLEGAL;
+case  800: ILLEGAL;
+case  801: ILLEGAL;
+case  802: ILLEGAL;
+case  803: ILLEGAL;
+case  804: ILLEGAL;
+case  805: ILLEGAL;
+case  806: ILLEGAL;
+case  807: ILLEGAL;
+case  808: ILLEGAL;
+case  809: ILLEGAL;
+case  810: ILLEGAL;
+case  811: ILLEGAL;
+case  812: ILLEGAL;
+case  813: ILLEGAL;
+case  814: ILLEGAL;
+case  815: ILLEGAL;
+case  816: ILLEGAL;
+case  817: ILLEGAL;
+case  818: ILLEGAL;
+case  819: ILLEGAL;
+case  820: ILLEGAL;
+case  821: ILLEGAL;
+case  822: ILLEGAL;
+case  823: ILLEGAL;
+case  824: INSTR("srawi"); LOGIC( (long)RS >> SH );/* XXX handle XER.bits.CA */
+case  825: ILLEGAL;
+case  826: ILLEGAL;
+case  827: ILLEGAL;
+case  828: ILLEGAL;
+case  829: ILLEGAL;
+case  830: ILLEGAL;
+case  831: ILLEGAL;
+case  832: ILLEGAL;
+case  833: ILLEGAL;
+case  834: ILLEGAL;
+case  835: ILLEGAL;
+case  836: ILLEGAL;
+case  837: ILLEGAL;
+case  838: ILLEGAL;
+case  839: ILLEGAL;
+case  840: ILLEGAL;
+case  841: ILLEGAL;
+case  842: ILLEGAL;
+case  843: ILLEGAL;
+case  844: ILLEGAL;
+case  845: ILLEGAL;
+case  846: ILLEGAL;
+case  847: ILLEGAL;
+case  848: ILLEGAL;
+case  849: ILLEGAL;
+case  850: ILLEGAL;
+case  851: ILLEGAL;
+case  852: ILLEGAL;
+case  853: ILLEGAL;
+case  854: UNIMP("Old MacDonald had a farm - eieio");
+case  855: ILLEGAL;
+case  856: ILLEGAL;
+case  857: ILLEGAL;
+case  858: ILLEGAL;
+case  859: ILLEGAL;
+case  860: ILLEGAL;
+case  861: ILLEGAL;
+case  862: ILLEGAL;
+case  863: ILLEGAL;
+case  864: ILLEGAL;
+case  865: ILLEGAL;
+case  866: ILLEGAL;
+case  867: ILLEGAL;
+case  868: ILLEGAL;
+case  869: ILLEGAL;
+case  870: ILLEGAL;
+case  871: ILLEGAL;
+case  872: ILLEGAL;
+case  873: ILLEGAL;
+case  874: ILLEGAL;
+case  875: ILLEGAL;
+case  876: ILLEGAL;
+case  877: ILLEGAL;
+case  878: ILLEGAL;
+case  879: ILLEGAL;
+case  880: ILLEGAL;
+case  881: ILLEGAL;
+case  882: ILLEGAL;
+case  883: ILLEGAL;
+case  884: ILLEGAL;
+case  885: ILLEGAL;
+case  886: ILLEGAL;
+case  887: ILLEGAL;
+case  888: ILLEGAL;
+case  889: ILLEGAL;
+case  890: ILLEGAL;
+case  891: ILLEGAL;
+case  892: ILLEGAL;
+case  893: ILLEGAL;
+case  894: ILLEGAL;
+case  895: ILLEGAL;
+case  896: ILLEGAL;
+case  897: ILLEGAL;
+case  898: ILLEGAL;
+case  899: ILLEGAL;
+case  900: ILLEGAL;
+case  901: ILLEGAL;
+case  902: ILLEGAL;
+case  903: ILLEGAL;
+case  904: ILLEGAL;
+case  905: ILLEGAL;
+case  906: ILLEGAL;
+case  907: ILLEGAL;
+case  908: ILLEGAL;
+case  909: ILLEGAL;
+case  910: ILLEGAL;
+case  911: ILLEGAL;
+case  912: ILLEGAL;
+case  913: ILLEGAL;
+case  914: ILLEGAL;
+case  915: ILLEGAL;
+case  916: ILLEGAL;
+case  917: ILLEGAL;
+case  918: INSTR("sthbrx");  
+	   temp = RS & 0xffff;
+	   MEM(u_short, WORD, RA0 + RB) = ((temp & 0xff) << 8 ) | (temp >> 8);
+           break;
+case  919: ILLEGAL;
+case  920: POWER("sraq");
+case  921: POWER("srea");
+case  922: INSTR("extsh");   LOGIC( (long)(RS << 16) >> 16 );
+case  923: ILLEGAL;
+case  924: ILLEGAL;
+case  925: ILLEGAL;
+case  926: ILLEGAL;
+case  927: ILLEGAL;
+case  928: ILLEGAL;
+case  929: ILLEGAL;
+case  930: ILLEGAL;
+case  931: ILLEGAL;
+case  932: ILLEGAL;
+case  933: ILLEGAL;
+case  934: ILLEGAL;
+case  935: ILLEGAL;
+case  936: ILLEGAL;
+case  937: ILLEGAL;
+case  938: ILLEGAL;
+case  939: ILLEGAL;
+case  940: ILLEGAL;
+case  941: ILLEGAL;
+case  942: ILLEGAL;
+case  943: ILLEGAL;
+case  944: ILLEGAL;
+case  945: ILLEGAL;
+case  946: ILLEGAL;
+case  947: ILLEGAL;
+case  948: ILLEGAL;
+case  949: ILLEGAL;
+case  950: ILLEGAL;
+case  951: ILLEGAL;
+case  952: POWER("sraiq");
+case  953: ILLEGAL;
+case  954: INSTR("extsb");  LOGIC( (long)(RS << 24) >> 24 );
+case  955: ILLEGAL;
+case  956: ILLEGAL;
+case  957: ILLEGAL;
+case  958: ILLEGAL;
+case  959: ILLEGAL;
+case  960: ILLEGAL;
+case  961: ILLEGAL;
+case  962: ILLEGAL;
+case  963: ILLEGAL;
+case  964: ILLEGAL;
+case  965: ILLEGAL;
+case  966: ILLEGAL;
+case  967: ILLEGAL;
+case  968: ILLEGAL;
+case  969: ILLEGAL;
+case  970: ILLEGAL;
+case  971: ILLEGAL;
+case  972: ILLEGAL;
+case  973: ILLEGAL;
+case  974: ILLEGAL;
+case  975: ILLEGAL;
+case  976: ILLEGAL;
+case  977: ILLEGAL;
+case  978:
+#ifdef MMU
+	INSTR("tlbld");  ONLY603  mmutab[RB >> 12] = RPA & 0xfffff00;  break;
+#else
+	UNIMP("tlbld");
+#endif
+case  979: ILLEGAL;
+case  980: ILLEGAL;
+case  981: ILLEGAL;
+case  982: INSTR("icbi");  break;
+case  983: ILLEGAL;
+case  984: ILLEGAL;
+case  985: ILLEGAL;
+case  986: ILLEGAL;
+case  987: ILLEGAL;
+case  988: ILLEGAL;
+case  989: ILLEGAL;
+case  990: ILLEGAL;
+case  991: ILLEGAL;
+case  992: ILLEGAL;
+case  993: ILLEGAL;
+case  994: ILLEGAL;
+case  995: ILLEGAL;
+case  996: ILLEGAL;
+case  997: ILLEGAL;
+case  998: ILLEGAL;
+case  999: ILLEGAL;
+case 1000: ILLEGAL;
+case 1001: ILLEGAL;
+case 1002: ILLEGAL;
+case 1003: ILLEGAL;
+case 1004: ILLEGAL;
+case 1005: ILLEGAL;
+case 1006: ILLEGAL;
+case 1007: ILLEGAL;
+case 1008: ILLEGAL;
+case 1009: ILLEGAL;
+case 1010:
+#ifdef MMU
+	INSTR("tlbli");  ONLY603  mmutab[RB >> 12] = RPA & 0xfffff00;  break;
+#else
+	UNIMP("tlbli");
+#endif
+case 1011: ILLEGAL;
+case 1012: ILLEGAL;
+case 1013: ILLEGAL;
+case 1014: UNIMP("dcbz");
+case 1015: ILLEGAL;
+case 1016: ILLEGAL;
+case 1017: ILLEGAL;
+case 1018: ILLEGAL;
+case 1019: ILLEGAL;
+case 1020: ILLEGAL;
+case 1021: ILLEGAL;
+case 1022: ILLEGAL;
+case 1023: ILLEGAL;
+			} /* End of big 31-class switch */
+		} /* End of main opcode switch */
+
+		continue;
+power:
+		if (!TBAR)
+		    printf("Unimplemented POWER instruction %08lx (%s) at %lx\n",
+		           (long)instruction, (long)opname, (long)CIA);
+		goto trapout;
+
+unimplemented:
+		if (!TBAR)
+		    printf("Unimplemented instruction %08lx (%s)at %lx\n",
+		           (long)instruction, (long)opname, (long)CIA);
+		goto trapout;
+
+illegal:
+		if (!TBAR)
+		    printf("Illegal instruction %08lx at %lx\n",
+			   (long)instruction, (long)CIA, (long)0);
+
+trapout:
+		if (TBAR) {
+			SRR0 = CIA;
+			SRR1 = MSR;
+			pc = TBAR + 0x700 - 4;
+			continue;
+		} else
+			return;
+
+	}  /* End of main loop */
+}
+
+
+umtimes(dhighp, dlowp, u1, u2)
+    u_long *dhighp, *dlowp;
+    u_long u1, u2;
+{
+    register u_long ah, al, bh, bl, tmp;
+    extern void dplus();
+
+    ah = u1>>16;  al = u1 & 0xffff;
+    bh = u2>>16;  bl = u2 & 0xffff;
+
+    *dhighp = ah*bh;  *dlowp = al*bl;
+    
+    tmp = ah*bl;
+    dplus((long *)dhighp, (long *)dlowp, (long)(tmp>>16), (long)(tmp<<16));
+
+    tmp = al*bh;
+    dplus((long *)dhighp, (long *)dlowp, (long)(tmp>>16), (long)(tmp<<16));
+}
+
+/* Carry calculation assumes 2's complement arithmetic. */
+#define CARRY(res,b)  ((u_long)res < (u_long)b)
+
+void
+dplus(dhighp, dlowp, shigh, slow)
+    register long *dhighp, *dlowp, shigh, slow;
+{
+    register long lowres;
+
+    lowres   = *dlowp + slow;
+    *dhighp += shigh + CARRY(lowres, slow);
+    *dlowp   = lowres;
+}
+
+
+#ifdef TRACE
+#include <sys/signal.h>
+dumpregs()
+{
+#ifdef ARGREGS
+	printf(
+	 "      r0         r1         r2         r3         r4         r5\n"
+	);
+	printf(
+	 "%8x   %8x   %8x   %8x   %8x   %8x\n\n",
+	 greg[ 0],  greg[ 1],   greg[ 2],  greg[ 3],  greg[ 4],  greg[ 5]
+	);
+
+	printf(
+	 "      r6         r7         r8         r9         r10        r11\n"
+	);
+	printf(
+	 "%8x   %8x   %8x   %8x   %8x   %8x\n\n",
+	 greg[ 6],  greg[ 7],   greg[ 8],  greg[ 9],  greg[10],  greg[11]
+	);
+#endif
+	printf(
+	 " r20  t0    r21  t1    r22  t2    r23  t3    r24  t4    r25  t5\n"
+	);
+	printf(
+	 "%8x   %8x   %8x   %8x   %8x   %8x\n\n",
+	 greg[20],  greg[21],   greg[22],  greg[23],  greg[24],  greg[25]
+	);
+	printf(
+	 " r26 base   r27  up    r28 tos    r29  ip    r30  rp    r31  sp\n"
+	);
+	printf(
+	 "%8x   %8x   %8x   %8x   %8x   %8x\n\n",
+	 greg[26],  greg[27],   greg[28],  greg[29],  greg[30],  greg[31]
+	);
+	printf("pc %x  LR %x  CTR %x  CR %x",
+		pc,    LR,    CTR,    CR.all
+	);
+#ifndef SIMROM
+	printf("  CALLS: %x", greg[29]	/* IP */);
+
+	if (greg[30])
+		printf(" %x %x %x",
+		 ((u_long *)greg[30])[0],	/* Return stack */
+		 ((u_long *)greg[30])[1],
+		 ((u_long *)greg[30])[2]
+		);
+	printf("\n");
+#endif
+}
+dumpallregs()
+{
+        int i;
+	for (i=0; i<8 ; i++)  printf("%9x", greg[i]);  putchar('\n');
+	for (   ; i<16; i++)  printf("%9x", greg[i]);  putchar('\n');
+	for (   ; i<24; i++)  printf("%9x", greg[i]);  putchar('\n');
+	for (   ; i<32; i++)  printf("%9x", greg[i]);  putchar('\n');
+
+	printf("pc %x  LR %x  CTR %x  CR %x  ",
+		pc,    LR,    CTR,    CR.all
+	);
+	printf("\n");
+}
+
+void
+handle_signal(foo)
+	int foo;
+{
+	dumpregs();
+	s_bye(1);
+}
+catch_signals()
+{
+	signal(SIGINT,handle_signal);
+	signal(SIGILL,handle_signal);
+	signal(SIGFPE,handle_signal);
+	signal(SIGSEGV,handle_signal);
+#ifdef UNIX
+	signal(SIGTRAP,handle_signal);
+//	signal(SIGEMT,handle_signal);
+	signal(SIGBUS,handle_signal);
+#endif
+}
+
+dumpmem(adr)
+	long adr;
+{
+	u_long *reladr;
+
+	reladr = (u_long *) &xmem[ (int)adr ];
+	printf("%x: %8x %8x %8x %8x %8x %8x %8x %8x\n",
+		adr,
+		reladr[0], reladr[1], reladr[2], reladr[3],
+		reladr[4], reladr[5], reladr[6], reladr[7]
+	);
+}
+
+#ifdef SIMROM
+#define GETLINE  (void)c_key();
+#else
+#define GETLINE
+#endif
+trace(name, instruction)
+	char *name;
+	u_long instruction;
+{
+	int done;
+	int arg;
+	int c;
+	static int stepping = 1;
+
+	if (!stepping & (!IABR || pc != IABR))
+		return;
+
+	IABR = 0;
+	stepping = 1;
+
+	printf("%x %x %s ", pc, greg[29], name);
+	for (done=0; !done; ) {
+		printf(" : ");
+#ifndef SIMROM
+		putchar(c = c_key());
+		putchar('\n');
+#else
+		c = c_key();
+#endif
+		switch(c)
+		{
+			case 'b':  scanf("%x", &IABR); stepping = 0; break;
+			case 'n':  IABR = greg[27]; stepping = 0; break;
+			case 'u':  scanf("%x", &arg);
+				   dumpmem((long)(greg[27]+arg));
+				   GETLINE;
+				   break;
+			case 'm':  scanf("%x", &arg);
+				   dumpmem((long)arg);
+				   GETLINE;
+				   break;
+			case 'q':  s_bye(0); break;
+			case 'r':  dumpregs();
+				   GETLINE;
+				   break;
+			case 'a':  dumpallregs();
+				   GETLINE;
+				   break;
+			case 'c':  stepping = 0; done=1; GETLINE; break;
+			default: done=1; break;
+		}
+	}
+}
+#endif
+
+#ifdef UNIX
+#include <sys/time.h>
+#else
+/* ARGSUSED */
+#endif
+void
+gettime(secp, nsecp)
+    long *secp, *nsecp;
+{
+#ifdef UNIX
+    struct timeval t;
+    extern int gettimeofday();
+
+    (void) gettimeofday(&t, (struct timezone *)0);
+    if (secp)
+	*secp = t.tv_sec;
+    if (nsecp)
+	*nsecp = t.tv_usec * 1000;
+#endif
+}
+#define TOKEN 4
+int
+xfindnext(adr, strlen, base, link, alf)
+    register u_char *adr;
+    register long strlen;
+    register long base;
+    register u_long link;
+    u_long *alf;
+{
+    register u_char *s, *p;
+    register int namelen, len;
+
+    while((link = *(u_long *)link + base) != base) {
+        link -= TOKEN;		/* link is now the absolute alf */
+        s = (u_char *)(link-1-strlen);
+        p = adr;
+	len = strlen;
+	while (len-- && *s == *p) {
+	    s++;
+	    p++;
+	}
+	if ((len < 0) && ((*s & 0x1f) == strlen)) {
+	    *alf = link;
+	    return(-1);
+	}
+    }
+    return(0);
+}
+
+// LICENSE_BEGIN
+// Copyright (c) 2007 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: cpu/ppc/ppcsim/simrom.c
===================================================================
--- cpu/ppc/ppcsim/simrom.c	                        (rev 0)
+++ cpu/ppc/ppcsim/simrom.c	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,62 @@
+// See license at end of file
+/*
+ * Main routine for calling the PowerPC simulator to simulate ROM images
+ */
+
+extern void simulate();
+extern char *malloc();
+
+char *loadaddr;
+
+#define MEMSIZE 0x800000
+
+main()
+{
+	int f;
+	if((f = open("fw.img", 0)) < 0) {
+		perror("can't open fw.img");
+		exit(1);
+	}
+	loadaddr = malloc(MEMSIZE);
+	(void) read(f, loadaddr, MEMSIZE);
+	close(f);
+	simulate(loadaddr, 0x100, 0, 0, 0, 0, 0, 1 /* 0=POWER, 1=PowerPC */);
+	exit(0);
+}
+int
+c_key()
+{
+	int i;
+	if ((i = getchar()) == -1)
+		exit (0);
+	return (i);
+}
+void
+s_bye()
+{
+	exit(0);
+}
+
+// LICENSE_BEGIN
+// Copyright (c) 2007 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: cpu/ppc/realcif.fth
===================================================================
--- cpu/ppc/realcif.fth	                        (rev 0)
+++ cpu/ppc/realcif.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,237 @@
+purpose: Real-mode client interface fixups
+\ See license at end of file
+
+headerless
+hex
+
+\ The client program is required to disable i&d translation and 
+\ disable interrupts before making a real-mode client interface call.
+\ The firmware must save and restore
+
+
+\ XXX finish the space optimization --- after exp fixups?
+\ /exc h# 18 + ( dsi )  20 + ( dbats )  54 + ( sprs )
+100 ( dsi )  20 + ( dbats )  54 + ( sprs )
+\ /rm-tlbmiss 2* + ( dtlbs )	\ add this in stand-init
+200 + ( dtlbs )
+value /env
+
+0 value fw-env
+0 value client-env
+
+code save-sprs   ( addr1 -- addr2 )	\ 54
+   addi   tos,tos,-4
+   mfspr  t0,sdr1	stwu  t0,4(tos)
+   mfspr  t0,sprg0	stwu  t0,4(tos)
+   mfspr  t0,sprg1	stwu  t0,4(tos)
+   mfspr  t0,sprg2	stwu  t0,4(tos)
+   mfspr  t0,sprg3	stwu  t0,4(tos)
+   set t1,h#10
+   begin
+      addi  t1,t1,-1
+      rlwinm  t0,t1,28,0,3
+      mfsrin  t0,t0	stwu  t0,4(tos)
+      cmpi  0,0,t1,0   <=
+   until
+   addi   tos,tos,4
+c;
+code restore-sprs   ( addr1 -- addr2 )
+   addi  tos,tos,-4
+   lwzu  t0,4(tos)	mtspr  sdr1,t0
+   lwzu  t0,4(tos)	mtspr  sprg0,t0
+   lwzu  t0,4(tos)	mtspr  sprg1,t0
+   lwzu  t0,4(tos)	mtspr  sprg2,t0
+   lwzu  t0,4(tos)	mtspr  sprg3,t0
+   set t1,h#10
+   sync		\ XXX move syncs inside the loop?
+   isync	\ XXX do we *really* need both syncs both times?
+   begin
+      addi  t1,t1,-1
+      rlwinm  t2,t1,28,0,3
+      lwzu  t0,4(tos)	mtsrin  t0,t2
+      cmpi  0,0,t1,0   <=
+   until
+   sync    
+   isync   
+   addi   tos,tos,4
+c;
+
+code save-dbats   ( addr1 -- addr2 )	\ 20
+   mfspr  t0,dbat0u	stw  t0,0(tos)
+   mfspr  t1,dbat0l	stw  t1,4(tos)
+   mfspr  t2,dbat1u	stw  t2,8(tos)
+   mfspr  t3,dbat1l	stw  t3,12(tos)
+   mfspr  t4,dbat2u	stw  t4,16(tos)
+   mfspr  t5,dbat2l	stw  t5,20(tos)
+   mfspr  t6,dbat3u	stw  t6,24(tos)
+   mfspr  t7,dbat3l	stw  t7,28(tos)
+   addi   tos,tos,32
+c;
+code restore-dbats   ( addr1 -- addr2 )
+   sync		\ XXX move syncs inside the loop?
+   isync	\ XXX do we *really* need both syncs both times?
+   lwz  t0,0(tos)	mtspr  dbat0u,t0
+   lwz  t1,4(tos)	mtspr  dbat0l,t1
+   lwz  t2,8(tos)	mtspr  dbat1u,t2
+   lwz  t3,12(tos)	mtspr  dbat1l,t3
+   lwz  t4,16(tos)	mtspr  dbat2u,t4
+   lwz  t5,20(tos)	mtspr  dbat2l,t5
+   lwz  t6,24(tos)	mtspr  dbat3u,t6
+   lwz  t7,28(tos)	mtspr  dbat3l,t7
+   sync    
+   isync   
+   addi   tos,tos,32
+c;
+
+code save-lomem   ( addr1 --  addr2 )	\ 120
+   addi  t0,tos,-4		\ Dst into t0
+   
+   \ save 300-3ff
+   300 4 -	set  t1,*	\ Src
+   100 4 /	set  t2,*	\ set length
+   mtspr ctr,t2		\ Count in count register
+   begin
+      lbzu  t2,4(t1)	\ Load byte
+      stbu  t2,4(t0)	\ Store byte
+   countdown		\ Decrement & Branch if nonzero
+   
+   \ check for 603-class processor
+   mfspr   t3,pvr
+   rlwinm  t3,t3,16,24,31
+   cmpi  0,0,t3,6  = if   set t3,3   then
+   cmpi  0,0,t3,7  = if   set t3,3   then
+   cmpi  0,0,t3,3  = if		\ this is a 603-class processor
+      \ save 1100-12ff
+      1100 4 -	set  t1,*	\ Src
+      200 4 /	set  t2,*	\ set length
+      mtspr ctr,t2		\ Count in count register
+      begin
+	 lbzu  t2,4(t1)	\ Load byte
+	 stbu  t2,4(t0)	\ Store byte
+      countdown		\ Decrement & Branch if nonzero
+   then
+   addi  tos,t0,4	\ addr2
+   mtspr ctr,up		\ Restore "next" pointer
+c;
+code restore-lomem   ( addr1 --  addr2 )
+   addi  t1,tos,-4		\ Src into t1
+   
+   \ restore 300-3ff
+   300 4 -	set  t0,*	\ Dst
+   100 4 /	set  t2,*	\ set length
+   mtspr ctr,t2		\ Count in count register
+   begin
+      lbzu  t2,4(t1)	\ Load byte
+      stbu  t2,4(t0)	\ Store byte
+   countdown		\ Decrement & Branch if nonzero
+   
+   \ check for 603-class processor
+   mfspr   t3,pvr
+   rlwinm  t3,t3,16,24,31
+   cmpi  0,0,t3,6  = if   set t3,3   then
+   cmpi  0,0,t3,7  = if   set t3,3   then
+   cmpi  0,0,t3,3  = if		\ this is a 603-class processor
+      \ restore 1100-12ff
+      1100 4 -	set  t0,*	\ Dst
+      200 4 /	set  t2,*	\ set length
+      mtspr ctr,t2		\ Count in count register
+      begin
+	 lbzu  t2,4(t1)	\ Load byte
+	 stbu  t2,4(t0)	\ Store byte
+      countdown		\ Decrement & Branch if nonzero
+   then
+   addi  tos,t1,4	\ addr2
+   mtspr ctr,up		\ Restore "next" pointer
+c;
+
+: save-environment   ( addr -- )   \ data handlers only???
+   save-lomem
+   save-dbats
+   save-sprs
+   drop
+;
+: restore-environment   ( addr -- )   \ data handlers only???
+   restore-lomem
+\   #tlb-lines invalidate-tlbs
+   restore-dbats
+   restore-sprs
+   drop
+;
+
+: ?real-mode-entry  ( -- )
+   client-env  save-environment
+   fw-env    restore-environment
+    \ msr@ h# 10 or msr!
+   msr@ h# 10 and 0= dcache-on? and if  dcache-off  then
+;
+: ?real-mode-exit  ( -- )
+    \ msr@ h# 10 invert and msr!
+   msr@ h# 10 and 0= if
+      \ If the cache was on when we entered, turn it back on
+      cif-reg-save 88 + @  h# 4000 or  if  dcache-on  then
+   then
+   client-env  restore-environment
+;
+
+headers
+stand-init: Real mode CIF
+\ : rm-cif ( XXX for testing )
+   use-real-mode?  if
+      \ XXX optimize later:
+      \ 603-class? if   /rm-tlbmiss 2* /env + to /env   then
+      \ exp?     if  /exp-tlbmiss 2* /env + to /env   then
+      /env alloc-mem to fw-env
+      /env alloc-mem to client-env
+      ['] ?real-mode-entry to rm-cif-entry
+      ['] ?real-mode-exit  to rm-cif-exit
+      fw-env save-environment
+   then
+;
+
+warning off
+dev /client-services
+: claim  ( align size virt -- base )
+   in-real-mode?  if    ( align size virt )
+      swap rot dup  if  ( virt size align )
+         rot drop       ( size align )
+         ['] mem-claim catch  if  2drop 0  then
+      else		( virt size 0 )
+         ['] mem-claim catch  if  3drop 0  then
+      then
+   else
+      claim
+   then
+;
+: release  ( size virt -- )
+   in-real-mode?  if              ( virt=phys size )
+      swap ?release-mem		  ( )
+   else                           ( virt size )
+      release
+   then
+;
+device-end
+warning on
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/reboot.fth
===================================================================
--- cpu/ppc/reboot.fth	                        (rev 0)
+++ cpu/ppc/reboot.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,62 @@
+purpose: Reboot system: save reboot info in nvram configuration variables
+\ See license at end of file
+
+headerless
+: put-env-number  ( n name$ -- )  hex   rot (.) 2swap (put-ge-var) drop  ;
+: get-env-number  ( name$ -- n )
+   hex   $getenv  if  0  else  $number  if  0  then  then
+;
+
+0 value reboot-info
+: +rb  ( offset -- adr )  reboot-info +  ;
+: copy-reboot-info  ( -- )
+   " reboot-command" $getenv  if  false to reboot?  exit  then
+
+   d# 140 alloc-mem  to reboot-info
+   " reboot-command" $getenv  if  " "  then  d#   0 +rb place
+   " reboot-line#"   get-env-number          d# 132 +rb !
+   " reboot-column#" get-env-number          d# 136 +rb !
+
+   " reboot-command" $unsetenv
+   " reboot-line#"   $unsetenv
+   " reboot-column#" $unsetenv
+
+   true to reboot?
+;
+
+: (save-reboot-info)  ( cmd$ line# column# -- )
+   " reboot-column#" put-env-number
+   " reboot-line#"   put-env-number
+   " reboot-command" (put-ge-var) drop
+;
+' (save-reboot-info) to save-reboot-info
+
+: (get-reboot-info)  ( -- cmd$ line# column# )
+   0 +rb count  d# 132 +rb @  d# 136 +rb @
+;
+' (get-reboot-info) to get-reboot-info
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/reenter.fth
===================================================================
--- cpu/ppc/reenter.fth	                        (rev 0)
+++ cpu/ppc/reenter.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,78 @@
+purpose: Handle various kinds of entries into Forth from traps, etc.
+\ See license at end of file
+
+headerless
+: .go-message  ( -- )
+   \ Restarting is only possible if the state that was first saved
+   \ is from a restartable exception.
+   state-valid @  -1 =  already-go? and  if
+      restartable? on
+      ." Type  'go' to resume" cr
+   then
+;
+
+: .entry  ( -- )
+   talign		\ ... in case dp is misaligned
+
+   aborted? @  if
+      aborted? off  hex cr  ." Keyboard interrupt" cr  .go-message   exit
+   then
+
+[ifdef] notyet
+   exittomon exittomon-end  inside?   if
+      ." Program terminated" cr  exit
+   then
+   reenter reenter-end  inside?   if
+      .go-message  %o0 to %tbr
+      %o2 to %itmr  exit
+   then
+[then]
+   [ also hidden ] (.exception) [ previous ]
+;
+
+headers
+stand-init:
+   ['] .entry is .exception
+;
+
+\ Temporary hacks until we implement these functions correctly
+
+defer user-interface ' quit to user-interface
+also client-services definitions
+" reenter.fth: Implement 'exit' client service correctly" ?reminder
+: exit  ( -- )
+   [ also hidden ] breakpoints-installed off  [ previous ]
+   [ifdef] vector  vector off  [then]
+
+   " restore"  stdout @  ['] $call-method  catch  if  3drop  then
+   " restore"  stdin  @  ['] $call-method  catch  if  3drop  then
+
+   user-interface
+;
+: enter  ( -- )  interact  ;
+previous definitions
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/regacc.fth
===================================================================
--- cpu/ppc/regacc.fth	                        (rev 0)
+++ cpu/ppc/regacc.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,81 @@
+purpose: Register access words for PowerPC
+\ See license at end of file
+
+code rl!  ( l addr -- )
+   lwz    t0,0(sp)	\ value
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   0<>  if
+      stw    t0,0(tos)
+   else
+      stwbrx t0,r0,tos
+   then
+   eieio sync
+   lwz    tos,1cell(sp)
+   addi   sp,sp,2cells
+c;
+code rl@  ( addr -- l )
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   0<>  if
+      lwz    tos,0(tos)
+   else
+      lwbrx  tos,r0,tos
+   then
+c;
+code rw!  ( w addr -- )
+   lwz    t0,0(sp)	\ value
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   0<>  if
+      sth    t0,0(tos)
+   else
+      sthbrx t0,r0,tos
+   then
+   eieio sync
+   lwz    tos,1cell(sp)
+   addi   sp,sp,2cells
+c;
+code rw@  ( addr -- w )
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   0<>  if
+      lhz    tos,0(tos)
+   else
+      lhbrx  tos,r0,tos
+   then
+c;
+code rb@  ( addr -- b )
+   lbz    tos,0(tos)
+c;
+code rb!  ( b addr -- )
+   lwz    t0,0(sp)
+   stb    t0,0(tos)
+   eieio sync
+   lwz    tos,1cell(sp)
+   addi   sp,sp,2cells
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/register.fth
===================================================================
--- cpu/ppc/register.fth	                        (rev 0)
+++ cpu/ppc/register.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,162 @@
+purpose: Display and modify the saved program state
+\ See license at end of file
+
+\ This code is highly machine-dependent.
+\
+\ Requires:
+\
+\ >state  ( offset -- addr )
+\	Returns an address within the processor state array given the
+\	offset into that array
+\
+\ Defines:
+\
+\ register names
+\ .registers
+
+needs action: objects.fth
+
+decimal
+headerless
+
+only forth hidden also forth also definitions
+
+d# 112 /l*  constant /save-area
+
+: state-valid   ( -- addr )  d# 40 /l* >state  ;
+: ?saved-state  ( -- )
+   state-valid @  0=  abort" No program state has been saved in this session."
+;
+
+: clear-save-area  ( -- )  0 >state /save-area erase  ;
+
+: >vmem ;
+
+3 actions
+action:  @ ?saved-state  >state @  ;
+action:  @               >state !  ; ( is )
+action:  @               >state    ; ( addr )
+: reg  \ name  ( offset -- )
+   create /l* ,
+   use-actions
+;
+: regs  \ name name ...  ( start #regs -- )
+   bounds  ?do  i reg  loop
+;
+3 actions
+action:  @ ?saved-state  >state 2@  ;
+action:  @               >state 2!  ; ( is )
+action:  @               >state     ; ( addr )
+: freg  \ name  ( offset -- )
+   create /l* ,
+   use-actions
+;
+: fregs  \ name name ...  ( start #regs -- )
+   2* bounds  ?do  i freg  2 +loop
+;
+
+
+headers
+ 0  8 regs  %r0  %r1  %r2  %r3  %r4  %r5  %r6  %r7
+ 8  8 regs  %r8  %r9  %r10 %r11 %r12 %r13 %r14 %r15
+
+16  8 regs  %r16 %r17 %r18 %r19 %r20 %r21 %r22 %r23
+24  8 regs  %r24 %r25 %r26 %r27 %r28 %r29 %r30 %r31
+20 12 regs  t0  t1  t2  t3  t4  t5 rbase up  tos ip  rp  sp
+
+32  6 regs  %xer %lr  %ctr %pc   %msr  %cr
+35  2 regs                 %srr0 %srr1
+
+38  1 regs  exception#
+39  3 regs  %saved-my-self  %state-valid  %restartable?  
+
+42  8 fregs  %f0  %f1  %f2  %f3  %f4  %f5  %f6  %f7
+58  8 fregs  %f8  %f9  %f10 %f11 %f12 %f13 %f14 %f15
+74  8 fregs  %f16 %f17 %f18 %f19 %f20 %f21 %f22 %f23
+90  8 fregs  %f24 %f25 %f26 %f27 %f28 %f29 %f30 %f31
+
+106     reg  %fpscr
+106    freg  f-tmp
+
+108 4  regs  %sprg0 %sprg1 %sprg2 %sprg3
+
+\ Following words defined here to satisfy the
+\ references to these "variables" anywhere else
+: saved-my-self ( -- addr )  addr %saved-my-self  ;
+: restartable?  ( -- addr )  addr %restartable?  ;
+
+headerless
+: .lx  ( l -- )  base @ >r hex  9 u.r  r> base !  ;
+
+headers
+: .registers ( -- )
+   ?saved-state
+   ??cr
+."        pc      msr      ctr       lr      xer       cr"     cr
+         %pc .lx %msr .lx %ctr .lx  %lr .lx %xer .lx  %cr .lx
+cr cr
+."        r0       r1       r2       r3       r4       r5       r6       r7" cr
+         %r0 .lx  %r1 .lx  %r2 .lx  %r3 .lx  %r4 .lx  %r5 .lx  %r6 .lx  %r7 .lx
+cr cr
+."        r8       r9      r10      r11      r12      r13      r14      r15" cr
+         %r8 .lx  %r9 .lx %r10 .lx %r11 .lx %r12 .lx %r13 .lx %r14 .lx %r15 .lx
+cr cr
+."       r16      r17      r18      r19      r20      r21      r22      r23" cr
+        %r16 .lx %r17 .lx %r18 .lx %r19 .lx %r20 .lx %r21 .lx %r22 .lx %r23 .lx
+cr cr
+."       r24      r25      r26      r27      r28      r29      r30      r31" cr
+        %r24 .lx %r25 .lx %r26 .lx %r27 .lx %r28 .lx %r29 .lx %r30 .lx %r31 .lx
+cr cr
+."     sprg0    sprg1    sprg2    sprg3     srr0     srr1" cr
+      %sprg0 .lx %sprg1 .lx %sprg2 .lx %sprg3 .lx %srr0 .lx %srr1 .lx
+cr cr
+;
+
+headerless
+: ud.r  ( d #columns -- )  >r  <# #s #>  r> over - spaces  type  ;
+: .fx  ( d -- )  base @ >r hex  d# 17 ud.r   r> base !  ;
+
+headers
+: .fregisters ( -- )
+   ??cr
+   %msr h# 2000 and  0=  if
+      ." Floating point registers were not saved because the floating point" cr
+      ." unit was not enabled at the time the registers were saved." cr
+      exit
+   then
+   ." fpcsr " %fpscr .lx  cr
+   ." f0-3   :"    %f0 .fx   %f1 .fx   %f2 .fx   %f3 .fx  cr
+   ." f4-7   :"    %f4 .fx   %f5 .fx   %f6 .fx   %f7 .fx  cr
+   ." f8-11  :"    %f8 .fx   %f9 .fx  %f10 .fx  %f11 .fx  cr
+   ." f12-15 :"   %f12 .fx  %f13 .fx  %f14 .fx  %f15 .fx  cr
+   ." f16-19 :"   %f16 .fx  %f17 .fx  %f18 .fx  %f19 .fx  cr
+   ." f20-23 :"   %f20 .fx  %f21 .fx  %f22 .fx  %f23 .fx  cr
+   ." f24-27 :"   %f24 .fx  %f25 .fx  %f26 .fx  %f27 .fx  cr
+   ." f28-31 :"   %f28 .fx  %f29 .fx  %f30 .fx  %f31 .fx  cr
+;
+
+only forth also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/resetvec.fth
===================================================================
--- cpu/ppc/resetvec.fth	                        (rev 0)
+++ cpu/ppc/resetvec.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,234 @@
+purpose: Reset vector handler for dropin-driver format
+\ See license at end of file
+
+\ create debug-reset
+
+[ifdef] debug-reset
+h# 8000.0000 constant io-base  \ Wrong for GoldenGate
+[then]
+
+\needs start-assembling fload ${BP}/cpu/ppc/asmtools.fth
+\needs write-dropin     fload ${BP}/tools/mkdropin.fth
+
+h#  e.0000  d# 16 rshift  constant inflate-offset    \ Shifted for addis
+h#  f.0000  d# 16 rshift  constant workspace-offset  \ Shifted for addis
+
+\ This code is intended to execute from ROM, in big-endian byte order
+
+start-assembling
+h# 20 to asm-origin	\ Skip dropin header
+
+" Copyright 1995 FirmWorks" c$,
+
+\ Destroys: r5, r6
+label strcmp  ( r3: str1 r4: str2 -- r3: 0 if match, nonzero if mismatch )
+   addi   r3,r3,-1    \ Account for pre-increment
+   addi   r4,r4,-1    \ Account for pre-increment
+   begin
+      lbzu  r5,1(r3)
+      lbzu  r6,1(r4)
+      cmp   0,0,r5,r6
+   = while
+      cmpi  0,0,r5,0
+      = if
+         set    r3,0
+         bclr   20,0
+      then
+   repeat         
+
+   subf  r3,r5,r6
+   bclr  20,0
+end-code
+
+label find-dropin    ( r3: module-name-ptr -- r3: address|-1 )
+   mfspr  r31,lr
+
+   mr     r30,r3
+
+   \ Compute ROMbase
+   here 4 +  bl *
+   mfspr  r29,lr
+   here 4 -  asm-base -  asm-origin +  negate  addi r29,r29,*
+
+   begin
+      lwz  r4,0(r29)
+      set  r5,h#4f424d44   \ 'OBMD'
+      cmp  0,0,r4,r5
+   = while
+      mr   r3,r30
+      addi r4,r29,16
+      strcmp  bl *
+      cmpi 0,0,r3,0
+      = if			\ It the strings match, we found the dropin
+         mr     r3,r29
+         mtspr  lr,r31
+         bclr   20,0
+      then
+      lwz     r3,4(r29)		\ Length of dropin image
+      add     r3,r3,r29		\ Added to base address of previous dropin
+      addi    r3,r3,35		\ Plus length of header (32) + roundup (3)
+      rlwinm  r29,r3,0,0,29	\ Aligned to 4-byte boundary = new dropin addr
+   repeat
+
+   set    r3,-1     \ No more dropins; return -1 to indicate failure
+
+   mtspr  lr,r31
+   bclr   20,0
+end-code
+
+label memcpy  ( r3: dst r4: src r5: n -- r3: dst )
+   mtspr  ctr,r5
+   mr     r6,r3
+
+   addi   r3,r3,-1	\ Account for pre-decrement
+   addi   r4,r4,-1	\ Account for pre-decrement
+   begin
+      lbzu r5,1(r4)
+      stbu r5,1(r3)
+   countdown
+
+   mr    r3,r6		\ Return dst
+   bclr  20,0
+end-code
+
+\ Firmware startup sequence:
+\ 1) Execute a dropin named "start", to initialize the host bridge and memory
+\ 2) Locate a dropin named "firmware", either copy it or inflate it into RAM,
+\    and execute it from RAM
+
+\ Add padding so "startup" begins at address h# 100
+
+h# 100 pad-to
+
+[ifdef] debug-reset
+label my-entry
+   0 ,				\ To be patched later
+end-code
+
+fload ${BP}/arch/prep/reports.fth
+[then]
+
+label startup  ( -- )
+
+   mfspr  r3,hid0
+   ori    r3,r3,2
+   mtspr  hid0,r3
+
+   " start" $find-dropin,  \ Assemble call to find-dropin with literal arg
+
+   \ What should we do it this fails?  Perhaps call a default routine
+   \ to try to initialize com1 and display a message?
+   \ For now, we assume success
+
+   addi   r3,r3,32	\ Skip dropin header
+   mtspr  ctr,r3
+   bcctrl 20,0
+
+   mr     r26,r3	\ Save firmware load address
+   mr     r27,r4	\ Save firmware RAM size
+
+[ifdef] debug-reset
+   ascii 0 ?report
+[then]
+
+   " firmware" $find-dropin,  \ Assemble call to find-dropin with literal arg
+
+   lwz   r4,12(r3)
+   cmpi  0,0,r4,0
+   <> if
+      \ The firmware dropin is compressed, so we load the inflater into RAM
+      \ and use it to inflate the firmware into RAM
+      mr  r28,r3		\ Save address of firmware dropin
+
+      " inflate" $find-dropin,  \ Assemble call to find-dropin with literal arg
+
+      lwz    r5,4(r3)		\ Length of inflater
+      addi   r4,r3,32		\ src: Base address of inflater code in ROM
+      inflate-offset  addis  r3,r26,*  \ Dst: Base address of inflater
+
+      memcpy  bl *		\ Returns dst
+      
+\ XXX we might want to turn on the cache, or perhaps flush it
+\ We should decide whether or not the cache is on when 'start' returns
+
+      mtspr  ctr,r3
+
+[ifdef] debug-reset
+   dot bl *
+   mr r3,r28 dot bl *
+   mr r3,r26 dot bl *
+   mr r3,r27 dot bl *
+   ascii 1 ?report
+[then]
+
+      addi   r3,r28,32		\ Address of compressed bits of firmware dropin
+      mr     r4,r26		\ Firmware RAM address
+      workspace-offset  addis  r5,r26,*  \ Scratch RAM for inflater
+      mr     r6,r27		\ Firmware RAM size
+      add    r1,r26,r27	        \ Stack for inflater
+      addi   r1,r1,h#-10	\ Because LR is saved at FP+8
+
+      bcctrl 20,0		\ Inflate the firmware
+
+   else
+      \ The firmware dropin isn't compressed, so we just copy it to RAM
+
+      addi    r4,r3,32		\ Skip dropin header
+      lwz     r5,4(r3)		\ Length of image
+      mr      r3,r26		\ Firmware RAM address
+      memcpy  bl *		\ Copy the firmware
+   then
+
+[ifdef] debug-reset
+   ascii 2 ?report
+[then]
+
+   mr     r3,r26		\ Firmware RAM address
+   mr     r4,r27		\ Firmware RAM size
+
+   mtspr  ctr,r26
+   bcctrl 20,0			\ Execute the firmware
+
+   \ Notreached, in theory
+   begin again
+end-code
+
+[ifdef] debug-reset
+startup  my-entry  put-branch
+[then]
+
+\ Add padding so this entire module ends at address h# 1e0.  Doing so makes
+\ it easy to concatenate a dropin driver (with its 32-byte header) to handle
+\ other exception vectors, the first of which begins at ROM offset h# 200
+
+h# 1e0 pad-to
+
+end-assembling
+
+writing resetvec.di
+asm-base here over -  0  " reset-vector" write-dropin
+ofd @ fclose
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/rombp.fth
===================================================================
--- cpu/ppc/rombp.fth	                        (rev 0)
+++ cpu/ppc/rombp.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,69 @@
+purpose: Patches to allow limited breakpointing of ROM code
+\ See license at end of file
+
+[ifndef] iabr!
+code iabr!  ( adr -- )
+   mtspr  iabr,tos
+   lwz    tos,0(sp)
+   addi   sp,sp,1cell
+c;
+[then]
+headerless
+: rom-op!  ( op adr -- )
+   2dup instruction!      ( op adr )
+   2dup op@ =  if         ( op adr )
+      2drop               ( )
+   else                   ( op adr )
+      swap breakpoint-opcode  =  if   ( adr )
+         2 or  %msr 5 >> 1 and or     ( iabr-val )
+      else                            ( adr )
+         drop 0                       ( iabr-val=0 )
+      then                            ( iabr-val )
+      iabr!                           ( )
+   then
+;
+: rom-at-bp?  ( adr -- flag )
+   iabr@  2 and  if
+      %msr 5 >> 1 and  iabr@ 1 and  =  if
+         dup  iabr@ 3 invert and  =  if  drop breakpoint-opcode exit  then
+      then
+   then
+   op@
+;
+patch rom-op! instruction! op!
+patch rom-at-bp? op@ at-breakpoint?
+
+headers
+
+stand-init:
+   h# 13 catch-exception
+;
+\ Hacros
+: --bp  --bp 0 iabr!  ;  : ++ ff30.0000 +  ;
+: t --bp  ++ till  ; \ till
+: s ++ to %pc ;	\ skip
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/rootnode.fth
===================================================================
--- cpu/ppc/rootnode.fth	                        (rev 0)
+++ cpu/ppc/rootnode.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,117 @@
+purpose: Methods for root node
+\ See license at end of file
+
+: root-map-in  ( phys len -- virt )
+   " /" " map-in" execute-device-method drop
+;
+: root-map-out  ( virt len -- )
+   " /" " map-out" execute-device-method drop
+;
+
+dev /
+extend-package
+
+hex
+
+\ Static methods
+: decode-unit  ( adr len -- phys )  push-hex  $number  if  0  then  pop-base  ;
+: encode-unit  ( phys -- adr len )  push-hex  (u.)  pop-base  ;
+
+\ Not-necessarily-static methods
+: open  ( -- true )  true  ;
+: close  ( -- )  ;
+
+: map-in   ( phys size -- virt )
+   in-real-mode?  if  drop exit  then
+   over  mmu-lowbits +  pagesize round-up >r   ( phys      r: size' )
+   chrp?  if                                   ( phys      r: size' )
+      dup  fw-virt-base  dup fw-virt-size +  within  if
+         r@ pagesize mmu-claim                 ( phys virt r: size' )
+      else
+         \ Return virt=phys
+         dup mmu-highbits                      ( phys virt r: size' )
+      then
+   else                                        ( phys      r: size' )
+      r@ pagesize mmu-claim                    ( phys virt r: size' )
+   then                                        ( phys virt r: size' )
+   >r  dup mmu-highbits                      ( phys phys'  r: size' virt )
+   r> r>  over >r                 ( phys  phys' virt size  r: virt )
+   -1 mmu-map                                ( phys        r: virt )
+   mmu-lowbits r> +                          ( virtual )
+;
+: map-out  ( virtual size -- )
+   in-real-mode?  if  2drop exit  then
+   chrp?  if  2drop exit  then
+   2dup mmu-unmap  mmu-release
+;
+
+: dma-alloc  ( size -- virt )  alloc-mem  ;
+: dma-free   ( virt size -- )  free-mem  ;
+
+: dma-map-in   ( virt size cacheable -- devaddr )
+   drop   2dup flush-d$-range  drop   ( virt )
+   in-real-mode? 0=  if
+      mmu-translate 0= abort" Invalid DMA address"	drop ( phys )
+   then
+;
+: dma-map-out  ( virt devaddr size -- )  nip flush-d$-range  ;
+
+: dma-sync  ( virt devaddr size -- )  nip flush-d$-range  ;
+: dma-push  ( virt devaddr size -- )  nip flush-d$-range  ;
+: dma-pull  ( virt devaddr size -- )  nip flush-d$-range  ;
+
+finish-device
+
+device-end
+
+\ Call this after the system-mac-address is determined, which is typically
+\ done near the end of the probing process.
+: set-system-id  ( -- )
+   system-mac-address  dup  if        ( adr 6 )
+      " /" find-device                ( adr 6 )
+
+      \ Convert the six bytes of the MAC address into a string of the
+      \ form 0NNNNNNNNNN, where N is an uppercase hex digit.
+      push-hex                        ( adr 6 )
+
+      <#  bounds  swap 1-  ?do        ( )
+         i c@  u# u#  drop            ( )
+      -1 +loop                        ( )
+      0 u# u#>                        ( adr len )
+
+      2dup upper                      ( adr len )  \ Force upper case
+
+      pop-base                        ( adr len )
+
+      encode-string  " system-id"  property   ( )
+
+      device-end
+   else
+      2drop
+   then
+;
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/savefort.fth
===================================================================
--- cpu/ppc/savefort.fth	                        (rev 0)
+++ cpu/ppc/savefort.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,101 @@
+purpose: Save the Forth dictionary to a file
+\ See license at end of file
+
+\ save-forth  ( filename -- )
+\	Saves the Forth dictionary to a file so it may be later used under Unix
+\
+\ save-image  ( header-adr header-len filename -- )
+\	Primitive save routine.  Saves the dictionary image to a file.
+\	The header is placed at the start of the file.  The latest definition
+\	whose name is the same as the "init-routine-name" argument is
+\	installed as the init-io routine.
+
+only forth also hidden also  forth definitions
+
+
+headerless
+: swap-size  ( -- n )  here  >swap-map-size  ;
+: be-lput  ( adr -- )
+   l@ lbsplit  ofd @ fputc  ofd @ fputc  ofd @ fputc  ofd @ fputc
+;
+: be-fputs  ( adr len -- )  bounds  ?do  i be-lput  4 +loop  ;
+: ?be-fputs  ( adr len -- )
+   3 + 2 >>  0  ?do              ( adr )
+      dup i la+                  ( adr adr' )
+      i swap-map bittest  if     ( adr adr' )
+         4 ofd @ fputs           ( adr )
+      else                       ( adr adr' )
+         be-lput                 ( adr )
+      then                       ( adr )
+   loop                          ( adr )
+   drop
+;
+: save-image  ( header header-len filename -- )
+   ['] ($find-next) is $find-next
+
+   new-file   ( header header-len )
+   in-little-endian?  if
+       ( header header-len )  be-fputs		\ Write header
+       origin   text-size     ?be-fputs		\ Write dictionary
+       up@      user-size     be-fputs		\ Write user area
+   else
+       ( header header-len )  ofd @  fputs	\ Write header
+       origin   text-size     ofd @  fputs	\ Write dictionary
+       up@      user-size     ofd @  fputs	\ Write user area
+   then
+   swap-map swap-size     ofd @  fputs		\ Write swap map
+   ofd @ fclose
+;
+headers
+
+0 value growth-size
+
+: make-bin-header  ( -- )
+   h# 48000020 h_magic l!	\ This is a   b .+0x20   instruction
+   text-size   h_tlen  l!       \ Set the text size in program header
+   user-size   h_dlen  l!       \ Set the data size in program header
+   growth-size h_blen  l!       \ Set the bss size in program header
+   0           h_slen  l!       \ Set the symbol size in program header
+   origin      h_entry l!       \ Set the current starting address
+   swap-size   h_trlen l!       \ Set the relocation size
+   0           h_drlen l!       \ Set the data relocation size
+;
+
+\ Save an image of the target system in a file.
+: save-forth  ( str -- )
+   8 (align)			\ Make sure image is 8 byte aligned
+
+   >r
+
+   make-bin-header
+
+   " sys-init-io" $find-name is init-io
+   " sys-init"  init-save
+   bin-header  /bin-header  r>  save-image
+;
+
+only forth also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/savemeta.fth
===================================================================
--- cpu/ppc/savemeta.fth	                        (rev 0)
+++ cpu/ppc/savemeta.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,81 @@
+purpose: Save the metacompiled kernel image into a file
+\ See license at end of file
+
+hex
+only forth labels also forth also definitions
+
+\ Program header
+create header   forth
+h# 4800.0020 l,  \ Branch past the header
+      0 l,    \ Text size, actual value will be set later
+      0 l,    \ Data size, actual value will be set later
+      0 l,    \ Bss  size
+      0 l,    \ Symbol Table size
+      0 l,    \ Entry
+      0 l,    \ Text Relocation Size
+      0 l,    \ Data Relocation Size
+\ End of header.
+here header -  constant /header
+
+only forth also meta also forth-h also definitions
+
+\ Save an image of the target system in the file whose name
+\ is the argument on the stack.
+
+: doubleword-align  ( n -- n' )  7 + 7 invert and  ;
+: text-base  ( -- adr )  origin-t >hostaddr  ;
+: text-size  ( -- n )  here-t origin-t -  doubleword-align  ;
+: swap-size  ( -- n )  here-t >swap-map-size-t  ;
+: user-base  ( -- adr )  userarea-t  ;
+: user-size  ( -- n )  user-size-t  doubleword-align  ;
+: save-meta ( str -- )
+
+   \ Doubleword alignment is required so that the user area image will
+   \ not be in the same doubleword as the end of the dictionary, thus
+   \ causing the copy loop to get the wrong value the first time.
+   begin  here-t  7 and  while  0 c,-t  repeat
+
+   new-file
+
+   \ Set the text and data sizes in the program header
+   h# 4800.0020          header h#  0 + l-t!		\ Branch past the header
+   text-size             header h#  4 + l-t!		\ Text size
+   user-size             header h#  8 + l-t!		\ Data size
+   0                     header h# 10 + l-t!		\ Symbol table size
+
+   0                     header h# 14 + l-t!		\ Entry point
+   swap-size             header h# 18 + l-t!		\ Swap map size
+
+   header               /header       ofd @  fputs
+   text-base            text-size     ofd @  fputs
+   user-base            user-size     ofd @  fputs
+   swap-map-t           swap-size     ofd @  fputs	\ Swap map
+
+   ofd @ fclose
+;
+
+only forth also meta also definitions
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/scrub.fth
===================================================================
--- cpu/ppc/scrub.fth	                        (rev 0)
+++ cpu/ppc/scrub.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,70 @@
+purpose: Fast memory scrubbing
+\ See license at end of file
+
+headerless
+code (berase)  ( adr #cache-blocks /dcache-block -- )
+				\ /dcache-block is already in tos
+   lwz     t1,0(sp)		\ #cache-blocks in t1
+   lwz     t0,1cell(sp)		\ Address in t0
+
+   mfspr   t2,ctr
+   mtspr   ctr,t1
+   begin
+      dcbz  r0,t0
+      dcbf  r0,t0
+      add   t0,t0,tos
+   countdown
+   mtspr   ctr,t2
+
+   lwz     tos,2cells(sp)
+   addi    sp,sp,3cells
+c;
+
+headers
+\ Usage requirements:
+\   adr must aligned on a cache line boundary
+\   len must a multiple of the cache line size
+\   the range must not overlap a 256 MB (h# 1000.0000) boundary
+\   the data cache must be turned on
+: berase  ( adr len -- )
+   dcache-on?  0=  dup >r  if  dcache-on  then
+   real-mode? 0=  if
+      over  h# f000.0000 and  		( adr len adr' )
+      dup h# 1000.0000  false  2 dbat 	( adr len pa va len io? bat# dbat )
+      bat!				( adr len )
+   then
+   \ XXX dcbz does not work on some versions of 620
+   620-class?  if
+      0 fill
+   else
+      /dcache-block /  /dcache-block  (berase)		( )
+   then
+   real-mode? 0=  if
+      0 0 2 dbat!
+   then
+   r>  if  dcache-off  then   
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/scrub601.fth
===================================================================
--- cpu/ppc/scrub601.fth	                        (rev 0)
+++ cpu/ppc/scrub601.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,53 @@
+purpose: Fast memory scrubbing - 601 version
+\ See license at end of file
+
+\ Usage requirements:
+\   adr must aligned on a cache line boundary
+\   len must a multiple of the cache line size
+\   the range must not overlap an 8 MB (h# 80.0000) boundary
+\   the data cache must be turned on
+: berase-range  ( adr len -- )
+   over  h# ff80.0000 and  dup h# 80.0000  false  2 i&dbats bat!
+   /dcache-block /  /dcache-block  (berase)
+   0 0 2 ibat!
+;
+: berase-601  ( adr len -- )
+   begin  dup  while                     ( adr len )
+      \ Find the length of a piece that doesn't overlap a BAT boundary
+      over  dup h# 7f.ffff or 1+ swap -  ( adr len len-to-boundary )
+      over umin                          ( adr len piece-len )
+      >r  over r@ berase-range           ( adr len )  ( r: piece-len )
+      r> /string                         ( adr' len' )
+   repeat                                ( adr' 0 )
+   2drop
+;
+warning @ warning off
+: berase  ( adr len -- )
+   601?  if  berase-601 exit  then
+   berase
+;
+warning !
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/scrub823.fth
===================================================================
--- cpu/ppc/scrub823.fth	                        (rev 0)
+++ cpu/ppc/scrub823.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,57 @@
+purpose: Fast memory scrubbing
+\ See license at end of file
+
+headerless
+code (berase)  ( adr #cache-blocks /dcache-block -- )
+				\ /dcache-block is already in tos
+   lwz     t1,0(sp)		\ #cache-blocks in t1
+   lwz     t0,1cell(sp)		\ Address in t0
+
+   mfspr   t2,ctr
+   mtspr   ctr,t1
+   begin
+      dcbz  r0,t0
+      dcbf  r0,t0
+      add   t0,t0,tos
+   countdown
+   mtspr   ctr,t2
+
+   lwz     tos,2cells(sp)
+   addi    sp,sp,3cells
+c;
+
+headers
+\ Usage requirements:
+\   adr must aligned on a cache line boundary
+\   len must a multiple of the cache line size
+\   the range must not overlap a 256 MB (h# 1000.0000) boundary
+\   the data cache must be turned on
+: berase  ( adr len -- )
+   dcache-on?  0=  dup >r  if  dcache-on  then
+   /dcache-block /  /dcache-block  (berase)		( )
+   r>  if  dcache-off  then   
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/segreg.fth
===================================================================
--- cpu/ppc/segreg.fth	                        (rev 0)
+++ cpu/ppc/segreg.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,40 @@
+purpose: Segment register access words
+\ See license at end of file
+
+code sr@  ( sr# -- n )
+   rlwinm  tos,tos,28,0,3	\ Convert to x000.0000
+   mfsrin  tos,tos
+c;
+code sr!  ( n sr# -- )
+   lwz     t1,0(sp)
+   rlwinm  tos,tos,28,0,3	\ Convert to x000.0000
+   sync isync
+   mtsrin  t1,tos
+   sync isync
+   lwz     tos,1cell(sp)
+   addi    sp,sp,2cells
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/spr.fth
===================================================================
--- cpu/ppc/spr.fth	                        (rev 0)
+++ cpu/ppc/spr.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,456 @@
+purpose: Special Purpose Register access for 604
+\ See license at end of file
+
+\ XER register: spr 1.
+\ contains overflow and carry bits and byte count for string instructions.
+code xer@ ( -- n )
+   stwu tos,-1cell(sp)
+   mfspr tos,xer
+c;
+code xer! ( n -- )
+   mtspr xer,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ link register: spr 8
+code lr@ ( -- n )
+   stwu tos,-1cell(sp)
+   mfspr tos,lr
+c;
+code lr! ( n -- )
+   mtspr lr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ count register: spr 9
+code ctr@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,ctr
+c;
+code ctr! ( n -- )
+   mtspr ctr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ DSISR: spr 18
+\ contains the status and cause of the DSI or alignment exception.
+\ updated along with DAR.
+
+code dsisr!  ( n -- )
+   mtspr  dsisr,tos
+   lwz    tos,0(sp)
+   addi   sp,sp,1cell
+c;
+code dsisr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,dsisr
+c;
+
+\ Data Address Register (DAR): spr 19
+\ contains the faulted address after a DSI or alignment exception.
+code dar@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,dar
+c;
+\ is this register writable? (ry)
+code dar! ( n -- )
+   mtspr dar,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ -------------------------------------------------------------
+\ These are defined in forthint.fth .  They should be here.
+\
+\ \ Decrementer: spr 22
+\ \ code dec!  ( n -- )
+\    mtspr  dec,tos
+\    lwz    tos,0(sp)
+\    addi   sp,sp,1cell
+\ c;
+\ code dec@  ( -- n )
+\    stwu   tos,-1cell(sp)
+\    mfspr  tos,dec
+\ c;
+
+\ SDR1 register: spr 25
+code sdr1@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,sdr1
+c;
+code sdr1! ( n -- )
+   mtspr sdr1,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ machine status Save and Restore Registers (SRR0 - SRR1): spr 26 - 27
+code srr0@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,srr0
+c;
+code srr0! ( n -- )
+   mtspr srr0,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code srr1@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,srr1
+c;
+code srr1! ( n -- )
+   mtspr srr1,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ SPRG0 to SPRG3: spr 272 - 275
+\ misc. spr for OS usage
+code sprg0@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,sprg0
+c;
+code sprg0! ( n -- )
+   mtspr sprg0,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code sprg1@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,sprg1
+c;
+code sprg1! ( n -- )
+   mtspr sprg1,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code sprg2@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,sprg2
+c;
+code sprg2! ( n -- )
+   mtspr sprg2,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code sprg3@ ( -- n)
+   stwu tos,-1cell(sp)
+   mfspr tos,sprg3
+c;
+code sprg3! ( n -- )
+   mtspr sprg3,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ external address register: spr 282.
+\ used with eciwx and ecowx instructions only.
+code ear@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,ear
+c;   
+\ is this register writable? (ry)
+code ear! ( n -- )
+   mtspr ear,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ timebase register (for writing): spr 284 - 285.
+\ use get-tb for reading. see getms.fth.
+: put-tb  ( tbu tbl -- )
+   ." writing to Time Base Register pair not implemented. " cr
+;
+
+\ processor version register: spr 287 (read only).
+code pvr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,pvr
+c;   
+: cpu-version  ( -- n )  pvr@ lwsplit nip  ;
+
+\ instruction Block Address Translation (BAT) registers: spr 528 - 535.
+\ data Block Address Translation (BAR) registers: spr 536-543
+\ see bat.fth.
+
+\ Monitor Mode Control Register 0 (MMCR0): spr 952
+\ Performance Monitor Counters (PMC1-2): spr 953 - 954
+code mmcr0@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,mmcr0
+c;   
+code mmcr0! ( n -- )
+   mtspr mmcr0,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code pmc1@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,pmc1
+c;   
+code pmc1! ( n -- )
+   mtspr pmc1,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code pmc2@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,pmc2
+c;   
+code pmc2! ( n -- )
+   mtspr pmc2,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ Sampled Instruction/Data Address (SIA, SDA): spr 955, 959
+code sia@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,sia
+c;   
+code sia! ( n -- )
+   mtspr sia,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code sda@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,sda
+c;   
+code sda! ( n -- )
+   mtspr sda,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ Hardware Implementation Dependent Register (HID0): spr 1008.
+code hid0@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,hid0
+c;   
+code hid0! ( n -- )
+   mtspr hid0,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ Instr/Data Address Breakpoint Register (IABR, DABR): spr 1010, 1013.
+code iabr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,iabr
+c;   
+code iabr! ( n -- )
+   mtspr iabr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code dabr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,dabr
+c;   
+code dabr! ( n -- )
+   mtspr dabr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ Process Identification Register (PIR): spr 1023
+code pir@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,pir
+c;   
+code pir! ( n -- )
+   mtspr pir,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code buscsr@  ( -- n )	\ 620-specific
+   stwu  tos,-1cell(sp)
+   mfspr tos,buscsr
+c;
+
+\ 603-Arthur L2 Cache Control Register (L2CR): spr 1017.
+code l2cr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,l2cr
+c;
+code l2cr! ( n -- )
+   mtspr l2cr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ 823-specific
+code ic-csr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,ic-csr
+c;   
+code ic-csr!  ( n -- )
+   sync
+   mtspr ic-csr,tos
+   isync
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code dc-csr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,dc-csr
+c;   
+code dc-csr!  ( n -- )
+   sync
+   mtspr dc-csr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code md-ctr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-ctr
+c;   
+code md-ctr!  ( n -- )
+   mtspr md-ctr,tos
+   sync isync
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code md-epn@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-epn
+c;   
+code md-epn!  ( n -- )
+   mtspr md-epn,tos
+   sync isync
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code md-rpn@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-rpn
+c;   
+code md-rpn!  ( n -- )
+   mtspr md-rpn,tos
+   sync isync
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code md-twc@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-twc
+c;   
+code md-twc!  ( n -- )
+   mtspr md-twc,tos
+   sync isync
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code md-ap@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-ap
+c;   
+code md-ap!  ( n -- )
+   mtspr md-ap,tos
+   sync isync
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code md-cam@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-cam
+c;   
+code md-cam!  ( n -- )
+   eieio
+   mtspr md-cam,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code md-ram0@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-ram0
+c;   
+code md-ram0!  ( n -- )
+   mtspr md-ram0,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code md-ram1@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,md-ram1
+c;   
+code md-ram1!  ( n -- )
+   mtspr md-ram1,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code m-twb@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,m-twb
+c;   
+code m-twb!  ( n -- )
+   mtspr m-twb,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code m-casid@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,m-casid
+c;   
+code m-casid!  ( n -- )
+   mtspr m-casid,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+code immr@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,immr
+c;   
+code immr! ( n -- )
+   mtspr immr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+code der@  ( -- n )
+   stwu   tos,-1cell(sp)
+   mfspr  tos,der
+c;
+code der!  ( n -- )
+   mtspr immr,tos
+   lwz tos,0(sp)
+   addi sp,sp,1cell
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/swapdic.fth
===================================================================
--- cpu/ppc/swapdic.fth	                        (rev 0)
+++ cpu/ppc/swapdic.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,74 @@
+purpose: Byte-swap the Forth dictionary
+\ See license at end of file
+
+\needs bittest  fload ${BP}/forth/lib/bitops.fth
+
+: lbflip  ( n -- n' )
+   lbsplit swap 2swap swap bljoin
+;
+: xlflips  ( adr len -- )
+   bounds  ?do  i l@  i la1+ l@  i l!  i la1+ l!  2 /l* +loop
+;
+
+h# 20 constant /iheader
+0 value /image
+0 value /itext
+0 value /iuser
+0 value /iswap
+0 value text-base
+0 value user-base
+0 value swap-map
+0 value buf
+
+: ?lbflips  ( -- )
+   /itext 4 /  0  do
+      i swap-map bittest  0=  if  text-base i la+ dup  l@ lbflip swap l!  loop
+   loop
+;
+
+: +buf  ( offset -- adr )  buf +  ;
+: little-endian-ify  ( "infile" "outfile" -- )
+   reading writing
+
+   ifd @ fsize to /image
+   /image 8 round-up  alloc-mem to buf
+   buf  /image  ifd @ fgets  drop   ifd @ fclose
+
+   4 +buf be-l@  to /itext
+   8 +buf be-l@  to /iuser
+   h# 18 +buf be-l@ to /iswap
+   /iheader +buf  to text-base
+   text-base /itext +  to user-base
+   user-base /iuser +  to swap-map
+
+   buf        /iheader  lbflips
+   ?lbflips
+   user-base  /iuser    lbflips
+   buf /image xlflips
+
+   buf /image ofd @ fputs  ofd @ fclose
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/syscall.fth
===================================================================
--- cpu/ppc/syscall.fth	                        (rev 0)
+++ cpu/ppc/syscall.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,195 @@
+purpose: Low-level I/O interface for use with the C "wrapper" program
+\ See license at end of file
+
+\ The C program provides the Forth kernel with an array of entry-points
+\ into C subroutines for performing the actual system calls.
+\ This scheme should be reasonably compatible with nearly any Unix
+\ implementation.  The only difference would be in the implementation of
+\ "syscall", which has to look up the address of the actual system call
+\ C routine in the system call table provided to it by the C program loader.
+\ It then has to convert the stack arguments into the same form as is
+\ expected by the C system call routines.  This obviously depends on the
+\ details of the C calling sequence, but should not be too hard because
+\ C compilers usually pass arguments on the stack.
+\    Syscall is defined in the kernel, because it is needed for basics like
+\ key and emit.
+
+decimal
+
+/l ualloc-t  dup equ syscall-user#
+user syscall-vec   \ long address of system call vector
+nuser sysretval
+
+\ I/O for running under an OS with a C program providing actual I/O routines
+
+meta
+code syscall ( call# -- )
+   lwz	 r3,0(sp)  	\ Get some arguments
+   lwz   r4,4(sp)
+   lwz   r5,8(sp)
+   lwz   r6,12(sp)
+   lwz   r7,16(sp)
+   lwz   r8,20(sp)
+
+   'user syscall-vec   lwz   t0,*	\ Get address of system call table
+   cmpi  0,0,t0,0
+   0<> if
+      andi. r0,t0,1	\ If low bit is set, this is not a TOC-based system
+      0<> if
+         rlwinm t0,t0,0,0,30	\ Clear low bit
+         lwzx   t2,t0,tos	\ Code address in t2
+      else
+         lwzx  t1,t0,tos	\ ptr-glue address in t1
+         lwz   t2,0(t1)		\ Code address
+         lwz   r2,4(t1)		\ New TOC
+      then
+      mtspr lr,t2
+      bclrl 20,0
+      mtspr ctr,up	\ Restore CTR
+   else
+      tw	0,tos,tos	\ XXX Hack for use with simulator
+   then
+
+   'user sysretval  stw  r3,*	\ Save the result
+
+   lwz   tos,0(sp)		\ Fix stack
+   addi  sp,sp,4
+c;
+: retval   ( -- return_value )     sysretval l@  ;
+: lretval  ( -- l.return_value )   sysretval l@  ;
+
+nuser errno	\ The last system error code
+: error?  ( return-value -- return-value error? )
+   dup 0< dup  if  60 syscall retval errno !  then   ( return-value flag )
+;
+
+true value powerpc?	\ As opposed to POWER.  Set by startup code
+
+code u/mod  (s u.dividend u.divisor -- u.remainder u.quotient )
+   second-to-t0	\ dividend
+   'user powerpc?   lwz t3,*
+   cmpi  0,0,t3,0
+   0=  if		\ Use POWER division (RS/6000)
+      mtspr mq,t0
+      addi  t0,r0,0
+      div   t1,t0,tos   \ quotient in t1
+      mfspr t2,mq
+   else
+      divwu t1,t0,tos   \ quotient in t1
+      mullw t2,t1,tos   \ quot*divisor in t2
+      subfc t2,t2,t0    \ remainder in t2 \ Use subfc for POWER compatibility
+   then
+   stw   t2,0(sp)	\ Put remainder on stack
+   mr    tos,t1		\ Put quotient on stack
+c;
+
+: /    (s n1 n2 -- quot )  /mod  nip   ;
+: mod  (s n1 n2 -- rem )   /mod  drop  ;
+
+\ 32*32->64 bit unsigned multiply
+\            y  rs2     y  rd
+
+code um*   ( n1 n2 -- x[lo hi] )
+   second-to-t0
+   'user powerpc?   lwz t3,*
+   cmpi  0,0,t3,0
+   0= if		\ Use POWER, not PowerPC, division
+      mul    tos,t0,tos
+      mfspr  t1,mq
+   else
+      mullw  t1,t0,tos
+      mulhwu tos,t0,tos
+   then
+   stw    t1,0(sp)
+c;
+
+code m*  ( n1 n2 -- low high )
+   second-to-t0
+   'user powerpc?  lwz t3,*	\ "patch" div instr for simulator
+   cmpi  0,0,t3,0
+   0= if		\ Use POWER, not PowerPC multiplication
+      mul    tos,t0,tos
+      mfspr  t1,mq
+   else
+      mullw  t1,t0,tos
+      mulhw  tos,t0,tos
+   then
+   stw    t1,0(sp)
+c;
+
+\ Rounds down to a block boundary.  This causes all file accesses to the
+\ underlying operating system to occur on disk block boundaries.  Some
+\ systems (e.g. CP/M) require this; others which don't require it
+\ usually run faster with alignment than without.
+
+\ Aligns to a 512-byte boundary
+hex
+: _falign  ( l.byte# fd -- l.aligned )  drop  1ff invert and  ;
+: _dfalign  ( d.byte# fd -- d.aligned )  drop  swap 1ff invert and swap  ;
+
+code $sim-find-next  (s adr len link -- adr len alf true  |  adr len false )
+   mr   r6,tos
+   mr   r5,base
+   lwz  r4,0(sp)
+   lwz  r3,1cell(sp)
+   addi sp,sp,-4
+   mr   r7,sp
+   twi  0,tos,0
+   or.  tos,tos,tos
+   0=  if
+      addi sp,sp,4
+   then
+c;
+
+: set-endian  ( -- )
+   here off  1 here c! here @ 1 = is in-little-endian?
+;
+
+\ : aix-flush-cache  ( adr -- adr )  4 swap sys-flush-cache nip  ;
+: sys-init-io  ( -- )
+\ ['] drop origin - ['] set-swap-bit >body >user !
+   install-wrapper-io
+\   ['] aix-flush-cache is flush-cache
+   install-disk-io
+   \ Don't poll the keyboard under Unix; block waiting for a key
+   ['] (key              ['] key            (is
+   syscall-vec @  0=  if  ['] $sim-find-next is $find-next  then
+
+   set-endian
+
+\   allocate-buffers
+
+\   init-keyboard
+\   init-disk-files
+
+\   decimal
+;
+' sys-init-io is init-io
+
+: sys-init ;  \ Environment initialization chain
+' sys-init is init-environment
+decimal
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/tagwords.fth
===================================================================
--- cpu/ppc/tagwords.fth	                        (rev 0)
+++ cpu/ppc/tagwords.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,132 @@
+purpose: Tag all words that are executed; show all tagged words.
+\ See license at end of file
+
+hex
+
+\ Generic tools for acting on all words
+
+defer each   ( nfa -- )   ' drop to each
+: every   ( voc -- )
+   follow   begin  another?  while  each  repeat
+;
+: everywhere   ( xt -- )
+   to each
+   voc-link  begin  another-link?  while	( v-link )
+      voc> dup every				( voc )
+      >voc-link					( v-link' )
+   repeat
+;
+
+\ verbose version
+hidden also
+: .vname   ( voc -- )
+   ??cr  cr .in  ['] vocabulary .name space  .name cr
+;
+: show-every   ( xt -- )
+   to each
+   voc-link  begin  another-link?  while	( v-link )
+      voc>
+      dup .vname
+      dup follow
+      begin  another?  while
+	 each
+	 exit? if  drop exit  then 
+      repeat
+      >voc-link					( v-link' )
+   repeat
+;
+previous forth
+
+\ \ For reference...
+\ label next
+\    lwzu  w,/token(ip)	\ w has token of next word to execute
+\    lwzux t1,w,base	\ t1 has offset of its code field
+\    add   t1,t1,base	\ t1 has acf
+\    mtspr lr,t1		\ go there
+\    bclr  20,0
+\ end-code
+
+\ Special version of "next" tags any word that is executed
+label tagnext
+   lwzu  w,/token(ip)	\ w has token of next word to execute
+   
+   add   t1,w,base	\ t2 has acf
+   set   t2,h#-10.0000	\ offset to tags
+   add   t1,t1,t2	\ t1 has address of tag byte
+   \ lbz   t2,0(t1)
+   set   t2,h#a5	\ set magic# to tag the word
+   stb   t2,0(t1)
+   
+   \ back to "next", which is already in progress...
+   lwzux t1,w,base	\ t1 has offset of its code
+   add   t1,t1,base	\ t1 has code address
+   mtspr lr,t1		\ go there
+   bclr  20,0
+end-code
+
+\ Turn on tagnext
+: tnext  ( -- )
+   tagnext up@ - h# 3ffffff and  h# 48000000 or  up@ instruction!
+;
+\ Revert to normal next
+: nnext   ( -- )   [ bug ] unbug [ forth ]  ;
+
+\ \ an example
+\ : tryit   ( -- )   tnext bl word drop nnext  ;
+
+: clear-tags   ( -- )
+   origin h# 10.0000 -  here origin -  erase
+;
+
+\ variable tagged
+\ : count-tagged   ( nfa -- )   name> 10.0000 - c@ a5 = if  1 tagged +!  then  ;
+\ : tagged?   ( -- )
+\    0 tagged !
+\    ['] count-tagged everywhere
+\    tagged ?
+\ ;
+
+: show-tagged?   ( nfa -- )
+   dup name> 10.0000 - c@ a5 = if
+      dup name>string nip .tab .id exit? if    
+	 exit 
+      then
+   else
+      drop
+   then
+;
+decimal
+: show-tagged   ( -- )
+   nnext
+   0 lmargin ! 64 rmargin ! 14 tabstops ! ??cr
+   ['] show-tagged? show-every
+;
+
+: stand-init-io   ( -- )
+   clear-tags  tnext
+   stand-init-io
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/target.fth
===================================================================
--- cpu/ppc/target.fth	                        (rev 0)
+++ cpu/ppc/target.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,291 @@
+purpose: Metacompiler target configuration for PowerPC
+\ See license at end of file
+
+only forth also meta definitions
+defer init-relocation-t
+defer set-relocation-bit-t
+
+decimal
+
+h# c000 constant max-kernel                 \ Maximum size of the kernel
+
+only forth also meta assembler definitions
+: normal ( -- )   \ Perform target-dependent assembler initialization
+;
+
+only forth also meta definitions
+
+: lobyte th 0ff and ;
+: hibyte 8 >> lobyte ;
+
+2 constant /w-t
+4 constant /l-t
+/l-t constant /n-t
+/l-t constant /a-t
+/a-t constant /thread-t
+/l-t constant /token-t
+/l-t constant /link-t
+/token-t constant /defer-t
+/n-t th 800 * constant user-size-t
+/n-t th 100 * constant ps-size-t
+/n-t th 200 * constant rs-size-t
+/l-t constant /user#-t
+
+\ 32 bit host Forth compiling 32-bit target Forth
+: l->n-t ; immediate
+: n->l-t ; immediate
+: n->n-t ; immediate
+: s->l-t ; immediate
+
+[ifdef] little-endian
+\ little-endian versions
+\ The address munging (7 xor) with c@/!-t is due to the fact that
+\ the system loads the target image in big-endian mode, and then
+\ switches to little-endian mode after executing a few instructions.
+: c!-t ( n add -- ) >hostaddr 7 xor c! ;
+: w!-t ( n add -- )  over lobyte over c!-t  ca1+ swap hibyte swap c!-t  ;
+: l!-t ( l add -- )  >r lwsplit swap r@ w!-t r> /w-t + w!-t  ;
+: c at -t ( target-address -- n ) >hostaddr 7 xor c@ ;
+: w at -t ( target-address -- n )  dup c at -t swap 1+ c at -t 8 << or  ;
+: l at -t ( target-address -- n )  dup >r /w-t + w at -t  r> w at -t  swap wljoin  ;
+[else]
+\ big-endian versions
+: c!-t ( n add -- ) >hostaddr c! ;
+: w!-t ( n add -- )  over hibyte over c!-t  ca1+ swap lobyte swap c!-t  ;
+: l!-t ( l add -- )  ( set-swap-bit-t )  >r lwsplit r@ w!-t r> /w-t + w!-t  ;
+: c at -t ( target-address -- n ) >hostaddr c@ ;
+: w at -t ( target-address -- n )  dup c at -t 8 << swap 1+ c at -t or  ;
+: l at -t ( target-address -- n )  dup >r /w-t + w at -t  r> w at -t  wljoin  ;
+[then]
+
+: le-l!-t ( l add -- )  >r lwsplit swap r@ w!-t r> /w-t + w!-t  ;
+: be-l!-t ( l add -- )  >r lwsplit      r@ w!-t r> /w-t + w!-t  ;
+
+: !-t  ( n add -- ) l!-t ;
+: @-t  ( target-address -- n ) l at -t ;
+
+\ Store target data types into the host address space.
+: c-t!  ( c host-address -- )  c!  ;
+: w-t!  ( w host-address -- )
+   over hibyte  over c-t!  ca1+  swap lobyte swap c-t!
+;
+: l-t!  ( l host-address -- )  >r  lwsplit  r@ w-t!  r> /w-t + w-t!  ;
+: n-t!  ( n host-address -- )  l-t!  ;
+
+: c,-t ( byte -- )  here-t dup set-swap-bit-t  1 allot-t  c!-t ;
+: w,-t ( word -- )  here-t /w-t allot-t w!-t ;
+: l,-t ( long -- )  here-t /l-t allot-t l!-t ;
+
+: ,-t ( n -- )  l,-t ;  \ for 32 bit stacks
+: ,user#-t ( user# -- )  l,-t  ;
+
+: a at -t ( target-address -- target-address )  l at -t  ;
+: a!-t ( token target-address -- )  ( set-relocation-bit-t )  l!-t  ;
+: token at -t ( target-address -- target-acf )  a at -t  ;
+: token!-t ( acf target-address -- )  a!-t  ;
+
+: rlink at -t  ( occurrence -- next-occurrence )  a at -t  ;
+: rlink!-t  ( next-occurrence occurrence -- )  token!-t  ;
+
+
+\ Machine independent
+: a,-t  ( adr -- )  here-t /a-t allot-t  a!-t  ;
+: token,-t ( token -- )  here-t /token-t allot-t  token!-t  ;
+
+\ These versions of linkx-t are for absolute links
+: link at -t ( target-address -- target-address' )  a at -t  ;
+: link!-t ( target-address target-address -- )  a!-t  ;
+: link,-t ( target-address -- )  a,-t  ;
+
+: a-t@ ( host-address -- target-address )
+[ also forth ]
+   dup  origin here within  over up@  dup user-size +  within  or  if
+[ previous ]
+      l@
+   else
+      hostaddr> a at -t
+   then
+;
+: a-t! ( target-address host-address -- )
+[ also forth ]
+   dup  origin here within  over up@  dup user-size +  within  or  if
+[ previous ]
+      l!
+   else   
+      hostaddr> a!-t
+   then
+;
+: rlink-t@  ( host-adr -- target-adr )  a-t@  ;
+: rlink-t!  ( target-adr host-adr -- )  a-t!  ;
+
+: token-t@ ( host-address -- target-acf )  a-t@  ;
+: token-t! ( target-acf host-address -- )  a-t!  ;
+: link-t@  ( host-address -- target-address )  a-t@  ;
+: link-t!  ( target-address host-address -- )  a-t!  ;
+
+\ Machine independent
+: a-t, ( target-address -- )  here  /a-t allot  a-t!  ;
+: token-t, ( target-address -- )  here  /token-t allot  token-t!  ;
+: >body-t  ( cfa-t -- pfa-t )
+   \ The code fields of DOES> and ;CODE words contain an extra token
+   " dodoes" ['] labels $vfind  if
+      execute
+      over token at -t  =  if  /token-t +  then
+   else
+      drop
+   then
+   /token-t +
+;
+
+
+\ 32 constant #threads-t
+1 constant #threads-t
+create (threads-t)    #threads-t 1+ /link-t * allot
+: threads-t  ( -- adr )  (threads-t)  7 + 7 invert and  ;
+
+: $hash-t  ( adr len voc-ptr -- thread )
+   -rot nip #threads-t 1- and  /thread-t * +
+;
+
+\ Should allocate these dynamically.
+\ The dictionary space should be dynamically allocated too.
+
+\ The user area image lives in the host address space.
+\ We wish to store into the user area with -t commands so as not
+\ to need separate words to store target items into host addresses.
+\ That is why user+ returns a target address.
+
+\ Machine Independent
+
+0 constant userarea-t
+: setup-user-area ( -- )
+   user-size-t alloc-mem is userarea-t
+   userarea-t user-size-t  erase
+;
+
+: >user-t ( cfa-t -- user-address-t )
+   >body-t
+   @-t
+   userarea-t  +
+;
+
+: n>link-t ( anf-t -- alf-t )  /link-t - ;
+: l>name-t ( alf-t -- anf-t )  /link-t + ;
+
+decimal
+/l constant #align-t
+/l constant #talign-t
+/l constant #linkalign-t
+/l constant #acf-align-t
+: aligned-t  ( n1 -- n2 )  #align-t 1- +  #align-t negate and  ;
+: acf-aligned-t  ( n1 -- n2 )  #acf-align-t 1- +  #acf-align-t negate and  ;
+
+\ NullFix bl -> 0
+: align-t ( -- )
+   begin   here-t #align-t  1- and   while   0 c,-t   repeat
+;
+: talign-t ( -- )
+   begin   here-t #talign-t 1- and   while   0 c,-t   repeat
+;
+: linkalign-t  ( -- )
+   begin   here-t #linkalign-t 1- and   while   0 c,-t   repeat
+;
+: acf-align-t  ( -- )  talign-t  ;
+
+: entercode ( -- )
+   only forth also labels also meta also ppc-assembler
+   [ also ppc-assembler ]
+   ['] $ppc-assem-do-undefined is $do-undefined
+   [ previous ]
+\   assembler
+;
+
+\ Next 5 are Machine Independent
+: cmove-t ( from to-t n -- )
+  0 do over c@  over c!-t  1+ swap 1+ swap loop  2drop
+;
+: place-cstr-t  ( adr len cstr-adr-t -- cstr-adr-t )
+   >r  tuck r@ swap cmove-t  ( len ) r@ +  0 swap c!-t  r>
+;
+: "copy-t ( from to-t -- )
+  over c@ 2+  cmove-t
+;
+: toggle-t ( addr-t n -- ) swap >r r@ c at -t xor r> c!-t ;
+
+: clear-threads-t  ( hostaddr -- )
+   #threads-t /link-t * bounds  do
+      origin-t i link-t!
+   /link +loop
+;
+: initmeta  ( -- )
+  init-swap-t
+  threads-t   #threads-t /link-t * bounds  do
+     origin-t i link-t!
+  /link +loop
+  threads-t current-t !
+;
+
+\ For compiling branch offsets used by control constructs.
+\ These compile relative branches.
+
+/l-t constant /branch
+: branch! ( offset addr-t -- )
+   over - ( from offset ) swap
+   l!-t
+;
+: branch, ( offset -- )
+   here-t -
+   l,-t
+;
+
+\ Store actions for some data structures.  This has to be in this
+\ file because it depends on the location of the user area (in some
+\ versions, the user area has to be in the dictionary for
+\ relocation to work right, but in other versions, the user area
+\ is elsewhere.  Ultimately, separate relocation for the user area is
+\ needed.
+
+: isuser   ( n acf -- )     >user-t n-t!  ;
+: istuser  ( acf1 acf -- )  >user-t token-t!  ;
+: isvalue  ( n acf -- )     >user-t n-t!  ;
+: isdefer  ( acf acf -- )   >user-t token-t!  ;
+
+: thread-t!  ( thread adr -- )  link-t!  ;
+
+only forth also meta also definitions
+: install-target-assembler  ( -- )
+   [ assembler ]
+\   ['] dp-t   is asmdp
+   ['] here-t  is here
+   ['] allot-t is asm-allot
+   ['] l at -t    is asm@
+   ['] l!-t    is asm!
+   [ meta ]
+;
+: install-host-assembler  ( -- )
+   [ assembler ] resident-assembler [ meta ]
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/testmmu.fth
===================================================================
--- cpu/ppc/testmmu.fth	                        (rev 0)
+++ cpu/ppc/testmmu.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,175 @@
+purpose: Initialization code for PowerPC MMU
+\ See license at end of file
+
+headerless
+code v>p  ( virt -- phys&mode )
+   mr     r3,tos
+   get-phys  bl  *
+   mr     tos,r3
+c;
+code vtopte  ( virt -- vsid pteg )
+   mr fault,tos
+   find-pte  bl *
+   stwu  vsid,-4(sp)
+   mr tos,pteg
+c;
+headers
+: .htab   htab /htab  bounds  do  i @  if  i .  then  8 +loop  ;
+
+headerless
+list: translations-list
+
+: init-srs  ( -- )  h# 10 0  do  i i sr!  loop  ;
+
+[ifndef] initial-map
+also forth definitions
+: fw-base  ( -- adr )  origin pagesize round-down  ;
+
+headers
+defer initial-map
+: (initial-map)  ( -- )
+[ '#adr-cells @ 2 = ] [if]
+\            0 0          0  2000.0000 -1 map	\ Memory
+
+           0 0    over     2.0000 -1 map	\ Hash table and trap vectors
+      2.0000 0    over  fw-base over -  -1 map	\ program load area
+     e0.0000 0    over    10.0000 -1 map	\ Displacement flush area
+     f0.0000 0    over    10.0000 -1 map	\ Firmware 
+
+   f100.0000 0    over   100.0000 -1 map	\ Firmware I/O
+\  2000.0000 0    over  e000.0000 -1 map	\ I/O
+[else]
+   0                    0        memsize  -1 map  \ Trap vects, pgm load area
+   fw-base virt-phys -  fw-base  htab /htab + over -   -1 map  \ Firmware 
+[then]
+
+[ifdef] io-base
+   io-base  io-base  h# 10000 -1  map
+[then]
+;
+' (initial-map) to initial-map
+
+headerless
+defer unmap-temp-io
+: (unmap-temp-io)  ( virt -- )  \ Remove temporary I/O mapping
+[ifdef] io-base
+   dup io-base =  if  drop  else  h# 1000  unmap  then
+[else]
+   drop
+[then]
+;
+' (unmap-temp-io) to unmap-temp-io
+[then]
+previous definitions
+[then]
+
+: init-virtual-list  ( -- )
+   0 memrange !				\ Clear free list
+   d# 500  memrange  more-nodes		\ Get enough nodes "forever"
+
+   \ Create the available memory list from which the firmware is allowed
+   \ to dynamically allocate virtual memory.
+
+   fw-virt-base  fw-virt-size   set-node  fwvirt  insert-after
+
+   \ Setup the virtual list from which the firmware isn't permitted to allocate
+   0                            fw-virt-base add-os-piece
+   fw-virt-base fw-virt-size + ?dup  if  0 add-os-piece  then
+   
+[ '#adr-cells @ 2 = ] [if]
+   \ XXX Claim the firmware and displacement flush areas for now
+   e0.0000                    20.0000     claim-virtual drop
+[else]
+   fw-base        htab /htab + over -     claim-virtual drop
+[then]
+;
+
+headers
+warning off
+: open  ( -- )
+   init-srs
+
+   use-real-mode?  if
+      install-bat-handler 
+      setup-real-bat-table
+      clear-bats      mapping-on
+      true  exit  
+   then
+
+   set-mmu
+
+   init-virtual-list
+
+   translations-list to translations
+
+   d# 50 translation-node more-nodes
+
+   translations virt-phys - 4f8 !  \ physical
+   virt-phys                4fc !  \ virtual minus physical
+   0                        4f4 !  \ Replacement offset
+   save-state virt-phys -   4f0 !  \ fallback handler address
+
+   init-paged-mmu
+
+   initial-map
+
+   configure-tlb
+
+[ifdef] install-tlb-miss
+[ifdef] exponential
+   704-class? if
+      install-exp-tlb-miss
+   else      
+      install-tlb-miss
+   then
+[else]
+   install-tlb-miss
+[then]
+[then]
+
+   htab-dsi-handler h# 300 put-exception
+   htab-isi-handler h# 400 put-exception
+
+   virt-phys  if  mapping-on clear-bats  else  clear-bats mapping-on  then
+
+   false to in-real-mode?
+
+   true
+;
+warning on
+
+[ifdef] NOTYET
+Allocate contiguous physical memory and add nodes to the translations
+list.  The memory should have one extra cell at the beginning, which is
+the list head.  Set "translations" to the virtual base address of the
+beginning of that memory.
+Store the difference between the physical and virtual base address of
+that memory somewhere that the trap handler can find.
+This is necessary because the fault handler runs in real mode, and needs
+a convenient way to chase the list links without having to apply different
+translations to different list nodes.
+[then]
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/tlb.fth
===================================================================
--- cpu/ppc/tlb.fth	                        (rev 0)
+++ cpu/ppc/tlb.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,61 @@
+purpose: TLB invalidation
+\ See license at end of file
+
+headerless
+code invalidate-tlb-entry  ( virtual -- )
+   sync isync
+   tlbie   tos
+
+   mfspr  tos,pvr
+   rlwinm tos,tos,16,16,31
+   cmpi   0,0,tos,1
+   <> if
+      tlbsync
+   then
+
+   lwz    tos,0(sp)
+   addi   sp,sp,1cell
+c;
+code invalidate-tlb  ( -- )
+   'user #tlb-lines  lwz t0,*
+
+   sync isync
+   rlwinm t0,t0,12,4,19
+
+   begin
+      addic.  t0,t0,h#-1000
+      tlbie   t0
+   0= until
+   
+   mfspr  t0,pvr
+   rlwinm t0,t0,16,16,31
+   cmpi   0,0,t0,1
+   <> if
+      tlbsync
+   then
+c;
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/tlb601.fth
===================================================================
--- cpu/ppc/tlb601.fth	                        (rev 0)
+++ cpu/ppc/tlb601.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,59 @@
+purpose: TLB invalidation for 601
+\ See license at end of file
+
+code invalidate-tlb-entry  ( virtual -- )
+   sync isync
+   tlbie   tos
+
+   mfspr  tos,pvr
+   rlwinm tos,tos,16,16,31
+   cmpi   0,0,tos,1
+   <> if
+      tlbsync
+   then
+
+   lwz    tos,0(sp)
+   addi   sp,sp,1cell
+c;
+code invalidate-tlb  ( -- )
+   'user #tlb-lines  lwz t0,*
+
+   sync isync
+   rlwinm t0,t0,12,4,19
+
+   begin
+      addic.  t0,t0,h#-1000
+      tlbie   t0
+   0= until
+   
+   mfspr  tos,pvr
+   rlwinm tos,tos,16,16,31
+   cmpi   0,0,tos,1
+   <> if
+      tlbsync
+   then
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/tlbmiss.fth
===================================================================
--- cpu/ppc/tlbmiss.fth	                        (rev 0)
+++ cpu/ppc/tlbmiss.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,318 @@
+purpose: TLB miss handlers for 603-style (software PTE search) MMU
+\ See license at end of file
+
+also assembler definitions
+\needs set-y  : set-y  ( -- )  h# 0020.0000 add-bits  ;
+previous definitions
+
+headerless
+label itlb-miss
+   \ Adapted from the code in section 7.6.3.2.2 of the 603 manual
+   mfspr   r2,hash1		\ PTEG address
+   mfspr   r0,ctr		\ Save CTR
+   mfspr   r3,icmp		\ Comparison value
+   begin
+      mfmsr   r1
+      andi.   r1,r1,1
+      <> if			\ Little-endian
+         addi    r2,r2,-4	\ Account for pre-increment and endianness
+      else
+         addi    r2,r2,-8	\ Account for pre-increment
+      then
+      addi    r1,0,8		\ PTEs per PTEG
+      mtspr   ctr,r1		\ Load CTR
+      begin
+         lwzu  r1,8(r2)		\ Get first word of PTE
+         cmp   0,0,r1,r3	\ Found PTE?
+      = ctr=0 until
+      = if			\ Found?
+         \ Found a matching TLB entry
+         mfmsr   r1
+         andi.   r1,r1,1
+         <> if			\ Little-endian
+            addi  r2,r2,-8	\ Bias address to account for endianness
+         then
+         lwz   r1,4(r2)		\ Get physical word of matching TLB entry
+         andi. r3,r1,8		\ Check G bit
+         1 F: <> brif		\ ISI because of ifetch of guarded page
+
+         mtspr ctr,r0		\ Restore CTR
+         mfspr r0,imiss		\ Miss address
+         mfspr r3,srr1		\ saved cr0 bits
+         mtcrf h#80,r3		\ Restore CR0
+         mtspr rpa,r1		\ Set PTE
+         ori   r1,r1,h#100	\ Set the reference bit
+         tlbli r0		\ Load the TLB entry
+         tlbsync		\ wait for tlbli to complete
+         stw  r1,4(r2)		\ update page table with R bit set
+         sync			\ wait for page table store to complete
+         rfi
+      then
+
+      \ Not found; try secondary hash or signal exception
+      andi.   r1,r3,h#40	\ See if we have done second hash
+   0= while
+      mfspr   r2,hash2		\ Try secondary hash
+      ori     r3,r3,h#40	\ Set H bit in compare value
+   repeat
+
+   \ No HTAB entry; let the normal IAE handler take care of it
+   mfspr  r3,srr1		\ Get SRR1
+   rlwinm r2,r3,0,16,31 	\ Clear high bits
+   addis  r2,r2,h#4000  	\ Or in srr1<1> = 1 to flag PTE not found
+   2 F: always brif		\ Branch to common IAE code
+
+1 L:				\ Protection violation (guarded page)
+   mfspr  r3,srr1		\ Get SRR1
+   rlwinm r2,r3,0,16,31 	\ Clear high bits
+   addis  r2,r2,h#0800  	\ Or in srr1<4> = 1 to flag prot. violation
+   
+2 L:				\ Common code for instruction access exception
+   mtspr  ctr,r0		\ Restore CTR
+   mtspr  srr1,r2		\ Put back fixed SRR1
+   mfmsr  r0			\ Get MSR
+   xoris  r0,r0,h#0002		\ Flip the MSR<tgpr> bit
+   mtcrf  h#80,r3		\ Restore CR0
+   mtmsr  r0			\ Go back to the normal GPRs
+   h# 400 ba *			\ Go to the normal ISI handler
+end-code
+here itlb-miss - constant /itlb-miss
+
+\ This handler is used for both load and store exceptions because, since
+\ we don't do demand paging, we need not maintain the "C" (changed) bit.
+
+label dtlb-r-miss
+   \ Adapted from the code in section 7.6.3.2.2 of the 603 manual
+   mfspr   r2,hash1	\ PTEG address
+   mfspr   r0,ctr	\ Save CTR
+   mfspr   r3,dcmp	\ Comparison value
+   begin
+      mfmsr   r1
+      andi.   r1,r1,1
+      <> if			\ Little-endian
+         addi    r2,r2,-4	\ Account for pre-increment and endianness
+      else
+         addi    r2,r2,-8	\ Account for pre-increment
+      then
+      addi    r1,0,8		\ PTEs per PTEG
+      mtspr   ctr,r1		\ Load CTR
+      begin
+         lwzu  r1,8(r2)		\ Get first word of PTE
+         cmp   0,0,r1,r3	\ Found PTE?
+      = ctr=0 until
+      = if
+         \ Found a matching TLB entry
+         mfmsr   r1
+         andi.   r1,r1,1
+         <> if			\ Little-endian
+            addi  r2,r2,-8	\ Bias address to account for endianness
+         then
+         lwz   r1,4(r2)		\ Get physical word of matching TLB entry
+         mtspr ctr,r0		\ Restore CTR
+         mfspr r0,dmiss		\ Miss address
+         mfspr r3,srr1		\ saved cr0 bits
+         mtcrf h#80,r3		\ Restore CR0
+         mtspr rpa,r1		\ Set PTE
+         ori   r1,r1,h#100	\ Set the referenced bit
+         tlbld r0		\ Load the TLB entry
+         tlbsync		\ Wait for tlbld to complete
+         stw   r1,4(r2)		\ Update TLB entry
+         sync			\ Wait for page table store to complete
+	 rfi
+      then
+
+      \ Not found; try secondary hash or signal exception
+      andi.   r1,r3,h#40	\ See if we have done second hash
+   0= while
+      mfspr   r2,hash2		\ Try secondary hash
+      ori     r3,r3,h#40	\ Set H bit in compare value
+   repeat
+
+   set    r1,h#4000.0000	\ Set dsisr1<1> = 1 to flag PTE not found
+   
+   mfspr  r3,srr1		\ Get SRR1
+   mtspr  ctr,r0		\ Restore CTR
+   rlwinm r2,r3,0,16,31		\ Clear upper bits of SRR1
+   mtspr  srr1,r2		\ Put back fixed SRR1
+   mtspr  dsisr,r1		\ Set DSISR
+   mfspr  r1,dmiss		\ Get miss address
+
+   rlwinm. r2,r2,0,31,31  	\ Test LE bit
+   <> if			\ Little-endian
+				\ Note: this is naive; the processor's address
+				\ swizzling is size-dependent.  However, this
+				\ is what the example code in the 603 data
+				\ book does.
+      xori  r1,r1,7		\ convert to little-endian data address
+   then
+
+   mtspr  dar,r1		\ Set DAR
+   mfmsr  r0			\ Get MSR
+   xoris  r0,r0,h#0002		\ Flip the MSR<tgpr> bit
+   mtcrf  h#80,r3		\ Restore CR0
+   mtmsr  r0			\ Go back to the normal GPRs
+   h# 300 ba *			\ Go to the normal DSI handler
+end-code
+here dtlb-r-miss - constant /dtlb-r-miss
+
+label dtlb-w-miss
+   \ Adapted from the code in section 7.6.3.2.2 of the 603 manual
+   mfspr   r2,hash1	\ PTEG address
+   mfspr   r0,ctr	\ Save CTR
+   mfspr   r3,dcmp	\ Comparison value
+   begin
+      mfmsr   r1
+      andi.   r1,r1,1
+      <> if			\ Little-endian
+         addi    r2,r2,-4	\ Account for pre-increment and endianness
+      else
+         addi    r2,r2,-8	\ Account for pre-increment
+      then
+      addi    r1,0,8		\ PTEs per PTEG
+      mtspr   ctr,r1		\ Load CTR
+      begin
+         lwzu  r1,8(r2)		\ Get first word of PTE
+         cmp   0,0,r1,r3	\ Found PTE?
+      = ctr=0 until
+      = if
+         \ Found a matching TLB entry
+
+         mfmsr   r1
+         andi.   r1,r1,1
+         <> if			\ Little-endian
+            addi  r2,r2,-8	\ Bias address to account for endianness
+         then
+
+         lwz   r1,4(r2)		\ Get physical word of matching TLB entry
+         andi. r3,r1,h#80	\ Check the C bit
+         0 F: = brif		\ If (C==0) goto cEq0ChkProt (check prot modes)
+
+1 L:				\ (ceq2:)
+         mtspr ctr,r0		\ Restore CTR
+         mfspr r0,dmiss		\ Miss address
+         mfspr r3,srr1		\ saved cr0 bits
+         mtcrf h#80,r3		\ Restore CR0
+         mtspr rpa,r1		\ Set PTE
+         tlbld r0		\ Load the TLB entry
+         tlbsync		\ Wait for tlbld to complete
+         sync
+         rfi
+      then
+
+      \ Not found; try secondary hash or signal exception
+      andi.   r1,r3,h#40	\ See if we have done second hash
+   0= while
+      mfspr   r2,hash2		\ Try secondary hash
+      ori     r3,r3,h#40	\ Set H bit in compare value
+   repeat
+
+   set    r1,h#4200.0000	\ Set dsisr1<1> = 1 to flag PTE not found,
+				\ <6>=1 to denote "store" operation)
+   3 F: always brif
+
+2 L:
+   set    r1,h#0a00.0000		\ Set dsisr1<4> = 1 to flag prot. violation
+				\           <6> = 1 to denote "store" operation
+3 L:
+   mfspr  r3,srr1		\ Get SRR1
+   mtspr  ctr,r0		\ Restore CTR
+   rlwinm r2,r3,0,16,31		\ Clear upper bits of SRR1
+   mtspr  srr1,r2		\ Put back fixed SRR1
+   mtspr  dsisr,r1		\ Set DSISR
+   mfspr  r1,dmiss		\ Get miss address
+
+   rlwinm. r2,r2,0,31,31  	\ Test LE bit
+   <> if			\ Little-endian
+				\ Note: this is naive; the processor's address
+				\ swizzling is size-dependent.  However, this
+				\ is what the example code in the 603 data
+				\ book does.
+      xori  r1,r1,7		\ convert to little-endian data address
+   then
+
+   mtspr  dar,r1		\ Set DAR
+   mfmsr  r0			\ Get MSR
+   xoris  r0,r0,h#0002		\ Flip the MSR<tgpr> bit
+   mtcrf  h#80,r3		\ Restore CR0
+   mtmsr  r0			\ Go back to the normal GPRs
+   h# 300 ba *			\ Go to the normal DSI handler
+
+0 L:				\ (cEq0ChkProt:)
+\	We found the PTE in the page table and it has the
+\	C (changed) bit set to zero. Check the protection bits.
+\	PP:	00	SRSW
+\		01	SRWUR
+\		10	SRWURW
+\		11	SRUR
+   rlwinm.	r3,r1,30,0,1	\ test PP
+    
+   < if 			\ if (PP==10 or PP==11)
+      andi.   r3,r1,1		\ test PP[0]
+      4 F:  = brif set-y	\ return if PP==10
+      2 B:  always brif		\ else Data Access Exception Protection (PP=11)
+
+   then
+
+   \ (chk0:)
+   \ PP==00 or PP==01
+   \ Test MSR[PR] to determine protection violation.
+
+   mfspr	r3,srr1		\ get old msr
+   andi.	r3,r3,0x4000	\ test PR bit
+
+   <> if set-y			\ if (PR!=0)
+      mfspr	r3,dmiss	\ get miss address
+      mfsrin	r3,r3		\ get associated segment register
+      andis.	r3,r3,0x2000	\ test Kp bit
+      4 F:  = brif set-y	\ if (Kp==0) goto chk2
+      2 B:  always brif		\ else Data Access Exception Protection
+   then
+
+   mfspr   r3,dmiss		\ get miss address (chk1:)
+   mfsrin  r3,r3		\ get associated segment register
+   andis.  r3,r3,0x4000		\ test Ks bit
+   4 F:  = brif set-y		\ if (Ks==0) goto chk2
+   2 B:  always brif		\ else Data Access Exception Protection
+
+4 L:				\ (chk2:) No protection violation
+   ori  r1,r1,0x180		\ set reference and change bit
+   stw	r1,4(r2)		\ update page table
+   1 B: always brif		\ go back to main-line handler code
+
+end-code
+here dtlb-w-miss - constant /dtlb-w-miss
+
+: put-handler  ( adr exc-adr len -- )  2dup 2>r move  2r> sync-cache  ;   
+
+: install-tlb-miss  ( -- )
+   software-tlb-miss?  if
+      itlb-miss   h# 1000 /itlb-miss   put-handler   \ Ifetch TLB miss
+      dtlb-r-miss h# 1100 /dtlb-r-miss put-handler   \ Data load TLB miss
+      dtlb-w-miss h# 1200 /dtlb-w-miss put-handler   \ Data store TLB miss
+   then
+;
+headers
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/tlbms823.fth
===================================================================
--- cpu/ppc/tlbms823.fth	                        (rev 0)
+++ cpu/ppc/tlbms823.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,127 @@
+purpose: TLB miss handlers for 823-style MMU
+\ See license at end of file
+
+also assembler definitions
+\needs set-y  : set-y  ( -- )  h# 0020.0000 add-bits  ;
+previous definitions
+
+headerless
+
+h# 00d constant twc-mem		\ Unguarded, 8MB, writeback
+h# 01f constant twc-io		\ Guarded, 8MB, writethrough
+h# 9fd constant rpn-mem		\ Cacheable
+h# 9ff constant rpn-io		\ Cache inhibit
+
+\ On entry:
+\ sprg0 = &exception-save-area  (don't clobber it!)
+
+\ Save registers in:
+\ sprg1 = cr
+\ sprg2 = r2
+\ sprg3 = r3
+
+label dtlb-miss
+
+   mtspr  sprg3,r3		\ Save R3
+   mtspr  sprg2,r2		\ Save R2
+
+   mfcr   r3
+   mtspr  sprg1,r3		\ Save cr
+
+   mfmsr  r3
+   rlwinm r3,r3,0,15,28,26	\ Disable DR
+   mtmsr  r3
+
+   \ Generate new TLB
+   set    r3,h#2000.0000
+   mfspr  r2,md-epn		\ Get effective address
+   rlwinm r2,r2,0,0,19
+   cmpl   0,0,r2,r3
+   <  if
+      twc-mem set    r3,*
+      mtspr   md-twc,r3		\ Table Walk Control Reg
+      rpn-mem set    r3,*
+   else
+      twc-io  set    r3,*
+      mtspr  md-twc,r3		\ Table Walk Control Reg
+      rpn-io  set    r3,*
+   then
+
+   or     r3,r3,r2
+   mtspr  md-rpn,r3		\ Real Page Number Reg
+   sync isync
+
+   \ Restore registers
+   mfmsr  r3
+   ori    r3,r3,h#10		\ Enable DR
+   mtmsr  r3
+
+   mfspr  r3,sprg1
+   mtcrf  h#ff,r3		\ Restore CR
+   mfspr  r2,sprg2		\ Restore R2
+   mfspr  r3,sprg3		\ Restore R3
+
+   \ Return from interrupt
+   rfi
+end-code
+here dtlb-miss - constant /dtlb-miss
+
+: init-dtlb  ( -- )
+   0 m-casid!			\ Current address space
+   0 md-ap!			\ Access protection groups
+   h# 0400.0000 md-ctr!		\ PowerPC mode, Page res protection, TWAN=1
+				\ DTLB_INDX dec mod 8, ignore problem/privilege
+				\ DTLB_INDX=0
+;
+: init-tlb-entries  ( -- )
+   h# 0000.0200 md-epn!			\ EPN=0
+   twc-mem      md-twc!
+   h# 0000.0000 rpn-mem or md-rpn!	\ RPN=EPN
+
+   h# 0080.0200 md-epn!			\ EPN=80.0000
+   twc-mem      md-twc!
+   h# 0080.0000 rpn-mem or md-rpn!	\ RPN=EPN
+
+   h# fa20.0200 md-epn!			\ EPN=FA20.0000
+   twc-io       md-twc!
+   h# fa20.0000 rpn-io or md-rpn!	\ RPN=EPN
+;
+defer init-tlb		' init-dtlb to init-tlb
+
+: put-handler  ( adr exc-adr len -- )  2dup 2>r move  2r> sync-cache  ;   
+
+: install-tlb-miss  ( -- )
+   software-tlb-miss?  if
+      dtlb-miss h# 1200 /dtlb-miss put-handler   \ Data TLB miss
+   then
+   \ Redirect the implementation-dependent emulation trap, which
+   \ is what the 8xx PPC core generates instead of the usual program
+   \ interrupt, to the program interrupt vector.
+   h# 700 h# 1000 put-branch
+;
+headers
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/tmmu823.fth
===================================================================
--- cpu/ppc/tmmu823.fth	                        (rev 0)
+++ cpu/ppc/tmmu823.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,114 @@
+purpose: Initialization code for PowerPC 823 MMU
+\ See license at end of file
+
+headerless
+: dmapping-on   ( -- )  msr@ h# 10 or          msr!  ;
+: dmapping-off  ( -- )  msr@ h# 10 invert and  msr!  ;
+
+headerless
+list: translations-list
+
+[ifndef] initial-map
+also forth definitions
+: fw-base  ( -- adr )  origin pagesize round-down  ;
+
+headers
+defer initial-map
+: (initial-map)  ( -- )
+[ '#adr-cells @ 2 = ] [if]
+\            0 0          0  2000.0000 -1 map	\ Memory
+
+           0 0    over     2.0000 -1 map	\ Hash table and trap vectors
+      2.0000 0    over  fw-base over -  -1 map	\ program load area
+     e0.0000 0    over    10.0000 -1 map	\ Displacement flush area
+     f0.0000 0    over    10.0000 -1 map	\ Firmware 
+
+   f100.0000 0    over   100.0000 -1 map	\ Firmware I/O
+\  2000.0000 0    over  e000.0000 -1 map	\ I/O
+[else]
+   0                    0        memsize  -1 map  \ Trap vects, pgm load area
+   fw-base virt-phys -  fw-base  20.0000  -1 map  \ Firmware 
+[then]
+;
+' (initial-map) to initial-map
+
+headerless
+defer unmap-temp-io		' noop to unmap-temp-io
+[then]
+previous definitions
+[then]
+
+: init-virtual-list  ( -- )
+   0 memrange !				\ Clear free list
+   d# 500  memrange  more-nodes		\ Get enough nodes "forever"
+
+   \ Create the available memory list from which the firmware is allowed
+   \ to dynamically allocate virtual memory.
+
+   fw-virt-base  fw-virt-size   set-node  fwvirt  insert-after
+
+   \ Setup the virtual list from which the firmware isn't permitted to allocate
+   0                            fw-virt-base add-os-piece
+   fw-virt-base fw-virt-size + ?dup  if  0 add-os-piece  then
+   
+   fw-base                    20.0000     claim-virtual drop
+;
+
+headers
+warning off
+: open  ( -- )
+   init-virtual-list
+
+   translations-list to translations
+
+   d# 50 translation-node more-nodes
+
+   translations virt-phys - 4f8 !  \ physical
+   virt-phys                4fc !  \ virtual minus physical
+   0                        4f4 !  \ Replacement offset
+   save-state virt-phys -   4f0 !  \ fallback handler address
+
+   configure-tlb
+   init-tlb
+   invalidate-tlb
+   init-tlb-entries
+   initial-map
+   install-tlb-miss
+   dmapping-on
+
+   true to in-real-mode?
+   true
+;
+
+: tlb0!  ( rpn -- )
+   200 md-epn!  d md-twc!  md-rpn!
+   md-ctr@ 700 invert and md-ctr!
+   0 md-cam!
+   md-cam@ u. md-ram0@ u. md-ram1@ u. cr
+;
+warning on
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/tools.bth
===================================================================
--- cpu/ppc/tools.bth	                        (rev 0)
+++ cpu/ppc/tools.bth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,49 @@
+purpose: Load file for Forth toolkit, without firmware
+\ See license at end of file
+
+dictionary: ${BP}/cpu/ppc/build/kernel.dic
+command: &ppcforth &dictionary &this
+build-now
+
+\ ' $report-name is include-hook
+\ ' noop is include-hook
+\ : rn  (cr 2dup type 15 spaces  ;  ' rn is include-hook
+
+create resident-packages
+
+fload ${BP}/forth/lib/fwsetup.fth
+
+transient
+true value assembler?		\ False to discard assembler after compilation
+resident
+
+fload ${BP}/forth/lib/loadcomm.fth	\ CPU-independent Forth tools
+fload ${BP}/cpu/ppc/loadmach.fth	\ CPU and OS-specific extensions
+
+[ifndef] no-heads
+.( --- Saving tools.dic --- )  "" tools.dic save-forth cr
+[then]
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/touchall.fth
===================================================================
--- cpu/ppc/touchall.fth	                        (rev 0)
+++ cpu/ppc/touchall.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,43 @@
+purpose: Forces all translations into the HTAB
+\ See license at end of file
+
+: touch  ( -- )
+   " /mmu" find-device
+   " translations" get-property  abort" No translations property"  ( adr len )
+   begin  dup  while
+      decode-int >r    ( r: virt )
+      decode-int >r    ( r: virt size )
+      decode-int drop  ( r: virt size )   \ Discard phys.hi
+      decode-int drop  ( r: virt size )   \ Discard phys.lo
+      decode-int  h# 20 and  if   ( r: virt size )  \ I/O
+         2r> 2drop
+      else
+         r> r> swap  bounds  ?do  i c@ drop  pagesize +loop
+      then
+   repeat
+   2drop
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/unalign.fth
===================================================================
--- cpu/ppc/unalign.fth	                        (rev 0)
+++ cpu/ppc/unalign.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,115 @@
+purpose: Unaligned memory access primitives
+\ See license at end of file
+
+0 value in-little-endian?
+
+code unaligned-l@   (s adr -- l )
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   <>  if	\ Little endian
+      lbz    t0,0(tos)	\ low byte
+      lbz    t1,1(tos)	\ next byte
+      rlwimi t0,t1,8,16,23
+      lbz    t1,2(tos)	\ next byte
+      rlwimi t0,t1,16,8,15
+      lbz    t1,3(tos)	\ High byte
+      rlwimi t0,t1,24,0,7
+   else		\ Big endian
+      lbz    t0,3(tos)	\ low byte
+      lbz    t1,2(tos)	\ next byte
+      rlwimi t0,t1,8,16,23
+      lbz    t1,1(tos)	\ next byte
+      rlwimi t0,t1,16,8,15
+      lbz    t1,0(tos)	\ High byte
+      rlwimi t0,t1,24,0,7
+   then
+   mr tos,t0
+c;
+: unaligned-@  (s adr -- l )  unaligned-l@  ;
+code unaligned-w@  (s adr -- w )
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   <>  if	\ Little endian
+      lbz     t0,1(tos)	\ High byte
+      lbz     t1,0(tos)	\ low byte
+   else		\ Big endian
+      lbz     t0,0(tos)	\ High byte
+      lbz     t1,1(tos)	\ low byte
+   then
+   rlwimi  t1,t0,8,16,23
+   mr tos,t1
+c;
+code unaligned-l!   (s n adr -- )
+   second-to-t0	\ n in t0
+
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   <>  if	\ Little endian
+      stb     t0,0(tos)
+      rlwinm  t0,t0,24,0,31
+      stb     t0,1(tos)
+      rlwinm  t0,t0,24,0,31
+      stb     t0,2(tos)
+      rlwinm  t0,t0,24,0,31
+      stb     t0,3(tos)
+   else		\ Big endian
+      \ XXX I think the hardware will do this for you
+      stb     t0,3(tos)
+      rlwinm  t0,t0,24,0,31
+      stb     t0,2(tos)
+      rlwinm  t0,t0,24,0,31
+      stb     t0,1(tos)
+      rlwinm  t0,t0,24,0,31
+      stb     t0,0(tos)
+   then
+
+   pop1
+c;
+
+: unaligned-d!  ( d adr -- )
+   >r  in-little-endian?  if  swap  then
+   r@ unaligned-! r> na1+ unaligned-!
+;
+
+: unaligned-!   (s n adr -- )  unaligned-l!  ;
+code unaligned-w!   (s w adr -- )
+   second-to-t0	\ n in t0
+
+   'user in-little-endian?  lwz  t1,*
+   cmpi 0,0,t1,0
+   <>  if	\ Little endian
+      stb     t0,0(tos)
+      rlwinm  t0,t0,24,24,31
+      stb     t0,1(tos)
+   else		\ Big endian
+      \ XXX I think the hardware will do this for you
+      stb     t0,1(tos)
+      rlwinm  t0,t0,24,24,31
+      stb     t0,0(tos)
+   then
+   pop1
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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: cpu/ppc/xadd.fth
===================================================================
--- cpu/ppc/xadd.fth	                        (rev 0)
+++ cpu/ppc/xadd.fth	2007-07-05 17:19:17 UTC (rev 461)
@@ -0,0 +1,45 @@
+purpose: 64-bit addition and subtraction
+\ See license at end of file
+
+code x+  ( x1 x2 -- x3 )
+   lwz    t1,0(sp)	\ x2.low
+   lwz    t3,8(sp)	\ x1.low
+   lwz    t2,4(sp)	\ x1.high
+   addi   sp,sp,8	\ Pop args
+   addc   t1,t1,t3	\ x3.low
+   adde   tos,tos,t2	\ x3.high
+   stw    t1,0(sp)	\ Push result (x3.high already in tos)
+c;
+code x-  ( x1 x2 -- x3 )
+   lwz    t1,0(sp)	\ x2.low
+   lwz    t2,4(sp)	\ x1.high
+   lwz    t3,8(sp)	\ x1.low
+   addi   sp,sp,8	\ Pop args
+   subfc  t1,t1,t3	\ x3.low
+   subfe  tos,tos,t2	\ x3.high
+   stw    t1,0(sp)	\ Push result (x3.high already in tos)
+c;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 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




More information about the OpenBIOS mailing list