目次

アセンブラ開発

 i8048のアセンブラは、PROASM-IIを利用しています。

 PROASMは、MS-DOS用アセンブラなので、UnixやMacOSX
 では動作しません。

 マルチプラットホームのアセンブラを設計、開発して
 OSに依存しないアプリケーションプログラムとして
 おきます。

 RaspberryPiでも使えるように、PythonあるいはAWKを
 開発言語としておきます。

 AWKを利用して、1バイト、2バイトの命令を
 アセンブル処理を記述。

BEGIN {
  print "================================="
}

function i2h0(x)
{
  xx = "0123456789ABCDEF"

  result = substr(xx,x+1,1)

  return result
}

function i2h(x)
{
  result = i2h0(x/16) i2h0(x%16)

  return result
}

{
  #code = toupper($0)
  # separate
  if ( NF == 1 ) {
    xx = toupper($1)
    l = length(xx)
    if ( xx == "NOP"  ) { printf("%s -> 00\n",$0) }
    if ( xx == "RET"  ) { printf("%s -> 83\n",$0) }
    if ( xx == "RETR" ) { printf("%s -> 93\n",$0) }
    yy = substr(xx,l,1)
    if ( yy == ":" ) { printf("%s -> %s\n",$0,substr(xx,1,l-1)) }
  }
  if ( NF == 2 ) {
    opcode = toupper($1)
    oprand = toupper($2)
    split(oprand,aa,",")
    # MOV
    if ( opcode == "MOV" ) {
      # MOV A
      if ( aa[1] == "A" ) {
        # MOV A,PSW
        if ( aa[2] == "PSW" ) {
          x = 199
	  printf("%s -> %02X\n",$0,x)
        }
        # MOV A,T
        if ( aa[2] == "T" ) {
          x = 66
	  printf("%s -> %02X\n",$0,x)
        }
        # MOV A,#??
        if ( substr(aa[2],1,1) == "#" ) {
          if ( substr(aa[2],2,1) == "H" ) {
            xx = substr(aa[2],3)
	    printf("%s -> 23 %s\n",$0,xx)
          }
          if ( substr(aa[2],2,1) != "H" && aa[2] != "T" ) {
            xx = int(substr(aa[2],2))
	    printf("%s -> 23 %02X\n",$0,xx)
          }
        }
        # MOV A,@RX
        if ( substr(aa[2],1,1) == "@" ) {
          xx = substr(aa[2],3,1)
          x = 240 + int(xx)
	  printf("%s -> %02X\n",$0,x)
        }
        # MOV A,RX
        if ( substr(aa[2],1,1) == "R" ) {
          xx = substr(aa[2],2,1)
          x = 248 + int(xx)
	  printf("%s -> %02X\n",$0,x)
        }
      }
      # MOV RX,A
      if ( substr(aa[1],1,1) == "R" && aa[2] == "A" ) {
        l = length(aa[1])
        xx = substr(aa[1],l,1)
        if ( l == 3 ) { x = 160 + int(xx) }
        if ( l == 2 ) { x = 168 + int(xx) }
	printf("%s -> %02X\n",$0,x)
      }
      # MOV RX,#*
      if ( substr(aa[2],1,1) == "#" && aa[1] != "A" ) {
        xx = substr(aa[1],2,1)
        x = 184 + int(xx)
        if ( substr(aa[2],2,1) == "H" ) {
          y = substr(aa[2],3)
	  printf("%s -> %02X %s\n",$0,x,y)
        } else {
          yy = int(substr(aa[2],2))
	  printf("%s -> %02X %02X\n",$0,x,yy)
        }
      }
    }
    # MOV PSW,A
    if ( aa[1] == "PSW" && aa[2] == "A" ) { printf("%s -> D7\n",$0) }
    # MOV T,A
    if ( aa[1] == "T" && aa[2] == "A" ) { printf("%s -> 62\n",$0) }
    # XCH A
    if ( opcode == "XCH" ) {
      if ( aa[1] == "A" ) {
        l = length( aa[2] )
        xx = substr(aa[2],l,1)
        if ( l == 3 ) { x = 32 + int(xx) }
        if ( l == 2 ) { x = 40 + int(xx) }
	printf("%s -> %02X\n",$0,x)
      }
    }
    # ANL , ORL , XRL
    if ( opcode == "ANL" || opcode == "ORL" || opcode == "XRL" ) {
      if ( aa[1] == "A" && substr(aa[2],1,1) != "#" ) {
        l = length( aa[2] )
        xx = substr(aa[2],l,1)
        if ( opcode == "ANL" ) {
          if ( l == 3 ) { x = 80 + int(xx) }
          if ( l == 2 ) { x = 88 + int(xx) }
        }
        if ( opcode == "ORL" ) {
          if ( l == 3 ) { x = 64 + int(xx) }
          if ( l == 2 ) { x = 72 + int(xx) }
        }
        if ( opcode == "XRL" ) {
          if ( l == 3 ) { x = 208 + int(xx) }
          if ( l == 2 ) { x = 216 + int(xx) }
        }
        printf("%s -> %02X\n",$0,x)
      }
      if ( aa[1] == "A" && substr(aa[2],1,1) == "#" ) {
        if ( opcode == "ANL" ) { x =  83 }
        if ( opcode == "ORL" ) { x =  67 }
        if ( opcode == "XRL" ) { x = 211 }
        if ( substr(aa[2],2,1) == "H" ) {
          y = substr(aa[2],3)
	  printf("%s -> %02X %s\n",$0,x,y)
        } else {
          yy = int(substr(aa[2],2))
	  printf("%s -> %02X %02X\n",$0,x,yy)
        }
      }
      if ( aa[1] != "A" && substr(aa[2],1,1) == "#" ) {
        if ( aa[1] == "BUS" ) { xx = 0 }
        if ( substr(aa[1],1,1) == "P" ) { xx = substr(aa[1],2,1) }
        if ( opcode == "ANL" ) { x = 152 + int(xx) }
        if ( opcode == "ORL" ) { x = 136 + int(xx) }
        if ( substr(aa[2],2,1) == "H" ) {
          y = substr(aa[2],3)
	  printf("%s -> %02X %s\n",$0,x,y)
        } else {
          yy = int(substr(aa[2],2))
	  printf("%s -> %02X %02X\n",$0,x,yy)
        }
      }
    }
    # ADD A , ADDC A
    if ( opcode == "ADD" || opcode == "ADDC" ) {
      if ( aa[1] == "A" && substr(aa[2],1,1) != "#" ) {
        l = length( aa[2] )
        xx = substr(aa[2],l,1)
        if ( opcode == "ADD" ) {
          if ( l == 3 ) { x =  96 + int(xx) }
          if ( l == 2 ) { x = 104 + int(xx) }
        }
        if ( opcode == "ADDC" ) {
          if ( l == 3 ) { x = 112 + int(xx) }
          if ( l == 2 ) { x = 120 + int(xx) }
        }
        printf("%s -> %02X\n",$0,x)
      }
      if ( aa[1] == "A" && substr(aa[2],1,1) == "#" ) {
        if ( opcode == "ADD"  ) { x =  3 }
        if ( opcode == "ADDC" ) { x = 19 }
        if ( substr(aa[2],2,1) == "H" ) {
          y = substr(aa[2],3)
	  printf("%s -> %02X %s\n",$0,x,y)
        } else {
          yy = int(substr(aa[2],2))
	  printf("%s -> %02X %02X\n",$0,x,yy)
        }
      }
    }
    # INC , DEC 
    if ( opcode == "INC" || opcode == "DEC" ) {
      l = length( aa[1] )
      xx = substr(aa[1],l,1)
      if ( opcode == "INC" ) {
        if ( l == 1 ) { x = 23 }
        if ( l == 2 ) { x = 24 + int(xx) }
        if ( l == 3 ) { x = 16 + int(xx) }
      }
      if ( opcode == "DEC" ) {
        if ( l == 1 ) { x = 7 }
        if ( l == 2 ) { x = 200 + int(xx) }
      }
      printf("%s -> %02X\n",$0,x)
    }
    # CLR
    if ( opcode == "CLR" ) {
      if ( oprand == "A" ) { x =  39 }
      if ( oprand == "C" ) { x = 151 }
      printf("%s -> %02X\n",$0,x)
    }
    # CPL
    if ( opcode == "CPL" ) {
      if ( oprand == "A"  ) { x =  55 }
      if ( oprand == "C"  ) { x = 167 }
      if ( oprand == "F0" ) { x = 149 }
      if ( oprand == "F1" ) { x = 181 }
      printf("%s -> %02X\n",$0,x)
    }
    # DA
    if ( opcode == "DA" ) {
      if ( oprand == "A"  ) { x = 87 }
      printf("%s -> %02X\n",$0,x)
    }
    # SWAP
    if ( opcode == "SWAP" ) {
      if ( oprand == "A"  ) { x = 71 }
      printf("%s -> %02X\n",$0,x)
    }
    # RL
    if ( opcode == "RL" ) {
      if ( oprand == "A"  ) { x = 231 }
      printf("%s -> %02X\n",$0,x)
    }
    # RLC
    if ( opcode == "RLC" ) {
      if ( oprand == "A"  ) { x = 247 }
      printf("%s -> %02X\n",$0,x)
    }
    # RR
    if ( opcode == "RR" ) {
      if ( oprand == "A"  ) { x = 119 }
      printf("%s -> %02X\n",$0,x)
    }
    # RRC
    if ( opcode == "RRC" ) {
      if ( oprand == "A"  ) { x = 103 }
      printf("%s -> %02X\n",$0,x)
    }
    # IN
    if ( opcode == "IN" ) {
      if ( aa[1] == "A" ) {
        l = length(aa[2])
        xx = substr(aa[2],l,1)
        x = 8 + int(xx)
      }
      printf("%s -> %02X\n",$0,x)
    }
    # OUTL
    if ( opcode == "OUTL" ) {
      if ( aa[2] == "A" && substr(aa[1],1,1) == "P" ) {
        l = length(aa[1])
        xx = substr(aa[1],l,1)
        x = 56 + int(xx)
        printf("%s -> %02X\n",$0,x)
      }
      if ( aa[2] == "A" && aa[1] == "BUS" ) {
        printf("%s -> 02\n",$0)
      }
    }
    # INS
    if ( opcode == "INS" ) {
      if ( aa[1] == "A" && aa[2] == "BUS" ) {
        printf("%s -> 08\n",$0)
      }
    }
    # SEL
    if ( opcode == "SEL" ) {
      if ( oprand == "RB0" ) { x = 197 }
      if ( oprand == "RB1" ) { x = 213 }
      if ( oprand == "MB0" ) { x = 229 }
      if ( oprand == "MB1" ) { x = 245 }
      printf("%s -> %02X\n",$0,x)
    }
    # ENT0 CLK
    if ( opcode == "ENT0" ) {
      if ( oprand == "CLK" ) { x = 117 }
      printf("%s -> %02X\n",$0,x)
    }
    # STRT
    if ( opcode == "STRT" ) {
      if ( oprand == "T"   ) { x = 85 }
      if ( oprand == "CNT" ) { x = 69 }
      printf("%s -> %02X\n",$0,x)
    }
    # STOP
    if ( opcode == "STOP" ) {
      if ( oprand == "TCNT" ) { x = 101 }
      printf("%s -> %02X\n",$0,x)
    }
    # EN
    if ( opcode == "EN" ) {
      if ( oprand == "I"     ) { x =  5 }
      if ( oprand == "TCNTI" ) { x = 37 }
      printf("%s -> %02X\n",$0,x)
    }
    # DIS
    if ( opcode == "DIS" ) {
      if ( oprand == "I"     ) { x = 21 }
      if ( oprand == "TCNTI" ) { x = 53 }
      printf("%s -> %02X\n",$0,x)
    }
    # CALL
    if ( opcode == "CALL" ) {
      x = 20
      printf("%s -> %02X ??\n",$0,x)
    }
    # DJNZ
    if ( opcode == "DJNZ" ) {
      xx = substr(aa[1],2,1)
      x = 232 + int(xx)
      printf("%s -> %02X ??\n",$0,x)
    }
    # JC
    if ( opcode == "JC" ) {
      x = 246
      printf("%s -> %02X ??\n",$0,x)
    }
    # JNC
    if ( opcode == "JNC" ) {
      x = 230
      printf("%s -> %02X ??\n",$0,x)
    }
    # JZ
    if ( opcode == "JZ" ) {
      x = 198
      printf("%s -> %02X ??\n",$0,x)
    }
    # JNZ
    if ( opcode == "JNZ" ) {
      x = 150
      printf("%s -> %02X ??\n",$0,x)
    }
    # JT0
    if ( opcode == "JT0" ) {
      x = 54
      printf("%s -> %02X ??\n",$0,x)
    }
    # JNT0
    if ( opcode == "JNT0" ) {
      x = 38
      printf("%s -> %02X ??\n",$0,x)
    }
    # JT1
    if ( opcode == "JT1" ) {
      x = 86
      printf("%s -> %02X ??\n",$0,x)
    }
    # JNT1
    if ( opcode == "JNT1" ) {
      x = 70
      printf("%s -> %02X ??\n",$0,x)
    }
    # JF0
    if ( opcode == "JF0" ) {
      x = 182
      printf("%s -> %02X ??\n",$0,x)
    }
    # JF1
    if ( opcode == "JF1" ) {
      x = 118
      printf("%s -> %02X ??\n",$0,x)
    }
  }
}
END {
  print "================================="
}

 1バイト、2バイトの命令を弁別するだけの
 ソースコードを書いて、アセンブラが正しく
 動作しているかを確認してみます。
 
 ソースコードは、以下。

mov	a,#12
mov	a,#h12
mov	a,@r0
mov	a,@r1
mov	a,r0
mov	a,r1
mov	a,r2
mov	a,r3
mov	a,r4
mov	a,r5
mov	a,r6
mov	a,r7
mov	a,psw
mov	psw,a
xch	a,@R0
xch	a,@R1
xch	a,R0
xch	a,R1
xch	a,R2
xch	a,R3
xch	a,R4
xch	a,R5
xch	a,R6
xch	a,R7
mov	@r0,a
mov	@r1,a
mov	r0,a
mov	r1,a
mov	r2,a
mov	r3,a
mov	r4,a
mov	r5,a
mov	r6,a
mov	r7,a
mov	r0,#00
mov	r1,#01
mov	r2,#hF0
mov	r3,#hF1
mov	r4,#00
mov	r5,#01
mov	r6,#hF0
mov	r7,#hF1
anl	a,@R0
anl	a,@R1
anl	a,R0
anl	a,R1
anl	a,R2
anl	a,R3
anl	a,R4
anl	a,R5
anl	a,R6
anl	a,R7
anl	a,#21
anl	a,#h12
orl	a,@R0
orl	a,@R1
orl	a,R0
orl	a,R1
orl	a,R2
orl	a,R3
orl	a,R4
orl	a,R5
orl	a,R6
orl	a,R7
orl	a,#21
orl	a,#h12
xrl	a,@R0
xrl	a,@R1
xrl	a,R0
xrl	a,R1
xrl	a,R2
xrl	a,R3
xrl	a,R4
xrl	a,R5
xrl	a,R6
xrl	a,R7
xrl	a,#21
xrl	a,#h12
add	a,@R0
add	a,@R1
add	a,R0
add	a,R1
add	a,R2
add	a,R3
add	a,R4
add	a,R5
add	a,R6
add	a,R7
add	a,#21
add	a,#h12
addc	a,@R0
addc	a,@R1
addc	a,R0
addc	a,R1
addc	a,R2
addc	a,R3
addc	a,R4
addc	a,R5
addc	a,R6
addc	a,R7
addc	a,#21
addc	a,#h12
inc	a
inc	@R0
inc	@R1
inc	R0
inc	R1
inc	R2
inc	R3
inc	R4
inc	R5
inc	R6
inc	R7
dec	a
dec	R0
dec	R1
dec	R2
dec	R3
dec	R4
dec	R5
dec	R6
dec	R7
clr	a
clr	c
cpl	a
cpl	c
cpl	f0
cpl	f1
da	a
swap	a
rl	a
rlc	a
rr	a
rrc	a
in	a,P1
in	a,P2
outl	P1,a
outl	P2,a
anl	P1,#12
anl	P2,#h12
anl	bus,#12
anl	bus,#h12
orl	P1,#12
orl	P2,#h12
orl	bus,#12
orl	bus,#h12
ins	a,bus
outl	bus,a
sel	rb0
sel	rb1
sel	mb0
sel	mb1
ent0	clk
mov	a,t
mov	t,a
strt	t
strt	cnt
stop	tcnt
en	i
dis	i
en	tcnti
dis	tcnti
nop
ret
retr
jc	x
jnc	x
jz	x
jnz	x
jt0	x
jnt0	x
jt1	x
jnt1	x
jf0	x
jf1	x
djnz	r0,x
djnz	r1,x
djnz	r2,x
djnz	r3,x
djnz	r4,x
djnz	r5,x
djnz	r6,x
djnz	r7,x
call	xxx
L:
main:
loop:

 アセンブル結果は、次のようになりました。

=================================
mov	a,#12 -> 23 0C
mov	a,#h12 -> 23 12
mov	a,@r0 -> F0
mov	a,@r1 -> F1
mov	a,r0 -> F8
mov	a,r1 -> F9
mov	a,r2 -> FA
mov	a,r3 -> FB
mov	a,r4 -> FC
mov	a,r5 -> FD
mov	a,r6 -> FE
mov	a,r7 -> FF
mov	a,psw -> C7
mov	psw,a -> D7
xch	a,@R0 -> 20
xch	a,@R1 -> 21
xch	a,R0 -> 28
xch	a,R1 -> 29
xch	a,R2 -> 2A
xch	a,R3 -> 2B
xch	a,R4 -> 2C
xch	a,R5 -> 2D
xch	a,R6 -> 2E
xch	a,R7 -> 2F
mov	r0,a -> A8
mov	r1,a -> A9
mov	r2,a -> AA
mov	r3,a -> AB
mov	r4,a -> AC
mov	r5,a -> AD
mov	r6,a -> AE
mov	r7,a -> AF
mov	r0,#00 -> B8 00
mov	r1,#01 -> B9 01
mov	r2,#hF0 -> BA F0
mov	r3,#hF1 -> BB F1
mov	r4,#00 -> BC 00
mov	r5,#01 -> BD 01
mov	r6,#hF0 -> BE F0
mov	r7,#hF1 -> BF F1
anl	a,@R0 -> 50
anl	a,@R1 -> 51
anl	a,R0 -> 58
anl	a,R1 -> 59
anl	a,R2 -> 5A
anl	a,R3 -> 5B
anl	a,R4 -> 5C
anl	a,R5 -> 5D
anl	a,R6 -> 5E
anl	a,R7 -> 5F
anl	a,#21 -> 53 15
anl	a,#h12 -> 53 12
orl	a,@R0 -> 40
orl	a,@R1 -> 41
orl	a,R0 -> 48
orl	a,R1 -> 49
orl	a,R2 -> 4A
orl	a,R3 -> 4B
orl	a,R4 -> 4C
orl	a,R5 -> 4D
orl	a,R6 -> 4E
orl	a,R7 -> 4F
orl	a,#21 -> 43 15
orl	a,#h12 -> 43 12
xrl	a,@R0 -> D0
xrl	a,@R1 -> D1
xrl	a,R0 -> D8
xrl	a,R1 -> D9
xrl	a,R2 -> DA
xrl	a,R3 -> DB
xrl	a,R4 -> DC
xrl	a,R5 -> DD
xrl	a,R6 -> DE
xrl	a,R7 -> DF
xrl	a,#21 -> D3 15
xrl	a,#h12 -> D3 12
add	a,@R0 -> 60
add	a,@R1 -> 61
add	a,R0 -> 68
add	a,R1 -> 69
add	a,R2 -> 6A
add	a,R3 -> 6B
add	a,R4 -> 6C
add	a,R5 -> 6D
add	a,R6 -> 6E
add	a,R7 -> 6F
add	a,#21 -> 03 15
add	a,#h12 -> 03 12
addc	a,@R0 -> 70
addc	a,@R1 -> 71
addc	a,R0 -> 78
addc	a,R1 -> 79
addc	a,R2 -> 7A
addc	a,R3 -> 7B
addc	a,R4 -> 7C
addc	a,R5 -> 7D
addc	a,R6 -> 7E
addc	a,R7 -> 7F
addc	a,#21 -> 13 15
addc	a,#h12 -> 13 12
inc	a -> 17
inc	@R0 -> 10
inc	@R1 -> 11
inc	R0 -> 18
inc	R1 -> 19
inc	R2 -> 1A
inc	R3 -> 1B
inc	R4 -> 1C
inc	R5 -> 1D
inc	R6 -> 1E
inc	R7 -> 1F
dec	a -> 07
dec	R0 -> C8
dec	R1 -> C9
dec	R2 -> CA
dec	R3 -> CB
dec	R4 -> CC
dec	R5 -> CD
dec	R6 -> CE
dec	R7 -> CF
clr	a -> 27
clr	c -> 97
cpl	a -> 37
cpl	c -> A7
cpl	f0 -> 95
cpl	f1 -> B5
da	a -> 57
swap	a -> 47
rl	a -> E7
rlc	a -> F7
rr	a -> 77
rrc	a -> 67
in	a,P1 -> 09
in	a,P2 -> 0A
outl	P1,a -> 39
outl	P2,a -> 3A
anl	P1,#12 -> 99 0C
anl	P2,#h12 -> 9A 12
anl	bus,#12 -> 98 0C
anl	bus,#h12 -> 98 12
orl	P1,#12 -> 89 0C
orl	P2,#h12 -> 8A 12
orl	bus,#12 -> 88 0C
orl	bus,#h12 -> 88 12
ins	a,bus -> 08
outl	bus,a -> 02
sel	rb0 -> C5
sel	rb1 -> D5
sel	mb0 -> E5
sel	mb1 -> F5
ent0	clk -> 75
mov	a,t -> 42
mov	t,a -> 62
strt	t -> 55
strt	cnt -> 45
stop	tcnt -> 65
en	i -> 05
dis	i -> 15
en	tcnti -> 25
dis	tcnti -> 35
nop -> 00
ret -> 83
retr -> 93
jc	x -> F6 ??
jnc	x -> E6 ??
jz	x -> C6 ??
jnz	x -> 96 ??
jt0	x -> 36 ??
jnt0	x -> 26 ??
jt1	x -> 56 ??
jnt1	x -> 46 ??
jf0	x -> B6 ??
jf1	x -> 76 ??
djnz	r0,x -> E8 ??
djnz	r1,x -> E9 ??
djnz	r2,x -> EA ??
djnz	r3,x -> EB ??
djnz	r4,x -> EC ??
djnz	r5,x -> ED ??
djnz	r6,x -> EE ??
djnz	r7,x -> EF ??
L: -> L
main: -> MAIN
loop: -> LOOP
=================================

 イミディエイト、分岐の命令だけが2バイトと
 なることを理解できました。

 AWKでは16進数で扱わないで、最後に変換して
 わかりやすくしておきました。

 極力PROASMのアセンブリ言語のフォーマットに
 近づけたいですが、16進数、10進数の指定には
 数字の前に、Hをつけるかどうかで判定する仕様。

 処理ロジックがわかれば、Pythonで実現するために
 必要な関数、手続きを定義して、使うようにします。

 闇雲に開発すると、余計な時間をかけることが多い
 ので、設計仕様を固めておきます。

 テーブル参照を使うには、Pythonで扱える連想配列を活用。
 連想配列は、次のように宣言して活用

 .EQU -> tblequ
 .ORG -> tblorg
 .END -> tblend


(under construction)

目次

inserted by FC2 system