Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Forth > 8051 simulation...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 1 Topic 3760 of 4136
Post > Topic >>

8051 simulation..

by mark4 <i440r@[EMAIL PROTECTED] > Feb 11, 2008 at 09:53 PM

I have also fixed some bugs in my 8051 assembler and disassembler that
were published as part of my Linux Isforth compiler.  The site hosting
isforth (an isp in northern indiana) seems to have gone kaput but I
will have a new home soon as i have been offered space on a friends
system.

The fixed assembler and disassembler will be released once I have the
new site up and running but for those of you who are interested heres
the simulator.  This code will simulate the execution of 8051 opcodes
within a forth environment.  I believe that the execution is correct
but I have not fully tested all opcodes yet.

sorry for length of posting ...

regards
  mark

( it looked nice BEFORE i pasted it... honest!)


\ sim51.f         - 8051 simulator by Mark I Manning IV
\
------------------------------------------------------------------------

\ This isnt quite redy for prime time yet but its getting very close
\ This is also just the opcode execution engine, the code for the
front
\ end debugger is still in the early states of development.  Its
useable,
\ even looks nice but there are some very embarrasing sections of
code
\ in there still :)
\
\ This code was also developed with the as yet unreleased DOS version
of
\ my Linux forth compiler.  Eventually I will be releasing that and
the
\ entire 8051 development environment (assembler, disassembler,
debugger)
\
\ This code is also NOT ans compliant and makes use of words that you
\ wount find defined anywhere except within my Forth compilers.
\
\    ?:    My replacement for if/else/then.
\
\          if/else/then               ?: (more efficient!)
\          ----------------------------------------------------------
\
\             Test here               test here
\             ?branch L0000           ?:
\             do-if-part                Do-if-part
\             branch L0001              do-else-part
\          L0000
\             do-else-part
\          L0001                     thats 3 execution tokens in my
\             continue               code and 6 in the other
\
\   var      my name for what other forths limp wristedly call
"value"
\
\            I never liked the name "value",  a variable has a value
\            a constant has a value, an ADDRES has a value!  The name
\            value does not in any way shape or form express that the
\            said 'value' is a VARIALBE so I named it var.
\
\            I also have a word called const that will create a state
\            smart immediate word.  0 const zero will create a word
\            called zero which will either return its value (when in
\            interpret mode) or will compile a literal (when in
\            compile mode).
\
\  not       I do NOT use the word invert.  This word BOGGLES THE MIND
\            The fig (or was it the 79) standard forth had a broken
\            definition of not (it was identical to the definition of
\            0=) which was subsequently FIXED in the 83 standard.
\
\            Along come the ANS committee and in another totally
\            limp wristed manner they refuse to define the word NOT
\            because no matter which definition they chose for it
\            SOMEONE would have to modify their existing sources
\            shock horror!.
\
\            So... they come up with a NEW word which just doesnt
\            scan right to me
\
\            ans forth                     forth
\
\            xxx yyy < invert              xxx yyy < not
\            if                            if
\              blah                          blah
\            then                          then
\
\ case:      I do not use the standard case construct in my forths
\            because they encourage VERY POOR coding practices as
\            follows....
\
\            case
\              1 of 50 lines of code endof
\              2 of 20 lines of code endof
\              ...
\            end-case
\
\            my case construct allows ONE WORD PER CASE and does
\            not have or need an endof.  because of these
\            differences it was requested of me that i change the
\            names of the case compiling constructs.
\
\            so... case became case:  of became opt and endof
\            became a dodo and end-case became ;case.
\
\ l****ft     might as well call these "****ft-sell-left-one-bit"
\ r****ft     and "****ft-cell-right-one-bit" or some other overly
\            verbose name.
\
\            the entire world has come to the conclusion that bit
\            ****fts are done with << and >> which is exactly what i
\            called them.
\
\            if those words functions are too cryptic for us then
\            we are in deep trouble.  i personaly have no problems
\            reading FETCH when i see @[EMAIL PROTECTED]
 or reading STORE when i
\            see !.  what is difference?
\
\ to         this word is incomplete.  it does not IMHO correctly
\            state exactly what it is doing.  In forth the symbpl
\            ! is read 'store'.  the symbol > is read 'to'.  when
\            modifying the contents of a VAR i use !> which is read
\            STORE to. not just "to".
\
\ ok so the 'not' thing above is a small gripe but I always thougth
that
\ if it aint broke dont fix it applied.  or... in this case...if it
IS
\ FIXED dont fix it but the ans team dun fixed it good and proper.
The
\ ans standard team says new code should not use the word not. well
\ i will INVERT use the word invert!
\
\ the word TO above also fals under the "it wasnt broke so why
exactly
\ did you feel the need to DUN FIX it?" catagory :/

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

 .( loading sim51.f ) cr

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

 vocabulary sim51 sim51 definitions

\
------------------------------------------------------------------------
\ 8051 memory spaces

 0 var _sfr                 \ segment address of special function regs
 0 var _iram                \ segment address of internal ram
 0 var _xram                \ segment address of external ram
 0 var _code                \ segment address of code space

\
------------------------------------------------------------------------
\ not used by the sim but is used by the debugger. defined here to be
in
\ context with the above definitions

 0 var x-size               \ size of xram
 0 var c-size               \ size of code space

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

 0 var pc51                 \ 8051 program counter

\
------------------------------------------------------------------------
\ fetch / store byte from / to specified seg address

\ this assumes a non pmode operating system. you can get rid of them
\ if you ****t this to some flat address space :)

: swap@[EMAIL PROTECTED]
           ( a1 seg --- c1 ) swap c@[EMAIL PROTECTED]
 ;
: swap!           ( c1 a1 seg --- ) swap c!l ;

\
------------------------------------------------------------------------
\ mask n1 to 8 bits

: <ff>      ( n1 --- c1 ) $ff and ;

\
------------------------------------------------------------------------
\ fetch / store from / to specific 8051 memory spaces

: iram@[EMAIL PROTECTED]
           ( a1 --- c1 ) _iram swap@[EMAIL PROTECTED]
 ;
: iram!           ( c1 a1 --- ) _iram swap! ;
: xram@[EMAIL PROTECTED]
           ( a1 --- c1 ) _xram swap@[EMAIL PROTECTED]
 ;
: xram!           ( c1 a1 --- ) _xram swap! ;
: code@[EMAIL PROTECTED]
           ( a1 --- c1 ) _code swap@[EMAIL PROTECTED]
 ;

\
------------------------------------------------------------------------
\ fetch next byte of code at 8051's program counter address and bump
pc

: $@[EMAIL PROTECTED]
             ( --- c1 )
  pc51 code@[EMAIL PROTECTED]
 incr> pc51 ;

\
------------------------------------------------------------------------
\ count number of set bits in n1 so we can set the parity flag

\ i think there is a problem here, i noticed my parity flag doing some
\ funky stuff while single stepping some code but i have not taken the
\ time to fix it yet.

: ?parity         ( n1 --- n2 )
  0 swap                    \ 0 bits so far...
  begin
    tuck                    \ keep copy of n1
  while                     \ while n1 is not zero do
    1+ swap                 \ increment bitcount
    dup 1- and              \ and n1 with n1-1 (removes 1 bit)
  repeat
  nip 1 and ;

\
------------------------------------------------------------------------
\ fetch contents of specified sfr

: sfr@[EMAIL PROTECTED]
            ( sfr --- )
  $80 - _sfr swap@[EMAIL PROTECTED]
 ;        \ map sfr address to buffer offset and
fetch

\
------------------------------------------------------------------------
\ store c1 in specified sfr. update parity if sfr was acc

: sfr!            ( c1 sfr --- )
  tuck                      \ keep copy of sfr to modify...
  $80 - _sfr swap!          \ map sfr address to buffer offset and
store
  $e0 =                     \ was the sfr we just modified acc?
  if
    $e0 sfr@[EMAIL PROTECTED]
 ?parity        \ yes get value back and count its bits...
    $d0 sfr@[EMAIL PROTECTED]
 $fe and or     \ get psw and mask out old party set new
    $d0 recurse             \ omg did i just use recursion? wtf!
  then ;

\
------------------------------------------------------------------------
\ get state of one bit of psw

: psw@[EMAIL PROTECTED]
            ( mask --- 0 | 1 )
  $d0 sfr@[EMAIL PROTECTED]
                  \ get psw
  and 0<>                   \ mask requested bit convert bit to 0 or
-1
  1 and ;                   \ convert bit to 0 or 1  (could use abs
here)

\
------------------------------------------------------------------------
\ set state of one bit of psw

: psw!            ( state mask --- )
  dup>r not                 \ copy mask to rstack and invert mask
  $d0 sfr@[EMAIL PROTECTED]
 and              \ get psw and mask out specified bit
  swap r> swap              \ ( psw mask state --- )
  ?: or drop                \ set or clear bit ?
  $d0 sfr! ;                \ store result back in psw

\
------------------------------------------------------------------------
\ get or set specific bits in the psw

: cy@[EMAIL PROTECTED]
             ( --- bit ) $80 psw@[EMAIL PROTECTED]
 ;
: cy!             ( bit --- ) $80 psw! ;
: ac@[EMAIL PROTECTED]
             ( --- bit ) $40 psw@[EMAIL PROTECTED]
 ;
: ac!             ( bit --- ) $40 psw! ;
: ov@[EMAIL PROTECTED]
             ( --- bit ) $04 psw@[EMAIL PROTECTED]
 ;
: ov!             ( bit --- ) $04 psw! ;
: pt@[EMAIL PROTECTED]
             ( --- bit ) $01 psw@[EMAIL PROTECTED]
 ;
: pt!             ( bit --- ) $01 psw! ;

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

: set-cy          ( --- ) 1 cy! ;
: clr-cy          ( --- ) 0 cy! ;
: set-ac          ( --- ) 1 ac! ;
: clr-ac          ( --- ) 0 ac! ;
: set-ov          ( --- ) 1 ov! ;
: clr-ov          ( --- ) 0 ov! ;

\
------------------------------------------------------------------------
\ direct access can access iram or sfr depending on address specified

: direct@[EMAIL PROTECTED]
         ( a1 --- c1 ) dup $80 < ?: iram@[EMAIL PROTECTED]
 sfr@[EMAIL PROTECTED]
 ;
: direct!         ( c1 a1 --- ) dup $80 < ?: iram! sfr! ;

\
------------------------------------------------------------------------
\ convert bit number into a bit position

: bit>mask        ( bit# --- mask ) 1 swap << ;

\
------------------------------------------------------------------------
\ read one bit from a 'bit addressable' iram / sfr location

: bit@[EMAIL PROTECTED]
            ( bit-addr --- 0 | 1 )
  dup 7 and bit>mask        \ extract bit position from address
  swap $f8 and              \ extract get iram / sfr address
  direct@[EMAIL PROTECTED]
                   \ read the byte containing the requested
bit
  and 0<> 1 and ;           \ return bits state

\
------------------------------------------------------------------------
\ write one bit to a 'bit addressable' iram / sfr location

: bit!            ( bit bit-addr --- )
  tuck                      \ keep copy of bit address
  7 and                     \ extract bit number from bit address
  1 over << not >r          \ convert but number into a ~bit mask
  << r>                     \ ****ft bit value to set into position too
  rot dup $30 < $20 and
  swap $f8 and +
  dup>r                     \ convert bit address to byte address
  direct@[EMAIL PROTECTED]
 and or            \ read byte, mask out bit and write in new
val
  r> direct! ;              \ write byte back

\
------------------------------------------------------------------------
\ idkwtf opcode that was!

: noexec          ( --- ) decr> pc51 ;

\
------------------------------------------------------------------------
\ branch to specified offset from current pc

: branch          ( offset --- )
  8 << 8 >>                 \ convert 8 bit signed to 16 bit signed
  +!> pc51 ;                \ add signed offset to pc

\ "$80 and 0<> $ff00 and" would work too

\
------------------------------------------------------------------------
\ fetch and store to some specific common sfr's (not all are defined)

: acc@[EMAIL PROTECTED]
            ( --- c1 ) $e0 sfr@[EMAIL PROTECTED]
 ;
: acc!            ( c1 --- ) $e0 sfr! ;
: dpl@[EMAIL PROTECTED]
            ( --- c1 ) $82 sfr@[EMAIL PROTECTED]
 ;
: dpl!            ( c1 --- ) $82 sfr! ;
: dph@[EMAIL PROTECTED]
            ( --- c1 ) $83 sfr@[EMAIL PROTECTED]
 ;
: dph!            ( c1 --- ) $83 sfr! ;

\
------------------------------------------------------------------------
\ convert reg number into an iram address (based on current bank
setting)

: >reg            ( rn --- addr ) $18 psw@[EMAIL PROTECTED]
 + ;

\
------------------------------------------------------------------------
\ get or set value of specified register

: rn>             ( rn --- c1 ) >reg iram@[EMAIL PROTECTED]
 ;
: >rn             ( c1 rn --- ) >reg iram! ;

\
------------------------------------------------------------------------
\ add value c1 to a  (add in specified carry too )

: <add>           ( c1 carry --- )
  + acc@[EMAIL PROTECTED]
 2dup + acc!        \ add carry + c1 to acc ( c1 acc --- )

  2dup $f and swap $f and + \ test if addition generated an aux carry
  $f > ?: set-ac clr-ac
  2dup
  4 >> swap 4 >> swap +     \ test if addition generated a carry
  $f > ?: set-cy clr-cy

  2* <ff> swap 2* <ff> +    \ overflow set if carry generated out of
  $ff > cy@[EMAIL PROTECTED]
 0<> xor         \ bit 6 or out of bit 7 but not both
  ?: clr-ov set-ov ;

\
------------------------------------------------------------------------
\ subtract with specified borrow...

: <sub>           ( c1 carry )
  - acc@[EMAIL PROTECTED]
 2dup swap - acc!

  2dup $f and swap $f and -
  0 < ?: set-ac clr-ac
  2dup
  4 >> swap 4 >> swap -
  0 < ?: set-cy clr-cy

  $7f and swap $7f and -
  0 < cy@[EMAIL PROTECTED]
 0<> xor
  ?: clr-ov set-ov ;

\
------------------------------------------------------------------------
\ push or pop 8 or 16 bit values onto the stack

: push8           ( c1 --- ) $81 sfr@[EMAIL PROTECTED]
 1+ dup $81 sfr! iram! ;
: pop8            ( --- c1 ) $81 sfr@[EMAIL PROTECTED]
 dup 1- $81 sfr! iram@[EMAIL PROTECTED]
 ;
: push16          ( n1 --- ) split swap push8 push8 ;
: pop16           ( --- n1 ) pop8 8 << pop8 or ;

\
------------------------------------------------------------------------
\ get or set xram addressed by dptr

: dptr@[EMAIL PROTECTED]
           ( --- c1 ) dph@[EMAIL PROTECTED]
 8 << dpl@[EMAIL PROTECTED]
 + xram@[EMAIL PROTECTED]
 ;
: dptr!           ( c1 --- ) dph@[EMAIL PROTECTED]
 8 << dpl@[EMAIL PROTECTED]
 + xram! ;

\
------------------------------------------------------------------------
\ some actual opcode simulation...
\
------------------------------------------------------------------------

\
------------------------------------------------------------------------
\ a difficult one...

: nop             ( --- )  noop ;

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

: ljmp            ( --- )
  $@[EMAIL PROTECTED]
 8 <<                  \ fetch hi byte of target address
  $@[EMAIL PROTECTED]
 +                     \ fetch lo byte
  !> pc51 ;                 \ go there

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

: rr-a            ( --- )
  acc@[EMAIL PROTECTED]
 dup 7 <<             \ ****ft bit 0 of acc up to bit 7
  swap 2/ + <ff>            \ ****ft all other bits down and merge bits
  acc! ;                    \ and store back

\
------------------------------------------------------------------------
\ increnent a

: inc-a           ( --- )
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  1+ acc! ;                 \ increment it and put it back

\
------------------------------------------------------------------------
\ increment direct address (can also be acc :)

: inc-dir         ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but keep address
too
  1+ swap direct! ;         \ increment value and put it back in
addres

\
------------------------------------------------------------------------
\ opcodes in the form 0000 xxxx

: op0x            ( op-lo --- )
  case:
    $00 opt nop                                                \ 0000
0000
    $02 opt ljmp                                               \ 0000
0010
    $03 opt rr-a                                               \ 0000
0011
    $04 opt inc-a                                              \ 0000
0100
    $05 opt inc-dir                                            \ 0000
0101
  dflt
    noexec             \ this wont ever hapen but its here because its
  ;case ;              \ absense might raise questions :)

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

: jbc             ( --- )
  $@[EMAIL PROTECTED]
 dup bit@[EMAIL PROTECTED]
              \ get bit to be tested
  0 rot bit!                \ clear it
  $@[EMAIL PROTECTED]
 swap                  \ branch or dont branch to this offset
  ?: branch drop ;

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

: lcall           ( --- )
  pc51 2+ push16            \ save return address
  ljmp ;                    \ jump to target address

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

: rrc-a           ( --- )
  acc@[EMAIL PROTECTED]
 dup 1 and            \ get bit 0 of acc
  swap 2/                   \ ****ft all other bits down
  cy@[EMAIL PROTECTED]
 7 << +                \ get carry, ****ft it to bit 7 and merge
  acc! cy! ;                \ store bit 0 in carry

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

: dec-a           ( --- )
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  1- acc! ;                 \ decrement it and put it back

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

: dec-dir         ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
 1-            \ get contents and decrement it but keep
addr
  swap direct! ;            \ store result back in direct address

\
------------------------------------------------------------------------
\ opcodes in the form 0001 xxxx

: op1x            ( op-lo --- )
  case:
    $00 opt jbc                                                \ 0001
0000
    $02 opt lcall                                              \ 0001
0010
    $03 opt rrc-a                                              \ 0001
0011
    $04 opt dec-a                                              \ 0001
0100
    $05 opt dec-dir                                            \ 0001
0101
  dflt
    noexec
  ;case ;

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

: jb              ( --- )
  $@[EMAIL PROTECTED]
 bit@[EMAIL PROTECTED]
                  \ get contents of specified bit address
  $@[EMAIL PROTECTED]
 swap                  \ get branch target
  ?: branch drop ;          \ branch if bit set

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

: ret             ( --- )
  pop16                     \ pop 16 bits from stack
  !> pc51 ;                 \ pur in pc

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

: rl-a            ( --- )
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  dup $80 and 7 >>          \ ****ft bit 7 down to bit 0
  swap 2* +                 \ ****ft everything else up 21 bit
  <ff> acc! ;               \ store result back in acc

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

: add-a-#         ( --- )
  $@[EMAIL PROTECTED]
                       \ get immediate
  0 <add> ;                 \ add to acc

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

: add-a-dir       ( --- )
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  0 <add> ;                 \ add to acc

\
------------------------------------------------------------------------
\ opcodes in the form 0010 xxxx

: op2x            ( op-lo --- )
  case:
    $00 opt jb                                                 \ 0010
0000
    $02 opt ret                                                \ 0010
0010
    $03 opt rl-a                                               \ 0010
0011
    $04 opt add-a-#                                            \ 0010
0100
    $05 opt add-a-dir                                          \ 0010
0101
  dflt
    noexec
  ;case ;

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

: jnb-bit         ( --- )
  $@[EMAIL PROTECTED]
 bit@[EMAIL PROTECTED]
                  \ get state of bit to test
  $@[EMAIL PROTECTED]
 swap                  \ get branch offset
  ?: drop branch ;          \ branch or not

\
------------------------------------------------------------------------
\ this also affects interrupt logic: not implemented yet

: reti            ( --- )
  ret ;

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

: rlc-a           ( --- )
  acc@[EMAIL PROTECTED]
                      \ get acc contents
  dup $80 and               \ get bit 7 of acc
  swap 2* <ff>              \ ****ft acc left 1 bit
  cy@[EMAIL PROTECTED]
 + acc!                \ put carry in bit 0, store result
  7 >> cy! ;                \ put bit 7 of acc in cy

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

: addc-a-#        ( --- )
  $@[EMAIL PROTECTED]
                       \ get immediate
  cy@[EMAIL PROTECTED]
 <add> ;               \ add with carry

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

: addc-a-dir      ( --- )
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  cy@[EMAIL PROTECTED]
 <add> ;               \ add with carry

\
------------------------------------------------------------------------
\ opcodes in the form 0011 xxxx

: op3x            ( op-lo --- )
  case:
    $00 opt jnb-bit                                            \ 0011
0000
    $02 opt reti                                               \ 0011
0010
    $03 opt rlc-a                                              \ 0011
0011
    $04 opt addc-a-#                                           \ 0011
0100
    $05 opt addc-a-dir                                         \ 0011
0101
  dflt
    noexec
  ;case ;

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

: jc              ( --- )
  $@[EMAIL PROTECTED]
 cy@[EMAIL PROTECTED]
                   \ get branch target and state of carry
  ?: branch drop ;          \ branch or not

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

: orl-dir-a       ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but remember
address
  acc@[EMAIL PROTECTED]
 or                   \ or in value from acc
  swap direct! ;            \ store result back in direct address

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

: orl-dir-#       ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but remember
address
  $@[EMAIL PROTECTED]
 or                    \ get immediate and or it in
  swap direct! ;            \ store result back in direct address

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

: orl-a-#         ( --- )
  acc@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
                  \ get acc and immediate
  or acc! ;                 \ or together and store result in acc

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

: orl-a-dir       ( --- )
  acc@[EMAIL PROTECTED]
                      \ get acc
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  or acc! ;                 \ or togrther and store result back in acc

\
------------------------------------------------------------------------
\ opcodes in the form 0100 xxxx

: op4x            ( op-lo --- )
  case:
    $00 opt jc                                                 \ 0100
0000
    $02 opt orl-dir-a                                          \ 0100
0010
    $03 opt orl-dir-#                                          \ 0100
0011
    $04 opt orl-a-#                                            \ 0100
0100
    $05 opt orl-a-dir                                          \ 0100
0101
  dflt
    noexec
  ;case ;

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

: jnc             ( --- )
  $@[EMAIL PROTECTED]
 cy@[EMAIL PROTECTED]
                   \ get branch target acd state of carry
  ?: drop branch ;          \ dont branch or branch

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

: anl-dir-a       ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but keep address
too
  acc@[EMAIL PROTECTED]
 and                  \ and with acc
  swap direct! ;            \ store result back in direct address

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

: anl-dir-#       ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but keep address
too
  $@[EMAIL PROTECTED]
 and                   \ and this with immediate value
  swap direct! ;            \ store result back in direct address

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

: anl-a-#         ( --- )
  acc@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
                  \ get acc and immed
  and acc! ;                \ and together and store result back in
acc

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

: anl-a-dir       ( --- )
  acc@[EMAIL PROTECTED]
                      \ get acc
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  and acc! ;                \ and together and store result back in
acc

\
------------------------------------------------------------------------
\ opcodes in the form 0101 xxxx

: op5x            ( op-lo --- )
  case:
    $00 opt jnc                                                \ 0101
0000
    $02 opt anl-dir-a                                          \ 0101
0010
    $03 opt anl-dir-#                                          \ 0101
0011
    $04 opt anl-a-#                                            \ 0101
0100
    $05 opt anl-a-dir                                          \ 0101
0101
  dflt
    noexec
  ;case ;

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

: jz              ( --- )
  $@[EMAIL PROTECTED]
 acc@[EMAIL PROTECTED]
                  \ get branch target and acc
  ?: drop branch ;          \ branch if acc is zero

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

: xrl-dir-a       ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but keep address
too
  acc@[EMAIL PROTECTED]
 xor                  \ xor this with acc
  swap direct! ;            \ and store result back in direct address

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

: xrl-dir-#       ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but keep address
too
  $@[EMAIL PROTECTED]
 xor                   \ xor this with immediate
  swap direct! ;            \ store result back in direct address

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

: xrl-a-#         ( --- )
  acc@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
                  \ get acc and immediate
  xor acc! ;                \ xor together and store result back in
acc

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

: xrl-a-dir       ( --- )
  acc@[EMAIL PROTECTED]
                      \ get acc
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  xor acc! ;                \ xor together and store result back in
acc

\
------------------------------------------------------------------------
\ opcodes in the form 0110 xxxx

: op6x            ( op-lo -- )
  case:
    $00 opt jz                                                 \ 0110
0000
    $02 opt xrl-dir-a                                          \ 0110
0010
    $03 opt xrl-dir-#                                          \ 0110
0011
    $04 opt xrl-a-#                                            \ 0110
0100
    $05 opt xrl-a-dir                                          \ 0110
0101
  dflt
    noexec
  ;case ;

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

: jnz             ( --- )
  $@[EMAIL PROTECTED]
 acc@[EMAIL PROTECTED]
                  \ get branch targer and acc
  ?: branch drop ;          \ branch if acc is not zero

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

: orl-c-bit       ( --- )
  cy@[EMAIL PROTECTED]
                       \ get carry state
  $@[EMAIL PROTECTED]
 bit@[EMAIL PROTECTED]
                  \ get contents of specified bit address
  or cy! ;                  \ or these together and store result in cy

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

: jmp-a-dptr      ( --- )
  dph@[EMAIL PROTECTED]
 8 << dpl@[EMAIL PROTECTED]
 +          \ get 16 bits of dptr
  acc@[EMAIL PROTECTED]
 +                    \ add contents of acc to this value
  !> pc51 ;                 \ set new program counter address

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

: mov-a-#         ( --- )
  $@[EMAIL PROTECTED]
 acc! ;                \ get immediate and store in acc

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

: mov-dir-#       ( --- )
  $@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
                   \ get direct address and immediate value
  swap direct! ;            \ store immediate value in direct address

\
------------------------------------------------------------------------
\ opcodes in the form 0111 xxxx

: op7x            ( op-lo --- )
  case:
    $00 opt jnz                                                \ 0111
0000
    $02 opt orl-c-bit                                          \ 0111
0010
    $03 opt jmp-a-dptr                                         \ 0111
0011
    $04 opt mov-a-#                                            \ 0111
0100
    $05 opt mov-dir-#                                          \ 0111
0101
  dflt
    noexec
  ;case ;

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

: sjmp            ( --- )
  $@[EMAIL PROTECTED]
 branch ;              \ get branch target address and go there

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

: anl-c-bit       ( --- )
  cy@[EMAIL PROTECTED]
                       \ get carry state
  $@[EMAIL PROTECTED]
 bit@[EMAIL PROTECTED]
                  \ get contents of specified bit address
  and cy! ;                 \ and together and store result in cy

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

: movc-a-pc       ( --- )
  pc51 acc@[EMAIL PROTECTED]
 +               \ get pc, add acc contents to this value
  code@[EMAIL PROTECTED]
                     \ fetch data at this code space address
  acc! ;                    \ store result back in acc

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

: div-ab          ( --- )
  acc@[EMAIL PROTECTED]
                      \ get acc
  $f0 sfr@[EMAIL PROTECTED]
 dup 0=           \ get b. if b is zero..
  if
    1 ov! 2drop exit        \ set overflow and exit
  then
  clr-ov clr-cy             \ otherwise clear overflow and carry
  /mod acc! $f0 sfr! ;      \ divand save result

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

: mov-dir-dir     ( --- )
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of first direct address
  $@[EMAIL PROTECTED]
 direct! ;             \ store this in second direct address

\
------------------------------------------------------------------------
\ opcodes in the form 1000 xxxx

: op8x       ( op-lo --- )
  case:
    $00 opt sjmp                                               \ 1000
0000
    $02 opt anl-c-bit                                          \ 1000
0010
    $03 opt movc-a-pc                                          \ 1000
0011
    $04 opt div-ab                                             \ 1000
0100
    $05 opt mov-dir-dir                                        \ 1000
0101
  dflt
    noexec
  ;case ;

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

: mov-dptr-#      ( --- )
  $@[EMAIL PROTECTED]
 dph!                  \ get hi byte of immediate, put in dph
  $@[EMAIL PROTECTED]
 dpl! ;                \ get lo byte of immediate, put in dpl

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

: mov-bit-c       ( --- )
  cy@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
                   \ get current carry state and bit address
  bit! ;                    \ store cy in specified bit address

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

: movc-a-dptr     ( --- )
  dpl@[EMAIL PROTECTED]
 dph@[EMAIL PROTECTED]
 8 << +          \ get 16 bits of dptr
  acc@[EMAIL PROTECTED]
 +                    \ add in acc
  code@[EMAIL PROTECTED]
                     \ get contents of this code space address
  acc! ;                    \ put it in acc

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

: subb-a-#        ( --- )
  $@[EMAIL PROTECTED]
                       \ get immediate
  cy@[EMAIL PROTECTED]
 <sub> ;               \ subtract immediate from acc with borrow

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

: subb-a-dir      ( --- )
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  cy@[EMAIL PROTECTED]
 <sub> ;               \ subtract this from acc with borrow

\
------------------------------------------------------------------------
\ opcodes in the form 1001 xxxx

: op9x            ( op-lo --- )
  case:
    $00 opt mov-dptr-#                                         \ 1001
0000
    $02 opt mov-bit-c                                          \ 1001
0010
    $03 opt movc-a-dptr                                        \ 1001
0011
    $04 opt subb-a-#                                           \ 1001
0100
    $05 opt subb-a-dir                                         \ 1001
0101
  dflt
    noexec
  ;case ;

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

: orl-c-/bit      ( --- )
  $@[EMAIL PROTECTED]
 bit@[EMAIL PROTECTED]
 1 xor            \ get contents of specified bit and invert
it
  cy@[EMAIL PROTECTED]
 or cy! ;              \ or this with cy and store result in cy

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

: mov-c-bit       ( --- )
  $@[EMAIL PROTECTED]
 bit@[EMAIL PROTECTED]
                  \ get contents of specified bit address
  cy! ;                     \ store it in cy

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

: inc-dptr        ( --- )
  dpl@[EMAIL PROTECTED]
 1+ dup <ff> dpl!     \ add 1 to dpl
  $100 < ?exit              \ carry?
  dph@[EMAIL PROTECTED]
 1+ <ff> dph! ;       \ yes: add 1 to dph

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

: mul-ab          ( --- )
  acc@[EMAIL PROTECTED]
 $f0 sfr@[EMAIL PROTECTED]
 *           \ multiply a with b
  dup <ff> acc!             \ store lo 8 bits of result in acc
  dup 8 >> $f0 sfr!         \ store hi 8 bits of result in b
  clr-cy                    \ carry is always cleared but
  255 < ?exit               \ if product was greater than 255
  set-ov ;                  \ then set overflow

\
------------------------------------------------------------------------
\ opcodes in the form 1010 xxxx

: opax            ( op-lo --- )
  case:
    $00 opt orl-c-/bit                                         \ 1010
0000
    $02 opt mov-c-bit                                          \ 1010
0010
    $03 opt inc-dptr                                           \ 1010
0011
    $04 opt mul-ab                                             \ 1010
0100
    $05 opt noexec          \ $a5 not a legal opcode
  dflt
    noexec
  ;case ;

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

: anl-c-/bit      ( --- )
  cy@[EMAIL PROTECTED]
                       \ get current state of carry
  $@[EMAIL PROTECTED]
 bit@[EMAIL PROTECTED]
 1 xor            \ get contents of bit addrss and invert
  and cy! ;                 \ and with cy and store result in cy

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

: cpl-bit         ( --- )
  $@[EMAIL PROTECTED]
                       \ get specified bit address
  dup bit@[EMAIL PROTECTED]
                  \ get contents of address but keep address
too
  1 xor                     \ invert bit
  swap bit! ;               \ store result back in bit address

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

: cpl-c           ( --- )
  cy@[EMAIL PROTECTED]
                       \ get current state of cy
  1 xor                     \ invert it
  cy! ;                     \ store result back in cy

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

: (cjne)          ( c1 c2 --- )
  2dup <                    \ if c1 is less than c2 then
  ?: set-cy clr-cy          \ set cy. otherwise clear it
  = $@[EMAIL PROTECTED]
 swap                \ if c1 does not equal c2
  ?: drop branch ;          \ then branch.  otherwise dont

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

: cjne-a-#        ( --- )
  acc@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
                  \ get acc and immediate
  (cjne) ;                  \ branch or not, set or clear cy

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

: cjne-a-dir      ( --- )
  acc@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
          \ get acc and contents of direct address
  (cjne) ;                  \ branch or not, set or clear cy

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

: opbx            ( op-lo --- )
  case:
    $00 opt anl-c-/bit                                         \ 1011
0000
    $02 opt cpl-bit                                            \ 1011
0010
    $03 opt cpl-c                                              \ 1011
0011
    $04 opt cjne-a-#                                           \ 1011
0100
    $05 opt cjne-a-dir                                         \ 1011
0101
  dflt
    noexec
  ;case ;

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

: push-dir        ( --- )
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  push8 ;                   \ push it

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

: clr-bit         ( --- )
  0 $@[EMAIL PROTECTED]
                     \ get specified bit address
  bit! ;                    \ clear it

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

: clr-c           ( --- )
  clr-cy ;                  \ clear carry

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

: swap-a          ( --- )
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  dup 4 <<                  \ ****ft lo nibble up
  swap 4 >> or              \ ****ft hi nibble down
  acc! ;                    \ store result back in acc

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

: xch-a-dir       ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but keep address
too
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  swap acc!                 \ store contents of direct address in acc
  swap direct! ;            \ store contents of acc in direct address

\
------------------------------------------------------------------------
\ opcodes in the form 1100 xxxx

: opcx            ( op-lo --- )
  case:
    $00 opt push-dir                                          \ 1100
0000
    $02 opt clr-bit                                           \ 1100
0010
    $03 opt clr-c                                             \ 1100
0011
    $04 opt swap-a                                            \ 1100
0100
    $05 opt xch-a-dir                                         \ 1100
0101
  dflt
    noexec
  ;case ;

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

: pop-dir         ( --- )
  pop8                      \ pop one 8 bit item
  $@[EMAIL PROTECTED]
                       \ get specified direct address
  direct! ;                 \ store popped item in address

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

: setb-bit        ( --- )
  1 $@[EMAIL PROTECTED]
                     \ get specified bit address
  bit! ;                    \ set it

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

: setb-c          ( --- )
  set-cy ;                  \ set carry

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

: da-a            ( --- )
  acc@[EMAIL PROTECTED]
 dup>r                \ get contents of acc
  $f and 9 > ac@[EMAIL PROTECTED]
 or         \ if lower nibble is > 9 or aux carry is
set
  0<> 6 and r> + >r         \ then add 6 to acc
  r> $f0 and $90 > cy@[EMAIL PROTECTED]
 or   \ if hi nibble of acc is > 9 or carry is
set
  0<> $60 and +             \ add 6 to high nibble
  acc! ;                    \ store result back in acc

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

: djnz-dir        ( --- )
  $@[EMAIL PROTECTED]
                       \ get direct address
  dup direct@[EMAIL PROTECTED]
               \ get contents of address but keep address
too
  1- tuck                   \ decrement it by 1 and make copy of
result
  swap direct!              \ store result back in direct address
  $@[EMAIL PROTECTED]
 swap                  \ get branch target
  ?: branch drop ;          \ branch if result was not zero

\
------------------------------------------------------------------------
\ opcodes in the form 1101 xxxx

: opdx            ( op-lo --- )
  case:
    $00 opt pop-dir                                            \ 1101
0000
    $02 opt setb-bit                                           \ 1101
0010
    $03 opt setb-c                                             \ 1101
0011
    $04 opt da-a                                               \ 1101
0100
    $05 opt djnz-dir                                           \ 1101
0101
  dflt
    noexec
  ;case ;

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

: movx-a-dptr     ( --- )
  dph@[EMAIL PROTECTED]
 8 << dpl@[EMAIL PROTECTED]
 +          \ get 16 bit dptr address
  xram@[EMAIL PROTECTED]
 acc! ;              \ fetch contents of xram and put in acc

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

: clr-a           ( --- )
  0 acc! ;                  \ clear acc

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

: mov-a-dir       ( --- )
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  acc! ;                    \ put this data in acc

\
------------------------------------------------------------------------
\ opcodes in the form 1110 xxxx

: opex            ( op-lo --- )
  case:
    $00 opt movx-a-dptr                                        \ 1110
0000
    $02 opt noexec          \ movx a, @[EMAIL PROTECTED]
    $03 opt noexec          \ movx a, @[EMAIL PROTECTED]
    $04 opt clr-a                                              \ 1110
0100
    $05 opt mov-a-dir                                          \ 1110
0101
  dflt
    noexec
  ;case ;

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

: movx-dptr-a     ( --- )
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  dph@[EMAIL PROTECTED]
 8 << dpl@[EMAIL PROTECTED]
 +          \ get 16 but dptr address
  xram! ;                   \ store acc at xram pointed to by dptr

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

: cpl-a           ( --- )
  acc@[EMAIL PROTECTED]
 $ff xor              \ get acc and invert it
  acc! ;                    \ store result back in acc

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

: mov-dir-a       ( --- )
  acc@[EMAIL PROTECTED]
 $@[EMAIL PROTECTED]
                  \ get acc and direct address
  direct! ;                 \ store acc in direct address

\
------------------------------------------------------------------------
\ opcodes in the form 1111 xxxx

: opfx            ( op-lo --- )
  case:
    $00 opt movx-dptr-a                                        \ 1111
0000
    $02 opt noexec          \ movx @[EMAIL PROTECTED]
 a
    $03 opt noexec          \ movx @[EMAIL PROTECTED]
 a
    $04 opt cpl-a                                              \ 1111
0100
    $05 opt mov-dir-a                                          \ 1111
0101
  dflt
    noexec
  ;case ;

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

: inc-rn          ( rn --- )
  dup                       \ remember which register were messing
with
  rn> 1+ <ff>               \ get reg contents and increment it
  swap >rn ;                \ store result back in register

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

: dec-rn          ( rn --- )
  dup                       \ remember which register were messing
with
  rn> 1- <ff>               \ get contents of register and decrement
it
  swap >rn ;                \ store result back in register

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

: add-a-rn        ( rn --- )
  rn>                       \ get contents of register
  0 <add> ;                 \ add it to acc

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

: addc-a-rn       ( rn --- )
  rn>                       \ get contents of register
  cy@[EMAIL PROTECTED]
 <add> ;               \ add it to acc with carry

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

: orl-a-rn        ( rn --- )
  rn> acc@[EMAIL PROTECTED]
                  \ get contents of register and acc
  or acc! ;                 \ or together and store result back in acc

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

: anl-a-rn        ( rn --- )
  rn> acc@[EMAIL PROTECTED]
                  \ get contents of register and acc
  and acc! ;                \ and together and store result back in
acc

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

: xrl-a-rn        ( rn --- )
  rn> acc@[EMAIL PROTECTED]
                  \ get contents of register and acc
  xor acc! ;                \ cor together and store result back in
acc

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

: mov-rn-#        ( rn --- )
  $@[EMAIL PROTECTED]
                       \ get immediate value
  swap >rn ;                \ store in specified register

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

: mov-dir-rn      ( rn --- )
  rn> $@[EMAIL PROTECTED]
                   \ get register and direct address
  direct! ;                 \ store register in direct address

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

: subb-a-rn       ( rn --- )
  rn>                       \ get contents of specified register
  cy@[EMAIL PROTECTED]
 <sub> ;               \ subtract this from acc with borrow

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

: mov-rn-dir      ( rn --- )
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of specified direct address
  swap >rn ;                \ store in specified register

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

: cjne-rn-#       ( rn --- )
  rn> $@[EMAIL PROTECTED]
                   \ get contents of rn and immediate
  (cjne) ;                  \ branch or not, set or clear cy

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

: xch-a-rn        ( rn --- )
  dup                       \ remember which registe were messing with
  rn> acc@[EMAIL PROTECTED]
                  \ get contents of register and of acc
  swap acc!                 \ store contents of reg in acc
  swap >rn ;                \ store acc in specified register

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

: djnz-rn         ( rn --- )
  dup                       \ remember which registe were messing with
  rn> 1-                    \ fetch its contents and decrement it
  tuck swap >rn             \ keep copy of result but store back in
reg
  $@[EMAIL PROTECTED]
 swap                  \ get branch target
  ?: branch drop ;          \ branch if result was not zero

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

: mov-a-rn        ( rn --- )
  rn> acc! ;                \ get contents of register, store in acc

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

: mov-rn-a        ( rn --- )
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  swap >rn ;                \ store in specified register

\
------------------------------------------------------------------------
\ execute opcodes that act on rn

: op-rn?          ( op-hi op-lo --- )
  dup $8 and 8 <> ?exit
  7 and swap r>drop
  exec:
    inc-rn                                                    \ 0000
1rrr
    dec-rn                                                    \ 0001
1rrr
    add-a-rn                                                  \ 0010
1rrr
    addc-a-rn                                                 \ 0011
1rrr
    orl-a-rn                                                  \ 0100
1rrr
    anl-a-rn                                                  \ 0101
1rrr
    xrl-a-rn                                                  \ 0110
1rrr
    mov-rn-#                                                  \ 0111
1rrr
    mov-dir-rn                                                \ 1000
1rrr
    subb-a-rn                                                 \ 1001
1rrr
    mov-rn-dir                                                \ 1010
1rrr
    cjne-rn-#                                                 \ 1011
1rrr
    xch-a-rn                                                  \ 1100
1rrr
    djnz-rn                                                   \ 1101
1rrr
    mov-a-rn                                                  \ 1110
1rrr
    mov-rn-a ;                                                \ 1111
1rrr

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

: inc-@[EMAIL PROTECTED]
         ( ri --- )
  rn>                       \ get contents of specified register
  dup iram@[EMAIL PROTECTED]
                 \ get contents of iram address it points
to
  1+ <ff>                   \ increment contents of address
  swap iram! ;

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

: dec-@[EMAIL PROTECTED]
         ( ri --- )
  rn>                       \ get contents of specified register
  dup iram@[EMAIL PROTECTED]
                 \ get contents of iram address it points
to
  1- <ff>                   \ decrement contents of address
  swap iram! ;

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

: add-a-@[EMAIL PROTECTED]
       ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by
reg
  0 <add> ;                 \ add this to acc

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

: addc-a-@[EMAIL PROTECTED]
      ( ri --- )
  rn> dup                   \ get contents of address pointed to by
reg
  cy@[EMAIL PROTECTED]
 <add> ;               \ add this to acc with carry

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

: orl-a-@[EMAIL PROTECTED]
       ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by
reg
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  or acc! ;                 \ or together and store result back in acc

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

: anl-a-@[EMAIL PROTECTED]
       ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by
reg
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  and acc! ;                \ and togehter and store result back in
acc

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

: xrl-a-@[EMAIL PROTECTED]
       ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by
reg
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  xor acc! ;                \ xor together and store result back in
acc

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

: mov-@[EMAIL PROTECTED]
       ( ri --- )
  rn> $@[EMAIL PROTECTED]
                   \ get contents of specified reg and
immediate
  swap iram! ;              \ store immediate in address pointed to by
reg

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

: mov-dir-@[EMAIL PROTECTED]
     ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by
reg
  $@[EMAIL PROTECTED]
                       \ get direct address
  direct! ;                 \ store reg in direct address

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

: subb-a-@[EMAIL PROTECTED]
      ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by
reg
  cy@[EMAIL PROTECTED]
 <sub> ;               \ subtract this from acc

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

: mov-@[EMAIL PROTECTED]
     ( ri --- )
  rn>                       \ get contents of specified register
  $@[EMAIL PROTECTED]
 direct@[EMAIL PROTECTED]
               \ get contents of direct address
  swap iram! ;              \ store direct data in addr pointed to by
reg

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

: cjne-@[EMAIL PROTECTED]
      ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by ri
  $@[EMAIL PROTECTED]
                       \ get immediate value
  (cjne) ;                  \ branch or not, set or clear cy

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

: xch-a-@[EMAIL PROTECTED]
       ( ri --- )
  rn>                       \ get contents specified register (an
addr)
  dup iram@[EMAIL PROTECTED]
                 \ get contents of this addr but keep addr
too
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  swap acc!                 \ store contents of addr in acc
  swap iram! ;              \ store acc in addr

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

: (-xchd)         ( c1 acc --- c1' acc' )
  2dup swap                 \ ( c1 acc acc c1 --- )
  $f0 and swap              \ get c1-hi-acc-lo == c1'
  $f and or -rot
  $f0 and swap $f and or ;  \ get acc-hi-c1-lo == acc'

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

: xchd-a-@[EMAIL PROTECTED]
      ( ri --- )
  rn>                       \ get specified reg
  dup iram@[EMAIL PROTECTED]
                 \ get contents of addr it points, keep
addr
  acc@[EMAIL PROTECTED]
                      \ get contents of acc too
  (-xchd)                   \ exchange lo nibbles of both items
  swap acc!                 \ store new acc
  swap iram! ;              \ and new contents of address

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

: mov-a-@[EMAIL PROTECTED]
       ( ri --- )
  rn> iram@[EMAIL PROTECTED]
                 \ get contents of address pointed to by
reg
  acc! ;                    \ store in acc

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

: mov-@[EMAIL PROTECTED]
       ( ri --- )
  acc@[EMAIL PROTECTED]
                      \ get contents of acc
  swap rn>                  \ get contents of specified register
  iram! ;                   \ store acc in iram addr pointed to by reg

\
------------------------------------------------------------------------
\ execute opcodes that act on @[EMAIL PROTECTED]
 (indirect)

: op-@[EMAIL PROTECTED]
         ( op-hi op-lo --- )
  dup $e and 6 <> ?exit
  1 and swap r>drop
  exec:
    inc-@[EMAIL PROTECTED]
                                                    \ 0000
011i
    dec-@[EMAIL PROTECTED]
                                                    \ 0001
011i
    add-a-@[EMAIL PROTECTED]
                                                  \ 0010
011i
    addc-a-@[EMAIL PROTECTED]
                                                 \ 0011
011i
    orl-a-@[EMAIL PROTECTED]
                                                  \ 0100
011i
    anl-a-@[EMAIL PROTECTED]
                                                  \ 0101
011i
    xrl-a-@[EMAIL PROTECTED]
                                                  \ 0110
011i
    mov-@[EMAIL PROTECTED]
                                                  \ 0111
011i
    mov-dir-@[EMAIL PROTECTED]
                                                \ 1000
011i
    subb-a-@[EMAIL PROTECTED]
                                                 \ 1001
011i
    mov-@[EMAIL PROTECTED]
                                                \ 1010
011i
    cjne-@[EMAIL PROTECTED]
                                                 \ 1011
011i
    xch-a-@[EMAIL PROTECTED]
                                                  \ 1100
011i
    xchd-a-@[EMAIL PROTECTED]
                                                 \ 1101
011i
    mov-a-@[EMAIL PROTECTED]
                                                  \ 1110
011i
    mov-@[EMAIL PROTECTED]
 ;                                                \ 1111
011i

\
------------------------------------------------------------------------
\ cancluate target address of an ajmp or acall

: >ajmp           ( op --- addr )
  $e and 7 <<               \ bits 8, 9 and 10 of target address
  pc51 1+ $f800 and +       \ bits 11 to 15
  $@[EMAIL PROTECTED]
 + ;                   \ second byte of opcode = lower 8 bits of
addr

\
------------------------------------------------------------------------
\ is 8 bit opcode at tos an ajmp ?

: ajmp?           ( op-hi op-lo op --- )
  dup $1f and 1 <> ?exit
  2drop >ajmp !> pc51
  r>drop ;

\
------------------------------------------------------------------------
\ is 8 bit opcode at tos an acall?

: acall?          ( op-hi op-lo op --- )
  dup $1f and $11 <> ?exit
  2drop pc51 1+ push16
  >ajmp !> pc51
  r>drop ;

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

: movx-@[EMAIL PROTECTED]
      ( op-hi op-lo op --- )
  nip nip                   \ discard op lo and hi nibbles
  1 and                     \ extract ri from opcode
  rn>                       \ get contents of reg          = addr lo
byte
  $a0 sfr@[EMAIL PROTECTED]
 8 << +           \ get contents of ****t 2 latch = addr hi
byte
  acc@[EMAIL PROTECTED]
 swap xram! ;         \ store acc in this xram address

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

: movx-a-@[EMAIL PROTECTED]
      ( op-hi op-lo op --- )
  nip nip                   \ discard op lo and hi nibbles
  1 and                     \ extract ri from opcode
  $a0 sfr@[EMAIL PROTECTED]
 8 << +           \ get contents of ****t 2 latch = addr hi
byte
  xram@[EMAIL PROTECTED]
                     \ get contents of this xram address
  acc! ;                    \ store in acc

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

: movx-ri?        ( op-hi op-lo op --- )
  dup $fe and               \ mask opcode for testing it for...
  case:
    $f2 opt movx-@[EMAIL PROTECTED]
    $e2 opt movx-a-@[EMAIL PROTECTED]
  dflt
    exit                    \ none of the above, return
  ;case
  r>drop ;                  \ executed opcode, search no further

\
------------------------------------------------------------------------
\ simulate one 8051 instruction

: sim51           ( --- )
  $@[EMAIL PROTECTED]
                       \ get next opcode
  dup                       \ keep whole opcode intact for now
  dup                       \ split this into hi and lo nibbles as
follows
  4 u>>                     \ hi nibble of opcode
  swap $0f and              \ lo nibble of opcode
  rot                       \ bring full opcode back to the top

  ( hi lo op --- )      \ none of these next 5 return if a match is
found

  ajmp?                     \ acall or ajmp ?
  acall?
  movx-ri? drop             \ movx a,@[EMAIL PROTECTED]
 or movx @[EMAIL PROTECTED]
  op-rn?                    \ xxxx 1xxx opcode?
  op-@[EMAIL PROTECTED]
                   \ xxxx 011x opcode?

  ( hi lo --- )

  swap exec:                \ chose decoder based on hi byte of opcode
    op0x op1x op2x op3x op4x op5x op6x op7x
    op8x op9x opax opbx opcx opdx opex opfx ;

\
=======================================================================
 




 1 Posts in Topic:
8051 simulation..
mark4 <i440r@[EMAIL PR  2008-02-11 21:53:10 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Wed Jul 9 5:48:23 CDT 2008.