104 lines
2.5 KiB
Plaintext
104 lines
2.5 KiB
Plaintext
#
|
|
# 4bitadder.icn, emulate a 4 bit adder. Using only and, or, not
|
|
#
|
|
record carry(c)
|
|
|
|
#
|
|
# excercise the adder, either "test" or 2 numbers
|
|
#
|
|
procedure main(argv)
|
|
c := carry(0)
|
|
|
|
# cli test
|
|
if map(\argv[1]) == "test" then {
|
|
# Unicon allows explicit radix literals
|
|
every i := (2r0000 | 2r1001 | 2r1111) do {
|
|
write(i, "+0,3,9,15")
|
|
every j := (0 | 3 | 9 | 15) do {
|
|
ans := fourbitadder(t1 := fourbits(i), t2 := fourbits(j), c)
|
|
write(t1, " + ", t2, " = ", c.c, ":", ans)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
# command line, two values, if given, first try four bit binaries
|
|
cli := fourbitadder(t1 := (*\argv[1] = 4 & fourbits("2r" || argv[1])),
|
|
t2 := (*\argv[2] = 4 & fourbits("2r" || argv[2])), c)
|
|
write(t1, " + ", t2, " = ", c.c, ":", \cli) & return
|
|
|
|
# if no result for that, try decimal values
|
|
cli := fourbitadder(t1 := fourbits(\argv[1]),
|
|
t2 := fourbits(\argv[2]), c)
|
|
write(t1, " + ", t2, " = ", c.c, ":", \cli) & return
|
|
|
|
# or display the help
|
|
write("Usage: 4bitadder [\"test\"] | [bbbb bbbb] | [n n], range 0-15")
|
|
end
|
|
|
|
#
|
|
# integer to fourbits as string
|
|
#
|
|
procedure fourbits(i)
|
|
local s, t
|
|
if not numeric(i) then fail
|
|
if not (0 <= integer(i) < 16) then {
|
|
write("out of range: ", i)
|
|
fail
|
|
}
|
|
s := ""
|
|
every t := (8 | 4 | 2 | 1) do {
|
|
s ||:= if iand(i, t) ~= 0 then "1" else "0"
|
|
}
|
|
return s
|
|
end
|
|
|
|
#
|
|
# low level xor emulation with or, and, not
|
|
#
|
|
procedure xor(a, b)
|
|
return ior(iand(a, icom(b)), iand(b, icom(a)))
|
|
end
|
|
|
|
#
|
|
# half adder, and into carry, xor for result bit
|
|
#
|
|
procedure halfadder(a, b, carry)
|
|
carry.c := iand(a,b)
|
|
return xor(a,b)
|
|
end
|
|
|
|
#
|
|
# full adder, two half adders, or for carry
|
|
#
|
|
procedure fulladder(a, b, c0, c1)
|
|
local c2, c3, r
|
|
c2 := carry(0)
|
|
c3 := carry(0)
|
|
|
|
# connect two half adders with carry
|
|
r := halfadder(halfadder(c0.c, a, c2), b, c3)
|
|
c1.c := ior(c2.c, c3.c)
|
|
return r
|
|
end
|
|
|
|
#
|
|
# fourbit adder, as bit string
|
|
#
|
|
procedure fourbitadder(a, b, cr)
|
|
local cs, c0, c1, c2, s
|
|
cs := carry(0)
|
|
c0 := carry(0)
|
|
c1 := carry(0)
|
|
c2 := carry(0)
|
|
|
|
# create a string for subscripting. strings are immutable, new strings created
|
|
s := "0000"
|
|
# bit 0 is string position 4
|
|
s[4+:1] := fulladder(a[4+:1], b[4+:1], cs, c0)
|
|
s[3+:1] := fulladder(a[3+:1], b[3+:1], c0, c1)
|
|
s[2+:1] := fulladder(a[2+:1], b[2+:1], c1, c2)
|
|
s[1+:1] := fulladder(a[1+:1], b[1+:1], c2, cr)
|
|
# cr.c is the overflow carry
|
|
return s
|
|
end
|