Beispiel #1
0
def emit_kernel_words(vtmp):
    #### Page
    _start_page()
    _next.next3_rom_head()
    _next.next3_ram_rom()
    _next.next3_ram_ram()
    _docol_exit.do_restore_mode()
    _docol_exit.restore_mode()
    _docol_exit.exit()
    _docol_exit.docol_ram_ram()
    _memory.char_at()
    _memory.char_set()
    _arithmetic.increment()
    _arithmetic.decrement()
    _arithmetic.zero_equal()
    _literal.lit_rom_mode()
    _literal.char_lit_rom_mode()
    _branching.branch_rom_mode()
    ####
    _start_page()
    _branching.question_branch_rom_mode()
    _stackmanipulation.drop()
    _stackmanipulation.drop_two()
    _stackmanipulation.swap()
    _stackmanipulation.dup()
    _stackmanipulation.over()
    _stackmanipulation.rot()
    _stackmanipulation.two_swap()
    _arithmetic.bitwise()
    _arithmetic.invert()
    # No-op thread used for testing DOCOL and EXIT
    # This can probably be removed later
    label("forth.NOP")
    _docol_exit.make_thread()
    # Shifts have a special restart or quit trampoline to save space.
    align(0x100, 0x100)
    _shift.shift(vtmp)
    _start_page()
    _stackmanipulation.two_dup()
    _arithmetic.add()
    _memory.at()
    _memory.set()
    from . import _compiler

    _compiler.compile_file("core.f")
Beispiel #2
0
def setup_module():
    global vars, symbol_table, execution_address
    """Load the Emulator from the ROM script and Mandelbrot
    """
    reload(asm)
    name, _ = os.path.splitext(os.path.basename(SCRIPT))
    script_globals = {"__file__": str(SCRIPT.absolute()), "__name__": name}
    with SCRIPT.open("rb") as file:
        exec(compile(file.read(), SCRIPT, "exec"), script_globals)
    Emulator.load_rom_from_asm_module()
    vars = SimpleNamespace(**script_globals)

    # This sequence of calls is roughly taken from compilegcl.py
    old_rom_size = asm._romSize
    program = gcl.Program("Mandelbrot", forRom=False)
    user_code = asm.symbol("userCode")
    user_vars = asm.symbol("userVars")
    program.org(user_code)
    asm.align(1)
    asm.zpReset(user_vars)
    with GCL.open("r", encoding="utf-8") as fp:
        for line in fp.readlines():
            program.line(line)
    program.end()
    asm.end()

    # Copy the resulting data straight into RAM, in the appropriate blocks
    data = asm.getRom1()[old_rom_size:]
    index, more_data = 0, bool(data)
    while more_data:
        start_address = int.from_bytes(data[index:index + 2],
                                       "big",
                                       signed=False)
        index += 2
        size = data[index] or 256
        index += 1
        chunk = data[index:index + size]
        index += size
        RAM[start_address:start_address + len(chunk)] = chunk
        more_data = data[index]
    execution_address = program.execute
    symbol_table = program.vars
Beispiel #3
0
def emit_entry_page(vticks, vreturn):
    """Emit the data for NEXT and some other core routines

    The first page does not have the 'restart-or-quit' trampoline at 0x00
    So we can't put any Forth word in here.
    """
    while pc() & 255 < 255:
        nop()
    assert _next.INTERPRETER_ENTER_PAGE == pc() >> 8
    label("FORTH_ENTER")
    C("You are now entering... Forth")
    adda(_next.INBOUND_TICK_CORRECTION)
    # --- Page boundary ---
    align(0x100, 0x100)
    st([vticks])
    _next.next1(vticks)
    _next.next1_reenter(vticks)
    _next.next2(vticks)
    _next.exit(vticks, vreturn)
    _docol_exit.do_docol_rom()
    _docol_exit.do_docol_ram()
Beispiel #4
0
#-----------------------------------------------------------------------
#       Compile
#-----------------------------------------------------------------------

asm.loadBindings(args.sym)
if args.gt1x:
  asm.loadBindings('Core/interface-dev.json')

userCode = asm.symbol('userCode')
userVars = asm.symbol('userVars')

print('Compiling file %s' % args.gclSource)
program = gcl.Program('Main', forRom=False)
program.org(userCode)
asm.align(1)          # Forces default maximum ROM size
asm.zpReset(userVars) # User variables can start here
for line in open(args.gclSource).readlines():
  program.line(line)
program.end()
asm.end() # End assembly
data = asm.getRom1()

#-----------------------------------------------------------------------
#       Append ending
#-----------------------------------------------------------------------

address = program.execute

# Inject patch for reliable start using ROM v1 Loader application
# See: https://forum.gigatron.io/viewtopic.php?p=27#p27
result = zpByte(2)
# Used for storage
tmp = zpByte()
# Used for the continuation address after lookup.
continuation = zpByte()
# Used for the action to take with the high byte.
high_byte_action = zpByte()

# The following code implements a lookup table of floored quarter squares,
# for values up to 255.
# This is supposed to enable a fast multiplication for 7-bit numbers.

# First the high-bytes.
# The table is shifted down by 32 places, as the first 32 high-bytes are all zero
# This allows us to have code later in the page which we can branch back to.
align(0x100, size=0x100)
label("Quarter-squares lookup table")
for i in range(32, 256):
    val = math.floor(i**2 / 4)
    ld(hi(val))
    C(f"${val:04x} = {val} = floor({i} ** 2 / 4); ${val:04x} >> 8 = ${val >> 8:02x}"
      )

# We jump back here after looking up the low-byte of the result.
label("low-byte return point")
ld(hi("multiply 7x7"), Y)
jmp(Y, [continuation])
ld(hi(pc()), Y)  # Make it easy to get back here!
cost_of_low_byte_return = 3
label("table entry.possibly-negative")
# AC is negative, if b > a. Find absolute value
Beispiel #6
0
def _start_page():
    align(0x100, 0x100)
    _next.restart_or_quit()