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 ;
\
=======================================================================


|