Skip to content
This repository has been archived by the owner on Aug 12, 2021. It is now read-only.

Commit

Permalink
Adds insns between 0x40 and 0x7F
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertBaruch committed Jan 9, 2020
1 parent f670ada commit 9d5cf9e
Show file tree
Hide file tree
Showing 11 changed files with 599 additions and 3 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ This is a **WORK IN PROGRESS**!
* Release for [video 4](https://youtu.be/xqMtyCu4lME): [tag 0.04.0](https://github.com/RobertBaruch/n6800/tree/0.04.0)
* Release for [video 5](https://youtu.be/9MMb9dSnNvo): [tag 0.05.1](https://github.com/RobertBaruch/n6800/tree/0.05.1)
* Release for [video 6](https://youtu.be/C6sUaElP9hA): [tag 0.06.0](https://github.com/RobertBaruch/n6800/tree/0.06.0)
* Release for [video 7](https://youtu.be/AerXEa84jsc): [tag 0.07.0](https://github.com/RobertBaruch/n6800/tree/0.07.0)
* Release for [video 7](https://youtu.be/AerXEa84jsc): [tag 0.07.0](https://github.com/RobertBaruch/n6800/tree/0.07.0)
* Release for [video 8](https://youtu.be/6acCiGBjM6s): [tag 0.08.0](https://github.com/RobertBaruch/n6800/tree/0.08.0)
96 changes: 96 additions & 0 deletions alu8.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ class ALU8Func(IntEnum):
SEI = 16
CLZ = 17
SEZ = 18
COM = 19 # Not implemented using SUB or EOR
INC = 20 # Not implemented using ADD
DEC = 21 # Not implemented using SUB
ROL = 22
ROR = 23
ASL = 24
ASR = 25
LSR = 26


def LCat(*args) -> Value:
"""Left or logical concatenation.
Concatenates arguments such that the first argument is placed in the
highest bit positions, and the last is placed in the lowest bit positions.
"""
return Cat(*args[::-1])


class ALU8(Elaboratable):
Expand Down Expand Up @@ -132,6 +149,85 @@ def elaborate(self, platform: Platform) -> Module:
m.d.comb += self._ccs[Flags.N].eq(self.output[7])
m.d.comb += self._ccs[Flags.V].eq(0)

with m.Case(ALU8Func.INC):
m.d.comb += self.output.eq(self.input2 + 1)
m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
m.d.comb += self._ccs[Flags.N].eq(self.output[7])
m.d.comb += self._ccs[Flags.V].eq(self.output == 0x80)

with m.Case(ALU8Func.DEC):
m.d.comb += self.output.eq(self.input2 - 1)
m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
m.d.comb += self._ccs[Flags.N].eq(self.output[7])
m.d.comb += self._ccs[Flags.V].eq(self.output == 0x7F)

with m.Case(ALU8Func.COM):
m.d.comb += self.output.eq(0xFF ^ self.input2)
m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
m.d.comb += self._ccs[Flags.N].eq(self.output[7])
m.d.comb += self._ccs[Flags.V].eq(0)
m.d.comb += self._ccs[Flags.C].eq(1)

with m.Case(ALU8Func.ROL):
# IIIIIIIIC ->
# COOOOOOOO
m.d.comb += [
LCat(self._ccs[Flags.C], self.output).eq(
LCat(self.input2, self.ccs[Flags.C])),
self._ccs[Flags.Z].eq(self.output == 0),
self._ccs[Flags.N].eq(self.output[7]),
self._ccs[Flags.V].eq(
self._ccs[Flags.N] ^ self._ccs[Flags.C])
]

with m.Case(ALU8Func.ROR):
# CIIIIIIII ->
# OOOOOOOOC
m.d.comb += [
LCat(self.output, self._ccs[Flags.C]).eq(
LCat(self.ccs[Flags.C], self.input2)),
self._ccs[Flags.Z].eq(self.output == 0),
self._ccs[Flags.N].eq(self.output[7]),
self._ccs[Flags.V].eq(
self._ccs[Flags.N] ^ self._ccs[Flags.C])
]

with m.Case(ALU8Func.ASL):
# IIIIIIII0 ->
# COOOOOOOO
m.d.comb += [
LCat(self._ccs[Flags.C], self.output).eq(
LCat(self.input2, Const(0))),
self._ccs[Flags.Z].eq(self.output == 0),
self._ccs[Flags.N].eq(self.output[7]),
self._ccs[Flags.V].eq(
self._ccs[Flags.N] ^ self._ccs[Flags.C])
]

with m.Case(ALU8Func.ASR):
# 7IIIIIIII -> ("7" is the repeat of input[7])
# OOOOOOOOC
m.d.comb += [
LCat(self.output, self._ccs[Flags.C]).eq(
LCat(self.input2[7], self.input2)),
self._ccs[Flags.Z].eq(self.output == 0),
self._ccs[Flags.N].eq(self.output[7]),
self._ccs[Flags.V].eq(
self._ccs[Flags.N] ^ self._ccs[Flags.C])
]

with m.Case(ALU8Func.LSR):
# 0IIIIIIII ->
# OOOOOOOOC
m.d.comb += [
LCat(self.output, self._ccs[Flags.C]).eq(
LCat(Const(0), self.input2)),
self._ccs[Flags.Z].eq(self.output == 0),
self._ccs[Flags.N].eq(self.output[7]),
self._ccs[Flags.V].eq(
self._ccs[Flags.N] ^ self._ccs[Flags.C])
]

with m.Case(ALU8Func.CLC):
m.d.comb += self._ccs[Flags.C].eq(0)

Expand Down
2 changes: 2 additions & 0 deletions consts/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
class ModeBits(IntEnum):
"""Decoding of bits 4 and 5 for instructions >= 0x80."""
IMMEDIATE = 0
A = 0 # An alias for instructions in 0x40-0x7F
DIRECT = 1
B = 1 # An alias for instructions in 0x40-0x7F
INDEXED = 2
EXTENDED = 3

Expand Down
113 changes: 111 additions & 2 deletions core.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,30 @@ def execute(self, m: Module):
self.CL_SE_I(m)
with m.Case("0010----"): # Branch instructions
self.BR(m)
with m.Case("01--0000"): # NEG
self.ALU2(m, ALU8Func.SUB, 0, 1)
with m.Case("01--0011"): # COM
self.ALU2(m, ALU8Func.COM, 0, 1)
with m.Case("01--0100"): # LSR
self.ALU2(m, ALU8Func.LSR, 0, 1)
with m.Case("01--0110"): # ROR
self.ALU2(m, ALU8Func.ROR, 0, 1)
with m.Case("01--0111"): # ASR
self.ALU2(m, ALU8Func.ASR, 0, 1)
with m.Case("01--1000"): # ASL
self.ALU2(m, ALU8Func.ASL, 0, 1)
with m.Case("01--1001"): # ROL
self.ALU2(m, ALU8Func.ROL, 0, 1)
with m.Case("01--1010"): # DEC
self.ALU2(m, ALU8Func.DEC, 0, 1)
with m.Case("01--1100"): # INC
self.ALU2(m, ALU8Func.INC, 0, 1)
with m.Case("01--1101"): # TST
self.ALU2(m, ALU8Func.SUB, 1, 0, store=False)
with m.Case("011-1110"): # JMP
self.JMP(m)
with m.Case("01--1111"): # CLR
self.ALU2(m, ALU8Func.SUB, 1, 1)
with m.Case("1---0110"): # LDA
self.ALU(m, ALU8Func.LD)
with m.Case("1---0000"): # SUB
Expand Down Expand Up @@ -304,14 +326,18 @@ def execute(self, m: Module):
def read_byte(self, m: Module, cycle: int, addr: Statement, comb_dest: Signal):
"""Reads a byte starting from the given cycle.
The byte read is combinatorically placed in comb_dest.
The byte read is combinatorically placed in comb_dest. If, however, comb_dest
is None, then the byte read is in Din. In either case, that value is only
valid for the cycle after the given cycle. If you want it after that, you will
have to store it yourself.
"""
with m.If(self.cycle == cycle):
m.d.ph1 += self.Addr.eq(addr)
m.d.ph1 += self.RW.eq(1)

with m.If(self.cycle == cycle + 1):
m.d.comb += comb_dest.eq(self.Din)
if comb_dest is not None:
m.d.comb += comb_dest.eq(self.Din)
if self.verification is not None:
self.formalData.read(m, self.Addr, self.Din)

Expand Down Expand Up @@ -374,6 +400,79 @@ def ALU(self, m: Module, func: ALU8Func, store: bool = True):
m.d.ph1 += self.a.eq(self.alu8)
self.end_instr(m, self.pc)

def ALU2(self, m: Module, func: ALU8Func, operand1: int, operand2: int, store: bool = True):
with m.If(self.mode == ModeBits.A.value):
m.d.comb += self.src8_1.eq(Mux(operand1, self.a, 0))
m.d.comb += self.src8_2.eq(Mux(operand2, self.a, 0))
m.d.comb += self.alu8_func.eq(func)
if store:
m.d.ph1 += self.a.eq(self.alu8)
self.end_instr(m, self.pc)

with m.Elif(self.mode == ModeBits.B.value):
m.d.comb += self.src8_1.eq(Mux(operand1, self.b, 0))
m.d.comb += self.src8_2.eq(Mux(operand2, self.b, 0))
m.d.comb += self.alu8_func.eq(func)
if store:
m.d.ph1 += self.b.eq(self.alu8)
self.end_instr(m, self.pc)

with m.Elif(self.mode == ModeBits.EXTENDED.value):
operand = self.mode_ext(m)
self.read_byte(m, cycle=2, addr=operand, comb_dest=None)

with m.If(self.cycle == 3):
m.d.comb += self.src8_1.eq(Mux(operand1, self.Din, 0))
m.d.comb += self.src8_2.eq(Mux(operand2, self.Din, 0))
m.d.comb += self.alu8_func.eq(func)
# Output during cycle 4:
m.d.ph1 += self.tmp8.eq(self.alu8)
m.d.ph1 += self.VMA.eq(0)
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.RW.eq(1)

with m.Elif(self.cycle == 4):
# Output during cycle 5:
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.Dout.eq(self.tmp8)
m.d.ph1 += self.RW.eq(0)
if not store:
m.d.ph1 += self.VMA.eq(0)

with m.Elif(self.cycle == 5):
if store:
if self.verification is not None:
self.formalData.write(m, self.Addr, self.Dout)
self.end_instr(m, self.pc)

with m.Elif(self.mode == ModeBits.INDEXED.value):
operand = self.mode_indexed(m)
self.read_byte(m, cycle=3, addr=operand, comb_dest=None)

with m.If(self.cycle == 4):
m.d.comb += self.src8_1.eq(Mux(operand1, self.Din, 0))
m.d.comb += self.src8_2.eq(Mux(operand2, self.Din, 0))
m.d.comb += self.alu8_func.eq(func)
# Output during cycle 5:
m.d.ph1 += self.tmp8.eq(self.alu8)
m.d.ph1 += self.VMA.eq(0)
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.RW.eq(1)

with m.If(self.cycle == 5):
# Output during cycle 6:
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.Dout.eq(self.tmp8)
m.d.ph1 += self.RW.eq(0)
if not store:
m.d.ph1 += self.VMA.eq(0)

with m.If(self.cycle == 6):
if store:
if self.verification is not None:
self.formalData.write(m, self.Addr, self.Dout)
self.end_instr(m, self.pc)

def BR(self, m: Module):
operand = self.mode_immediate8(m)

Expand Down Expand Up @@ -451,11 +550,13 @@ def STA(self, m: Module):
operand = self.mode_direct(m)

with m.If(self.cycle == 1):
# Output during cycle 2:
m.d.ph1 += self.VMA.eq(0)
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.RW.eq(1)

with m.If(self.cycle == 2):
# Output during cycle 3:
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.Dout.eq(Mux(b, self.b, self.a))
m.d.ph1 += self.RW.eq(0)
Expand All @@ -471,11 +572,13 @@ def STA(self, m: Module):
operand = self.mode_ext(m)

with m.If(self.cycle == 2):
# Output during cycle 3:
m.d.ph1 += self.VMA.eq(0)
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.RW.eq(1)

with m.If(self.cycle == 3):
# Output during cycle 4:
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.Dout.eq(Mux(b, self.b, self.a))
m.d.ph1 += self.RW.eq(0)
Expand All @@ -491,11 +594,13 @@ def STA(self, m: Module):
operand = self.mode_indexed(m)

with m.If(self.cycle == 3):
# Output during cycle 4:
m.d.ph1 += self.VMA.eq(0)
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.RW.eq(1)

with m.If(self.cycle == 4):
# Output during cycle 5:
m.d.ph1 += self.Addr.eq(operand)
m.d.ph1 += self.Dout.eq(Mux(b, self.b, self.a))
m.d.ph1 += self.RW.eq(0)
Expand Down Expand Up @@ -600,16 +705,20 @@ def mode_indexed(self, m: Module) -> Statement:
operand = self.tmp16

with m.If(self.cycle == 1):
# Output during cycle 2:
m.d.ph1 += self.tmp16[8:].eq(0)
m.d.ph1 += self.tmp16[:8].eq(self.Din)
m.d.ph1 += self.pc.eq(self.pc + 1)
m.d.ph1 += self.Addr.eq(self.pc + 1)
m.d.ph1 += self.RW.eq(1)
m.d.ph1 += self.VMA.eq(0)
if self.verification is not None:
self.formalData.read(m, self.Addr, self.Din)

with m.If(self.cycle == 2):
# Output during cycle 3:
m.d.ph1 += self.tmp16.eq(self.tmp16 + self.x)
m.d.ph1 += self.VMA.eq(0)

return operand

Expand Down
Loading

0 comments on commit 9d5cf9e

Please sign in to comment.