예제 #1
0
def char_lit_rom_mode():
    """C-LIT - word that reads a byte encoded in the thread, and pushes it to the stack"""
    label("forth.internal.C-LIT")
    adda(-(cost_of_char_lit_rom_mode // 2))

    ld(-(cost_of_char_lit_rom_mode // 2))
    C("Store cost")
    st([tmp0])

    ld([data_stack_pointer])
    C("Decrement Data stack pointer and store high byte of 0")
    suba(1)  # 5
    ld(AC, X)
    ld(0)
    st([X])
    ld([data_stack_pointer])
    suba(2)  # 10
    ld(AC, X)
    st([data_stack_pointer])

    ld([IP_hi], Y)
    C("Jump to the code in the thread")
    ld(5)
    C("We're going to shift the IP by 5")
    nop(
    )  # 15, to meet requirement of move-ip that we must use an even number of cycles
    jmp(Y, [IP_lo])
    ld(0x00, Y)  # 17
예제 #2
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _rshift__amount_lt_8():
    label("forth.core.RSHIFT.n<8")
    adda(-add_cost_of_next(cost_of_rshift__amount_lt_8) / 2)  # 1
    # ld(data_stack_page, Y) # Happen in head of page, but still counted
    # ld([data_stack_pointer], X)
    ld(lo("forth.core.RSHIFT.n<8.continuation1"))
    st([continuation])  # 5
    bra("right-shift-by-n")
    ld([amount])
    label("forth.core.RSHIFT.n<8.continuation1")
    st([Y, Xpp])
    ld(lo("forth.core.RSHIFT.n<8.continuation2"))
    st([continuation])  # 10
    bra("left-shift-by-n")
    ld([transfer_amount])
    label("forth.core.RSHIFT.n<8.continuation2")
    ld([data_stack_pointer], X)
    ora([Y, X])
    st([Y, Xpp])  # 15
    ld(lo("forth.core.RSHIFT.n<8.continuation3"))
    st([continuation])
    bra("right-shift-by-n.second-time")
    ld([mask])
    label("forth.core.RSHIFT.n<8.continuation3")
    st([Y, X])  # 20
    NEXT(cost_of_rshift__amount_lt_8)
예제 #3
0
def _copy_W_to_IP(*, increment_by):
    ld([W_hi])
    C(f"Copy [W] to [IP], incrementing it by {increment_by}")
    st([IP_hi])
    ld([W_lo])
    adda(increment_by)
    st([IP_lo])
예제 #4
0
def set():
    """Write a call value at an aligned address ( x a-addr -- )"""
    label("forth.core.!")
    adda(-add_cost_of_next(cost_of_set) / 2)  # 1
    ld(data_stack_page, Y)
    C("Remove 4 bytes from stack (SP moves by 4)")
    ld([data_stack_pointer])
    ld(AC, X)
    adda(4)  # 5
    st([data_stack_pointer])  # 6
    address_low, address_high, data_low, data_high = tmp0, tmp1, tmp2, tmp3
    C("Copy stack data and low part of address to temporary")
    for dest in [address_low, address_high, data_low]:
        ld([Y, X])  # 1
        st([dest])
        st([Y, Xpp])  # 3
    ld([Y, X])  # 1
    st([data_high])
    C("Load address")
    ld([address_low], X)
    ld([address_high], Y)
    C("Write data")
    ld([data_low])  # 5
    st([Y, Xpp])
    ld([data_high])
    st([Y, X])  # 8
    NEXT(cost_of_set)
예제 #5
0
def docol():
    "Code that should be inlined at the start of each core word"
    adda(-add_cost_of_next(cost_of_docol_ram) / 2)
    ld(hi("forth.DO-DOCOL-RAM"), Y)
    jmp(Y, "forth.DO-DOCOL-RAM")
    ld(return_stack_page, Y)  # 4
    docol_rom_only()  # 4 + 4
예제 #6
0
 def drop():
     label("forth.core." + name)
     adda(-add_cost_of_next(cost_of_drop) / 2)
     ld([data_stack_pointer])
     adda(size)
     st([data_stack_pointer])
     NEXT(cost_of_drop)
예제 #7
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _lshift__amount_lt_8():
    """LSHIFT (x1 u -- x2)

    Special case where u < 8
    """
    label("forth.core.LSHIFT.n<8")
    adda(-add_cost_of_next(cost_of_lshift__amount_lt_8) / 2)  # 1
    # ld(data_stack_page, Y)
    # ld([data_stack_pointer], X)
    ld(lo("forth.core.LSHIFT.n<8.continuation1"))
    st([continuation])  # 5
    bra("right-shift-by-n")
    ld([transfer_amount])
    label("forth.core.LSHIFT.n<8.continuation1")
    st([high_byte_temp])
    ld(lo("forth.core.LSHIFT.n<8.continuation2"))
    st([continuation])  # 10
    bra("left-shift-by-n")
    ld([amount])
    label("forth.core.LSHIFT.n<8.continuation2")
    st([Y, Xpp])
    ld(lo("forth.core.LSHIFT.n<8.continuation3"))
    st([continuation])  # 15
    bra("left-shift-by-n")
    ld([amount])
    label("forth.core.LSHIFT.n<8.continuation3")
    ora([high_byte_temp])
    st([Y, X])  # 19
    NEXT(cost_of_lshift__amount_lt_8)
예제 #8
0
파일: _next.py 프로젝트: psr/gigatron-rom
def exit(vTicks, vReturn):
    label("forth.exit")  # Counting down
    label("forth.exit.from-failed-test")
    ld(-(cost_of_failed_next1 + 1) / 2)  # 7
    label("forth.exit.from-next1-reenter")
    label("forth.exit.from-next2")
    adda([vTicks])  # 6
    ld(hi("vBlankStart"), Y)  # 5
    bgt(pc() & 0xFF)  # 4
    suba(1)  # 3
    jmp(Y, [vReturn])  # 2
    nop()  # 1
예제 #9
0
def invert():
    label("forth.core.INVERT")
    adda(-add_cost_of_next(cost_of_invert) / 2)  # 1
    ld(data_stack_page, Y)
    ld([data_stack_pointer], X)
    ld([Y, X])
    xora(0xFF)  # 5
    st([Y, Xpp])
    ld([Y, X])
    xora(0xFF)
    st([Y, X])  # 9
    NEXT(cost_of_invert)
예제 #10
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _rshift__amount_eq_8():
    # Offset to n==8 case = 3
    label("forth.core.RSHIFT.n==8")
    adda(-add_cost_of_next(cost_of_rshift__amount_eq_8) / 2)  # 1
    # ld(data_stack_page, Y) # Happen in head of page, but still counted
    # ld([data_stack_pointer], X)
    st([Y, Xpp])  # Blat low byte
    ld([Y, X])  # 5
    ld([data_stack_pointer], X)
    st([Y, Xpp])
    ld(0)
    st([Y, X])  # 9
    NEXT(cost_of_rshift__amount_eq_8)
예제 #11
0
파일: _next.py 프로젝트: psr/gigatron-rom
def next3_rom_head():
    """Start the process of next3"""
    label("forth.next3")
    label("forth.next3.rom-mode")
    adda(-(cost_of_next3_rom // 2))  # 1
    ld(-(cost_of_next3_rom // 2))  # 2
    st([tmp0])  # 3
    ld(W, X)  # 4
    ld(3)  # We're going to shift the IP by 3
    ld([IP_hi], Y)  # 6
    nop()  # 7
    jmp(Y, [IP_lo])  # 8
    ld(0x00, Y)  # 9
예제 #12
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _two_times():
    """Implements a left-shift by one which is used for two words

    2* ( x1 -- x2 )
    CELLS ( n1 -- n2 )

    """
    label("forth.core.2*")
    label("forth.core.CELLS")
    adda(-add_cost_of_next(cost_of_two_times) / 2)  # 1
    # ld(data_stack_page, Y)  # Implemented in page header, but still counted here.
    # ld([data_stack_pointer], X)
    C("Load low-byte")
    ld([X])
    anda(0b1000_0000, X)  # 5
    C("Calculate bit to shift in to the high-byte")
    ld([X])
    st([tmp0])
    ld([data_stack_pointer], X)
    C("Reload and left-shift")
    ld([X])
    adda(AC)  # 10
    st([Y, Xpp])
    ld([Y, X])
    C("Load high byte and left-shift")
    adda(AC)
    adda([tmp0])
    st([Y, X])  # 15
    NEXT(cost_of_two_times)
예제 #13
0
파일: _next.py 프로젝트: psr/gigatron-rom
def next3_ram_rom():
    """NEXT3 to use when in RAM->ROM mode"""
    label("forth.next3.ram-rom-mode")
    adda(-(cost_of_next3_ram_rom / 2))  # 1
    ld([IP_hi], Y)  # 2
    C("W <- [IP]")
    ld([IP_lo], X)  # 3
    ld([Y, X])  # 4
    st([W_lo])  # 5
    ld([IP_lo])  # 6
    adda(1)  # 7
    ld(AC, X)  # 8
    ld([Y, X])  # 9
    # Increment IP
    st([W_hi])  # 10
    C("IP <- IP + 2")
    ld([IP_lo])  # 11
    adda(2)  # 12
    beq(pc() + 5)  # 13
    st([IP_lo])  # 14
    REENTER(14)
    label(".page-boundary")
    ld([IP_hi])  # 15
    adda(1)  # 16
    st([IP_hi])  # 17
    REENTER(17)
예제 #14
0
def do_restore_mode():
    label("forth.DO-RESTORE-MODE")
    adda(-add_cost_of_reenter(cost_of_do_restore_mode) / 2)
    ld(return_stack_page, Y)
    ld([return_stack_pointer], X)
    ld([return_stack_pointer])
    adda(1)
    st([return_stack_pointer])
    ld([Y, X])
    st([mode])
    ld(0, Y)
    ld(W, X)
    st(lo("forth.core.EXIT"), [Y, Xpp])
    st(hi("forth.core.EXIT"), [Y, Xpp])  # 12
    REENTER(cost_of_do_restore_mode)
예제 #15
0
def branch_rom_mode():
    """Unconditional Branch ( -- )"""
    label("forth.internal.rom-mode.BRANCH")
    adda(-cost_of_branch_rom_mode // 2)  # 1

    ld(-(cost_of_branch_rom_mode // 2))
    C("Store cost")
    st([tmp0])

    ld(W, X)
    C("X <- W")

    ld([IP_hi], Y)  # 5
    C("Jump to the code in the thread")
    jmp(Y, [IP_lo])
    ld(0x00, Y)  # 7
예제 #16
0
파일: _next.py 프로젝트: psr/gigatron-rom
def move_ip():
    """Page-Zero code to move the IP by the amount contained in AC

    This routine is used by the ROM mode next3, and also by literal, branch and zero_branch.
    As these routines all have different lengths, it uses a variable (tmp0) to tell it what length to return

    It always jumps to forth.next1.reenter.odd, and it has an odd length itself code calling it must have an even length
    """
    assert pc() >> 8 == 0
    label("forth.move-ip")
    adda([IP_lo])  # 1
    st([IP_lo])  # 2
    ld(hi("forth.next1.reenter"), Y)  # 3
    C("REENTER")
    jmp(Y, lo("forth.next1.reenter.odd"))  # 4
    ld([tmp0])  # 5
예제 #17
0
def two_dup():
    label("forth.core.2DUP")
    adda(-add_cost_of_next(cost_of_2dup) / 2)  # 1
    ld(data_stack_page, Y)
    ld([data_stack_pointer], X)  # 3
    for tmp in [tmp0, tmp1, tmp2, tmp3]:
        ld([Y, X])
        st([tmp])
        st([Y, Xpp])  # 15 = 3 + 4 * 3
    ld([data_stack_pointer])
    suba(4)
    st([data_stack_pointer], X)  # 18
    for tmp in [tmp0, tmp1, tmp2, tmp3]:
        ld([tmp])
        st([Y, Xpp])  # 26 = 18 + 4 * 2
    NEXT(cost_of_2dup)
예제 #18
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _lshift__amount_eq_8():
    """LSHIFT (x1 u -- x2)

    Special case where u = 8
    """
    label("forth.core.LSHIFT.n==8")
    adda(-add_cost_of_next(cost_of_lshift__amount_eq_8) / 2)  # 1
    # ld(data_stack_page, Y)
    # ld([data_stack_pointer], X)
    ld([Y, X])
    st([tmp0])  # 5
    ld(0)
    st([Y, Xpp])
    ld([tmp0])
    st([Y, X])  # 9
    NEXT(cost_of_lshift__amount_eq_8)
예제 #19
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _right_shift_by_n(vtmp):
    """
    Fixed cost routine to do a right-shift by 1-7 places

    Shift amount is passed in NEGATED in ac, value is loaded from [y, x].
    Control is returned to address in continuation.
    In the case of a right-shift by between 1 and 7 places, this needs to
    be called twice. in which case we can jump to right-shift-by-n.second-time
    with mask in ac.
    """
    label("right-shift-by-n")
    st([tmp0])  # 1
    adda(".end-of-set_bits_table")
    bra(AC)  # 3
    bra(lo(".end-of-set_bits_table"))  # 4
    ld(0b0011_1111)  # Shift by 7
    ld(0b0001_1111)  # Shift by 6
    ld(0b0000_1111)  # Shift by 5
    ld(0b0000_0111)  # Shift by 4
    ld(0b0000_0011)  # Shift by 3
    ld(0b0000_0001)  # Shift by 2
    ld(0b0000_0000)  # Shift by 1
    label(".end-of-set_bits_table")
    st([set_bits])  # 6
    # Take the opportunity to set vTmp
    ld(lo("forth.right-shift-return-point"))
    st([vtmp])
    ld([tmp0])
    adda(".end-of-mask-table")
    bra(AC)  # 11
    bra(lo(".end-of-mask-table"))  # 12
    ld(0b1000_0000)  # Shift by 7
    ld(0b1100_0000)  # Shift by 6
    ld(0b1110_0000)  # Shift by 5
    ld(0b1111_0000)  # Shift by 4
    ld(0b1111_1000)  # Shift by 3
    ld(0b1111_1100)  # Shift by 2
    ld(0b1111_1110)  # Shift by 1
    label(".end-of-mask-table")
    st([mask])  # 14
    label("right-shift-by-n.second-time")
    anda([Y, X])  # 15, 1
    ora([set_bits])
    ld(hi("shiftTable"), Y)
    jmp(Y, AC)  # 18, 4
    bra(0xFF)  # 19, 5
예제 #20
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _rshift__amount_gt_8():
    # offset to n > 8 case
    label("forth.core.RSHIFT.n>8")
    adda(-add_cost_of_next(cost_of_rshift__amount_gt_8) / 2)  # 1
    # ld(data_stack_page, Y) # Happen in head of page, but still counted
    # ld([data_stack_pointer], X)
    ld(lo("forth.core.RSHIFT.n>8.continuation"))
    st([continuation])  # 5
    bra("right-shift-by-n")
    ld([amount])
    label("forth.core.RSHIFT.n>8.continuation")
    st([Y, Xpp])
    st([Y, Xpp])
    ld([data_stack_pointer], X)  # 10
    ld(0)
    st([Y, X])  # 12
    NEXT(cost_of_rshift__amount_gt_8)
예제 #21
0
파일: _next.py 프로젝트: psr/gigatron-rom
def next1_reenter(vTicks):
    label("forth.next1.reenter")
    label(
        "forth.next1.reenter.even"
    )  # When a word took an even number of cycles, enter here
    nop()  # 1
    label(
        "forth.next1.reenter.odd"
    )  # Inbound code should round down ticks, because counting is from .even
    suba((cost_of_successful_test + cost_of_next1_reenter_success) / 2)  # 2
    adda([vTicks])  # 3
    st([vTicks])  # 4; If we exit successfully we'll be ready for next1
    suba(cost_of_failed_test / 2)  # 5
    blt(lo("forth.exit.from-next1-reenter"))  # 6
    vticks_error = cost_of_next1_reenter_success - cost_of_next1_reenter_failure
    ld((vticks_error / 2))  # 7  ; load vTicks wrongness into A
    bra(lo("forth.next1"))  # 8
    ld([vTicks])  # 9
예제 #22
0
def char_at():
    label("forth.core.C@")
    adda(-add_cost_of_next(cost_of_char_at) / 2)  # 1
    ld(data_stack_page, Y)
    ld([data_stack_pointer], X)
    ld([Y, X])
    st([tmp0])  # 5
    st([Y, Xpp])
    ld([Y, X])
    ld(AC, Y)
    ld([tmp0], X)
    ld([Y, X])  # 10
    ld(data_stack_page, Y)
    ld([data_stack_pointer], X)
    st([Y, Xpp])
    ld(0)
    st([Y, X])  # 15
    NEXT(cost_of_char_at)
예제 #23
0
def decrement():
    "Subtract one from the top of the stack (n -- n)"
    label("forth.core.1-")
    adda(-add_cost_of_next(cost_of_decrement) / 2)  # 1
    ld(data_stack_page, Y)
    ld([data_stack_pointer], X)
    ld([Y, X])
    beq(lo(".low-byte-was-zero"))  # 5
    suba(1)  # 6
    st([Y, X])  # 7
    NEXT(cost_of_decrement__one_word_written)

    label(".low-byte-was-zero")
    st([Y, Xpp])  # 7
    ld([Y, X])
    suba(1)
    st([Y, X])  # 10
    NEXT(cost_of_decrement__two_words_written)
예제 #24
0
def dup():
    label("forth.core.DUP")
    adda(-add_cost_of_next(cost_of_dup) / 2)
    ld([data_stack_pointer], X)
    ld([X])
    st([tmp0])
    ld([data_stack_pointer])  # 5
    adda(1, X)
    ld([X])
    st([tmp1])
    ld(data_stack_page, Y)
    ld([data_stack_pointer])  # 10
    suba(2)
    st([data_stack_pointer], X)
    ld([tmp0])
    st([Y, Xpp])
    ld([tmp1])  # 15
    st([Y, X])  # 16
    NEXT(cost_of_dup)
예제 #25
0
def zero_equal():
    """Logical not ( x -- flag )

    flag is true if and only if x is equal to zero.
    """
    label("forth.core.0=")
    adda(-add_cost_of_next(cost_of_zero_equal) / 2)  # 1
    ld(data_stack_page, Y)
    ld([data_stack_pointer], X)
    ld([Y, X])
    st([Y, Xpp])  # 5
    ora([Y, X])
    beq(pc() + 3)  # 7
    bra(pc() + 3)  # 8
    ld(0x00)  # 9 - If any bits were non-zero
    ld(0xFF)  # 9 - Otherwise
    ld([data_stack_pointer], X)  # 10
    st([Y, Xpp])
    st([Y, X])  # 12
    NEXT(cost_of_zero_equal)
예제 #26
0
파일: _shift.py 프로젝트: psr/gigatron-rom
def _lshift__amount_gt_8():
    """LSHIFT (x1 u -- x2)

    Special case where u > 8
    """
    label("forth.core.LSHIFT.n>8")
    adda(-add_cost_of_next(cost_of_lshift__amount_gt_8) / 2)  # 1
    # ld(data_stack_page, Y)
    # ld([data_stack_pointer], X)
    ld(lo("forth.core.LSHIFT.n>8.continuation"))
    st([continuation])  # 5
    bra("left-shift-by-n")  # 6
    ld([amount])  # 7
    label("forth.core.LSHIFT.n>8.continuation")
    st([Y, Xpp])  # 1
    st([Y, Xpp])  # 2
    ld([data_stack_pointer], X)  # 3
    ld(0)  # 4
    st([Y, Xpp])  # 5
    NEXT(cost_of_lshift__amount_gt_8)
예제 #27
0
def swap():
    label("forth.core.SWAP")
    adda(-add_cost_of_next(cost_of_swap) / 2)
    C("Copy top 4 bytes of stack to tmp")
    ld([data_stack_pointer], X)
    ld([X])
    st([tmp0])  # 4
    # TODO: should this loop be in the assembly, or is unrolled better?
    for i, location in enumerate([tmp1, tmp2, tmp3], start=1):
        ld([data_stack_pointer])
        adda(i)
        ld(AC, X)
        ld([X])
        st([location])  # 5
    ld(data_stack_page, Y)
    C("Copy back to stack in order")
    ld([data_stack_pointer], X)  # 2
    for location in [tmp2, tmp3, tmp0, tmp1]:
        ld([location])
        st([Y, Xpp])  # 2
    NEXT(cost_of_swap)
예제 #28
0
def rot():
    label("forth.core.ROT")
    adda(-add_cost_of_next(cost_of_rot) / 2)
    ld(data_stack_page, Y)  # 2
    # copy 3OS -> tmp{0,1}
    for offset, dest in enumerate([tmp0, tmp1], start=4):
        ld([data_stack_pointer])
        adda(offset, X)
        ld([X])
        st([dest])
    # Shift Everything down, Filling with tmp{0,1}
    ld([data_stack_pointer], X)  # 11 = 2 + 2 * 4 + 1
    for to, from_ in zip([tmp2, tmp0, tmp1, tmp2], [tmp0, tmp1, tmp2, tmp0]):
        ld([X])
        st([to])
        ld([from_])
        st([Y, Xpp])
    for src in [tmp1, tmp2]:  # 27 = 11 + 16
        ld([src])
        st([Y, Xpp])
    NEXT(cost_of_rot)
예제 #29
0
def char_set():
    """Write a character at an address ( char c-addr -- )"""
    label("forth.core.C!")
    adda(-add_cost_of_next(cost_of_char_set) / 2)  # 1
    ld(data_stack_page, Y)
    C("Pop 2 byte address to temp (SP moves by 4)")
    ld([data_stack_pointer])
    ld(AC, X)
    adda(4)  # 5
    st([data_stack_pointer])  # 6
    for dest in [tmp0, tmp1]:
        ld([Y, X])
        st([dest])
        st([Y, Xpp])
    ld([Y, X])
    C("Load low-byte of char - top byte ignored")
    ld([tmp0], X)
    ld([tmp1], Y)
    st([Y, X])
    C("Write")
    NEXT(cost_of_char_set)
예제 #30
0
파일: _next.py 프로젝트: psr/gigatron-rom
def next2(vTicks):
    label("forth.next2")
    label("forth.next2.odd")
    nop()
    label("forth.next2.even")
    # On entry AC holds the negative of the number of ticks taken by the just executed instruction
    # To have entered the instruction we must have also had a successful test,
    suba((cost_of_successful_test + cost_of_next2_success) / 2)  # 1
    adda([vTicks])  # 2
    st([vTicks])  # 3; If we exit successfully we'll be ready for next1
    ld([mode])  # 4
    st([W_lo])  # 5
    ld(hi("forth.next3"))  # 6  # TODO
    st([W_hi])  # 7
    ld([vTicks])  # 8
    suba((cost_of_failed_test) / 2)  # 9
    blt(lo("forth.exit.from-next2"))  # 10
    tick_correction = cost_of_next2_success - cost_of_next2_failure
    ld(tick_correction / 2)  # 11; Restore
    bra(lo("forth.next1"))  # 12
    ld([vTicks])  # 13