\ "dis.of" 17-Apr-2008
\
\ Tested only on development platform: 2003 G4 eMac w/ Open Firmware
\ v4.6.4.fi and 500 Mb RAM. Should also be useful with 603, 604, G3.
\ Feedback welcome on any corrections needed to make it work or
\ perform bettter on your own PowerPC Macintosh's Open Firmware.
\
\ To use, place an all-user-readable file named 'dis.of' containing
\ this source in the root directory of your Mac's Startup Volume
\ (boot disk). Make sure the backslash beginning the first line is
\ the very first character in the file. Restart, holding down the
\ Cmd-Option-O-F key combination. When Open Firmware's '0 > ' prompt
\ appears type:
\
\ boot hd:\dis.of
\
\ This revised 'dis' differs from bult-in original in that 'dis1'
\ (renamed 'disasm1' in this source) does the screen output. It
\ also jumps to the next-lowest 32-bit aligned address without
\ comment when requested to disassemble from a non aligned address.
hex \ just in case
0 value ADDR \ make addr of ppc inst'n being disassembled global
\ Rough mask sufficient to uniquely identify candidate G4 instr'n
: roughmask ( addr -- mask ) ( instruction address also in addr)
@[EMAIL PROTECTED]
d# 26 >> \ isolate hi 6-bit major opcode by shifting to far right
CASE
\ use return stack as ENDCASE reverts to stack in use prior to CASE
010 OF fc000003 >r ENDOF \ 'bc' group (4 instructions)
011 OF fc000003 >r ENDOF \ 'sc' (1 instruction)
012 OF fc000003 >r ENDOF \ 'b' (branch unconditional) (4)
013 OF fc0007ff >r ENDOF \ CR etc group (15 instructions)
014 OF fc000001 >r ENDOF \ 'rlwimi' 'rlwimi.' (2)
015 OF fc000001 >r ENDOF \ 'rlwinm' 'rlwinm.' (2)
017 OF fc000001 >r ENDOF \ 'rlwnm' 'rlwnm.' (2)
01f OF
\ ----------------------- Part One of mftb Patch -------------------
\ Sample patch: how Alternative Forms of instr'n may be implemented
( untidy code makes data placement independent of search direction )
\ the next 2 IFs move cryptic TBR spec fm operand to mnemonic
addr @[EMAIL PROTECTED]
( instr'n) fc1fffff ( mask ) AND 7c0c42e6 ( opcode ) =
IF fc1fffff >r ELSE \ mftb r0,268 becomes 'mftb r0'
addr @[EMAIL PROTECTED]
( instr'n) fc1fffff ( mask ) AND 7c0d42e6 ( opcode ) =
IF fc1fffff >r ELSE \ mftb r0,269 becomes 'mftbu r0'
\ -------------- (Part 2 of patch is in data table below) ----------
fc0007ff >r \ Load, Store, Arithmetic, Logic (151+2)
THEN THEN \ (--- this line belongs to Patch ---)
ENDOF
03b OF fc00003f >r ENDOF \ First Floating-point group (18)
\ 03e OF fc0007ff >r ENDOF ( needed only for 64-bit cpu's )
03f OF addr @[EMAIL PROTECTED]
d# 32 AND \ 2nd Floating-point group (47)
IF fc00003f >r
ELSE fc0007ff >r THEN
ENDOF
fc000000 >r \ Default: Major opcode alone identifies remainder
\ majority of load, store, plus some int arith & logic (39)
ENDCASE ( TOTAL PPC INSTRN'S = 285 + 2 aliases = 287 )
r>
;
\ In the operand-extraction functions which follow, "trimmed-
\ instruction" means the progressively reduced ppc instruction
\ remnant, after all bits to the right of the current operand
\ (if any) have been shifted out.
\ Single operand primitives. If they start with '.' they output to
\ screen. Otherwise they pass the result back to the instruction-
\ nominated calling routine which then has to do the output.
\
: .comma ( -- ) 2c emit ;
: .0x ( -- ) [CHAR] 0 emit [CHAR] x emit ;
: .hexdump ( u -- ) 0 <# # # # # # # # # #> type ;
\ can substitute '8 u.r' if it pads with 0's instead of blanks
: .nbr ( trimmed-instruction -- )
01f AND 0 <# decimal #s hex #> \ prints rhs 5 bits in decimal
type ;
: .gpr ( trimmed-instruction -- )
[CHAR] r emit .nbr ; \ outputs one of r0 r1 r2 ... r31
: .fpr ( trimmed-instruction -- )
[CHAR] f emit .gpr ; \ outputs one of fr0 fr1 fr2 ... fr31
: .fld ( trimmed-instruction -- )
07 AND 0 <# decimal #s hex #> type ; \ one of 0 1 2 ... n
: .segr ( trimmed-instruction -- )
0f AND 0 <# decimal #s hex #> type ; \ one of 0 1 2 ... 15
: .imm ( trimmed-instruction -- ) 0 <# # #> type ; \ 0 1 2 ... f
: .xx ( trimmed-instruction -- )
ff AND .0x 0 <# # # #> type ; \ one of 0x00 0x01 0x02 ... 0xff
: .cc ( trimmed-instruction -- ) 1f AND .xx ;
: .ui ( trimmed-instruction -- ) ( no trimming actually required)
ffff AND .0x 0 <# # # # # #> type ; \ 0xxxxx where x = hexdigit
: sign-extend ( ppc-instr'n -- immed-data-field-expanded-to-32-bits)
lwsplit drop ( works with rhs 16-bit immediate fields only )
dup 8000 AND
if ffff else 0000 then \ put sign extension on stack
wljoin
;
\ 0 alignment assumes code being disassembled fm executable location
: align-target ( branch-addr -- aligned-branch-addr )
-4 AND
;
: .si \ output signed immedate data as 4 hex digits
sign-extend dup abs 0
<# # # # #s [char] x hold [char] 0 hold rot sign #>
type ;
\ : .si \ more flexible if your computer's (.) output matches mine
\ sign-extend dup (.) rot dup 0< IF
\ swap 1- rot 1+ \ skip 1st char '-' and reduce length
\ swap rot \ unscramble stack
\ [char] - emit \ send a minus sign to output
\ THEN
\ -9 9 between NOT
\ IF .0x THEN \ only 1 numeric digit, so skip .0x
\ type
\ ;
: .sd ( trimmed-instruction -- ) .si ;
: .spr ( trimmed-instruction -- ) \ as in 'mtspr'.
0 <# decimal #s hex #> type ; \ output matches documentation
: btarget ( offset ppc-instr'n -- to-address ) ( 24-bit abs. field )
( for relative result, supply instrn addr; absolute rslt use 0 base)
swap
03fffffc AND dup ( + 2 alignment bits -> 26 bits )
02000000 AND ( most 32-bit G4 addr start with 00 or ff )
if fc000000 OR then \ if hi bit = 1, keep address hi
+ \ add the base address
;
\ These extract-and-display-multiple-operands routines are nominated
\ within the individual ppc instruction records which make up the
\ data table near the end of this source. By that means, individual
\ instruction tells disasm1 how to display its operands.
: nil ( instruction -- ) DROP \ instr'ns with no operands eg 'rfi'
9 spaces ;
: all ( instruction -- ) \ used by "data" pseudo-instruction only
.hexdump ;
: T*4a ( ppc-instruction -- ) \ used by 'ba' and 'bla'
0 btarget \ use zero base-addr with absolute source field
.hexdump ;
: T*4r ( ppc-instruction -- ) \ 'b','bl' ( r=relative src fld )
addr btarget ( base-addr = instrn-addr converts rel to absolute)
.hexdump
;
: cCbNT*4a ( ppc-instruction -- ) \ eg 'bcla'
align-target
dup 010 rshift dup 5 rshift
.xx .comma .nbr .comma sign-extend
.hexdump ;
: cCbNT*4r ( ppc-instruction -- ) \ eg 'bc'
align-target
dup 010 rshift dup 5 rshift
.xx .comma .nbr .comma sign-extend
addr + ( rel. field + curr. instr'n addr -> final target addr )
.hexdump ;
: cCrAsI ( ppc-instruction -- ) \ 'twi' only
dup 010 rshift dup 5 rshift
.cc .comma .gpr .comma .si
;
: cCbN ( ppc-instruction -- ) \ eg 'bcctr' ("branch to addr in CTR")
010 rshift dup 5 rshift
.cc .comma .nbr
;
: cCrAB ( ppc-instruction -- ) \ 'tw' only
0b rshift dup 5 rshift dup 5 rshift
.nbr .comma .gpr .comma .gpr
;
: rAB ( ppc-instruction -- ) \ eg, 'dcbf'
0b rshift \ discard all to right of right-most operand
dup 5 rshift \ push, then do similar for next operand
.gpr .comma .gpr \ pop and print opnd fields in orig. order
;
: rB ( ppc-instruction -- ) \ eg, 'tlbie'
0b rshift \ re-position field to rhs for processing
.gpr \ output field as a general purpose register
;
: rT ( ppc-instruction -- )
015 rshift .gpr ;
: rS rT ( ppc-instruction -- ) ;
: fpT ( ppc-instruction -- ) \ eg 'mffs.'
015 rshift .fpr ;
: nT ( ppc-instruction -- ) \ eg 'mtfsb0'
015 rshift .nbr
;
: rTA ( ppc-instruction -- ) \ eg, 'neg.'
010 rshift
dup 5 rshift
.gpr .comma .gpr ;
: rxSA ( ppc-instruction -- )
010 rshift
dup 5 rshift SWAP
.gpr .comma .gpr
;
: rTAB ( ppc-instruction -- ) \ eg, 'mullw'
0b rshift \ position first 5-bit field to rhs
dup 5 rshift dup 5 rshift \ push remainder fields in rvs order
.gpr .comma .gpr .comma .gpr ; \ pop and print them
: rSAB ( ppc-instruction -- ) rTAB ; \ eg 'stbx'
: rxSAB ( ppc-instruction -- ) \ eg. 'andc'
0b rshift
dup 5 rshift dup 5 rshift SWAP
.gpr .comma .gpr .comma .gpr
;
: fpTAB ( ppc-instruction -- ) \ eg 'fsubs'
0b rshift \ bring register to chopping block for trimming
dup 5 rshift dup 5 rshift
.fpr .comma .fpr .comma .fpr ;
: fpTrAB ( ppc-instruction -- ) \ eg,'lfsux'
0b rshift \ shift right til only operands (and major opc) remain
dup 5 rshift dup 5 rshift \ copy & push after prev oprnd removed
.fpr .comma .gpr .comma .gpr ;
: fpSrAB ( ppc-instruction -- ) fpTrAB ; \ eg 'stfsx'
: nTAB ( ppc-instruction -- ) \ eg 'crxor'
0b rshift
dup 5 rshift dup 5 rshift
.nbr .comma .nbr .comma .nbr ;
: rTAnB ( ppc-instruction -- )
0b rshift
dup 5 rshift dup 5 rshift
.gpr .comma .gpr .comma .nbr ;
: rSAnB ( ppc-instruction -- ) rTAnB ; \ eg 'stswi'
: rxSAnB ( ppc-instruction -- ) \ eg 'srw'
0b rshift
dup 5 rshift dup 5 rshift SWAP
.gpr .comma .gpr .comma .nbr
;
: fpTAxBC ( ppc-instruction -- ) \ eg, 'fmadds'
06 rshift
dup 5 rshift dup 5 rshift dup 5 rshift \ xBC = output C before B
.fpr .comma .fpr .comma SWAP .fpr .comma .fpr
;
: rxSAnBCD ( ppc-instruction -- ) \ eg, 'rlwimi'
01 rshift
dup 5 rshift dup 5 rshift dup 5 rshift dup 5 rshift
SWAP .gpr .comma .gpr .comma .nbr .comma .nbr .comma .nbr ;
: rxSABnCD ( ppc-instruction -- ) \ eg, 'rlwinm.'
01 rshift
dup 5 rshift dup 5 rshift dup 5 rshift dup 5 rshift
SWAP .gpr .comma .gpr .comma .gpr .comma .nbr .comma .nbr
;
: fpTAC ( ppc-instruction -- ) \ eg, 'fmuls.'
06 rshift
dup 0a rshift dup 5 rshift
.fpr .comma .fpr .comma .fpr
;
: rTB ( ppc-instruction -- )
0b rshift \ eg, 'mfsrin'
dup 0a rshift ( skips register-B and unused reg-A at same time)
.gpr .comma .gpr ;
: rSB ( ppc-instruction -- ) rTB ; \ eg, 'fctiwz'
: fpTB ( ppc-instruction -- )
0b rshift
dup 0a rshift
.fpr .comma .fpr
;
: fpTx(rA)sD ( ppc-instruction -- ) \ eg 'lfd'
dup 10 rshift dup 5 rshift
.fpr .comma SWAP .sd [CHAR] ( emit .gpr [CHAR] ) emit ;
: fpSx(rA)sD ( ppc-instruction -- ) fpTx(rA)sD \ eg, 'stfdu'
;
: fT ( ppc-instruction -- ) \ 'mcrxr' only
017 rshift
.fld
;
: fTS ( ppc-instruction -- )
012 rshift dup 5 rshift
.fld .comma .fld
;
: fT.rAB ( ppc-instruction -- ) \ eg, 'cmp'
0b rshift
dup 5 rshift dup 7 rshift 0 SWAP
.fld .comma .nbr .comma .gpr .comma .gpr ;
: fTfpAB ( ppc-instruction -- ) \ eg, 'fcmpo'
0b rshift
dup 5 rshift dup 7 rshift
.fld .comma .fpr .comma .fpr
;
: fT.rAsI ( ppc-instruction -- ) \ 'cmpi' only
dup 010 rshift dup 7 rshift 0 SWAP
.fld .comma .nbr .comma .gpr .comma .si ;
: fT.rAuI ( ppc-instruction -- ) \ 'cmpli' only
dup 010 rshift dup 7 rshift 0 SWAP
.fld .comma .nbr .comma .gpr .comma .ui
;
: fThB ( ppc-instruction -- ) \ eg 'mtfsfi.'
0c rshift dup 0b rshift .fld .comma .imm ;
: rTgR ( ppc-instruction -- ) \ 'mfsr' only
010 rshift dup 5 rshift .gpr .comma .segr
;
: rTx(A)sD ( ppc-instruction -- ) \ eg, 'lwzu'
dup 010 rshift dup 5 rshift
.gpr .comma SWAP .si [CHAR] ( emit .gpr [CHAR] ) emit ;
: rSx(A)sD ( ppc-instruction -- ) rTx(A)sD \ eg 'stbu'
;
: rTAsI ( ppc-instruction -- ) \ eg, 'subfic'
dup 010 rshift dup 5 rshift
.gpr .comma .gpr .comma .si ;
: rxSAuI ( ppc-instruction -- ) \ eg, 'ori'
dup 010 rshift dup 5 rshift SWAP
.gpr .comma .gpr .comma .ui ;
: mMfpB ( ppc-instruction -- ) \ eg, 'mtfsf'
0b rshift dup 6 rshift \ trim to reg B, push; ditto 8-bit mask
.xx .comma .fpr
;
: xrSmM ( ppc-instruction -- ) \ 'mtcrf' only )
0c rshift dup 9 rshift SWAP \ ignore hi 0 to left of 8-bit field
.xx .comma .gpr ;
: xrSgS ( ppc-instruction -- ) \ 'mtsr' only )
010 rshift dup 5 rshift
.gpr .comma .segr ;
\ swap halves of spr/tbr spec field lo-hi to hi-lo order for display
: swap-ends ( ppc-instruction -- spr-specification )
001ff800 AND \ trim extraneous data from spr spec
lwsplit \ separate hi and lo halves
swap \ reverse their order
6 rshift \ reposition hi half to 5 of 10 most sig. bits
+ \ recombine
;
: rTxLH ( ppc-instruction -- ) \ 'mfspr' and 'mftb'
dup swap-ends
swap
015 rshift .gpr .comma .spr ;
: xrSxLH ( ppc-instruction -- ) \ 'mtspr' only
dup swap-ends
..spr .comma 015 rshift .gpr
;
\ Works like , (comma) but appends string not number to dictionary
: s, ( fm-addr len -- ) \ NB: " string" in source puts args on stack
here swap move
2 cells allot
;
: records cells 5 * ;
0 value record->
0 value table
0 value last-record
here to table \ address to start building ppc-instr'n array on stack
\ The 'operands' fields below have names which are a form of
\ shorthand describing their composition. These tags are also
\ used to name and implement their extraction functions. Eg,
\ the most common register combinations derive from 5-bit fields
\ in fixed positions immediately following the obligatory six-bit
\ 'Major Opcode' on the far left of every 32-bit ppc instruction.
\ These most common operand fields are designated herein as T, A,
\ B, C. Any lower-case letters preceding those upper-case register
\ tags apply as modifiers to all following register names until
\ another lower-case letter supercedes it. Thus fpTrABnC would
\ represent one floating-point register (T), two general purpose
\ registers (A and B) and a five-bit number (C). The function
\ "fpTrABnC" developed to implement it would thus output (eg)
\ fr1,r31,r2,0x7e ,depending on the contents extracted from the
\ nominated fields within the fields so nominated.
\ There are a few infrequently encountered exceptions however. Eg a
\ lower-case exception is a single 'x' which augments but does not
\ supercede the following lower-case modifiers. It means that the
\ two registers to its right are displayed in the opposite order to
\ their relative positions within the 32-bit ppc instruction they
\ are extracted from. (Such an 'x' transcribes directly to the forth
\ word SWAP the way it is implemented here). Note that these tags
\ refer to their relative position within 32-bit ppc instructions.
\ The disassembler syntax usually BUT NOT ALWAYS displays the
\ operands in the same left-to-right order they were located
\ within the machine code instruction being disassembled.
\
\ For more insights into the meanings of the uppercase designators,
\ refer to "Optimising PowerPC Code" by Gary Kacmarcik (Addison-
\ Wesley 1995). That book is the source of much of the ppc data
\ utilized when writing this disassembler.
\
\ The lower-case modifier-prefixes are:
\
\ r = general purpose register
\ fp = floating point register
\ m = mask
\ n = a number extracted from the same fields as abv, no prefix
\ f = a 3-bit field nbr, typically upper 3 of normal 5-bit field
\ g = 4-bit number, eg seGment register id (displayed in decimal)
\ h = 4-bit immediate data, eg bitmap of field (displayed in Hex)
\ c = a code,eg, cC = a code of type 'condition'="condition code"
\ i = immediate data (often the rhs half-word of the ppc instr'n)
\ s = signed (to the ppc & optionally displayed as such by 'dis')
\ u = unsigned (applies to immed. data copied direct fm instr'n)
\ d = a displacement or fixed offset, prefixed to affected reg.
\ a = absolute address (as near as you can get with the major
\ opcode occupying the six lhs bits of the instruction).
\ ( = operand to be separated from prev one by '(' instead of ','
\ ) = Ignore. It is just there to make the meaning of '(' clearer
\ x = display the following two registers in reverse order
\ . = Display a constant '0' at this point without affecting
\ anything else. (It can only be '1' on 64-bit ppc's)
\
table d# 288 records BL fill \ pre-pad count must be >= #records
\ opcode final mask mnemonic operands (commas do the poking)
\ --------------------------------------------
00000000 , 00000000 , " data" s, ' all , ( the only pseudo-op)
\ The foll. 287 records (-2 aliases in mftb patch) = G4 instr set
7c000214 , fc0007ff , " add" s, ' rTAB ,
7c000215 , fc0007ff , " add." s, ' rTAB ,
7c000014 , fc0007ff , " addc" s, ' rTAB ,
7c000015 , fc0007ff , " addc." s, ' rTAB ,
7c000414 , fc0007ff , " addco" s, ' rTAB ,
7c000415 , fc0007ff , " addco." s, ' rTAB ,
7c00008a , fc0007ff , " adde" s, ' rTAB ,
7c00008b , fc0007ff , " adde." s, ' rTAB ,
7c00048a , fc0007ff , " addeo" s, ' rTAB ,
7c00048b , fc0007ff , " addeo." s, ' rTAB ,
38000000 , fc000000 , " addi" s, ' rTAsI ,
30000000 , fc000000 , " addic" s, ' rTAsI ,
34000000 , fc000000 , " addic." s, ' rTAsI ,
3c000000 , fc000000 , " addis" s, ' rTAsI ,
7c0001d4 , fc00ffff , " addme" s, ' rTA ,
7c0001d5 , fc00ffff , " addme." s, ' rTA ,
7c0005d4 , fc00ffff , " addmeo" s, ' rTA ,
7c0005d5 , fc00ffff , " addmeo." s, ' rTA ,
7c000614 , fc0007ff , " addo" s, ' rTAB ,
7c000615 , fc0007ff , " addo." s, ' rTAB ,
7c000194 , fc00ffff , " addze" s, ' rTA ,
7c000195 , fc00ffff , " addze." s, ' rTA ,
7c000594 , fc00ffff , " addzeo" s, ' rTA ,
7c000595 , fc00ffff , " addzeo." s, ' rTA ,
7c000038 , fc0007ff , " and" s, ' rxSAB ,
7c000039 , fc0007ff , " and." s, ' rxSAB ,
7c000078 , fc0007ff , " andc" s, ' rxSAB ,
7c000079 , fc0007ff , " andc." s, ' rxSAB ,
70000000 , fc000000 , " andi." s, ' rxSAuI ,
74000000 , fc000000 , " andis." s, ' rxSAuI ,
48000000 , fc000003 , " b" s, ' T*4r ,
48000002 , fc000003 , " ba" s, ' T*4a ,
40000000 , fc000003 , " bc" s, ' cCbNT*4r ,
40000002 , fc000003 , " bca" s, ' cCbNT*4a ,
4c000420 , fc00ffff , " bcctr" s, ' cCbN ,
4c000421 , fc00ffff , " bcctrl" s, ' cCbN ,
40000001 , fc000003 , " bcl" s, ' cCbNT*4r ,
40000003 , fc000003 , " bcla" s, ' cCbNT*4a ,
4c000020 , fc00ffff , " bclr" s, ' cCbN ,
4c000021 , fc00ffff , " bclrl" s, ' cCbN ,
48000001 , fc000003 , " bl" s, ' T*4r ,
48000003 , fc000003 , " bla" s, ' T*4a ,
7c000000 , fc6007ff , " cmp" s, ' fT.rAB ,
2c000000 , fc600000 , " cmpi" s, ' fT.rAsI ,
7c000040 , fc6007ff , " cmpl" s, ' fT.rAB ,
28000000 , fc600000 , " cmpli" s, ' fT.rAuI ,
7c000034 , fc00ffff , " cntlzw" s, ' rxSA ,
7c000035 , fc00ffff , " cntlzw." s, ' rxSA ,
4c000202 , fc0007ff , " crand" s, ' nTAB ,
4c000102 , fc0007ff , " crandc" s, ' nTAB ,
4c000242 , fc0007ff , " creqv" s, ' nTAB ,
4c0001c2 , fc0007ff , " crnand" s, ' nTAB ,
4c000042 , fc0007ff , " crnor" s, ' nTAB ,
4c000382 , fc0007ff , " cror" s, ' nTAB ,
4c000342 , fc0007ff , " crorc" s, ' nTAB ,
4c000182 , fc0007ff , " crxor" s, ' nTAB ,
7c0000ac , ffe007ff , " dcbf" s, ' rAB ,
7c0003ac , ffe007ff , " dcbi" s, ' rAB ,
7c00006c , ffe007ff , " dcbst" s, ' rAB ,
7c00022c , ffe007ff , " dcbt" s, ' rAB ,
7c0001ec , ffe007ff , " dcbtst" s, ' rAB ,
7c0007ec , ffe007ff , " dcbz" s, ' rAB ,
7c0003d6 , fc0007ff , " divw" s, ' rTAB ,
7c0003d7 , fc0007ff , " divw." s, ' rTAB ,
7c0007d6 , fc0007ff , " divwo" s, ' rTAB ,
7c0007d7 , fc0007ff , " divwo." s, ' rTAB ,
7c000396 , fc0007ff , " divwu" s, ' rTAB ,
7c000397 , fc0007ff , " divwu." s, ' rTAB ,
7c000796 , fc0007ff , " divwuo" s, ' rTAB ,
7c000797 , fc0007ff , " divwuo." s, ' rTAB ,
7c00026c , fc0007ff , " eciwx" s, ' rTAB ,
7c00036c , fc0007ff , " ecowx" s, ' rSAB ,
7c0006ac , ffffffff , " eieio" s, ' nil ,
7c000238 , fc0007ff , " eqv" s, ' rxSAB ,
7c000239 , fc0007ff , " eqv." s, ' rxSAB ,
7c000774 , fc00ffff , " extsb" s, ' rxSA ,
7c000775 , fc00ffff , " extsb." s, ' rxSA ,
7c000734 , fc00ffff , " extsh" s, ' rxSA ,
7c000735 , fc00ffff , " extsh." s, ' rxSA ,
fc000210 , fc1f07ff , " fabs" s, ' fpTB ,
fc000211 , fc1f07ff , " fabs." s, ' fpTB ,
fc00002a , fc00003f , " fadd" s, ' fpTAB ,
fc00002b , fc00003f , " fadd." s, ' fpTAB ,
ec00002a , fc00003f , " fadds" s, ' fpTAB ,
ec00002b , fc00003f , " fadds." s, ' fpTAB ,
fc000040 , fc6007ff , " fcmpo" s, ' fTfpAB ,
fc000000 , fc6007ff , " fcmpu" s, ' fTfpAB ,
fc00001c , fc1f07ff , " fctiw" s, ' fpTB ,
fc00001d , fc1f07ff , " fctiw." s, ' fpTB ,
fc00001e , fc1f07ff , " fctiwz" s, ' fpTB ,
fc00001f , fc1f07ff , " fctiwz." s, ' fpTB ,
fc000024 , fc00003f , " fdiv" s, ' fpTAB ,
fc000025 , fc00003f , " fdiv." s, ' fpTAB ,
ec000024 , fc0007ff , " fdivs" s, ' fpTAB ,
ec000025 , fc0007ff , " fdivs." s, ' fpTAB ,
fc00003a , fc00003f , " fmadd" s, ' fpTAxBC ,
fc00003b , fc00003f , " fmadd." s, ' fpTAxBC ,
ec00003a , fc00003f , " fmadds" s, ' fpTAxBC ,
ec00003b , fc00003f , " fmadds." s, ' fpTAxBC ,
fc000090 , fc1f07ff , " fmr" s, ' fpTB ,
fc000091 , fc1f07ff , " fmr." s, ' fpTB ,
fc000038 , fc00003f , " fmsub" s, ' fpTAxBC ,
fc000039 , fc00003f , " fmsub." s, ' fpTAxBC ,
ec000038 , fc00003f , " fmsubs" s, ' fpTAxBC ,
ec000039 , fc00003f , " fmsubs." s, ' fpTAxBC ,
fc000032 , fc00f83f , " fmul" s, ' fpTAC ,
fc000033 , fc00003f , " fmul." s, ' fpTAC ,
ec000032 , fc00f83f , " fmuls" s, ' fpTAC ,
ec000033 , fc00f83f , " fmuls." s, ' fpTAC ,
fc000110 , fc1f07ff , " fnabs" s, ' fpTB ,
fc000111 , fc1f07ff , " fnabs." s, ' fpTB ,
fc000050 , fc1f07ff , " fneg" s, ' fpTB ,
fc000051 , fc1f07ff , " fneg." s, ' fpTB ,
fc00003e , fc00003f , " fnmadd" s, ' fpTAxBC ,
fc00003f , fc00003f , " fnmadd." s, ' fpTAxBC ,
ec00003e , fc00003f , " fnmadds" s, ' fpTAxBC ,
ec00003f , fc00003f , " fnmadds." s, ' fpTAxBC ,
fc00003c , fc00003f , " fnmsub" s, ' fpTAxBC ,
fc00003d , fc00003f , " fnmsub." s, ' fpTAxBC ,
ec00003c , fc00003f , " fnmsubs" s, ' fpTAxBC ,
ec00003d , fc00003f , " fnmsubs." s, ' fpTAxBC ,
ec000030 , fc1f07ff , " fres" s, ' fpTB ,
ec000031 , fc1f07ff , " fres." s, ' fpTB ,
fc000018 , fc1f07ff , " frsp" s, ' fpTB ,
fc000019 , fc1f07ff , " frsp." s, ' fpTB ,
fc000034 , fc1f003f , " frsqrte" s, ' fpTB ,
fc000035 , fc1f003f , " frsqrte." s, ' fpTB ,
fc00002e , fc00003f , " fsel" s, ' fpTAxBC ,
fc00002f , fc00003f , " fsel." s, ' fpTAxBC ,
fc000028 , fc00003f , " fsub" s, ' fpTAB ,
fc000029 , fc00003f , " fsub." s, ' fpTAB ,
ec000028 , fc00003f , " fsubs" s, ' fpTAB ,
ec000029 , fc00003f , " fsubs." s, ' fpTAB ,
7c0007ac , ffe007ff , " icbi" s, ' rAB ,
4c00012c , ffffffff , " isync" s, ' nil ,
88000000 , fc000000 , " lbz" s, ' rTx(A)sD ,
8c000000 , fc000000 , " lbzu" s, ' rTx(A)sD ,
7c0000ee , fc0007ff , " lbzux" s, ' rTAB ,
7c0000ae , fc0007ff , " lbzx" s, ' rTAB ,
c8000000 , fc000000 , " lfd" s, ' fpTx(rA)sD ,
cc000000 , fc000000 , " lfdu" s, ' fpTx(rA)sD ,
7c0004ee , fc0007ff , " lfdux" s, ' fpTrAB ,
7c0004ae , fc0007ff , " lfdx" s, ' fpTrAB ,
c0000000 , fc000000 , " lfs" s, ' fpTx(rA)sD ,
c4000000 , fc000000 , " lfsu" s, ' fpTx(rA)sD ,
7c00046e , fc0007ff , " lfsux" s, ' fpTrAB ,
7c00042e , fc0007ff , " lfsx" s, ' fpTrAB ,
a8000000 , fc000000 , " lha" s, ' rTx(A)sD ,
ac000000 , fc000000 , " lhau" s, ' rTx(A)sD ,
7c0002ee , fc0007ff , " lhaux" s, ' rTAB ,
7c0002ae , fc0007ff , " lhax" s, ' rTAB ,
7c00062c , fc0007ff , " lhbrx" s, ' rTAB ,
a0000000 , fc000000 , " lhz" s, ' rTx(A)sD ,
a4000000 , fc000000 , " lhzu" s, ' rTx(A)sD ,
7c00026e , fc0007ff , " lhzux" s, ' rTAB ,
7c00022e , fc0007ff , " lhzx" s, ' rTAB ,
b8000000 , fc000000 , " lmw" s, ' rTx(A)sD ,
7c0004aa , fc0007ff , " lswi" s, ' rTAnB ,
7c00042a , fc0007ff , " lswx" s, ' rTAB ,
7c000028 , fc0007ff , " lwarx" s, ' rTAB ,
7c00042c , fc0007ff , " lwbrx" s, ' rTAB ,
80000000 , fc000000 , " lwz" s, ' rTx(A)sD ,
84000000 , fc000000 , " lwzu" s, ' rTx(A)sD ,
7c00006e , fc0007ff , " lwzux" s, ' rTAB ,
7c00002e , fc0007ff , " lwzx" s, ' rTAB ,
4c000000 , fc63ffff , " mcrf" s, ' fTS ,
fc000080 , fc63ffff , " mcrfs" s, ' fTS ,
7c000400 , fc7fffff , " mcrxr" s, ' fT ,
7c000026 , fc1fffff , " mfcr" s, ' rT ,
fc00048e , fc1fffff , " mffs" s, ' fpT ,
fc00048f , fc1fffff , " mffs." s, ' fpT ,
7c0000a6 , fc1fffff , " mfmsr" s, ' rT ,
7c0002a6 , fc0007ff , " mfspr" s, ' rTxLH ,
7c0004a6 , fc10ffff , " mfsr" s, ' rTgR ,
7c000526 , fc1f07ff , " mfsrin" s, ' rTB ,
\ comment out next line to reject non-documented MFR operands
7c0002e6 , fc0007ff , " mftb" s, ' rTxLH ,
\ ------------------------------------------------------------------
\ Part 2 of mftb Patch.Next 2 records are Extended Form alternatives
7c0c42e6 , fc1fffff , " mftb" s, ' rT , \ alias of mftb rX,268
7c0d42e6 , fc1fffff , " mftbu" s, ' rT , \ alias of mftb rX,269
( Const. data is duplicated in Part 1 of patch in 'roughmask' abv. )
\ ------------------------ (mftb Patch ends) -----------------------
7c000120 , fc100fff , " mtcrf" s, ' xrSmM ,
fc00008c , fc1fffff , " mtfsb0" s, ' nT ,
fc00008d , fc1fffff , " mtfsb0." s, ' nT ,
fc00004c , fc1fffff , " mtfsb1" s, ' nT ,
fc00004d , fc1fffff , " mtfsb1." s, ' nT ,
fc00058e , fe0107ff , " mtfsf" s, ' mMfpB ,
fc00058f , fe0107ff , " mtfsf." s, ' mMfpB ,
fc00010c , fc7f0fff , " mtfsfi" s, ' fThB ,
fc00010d , fc7f0fff , " mtfsfi." s, ' fThB ,
7c000124 , fc1fffff , " mtmsr" s, ' rS ,
7c0003a6 , fc0007ff , " mtspr" s, ' xrSxLH ,
7c0001a4 , fc0007ff , " mtsr" s, ' xrSgS ,
7c0001e4 , fc1f07ff , " mtsrin" s, ' rSB ,
7c000092 , fc0007ff , " mulhw" s, ' rTAB ,
7c000093 , fc0007ff , " mulhw." s, ' rTAB ,
7c000016 , fc0007ff , " mulhwu" s, ' rTAB ,
7c000017 , fc0007ff , " mulhwu." s, ' rTAB ,
1c000000 , fc000000 , " mulli" s, ' rTAsI ,
7c0001d6 , fc0007ff , " mullw" s, ' rTAB ,
7c0001d7 , fc0007ff , " mullw." s, ' rTAB ,
7c0005d6 , fc0007ff , " mullwo" s, ' rTAB ,
7c0005d7 , fc0007ff , " mullwo." s, ' rTAB ,
7c0003b8 , fc0007ff , " nand" s, ' rxSAB ,
7c0003b9 , fc0007ff , " nand." s, ' rxSAB ,
7c0000d0 , fc00ffff , " neg" s, ' rTA ,
7c0000d1 , fc00ffff , " neg." s, ' rTA ,
7c0004d0 , fc00ffff , " nego" s, ' rTA ,
7c0004d1 , fc00ffff , " nego." s, ' rTA ,
7c0000f8 , fc0007ff , " nor" s, ' rxSAB ,
7c0000f9 , fc0007ff , " nor." s, ' rxSAB ,
7c000378 , fc0007ff , " or" s, ' rxSAB ,
7c000379 , fc0007ff , " or." s, ' rxSAB ,
7c000338 , fc0007ff , " orc" s, ' rxSAB ,
7c000339 , fc0007ff , " orc." s, ' rxSAB ,
60000000 , fc000000 , " ori" s, ' rxSAuI ,
64000000 , fc000000 , " oris" s, ' rxSAuI ,
4c000064 , ffffffff , " rfi" s, ' nil ,
50000000 , fc000001 , " rlwimi" s, ' rxSAnBCD ,
50000001 , fc000001 , " rlwimi." s, ' rxSAnBCD ,
54000000 , fc000001 , " rlwinm" s, ' rxSAnBCD ,
54000001 , fc000001 , " rlwinm." s, ' rxSAnBCD ,
5c000000 , fc000001 , " rlwnm" s, ' rxSABnCD ,
5c000001 , fc000001 , " rlwnm." s, ' rxSABnCD ,
44000002 , fc000003 , " sc" s, ' nil ,
7c000030 , fc0007ff , " slw" s, ' rxSAB ,
7c000031 , fc0007ff , " slw." s, ' rxSAB ,
7c000630 , fc0007ff , " sraw" s, ' rxSAB ,
7c000631 , fc0007ff , " sraw." s, ' rxSAB ,
7c000670 , fc0007ff , " srawi" s, ' rxSAnB ,
7c000671 , fc0007ff , " srawi." s, ' rxSAnB ,
7c000430 , fc0007ff , " srw" s, ' rxSAB ,
7c000431 , fc0007ff , " srw." s, ' rxSAB ,
98000000 , fc000000 , " stb" s, ' rSx(A)sD ,
9c000000 , fc000000 , " stbu" s, ' rSx(A)sD ,
7c0001ee , fc0007ff , " stbux" s, ' rSAB ,
7c0001ae , fc0007ff , " stbx" s, ' rSAB ,
d8000000 , fc000000 , " stfd" s, ' fpSx(rA)sD ,
dc000000 , fc000000 , " stfdu" s, ' fpSx(rA)sD ,
7c0005ee , fc0007ff , " stfdux" s, ' fpSrAB ,
7c0005ae , fc0007ff , " stfdx" s, ' fpSrAB ,
7c0007ae , fc0007ff , " stfiwx" s, ' fpSrAB ,
d0000000 , fc000000 , " stfs" s, ' fpSx(rA)sD ,
d4000000 , fc000000 , " stfsu" s, ' fpSx(rA)sD ,
7c00056e , fc0007ff , " stfsux" s, ' fpSrAB ,
7c00052e , fc0007ff , " stfsx" s, ' fpSrAB ,
b0000000 , fc000000 , " sth" s, ' rSx(A)sD ,
7c00072c , fc0007ff , " sthbrx" s, ' rSAB ,
b4000000 , fc000000 , " sthu" s, ' rSx(A)sD ,
7c00036e , fc0007ff , " sthux" s, ' rSAB ,
7c00032e , fc0007ff , " sthx" s, ' rSAB ,
bc000000 , fc000000 , " stmw" s, ' rSx(A)sD ,
7c0005aa , fc0007ff , " stswi" s, ' rSAnB ,
7c00052a , fc0007ff , " stswx" s, ' rSAB ,
90000000 , fc000000 , " stw" s, ' rSx(A)sD ,
7c00052c , fc0007ff , " stwbrx" s, ' rSAB ,
7c00012d , fc0007ff , " stwcx." s, ' rSAB ,
94000000 , fc000000 , " stwu" s, ' rSx(A)sD ,
7c00016e , fc0007ff , " stwux" s, ' rSAB ,
7c00012e , fc0007ff , " stwx" s, ' rSAB ,
7c000050 , fc0007ff , " subf" s, ' rTAB ,
7c000051 , fc0007ff , " subf." s, ' rTAB ,
7c000010 , fc0007ff , " subfc" s, ' rTAB ,
7c000011 , fc0007ff , " subfc." s, ' rTAB ,
7c000410 , fc0007ff , " subfco" s, ' rTAB ,
7c000411 , fc0007ff , " subfco." s, ' rTAB ,
7c000110 , fc0007ff , " subfe" s, ' rTAB ,
7c000111 , fc0007ff , " subfe." s, ' rTAB ,
7c000510 , fc0007ff , " subfeo" s, ' rTAB ,
7c000511 , fc0007ff , " subfeo." s, ' rTAB ,
20000000 , fc000000 , " subfic" s, ' rTAsI ,
7c0001d0 , fc00ffff , " subfme" s, ' rTA ,
7c0001d1 , fc00ffff , " subfme." s, ' rTA ,
7c0005d0 , fc00ffff , " subfmeo" s, ' rTA ,
7c0005d1 , fc00ffff , " subfmeo." s, ' rTA ,
7c000450 , fc0007ff , " subfo" s, ' rTAB ,
7c000451 , fc0007ff , " subfo." s, ' rTAB ,
7c000190 , fc00ffff , " subfze" s, ' rTA ,
7c000191 , fc00ffff , " subfze." s, ' rTA ,
7c000591 , fc00ffff , " subfzeo" s, ' rTA ,
7c000590 , fc00ffff , " subfzeo." s, ' rTA ,
7c0004ac , ffffffff , " sync" s, ' nil ,
7c000264 , ffff07ff , " tlbie" s, ' rB ,
7c00046c , ffffffff , " tlbsync" s, ' nil ,
7c000008 , fc0007ff , " tw" s, ' cCrAB ,
0c000000 , fc000000 , " twi" s, ' cCrAsI ,
7c000278 , fc0007ff , " xor" s, ' rxSAB ,
7c000279 , fc0007ff , " xor." s, ' rxSAB ,
68000000 , fc000000 , " xori" s, ' rxSAuI ,
6c000000 , fc000000 , " xoris" s, ' rxSAuI ,
\ ====================================
here 1 records - to last-record
here to addr \ garbage better than +dis "Illegal memory access" err
0 value opcode
: find-record
table last-record DO \ search for opcode in table
I @[EMAIL PROTECTED]
opcode = IF I leave THEN \ found: put index on stack
I table = IF I leave THEN \ not found: make 'data' the instrn
-1 records +LOOP
;
: disasm1 ( address --) ( or use 'dis' with ret-key to single-step)
hex
fffffffc ( -4 ) and
\ enforces cell alignment so branch operands always accurate
dup to addr
.hexdump 3a emit BL emit ( print instruction address )
( addr @[EMAIL PROTECTED]
.hexdump 2 spaces ) \ uncomment to include raw code
addr dup @[EMAIL PROTECTED]
swap roughmask AND to opcode ( save candidate opc )
find-record to record->
record-> cell+ @[EMAIL PROTECTED]
( instr'n-nominated mask combined with )
addr @[EMAIL PROTECTED]
AND ( instruction gives exact opcode )
opcode <> IF ( does it match initially calculated opcode ? )
table to record-> THEN ( invalid inst'n, re-assign "data" )
record-> 2 cells + ( advance record pointer to mnemonic )
8 type BL emit ( output mnemonic )
addr @[EMAIL PROTECTED]
record-> 4 cells + @[EMAIL PROTECTED]
( ppc instr'n rec. nominates routine to )
execute ( extract,format and print its operands)
addr cell+ to addr ( pre-increment for next instruction )
cr
;
: dis ( address -- ) \ replaces built-in original
cr -1 swap
do i disasm1
exit? \ displays pagination prompt; use ret-key to single-step
if leave then
cell +loop
;
: +dis ( -- ) addr dis ; \ replaces built-in original
: dis-help \ For now it just disassembles start of each instr record
cr ." G4 Instruction Set with zero-filled operand fields "
cr ." default is hexadecimal for numbers > 4 digits "
cr
last-record 1 records + table
do i disasm1
exit?
if leave then
1 records +loop
;
cr
.." Public Domain replacement 'dis' for G4 Macintosh Open Firmware"
cr
.." dis, +dis, & dis-help await your command. Usage: <address> dis"
cr
.." by Neville Duguid (The Tinkerer) Brisbane Australia, April,2008"
cr


|