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,@R0
+h# d7 1mi xchd_a,@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@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,@dptr
+h# e2 1mi movx_a,@r0
+h# e3 1mi movx_a,@r1
+h# f0 1mi movx_@dptr,a
+h# f2 1mi movx_@r0,a
+h# f3 1mi movx_@r1,a
+h# 83 1mi movc_a,@a+pc
+h# 93 1mi movc_a,@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,@dptr 1110.0000
+\ movx_@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,@r0 1110.0010
+\ movx_@r0,a 1111.0010
+
+\ rr 0000.0011
+\ rrc 0001.0011
+\ rl 0010.0011
+\ rlc 0011.0011
+
+\ jmp@a+dptr 0111.0011
+\ movc_a,@a+pc 1000.0011
+\ movc_a,@a+dptr 1001.0011
+
+\ clrc 1100.0011
+\ setbc 1101.0011
+\ movx_a,@r1 1110.0011
+\ movx_@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,@r0 1101.0110 (shoehorned into djnz)
+\ xchd a,@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)