[OpenBIOS] r472 - cpu/i8051

svn at openbios.org svn at openbios.org
Wed Jul 18 07:09:39 CEST 2007


Author: wmb
Date: 2007-07-18 07:09:39 +0200 (Wed, 18 Jul 2007)
New Revision: 472

Added:
   cpu/i8051/assem.fth
Log:
Initial revision


Added: cpu/i8051/assem.fth
===================================================================
--- cpu/i8051/assem.fth	                        (rev 0)
+++ cpu/i8051/assem.fth	2007-07-18 05:09:39 UTC (rev 472)
@@ -0,0 +1,471 @@
+
+vocabulary 8051-assembler
+: assembler  8051-assembler  ;
+assembler also definitions
+
+defer asm8@	 also forth ' c@    previous   is asm8@
+defer asm8!	 also forth ' c!    previous   is asm8!
+defer here	 also forth ' here  previous   is here
+defer asm-allot	 also forth ' allot previous   is asm-allot
+
+\ append values to the end of a code definition which is being built.
+\ always little-endian:
+: asm8,   ( n -- )  here 1 asm-allot asm8!  ;
+
+d# -1 constant #
+d# -2 constant @R0
+d# -3 constant @R1
+d# -4 constant R7
+d# -5 constant R6
+d# -6 constant R5
+d# -7 constant R4
+d# -8 constant R3
+d# -9 constant R2
+d# -10 constant R1
+d# -11 constant R0
+d# -12 constant A
+
+\ Port bits
+: bitnum:  create , does> @ +  ;
+8 0 do  i bitnum:  loop   .0 .1 .2 .3 .4 .5 .6 .7
+
+\ SFRs
+h# 80 constant p0
+h# 81 constant sp
+h# 82 constant dpl
+h# 83 constant dph
+h# 87 constant pcon
+h# 88 constant tcon
+h# 89 constant tmod
+h# 8a constant tl0
+h# 8b constant tl1
+h# 8c constant th0
+h# 8d constant th1
+h# 90 constant p1
+h# 98 constant scon
+h# 99 constant sbuf \ not bit-addressable
+h# a0 constant p2
+h# a8 constant ie
+h# b0 constant p3
+h# b8 constant ip
+h# d0 constant psw
+h# e0 constant acc
+h# f0 constant b
+
+\ KB3700 extensions/changes
+h# 80 constant p0ie  \ Bits enable corresponding interrupt
+h# 86 constant pcon2 \ Various, see KB3700 manual (page 35)
+h# 90 constant p1ie  \ Bits enable corresponding interrupt
+h# 9a constant scon2 \ Extended baud rate divisor, low byte
+h# 9b constant scon3 \ Extended baud rate divisor, high byte
+h# b0 constant p3ie  \ Bits enable corresponding interrupt 
+h# d8 constant p0if  \ Bits report corresponding interrupt status
+h# e8 constant p1if  \ Bits report corresponding interrupt status
+h# f8 constant p3if  \ Bits report corresponding interrupt status
+
+
+: acall  ( adr -- )     \ ppp1.0001 llll.llll
+   \ XXX check that adr matches high 5 bits of PC
+   h# 7ff and  wbsplit        ( low high )
+   5 lshift  h# 11 or  asm8,  ( low )
+   asm8,
+;
+: ajmp  ( adr -- )     \ ppp1.0001 llll.llll
+   \ XXX check that adr matches high 5 bits of PC
+   h# 7ff and  wbsplit        ( low high )
+   5 lshift  h# 01 or  asm8,  ( low )
+   asm8,
+;
+
+: iram,  ( n -- )
+   dup h# ff >  abort" IRAM address too large"
+   asm8,
+;
+
+: immed,  ( n -- )
+   dup h# ff >  abort" Immediate value too large"
+   asm8,
+;
+: byte-offset?  ( offset -- flag )  h# -80 h# 7f between  ;
+: rel!  ( to from -- )
+   tuck  -    ( from offset )
+   dup byte-offset? 0= abort" Bad branch offset"
+   swap asm8!
+;
+: rel,  ( n -- )  here rel!  1 asm-allot  ;
+
+: add  ( n [ # or @ ] -- )
+   dup #  =  if  drop h# 24 asm8,  immed,  exit  then
+
+   dup @R0  =  if  drop h# 26 asm8,  exit  then
+   dup @R1  =  if  drop h# 27 asm8,  exit  then
+   dup R0 R7 between  if  R0 -  h# 28 + asm8,  exit  then
+
+   h# 25 asm8,  iram,
+;
+
+: addc  ( n [ # or @ ] -- )
+   dup #  =  if  drop h# 34 asm8,  immed,  exit  then
+
+   dup @R0  =  if  drop h# 36 asm8,  exit  then
+   dup @R1  =  if  drop h# 37 asm8,  exit  then
+   dup R0 R7 between  if  R0 -  h# 38 + asm8,  exit  then
+
+   h# 35 asm8,  iram,
+;
+
+: subb  ( n # | n | @Rn | Rn ] -- )
+   dup #  =  if  drop   h# 94 asm8,  immed, exit  then
+
+   dup @R0  =  if  drop h# 96 asm8,  exit  then
+   dup @R1  =  if  drop h# 97 asm8,  exit  then
+   dup R0 R7 between  if  R0 -  h# 98 + asm8,  exit  then
+
+   h# 95 asm8,  iram,
+;
+
+: anl  ( n # | n | @Rn | Rn ] -- )
+   dup #  =  if  drop  h# 54 asm8,  immed,  exit  then
+
+   dup @R0  =  if  drop h# 56 asm8,  exit  then
+   dup @R1  =  if  drop h# 57 asm8,  exit  then
+   dup R0 R7 between  if  R0 -  h# 58 + asm8,  exit  then
+   h# 55 asm8,  iram,
+;
+
+: anlr  ( iram -- )  h# 52 asm8,  asm8,  ;
+: anli  ( data iram -- )  h# 53 asm8,  asm8,  asm8,  ;  \ ANL iramadr,#data
+: anlc  ( bit-addr -- )  h# 82 asm8, asm8, asm8,  ;
+: anlc/ ( bit-addr -- )  h# b0 asm8, asm8, asm8,  ;
+
+: orl  ( n # | n | @Rn | Rn ] -- )
+   dup #  =  if  drop  h# 44 asm8,  immed,  exit  then
+
+   dup @R0  =  if  drop h# 46 asm8,  exit  then
+   dup @R1  =  if  drop h# 47 asm8,  exit  then
+   dup R0 R7 between  if  R0 -  h# 48 + asm8,  exit  then
+
+   h# 45 asm8,  iram,
+;
+
+: orlr  ( iram -- )  h# 42 asm8,  asm8,  ;
+: orli  ( data iram -- )  h# 43 asm8,  asm8,  asm8,  ;  \ ANL iramadr,#data
+: orlc  ( bit-addr -- )  h# 72 asm8, asm8, asm8,  ;
+: orlc/ ( bit-addr -- )  h# a0 asm8, asm8, asm8,  ;
+
+: xrli  ( data iram -- )  h# 63 asm8,  asm8,  asm8,  ;  \ XRL iramadr,#data
+: xrl  ( n # | n | @Rn | Rn ] -- )
+   dup #  =  if  drop  h# 64 asm8,  immed,  exit  then
+
+   dup @R0  =  if  drop h# 66 asm8,  exit  then
+   dup @R1  =  if  drop h# 67 asm8,  exit  then
+
+   dup R0 R7 between  if  R0 -  h# 68 + asm8,  exit  then
+
+   h# 65 asm8,  iram,
+;
+
+: mov  ( ? -- )   \ a,src
+   dup #  =  if  drop  h# 74 asm8,  immed,  exit  then
+
+   dup @R0  =  if  drop h# e6 asm8,  exit  then
+   dup @R1  =  if  drop h# e7 asm8,  exit  then
+
+   dup R0 R7 between  if  R0 -  h# e8 + asm8,  exit  then
+
+   h# e5 asm8,  iram,
+;
+
+: movr  ( ? -- )  \ dst,a
+   dup @R0  =  if  drop h# f6 asm8,  exit  then
+   dup @R1  =  if  drop h# f7 asm8,  exit  then
+
+   dup R0 R7 between  if  R0 -  h# f8 + asm8,  exit  then
+
+   h# f5 asm8,  iram,
+;
+
+: movc  ( bit -- )  h# a2 asm8,  asm8,  ;
+
+: movi  ( data ea -- )  \ ea,#data
+   dup @R0  =  if  drop h# 76 asm8,  immed,  exit  then
+   dup @R1  =  if  drop h# 77 asm8,  immed,  exit  then
+
+   dup R0 R7 between  if  R0 -  h# 78 + asm8,  immed, exit  then
+   h# 75 asm8,  iram,  immed,
+;
+
+: mov_to_iram  ( ea iram -- )  \ iram,ea
+   swap
+   dup @R0  =  if  drop h# 86 asm8,  iram,  exit  then
+   dup @R1  =  if  drop h# 87 asm8,  iram,  exit  then
+
+   dup R0 R7 between  if  R0 -  h# 88 + asm8,  iram, exit  then
+   h# 85 asm8,  iram,  iram,
+;
+
+: mov_from_iram  ( iram ea -- )  \ ea,iram
+   dup @R0  =  if  drop h# a6 asm8,  iram,  exit  then
+   dup @R1  =  if  drop h# a7 asm8,  iram,  exit  then
+
+   dup R0 R7 between  if  R0 -  h# a8 + asm8,  iram, exit  then
+   drop true abort" illegal addressing mode"
+;
+
+: xchg  ( n | @Rn | Rn ] -- )
+   dup @R0  =  if  drop h# c6 asm8,  exit  then
+   dup @R1  =  if  drop h# c7 asm8,  exit  then
+
+   dup R0 R7 between  if  R0 -  h# c8 + asm8,  exit  then
+
+   h# c5 asm8,  iram,
+;
+
+: dec  ( n | A | @Rn | Rn ] -- )
+   dup A =  if  drop   h# 14 asm8,  exit  then
+
+   dup @R0  =  if  drop h# 16 asm8,  exit  then
+   dup @R1  =  if  drop h# 17 asm8,  exit  then
+   dup R0 R7 between  if  R0 -  h# 18 + asm8,  exit  then
+
+   h# 15 asm8,  iram,
+;
+
+: djnz  ( adr n | @Rn | Rn ] -- )
+   dup R0 R7 between  if  R0 -  h# d8 + asm8, rel,  exit  then
+
+   h# d5 asm8,  iram,  rel,
+;
+
+: inc  ( n | A | @Rn | Rn ] -- )
+   dup A =  if  drop   h# 04 asm8,  exit  then
+
+   dup @R0  =  if  drop h# 06 asm8,  exit  then
+   dup @R1  =  if  drop h# 07 asm8,  exit  then
+   dup R0 R7 between  if  R0 -  h# 08 + asm8,  exit  then
+
+   h# 05 asm8,  iram,
+;
+
+: orlr  ( iram -- )  h# 62 asm8,  asm8,  ;
+: orli  ( data iram -- )  h# 63 asm8,  asm8,  asm8,  ;  \ ANL iramadr,#data
+
+: cjne  ( adr n # | n | @Rn | Rn ] -- )
+   dup #  =  if  drop  h# b4 asm8, immed, rel,  exit  then
+
+   dup @R0  =  if  drop h# b6 asm8,  rel, exit  then
+   dup @R1  =  if  drop h# b7 asm8,  rel, exit  then
+
+   dup R0 R7 between  if  R0 -  h# b8 + asm8,  rel, exit  then
+
+   h# b5 asm8,  iram,  rel,
+;
+
+: cpl   ( bit -- )  h# b2 asm8, asm8,  ;
+: clr   ( bit -- )  h# c2 asm8, asm8,  ;
+: setb  ( bit -- )  h# d2 asm8, asm8,  ;
+: jc    ( reladdr -- )  h# 40 asm8, rel,  ;
+: jnc   ( reladdr -- )  h# 50 asm8, rel,  ;
+: jz    ( reladdr -- )  h# 60 asm8, rel,  ;
+: jnz   ( reladdr -- )  h# 70 asm8, rel,  ;
+: sjmp  ( reladdr -- )  h# 80 asm8, rel,  ;
+: jb    ( reladdr bit -- )  h# 20 asm8, asm8, rel,  ;
+: jbc   ( reladdr bit -- )  h# 10 asm8, asm8, rel,  ;
+: jnb   ( reladdr bit -- )  h# 30 asm8, asm8, rel,  ;
+
+: 1mi  create c, does> c@ asm8, ;
+
+h# d6 1mi xchd_a, at R0
+h# d7 1mi xchd_a, at R1
+
+h# 00 1mi nop
+
+h# 22 1mi ret
+h# 32 1mi reti
+
+h# 03 1mi rr
+h# 13 1mi rrc
+h# 23 1mi rl
+h# 33 1mi rlc
+h# 73 1mi jmp at a+dptr
+h# a3 1mi incdptr
+h# b3 1mi cplc
+h# c3 1mi clrc
+h# d3 1mi setbc
+
+h# 84 1mi div
+h# a4 1mi mulab
+h# c4 1mi swapa
+h# d4 1mi da
+h# e4 1mi clra
+h# f4 1mi cpla
+
+h# e0 1mi movx_a, at dptr
+h# e2 1mi movx_a, at r0
+h# e3 1mi movx_a, at r1
+h# f0 1mi movx_ at dptr,a
+h# f2 1mi movx_ at r0,a
+h# f3 1mi movx_ at r1,a
+h# 83 1mi movc_a, at a+pc
+h# 93 1mi movc_a, at a+dptr
+
+: ladr,  ( adr -- )  wbsplit asm8, asm8,  ;
+: ljmp  ( adr -- )  h# 02 asm8, ladr,  ;
+: lcall ( adr -- )  h# 12 asm8, ladr,  ;
+
+: push ( iram -- )  h# c0 asm8, iram,  ;
+: pop  ( iram -- )  h# d0 asm8, iram,  ;
+
+: xjmp  ( adr -- )
+   dup here -  byte-offset?  if  sjmp  else  ljmp  then
+;
+: xcall  ( adr -- )
+   dup  here 2+  xor h# f800 and  ( adr page-different? )
+   if  lcall  else  acall  then   ( adr )
+;
+: put-ljmp  ( to from -- )
+   >r
+   h# 12 r@ asm8!   ( to r: from )
+   wbsplit          ( to.lo to.hi r: from )
+   r@ 1+ asm8!      ( to.lo r: from )
+   r> 2+ asm8!      ( )
+;
+
+hex
+
+h# 10 constant bit-set?&clr \ JBC
+h# 20 constant bit-clr?     \ JB
+h# 30 constant bit-set?     \ JNB
+h# 40 constant no-carry?    \ JC
+h# 50 constant carry?       \ JNC
+h# 60 constant 0<>          \ JZ
+h# 70 constant 0=           \ JNZ
+
+: put-cond ( [ bit# ] cond -- )
+   dup asm8,                 \ Conditional branch
+   h# 40 <  if  asm8,  then  \ Include bit# if necessary
+;
+
+\ >mark must return the address of the opcode, not the address
+\ of the offset, in order for loclabel.fth to work.
+: >mark  ( -- from )  here  ;
+: >resolve  ( from -- )
+   dup asm8@ h# 40 <  if  2+  else  1+  then  \ Skip opcode [ and bit# ]
+   here  swap  rel!
+;
+: <mark  ( -- to )  here  ;
+: <resolve  ( from -- )  here  rel!  ;
+
+: but  ( mark1 mark1 -- mark2 mark1 )  swap  ;
+: yet  ( mark -- mark mark )  dup  ;
+
+\ Assemble DJNZ in either Rn or direct form
+: ,loop  ( to [ iram | reg ] -- )     
+   dup R0 R7 between  if    ( to reg )
+      R0 -  h# d8 +  asm8,  ( to )      \ 2-byte Rn form
+   else                     ( to iram )
+      h# d5 asm8,  asm8,    ( to iram ) \ 3-byte direct form
+   then                     ( to )
+   <resolve
+;
+
+\ After we start redefining control structure words, we have to be
+\ careful not to use them with the expectation of their Forth meanings.
+: if     ( [ bit# ] cond -- from )  >mark >r   put-cond  0 asm8,  r>  ;
+: until  ( to [ bit# ] cond -- )  h# 10 xor  put-cond  here rel!  ;
+
+: then   ( from -- )        >resolve  ;
+: begin  ( -- to )          <mark   ;
+: ahead  ( -- from )        h# 80  if  ;               \ SJMP
+: else   ( from -- from' )  ahead  but  then  ;
+: again  ( to -- )          h# 80 asm8,  <resolve  ;   \ SJMP
+: while  ( to -- from to )  if  but  ;
+: repeat ( from to -- )     again  then  ;
+
+only forth also definitions
+
+\ If xxxx.1rrr bit is set, it is a regular form where the EA is R0..7
+\ If xxxx.0100 the EA is often #immed
+\ If xxxx.0101 the EA is often iram
+\ If xxxx.0110 the EA is always @R0
+\ If xxxx.0111 the EA is always @R1
+
+\  nop             0000.0000
+
+\  jbc bit reladr  0001.0000 bit reladr
+\  jb  bit reladr  0010.0000 bit reladr
+\  jnb bit reladr  0011.0000 bit reladr
+
+\  jc   reladr     0100.0000 reladr
+\  jnc  reladr     0101.0000 reladr
+\  jz   reladr     0110.0000 reladr
+\  jnz  reladr     0111.0000 reladr
+\  sjmp reladr     1000.0000 reladr
+
+\  movx_a, at dptr    1110.0000
+\  movx_ at dptr,a    1111.0000
+
+\  acall           ppp1.0001 llll.llll
+\  ajmp            ppp0.0001 llll.llll
+
+\  orl c,/bit      1010.0000 n n
+\  anl c,/bit      1011.0000 n n
+\  push            1100.0000 iram
+\  pop             1101.0000 iram
+
+\  orl c,bit       0111.0010 n n
+\  anl c,bit       1000.0010 n n
+\  clr bit         1100.0010 bit
+\  setb bit        1101.0010 bit
+
+
+\  ljmp  adr       0000.0010 adr adr
+\  lcall adr       0001.0010 adr adr
+\  ret             0010.0010
+\  reti            0011.0010
+
+\  movx_a, at r0      1110.0010
+\  movx_ at r0,a      1111.0010
+
+\  rr              0000.0011
+\  rrc             0001.0011
+\  rl              0010.0011
+\  rlc             0011.0011
+
+\  jmp at a+dptr      0111.0011
+\  movc_a, at a+pc    1000.0011
+\  movc_a, at a+dptr  1001.0011
+
+\  clrc            1100.0011
+\  setbc           1101.0011
+\  movx_a, at r1      1110.0011
+\  movx_ at r1,a      1111.0011
+
+\  div             1000.0100  (shoehorned into mov iram,ea)
+\  mulab           1010.0100  (shoehorned into mov ea,iram)
+\  swap            1100.0100  (shoehorned into xchg)
+\  da              1101.0100  (shoehorned into djnz)
+\  clra            1110.0100  (shoehorned into mov a,ea)
+
+\  xchd a, at r0      1101.0110  (shoehorned into djnz)
+\  xchd a, at r1      1101.0111  (shoehorned into djnz)
+
+\  inc         0000.mmmm
+\  dec         0001.mmmm
+\  add         0010.mmmm
+\  addc        0011.mmmm
+\  orl         0100.mmmm
+\  anl         0101.mmmm
+\  xrl         0110.mmmm
+\  mov ea,#    0111.mmmm data
+\  mov iram,ea 1000.mmmm iram
+\  subb        1001.mmmm
+\  mov ea,iram 1010.mmmm iram
+\  cjne        1011.mmmm idata reladdr (cplc shoehorned at 3, cplbit at 2)
+\  xchg        1100.mmmm reladdr
+\  djnz        1101.mmmm reladdr   (da shoehorned at 4, xchd at 6,7)
+\  mov a,ea    1110.mmmm           (clr shoehorned at 4)
+\  mov ea,a    1111.mmmm           (cpla shoehorned at 4)
+\  cpl a       1111.0100
+
+\  undef       1010.0101 \ shoehorned into mov ea,iram (redundant with 85)




More information about the OpenBIOS mailing list