Franck Pommereau

changed div operation, updated mod macro

......@@ -137,11 +137,9 @@ stdlib = """
%ifndef mod
%def mod left right result
# ➡️ `div left right result`<br>
# ▶️ `mul result right result`<br>
# ▶️ `sub left result result`
# ▶️ `mov CR`
div left right result
mul result right result
sub left result result
mov CR result
%end
%endif
%ifndef intr
......@@ -162,7 +160,7 @@ stdlib = """
# if `target` is a register
# ➡️ `clr target`
# otherwise
# ➡️ `cla` target
# ➡️ `cla target`
%ifreg target
clr target
%else
......@@ -455,7 +453,7 @@ def parse_num (literal, kind="W") :
return (int(literal, int(base)) + info.numbias[kind]) % _MOD[kind]
_esc = {"\\" : "\\",
"'" : "'",
"'" : "'",
'"' : '"',
"a" : "\a",
"b" : "\b",
......
......@@ -294,7 +294,7 @@ class CPU (object) :
await self.setreg("CR", carry)
@trace("cpu.op.sub")
async def op_sub (self, left, right, target) :
#2RRR set `target` to `left` - `right`
#2RRR set `target` to `left` - `right` with carry in `CR`
lft = await self.getreg(left)
rgt = await self.getreg(right)
val = lft - rgt
......@@ -307,7 +307,7 @@ class CPU (object) :
await self.setreg("CR", carry)
@trace("cpu.op.mul")
async def op_mul (self, left, right, target) :
#3RRR set `target` to `left` * `right`
#3RRR set `target` to `left` * `right` with carry in `CR`
lft = await self.getreg(left)
rgt = await self.getreg(right)
carry, val = divmod(lft * rgt, INT_MOD)
......@@ -315,15 +315,15 @@ class CPU (object) :
await self.setreg("CR", carry)
@trace("cpu.op.div")
async def op_div (self, left, right, target) :
#4RRR set `target` to `left` / `right`
#4RRR set `target` to `left` / `right` with remainder in `CR`
lft = await self.getreg(left)
rgt = await self.getreg(right)
if rgt == 0 :
await self.setintr(IRQ_CPUERR)
else :
val = lft // rgt
val, rem = divmod(lft, rgt)
await self.setreg(target, val)
await self.setreg("CR", 0)
await self.setreg("CR", rem)
@trace("cpu.op.and")
async def op_and (self, left, right, target) :
#5RRR set `target` to `left` AND `right`
......
......@@ -2,7 +2,7 @@ codeop2mnemo = {'0000': 'halt', '0001': 'nop', '0002': 'iret', '0003': 'ret', '0
mnemo2codeop = {'halt': '0000', 'nop': '0001', 'iret': '0002', 'ret': '0003', 'cla': '0004', 'nintr': '001', 'rintr': '002', 'clr': '003', 'reset': '004', 'set': '005', 'push': '006', 'pop': '007', 'inc': '008', 'dec': '009', 'rand': '00A', 'zset': '01', 'nzset': '02', 'mov': '03', 'not': '04', 'ld': '05', 'st': '06', 'add': '1', 'sub': '2', 'mul': '3', 'div': '4', 'and': '5', 'or': '6', 'lshift': '7', 'rshift': '8', 'eq': '9', 'gt': 'A', 'zmov': 'B', 'nzmov': 'C', 'ldi': 'D', 'sti': 'E', 'bus': 'F'}
parameters = {'halt': (), 'nop': (), 'iret': (), 'ret': (), 'cla': (), 'nintr': (('num', 'S'),), 'rintr': (('reg', 'R'),), 'clr': (('target', 'R'),), 'reset': (('reg', 'R'),), 'set': (('reg', 'R'),), 'push': (('reg', 'R'),), 'pop': (('reg', 'R'),), 'inc': (('reg', 'R'),), 'dec': (('reg', 'R'),), 'rand': (('reg', 'R'),), 'zset': (('test', 'R'), ('reg', 'R')), 'nzset': (('test', 'R'), ('reg', 'R')), 'mov': (('source', 'R'), ('target', 'R')), 'not': (('source', 'R'), ('target', 'R')), 'ld': (('address', 'R'), ('target', 'R')), 'st': (('source', 'R'), ('address', 'R')), 'add': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'sub': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'mul': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'div': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'and': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'or': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'lshift': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'rshift': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'eq': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'gt': (('left', 'R'), ('right', 'R'), ('target', 'R')), 'zmov': (('test', 'R'), ('source', 'R'), ('target', 'R')), 'nzmov': (('test', 'R'), ('source', 'R'), ('target', 'R')), 'ldi': (('target', 'R'), ('shift', 'B')), 'sti': (('source', 'R'), ('shift', 'B')), 'bus': (('command', 'R'), ('address', 'R'), ('data', 'R'))}
extra = {'halt': (), 'nop': (), 'iret': (), 'ret': (), 'cla': ('W',), 'nintr': (), 'rintr': (), 'clr': (), 'reset': (), 'set': ('W',), 'push': (), 'pop': (), 'inc': (), 'dec': (), 'rand': (), 'zset': ('W',), 'nzset': ('W',), 'mov': (), 'not': (), 'ld': (), 'st': (), 'add': (), 'sub': (), 'mul': (), 'div': (), 'and': (), 'or': (), 'lshift': (), 'rshift': (), 'eq': (), 'gt': (), 'zmov': (), 'nzmov': (), 'ldi': (), 'sti': (), 'bus': ()}
description = {'halt': 'power off the machine', 'nop': 'keep the CPU idle for one cycle', 'iret': 'return from an interrupt', 'ret': 'return from a subroutine', 'cla': 'call the subroutine whose address is stored in next word', 'nintr': 'raise interrupt number `num`', 'rintr': 'raise interrupt whose number is stored in `reg`', 'clr': 'call the subroutine whose address is stored in `target`', 'reset': 'set register `reg` to zero', 'set': 'assign the word following the instruction to register `reg`', 'push': 'push the value stored in register `reg` onto the stack', 'pop': 'pop one word from the stack into register `reg`', 'inc': 'increment register `reg` by 1', 'dec': 'decrement register `reg` by 1', 'rand': 'assign register `reg` with a random value', 'zset': 'do `set reg` if `test` holds zero', 'nzset': 'do `set reg` if `test` does not hold zero', 'mov': 'copy the value of register `source` to `target`', 'not': 'set `target` to the binary negation of `source`', 'ld': 'load the word whose address is in `address` into `target`', 'st': 'store the value of `source` onto the address in `address`', 'add': 'set `target` to `left` + `right` with carry in `CR`', 'sub': 'set `target` to `left` - `right`', 'mul': 'set `target` to `left` * `right`', 'div': 'set `target` to `left` / `right`', 'and': 'set `target` to `left` AND `right`', 'or': 'set `target` to `left` OR `right`', 'lshift': 'set `target` to `left` << `right` (left-shift)', 'rshift': 'set `target` to `left` >> `right` (right-shift)', 'eq': 'set `target` to `left` == `right` (FFFF is True, 0000 is False)', 'gt': 'set `target` to `left` > `right` (FFFF is True, 0000 is False)', 'zmov': 'do `mov source target` if `test` holds zero', 'nzmov': 'do `mov source target` if `test` does not hold zero', 'ldi': 'load the word at address `BP`+`shift` (signed) into `target`', 'sti': 'store `source` onto address `BP`+`shift` (signed)', 'bus': 'activate the bus passing/updating `command`/`address`/`data` registers'}
description = {'halt': 'power off the machine', 'nop': 'keep the CPU idle for one cycle', 'iret': 'return from an interrupt', 'ret': 'return from a subroutine', 'cla': 'call the subroutine whose address is stored in next word', 'nintr': 'raise interrupt number `num`', 'rintr': 'raise interrupt whose number is stored in `reg`', 'clr': 'call the subroutine whose address is stored in `target`', 'reset': 'set register `reg` to zero', 'set': 'assign the word following the instruction to register `reg`', 'push': 'push the value stored in register `reg` onto the stack', 'pop': 'pop one word from the stack into register `reg`', 'inc': 'increment register `reg` by 1', 'dec': 'decrement register `reg` by 1', 'rand': 'assign register `reg` with a random value', 'zset': 'do `set reg` if `test` holds zero', 'nzset': 'do `set reg` if `test` does not hold zero', 'mov': 'copy the value of register `source` to `target`', 'not': 'set `target` to the binary negation of `source`', 'ld': 'load the word whose address is in `address` into `target`', 'st': 'store the value of `source` onto the address in `address`', 'add': 'set `target` to `left` + `right` with carry in `CR`', 'sub': 'set `target` to `left` - `right` with carry in `CR`', 'mul': 'set `target` to `left` * `right` with carry in `CR`', 'div': 'set `target` to `left` / `right` with remainder in `CR`', 'and': 'set `target` to `left` AND `right`', 'or': 'set `target` to `left` OR `right`', 'lshift': 'set `target` to `left` << `right` (left-shift)', 'rshift': 'set `target` to `left` >> `right` (right-shift)', 'eq': 'set `target` to `left` == `right` (FFFF is True, 0000 is False)', 'gt': 'set `target` to `left` > `right` (FFFF is True, 0000 is False)', 'zmov': 'do `mov source target` if `test` holds zero', 'nzmov': 'do `mov source target` if `test` does not hold zero', 'ldi': 'load the word at address `BP`+`shift` (signed) into `target`', 'sti': 'store `source` onto address `BP`+`shift` (signed)', 'bus': 'activate the bus passing/updating `command`/`address`/`data` registers'}
regname = ['R0', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8', 'R9', 'BP', 'CR', 'IR', 'MR', 'IP', 'SP']
regnum = {'R0': 0, 'R1': 1, 'R2': 2, 'R3': 3, 'R4': 4, 'R5': 5, 'R6': 6, 'R7': 7, 'R8': 8, 'R9': 9, 'BP': 10, 'CR': 11, 'IR': 12, 'MR': 13, 'IP': 14, 'SP': 15}
regdoc = {'BP': 'base pointer for `ldi` and `sti`', 'CR': 'carry register', 'IR': 'instruction register', 'MR': 'interrupt mask register', 'IP': 'instruction pointer', 'SP': 'stack pointer'}
......
......@@ -492,7 +492,8 @@ class ShellRunner (Runner) :
- intr: CPU interrupt vector
- clock: CPU clock ticks
- [ADDR], [ADDR:ADDR]: RAM content at specific address or range
- screen: text screen
- screen: text screen with colors
- screen.text: text screen as ASCII text
"""
for comp in component :
if comp in self.eval_env :
......@@ -553,6 +554,8 @@ class ShellRunner (Runner) :
base += 8
elif comp == "screen" :
print(self.ttc.screen.ansi())
elif comp == "screen.text" :
print(self.ttc.screen.ascii())
else :
self.err(f"cannot print unknown component {comp!r}")
......
......@@ -78,11 +78,11 @@
* `add left right target`<br>
set `target` to `left` + `right` with carry in `CR`
* `sub left right target`<br>
set `target` to `left` - `right`
set `target` to `left` - `right` with carry in `CR`
* `mul left right target`<br>
set `target` to `left` * `right`
set `target` to `left` * `right` with carry in `CR`
* `div left right target`<br>
set `target` to `left` / `right`
set `target` to `left` / `right` with remainder in `CR`
* `and left right target`<br>
set `target` to `left` AND `right`
* `or left right target`<br>
......@@ -131,8 +131,7 @@
➡️ `nzset test IP target`
* `mod left right result`<br>
➡️ `div left right result`<br>
▶️ `mul result right result`<br>
▶️ `sub left result result`
▶️ `mov CR`
* `intr nbr`<br>
if `nbr` is a register
➡️ `rintr nbr`<br>
......@@ -142,7 +141,7 @@
if `target` is a register
➡️ `clr target`
otherwise
➡️ `cla` target
➡️ `cla target`
# Preprocessor
......