Skip to content

Latest commit

 

History

History
224 lines (160 loc) · 5.42 KB

design.org

File metadata and controls

224 lines (160 loc) · 5.42 KB

Assembler and VM for the BETA CPU

<2020-09-23 Wed>

The goal is to get tinyOS running on this, running a webserver that is keeping track of the VM state,

Maybe there is a display.

Assembler

Stages.

first stage defines the macros

second stage <2020-09-23 Wed>

expand the macros until they are all expanded. if there are any callable forms left, then a macro was not defined.

  • DONE all macro definitions need to go into the multiargument vector also, make a cleaner/std interface for storing/getting macros from the environment.
  • TODO consider assignments inside macros .. they should be local to the macro, or not be allowed at all.

stage three

Next byte to be assembled

this is tracked in the environment for now. lisp has dibs on the dot (.) char, so use ($) instead.

uasm uses . = 24 this will use (= $ 24)

Labels

Design mistake 1. <2020-09-26 Sat 08:04>

I waited until all the macros were expanded before figuring out when to increment the cur-byte-location assembler.

Clarify.

The cur-byte-location symbol $ is not replaced until the end because the users can set it will assignment, like

(set $ 123)

another thing:

$ $ $ $ $ will assemble to the byte sequence 0 1 2 3 4.

Here is the problem.

(set $ 0) (ADD $ $ $) …

should expand to 4 bytes

byte 0: 00 byte 1: 00 byte 2: 00 byte 3: 80

because the assembler should evaluate $ as 0 for all $ in the macro expansion. However, currently, since the macro is expanded into bytes and since all the $s are calculated at the end, then there is no way for the assembler to know that the bytes originating from the same macro are associated with the same $.

The problem manifests effectively as

(set $ 0) (ADD $ $ $) should be interpreted as (ADD 0 0 0)

Currently, it is interpreted erroneously as

(set $ = 0) (ADD 0 1 2)

modulo any reordering.

----

A solution <2020-09-26 Sat 09:35>

After the macro declaration pass, surround the top-level macrocalls (set $ = 0) (pause-incrementing-$) (ADD 0 1 2) (unpause-incrementing-$)

One more level of subtlety. pause-incrementing doesn’t mean that the assembler should stop keeping track of which byte location is currently being assembled at, only that when (current-byte-location) is called, that it returns the current-byte-location when pause-incrementing-$ was encountered.

Therefore, more state is needed.

paused-byte-location current-byte-location

An Aside

Maybe using a set of lisp macros to implement the ISA would be better.

Bug <2020-09-26 Sat 13:01>

(set $ 42)

not only must this set the cur-byte-location to 42, but it needs to fill from cur-location up to and including location 41 with zeros.

Bug <2020-09-30 Wed 10:29>

(test-assemble-beta ‘($ $ (betabr 0 0 0 4) $ $) (hexs :00000100 :0000ffff :00000908)) ;; test error: expecting (0 1 0 0 255 255 0 0 8 9 0 0), ;; got: (0 1 0 0 0 0 0 0 8 9 0 0)

Why 255 instead of 0? When should the 255 show up? Check the each pass to see when the digits 5 and 6 show up.

Could (.align) be causing problems?

this works fine: (test-assemble-beta ‘($ $ (add 0 0 0) $ $) (hexs :00000100 :80000000 :00000908))

this does not: (test-assemble-beta ‘($ $ $ $ (betabr 0 0 0 4)) (hexs :03020100 :0000ffff)) test error: expecting (0 1 2 3 255 255 0 0), got: (0 1 2 3 0 0 0 0)

this works fine: (test-assemble-beta ‘($ $ $ $ (betabr 0 0 0 0)) (hexs :03020100 :0000ffff))

Ok, so definitions:

(defmacro BETABR (OP RA RC LABEL)
   (betaopc OP RA (- (>> (- LABEL $) 2) 1) RC))


(defmacro betaopc (OP RA CC RC)
   (.align 4) 
   (WORD (+ (<< OP 26)
         (<< (% RC #x20) 21) 
         (<< (% RA #x20) 16) 
         (% CC #x10000))))

Check the JSIM source.

Test SHORT macro Test WORD macro

(assemble '((%
                (+ (<< 0 26)
                   (<< (% 0 32) 21)
                   (<< (% 0 32) 16)
                   (%
                    (-
                     (>> (- 4 0) 2)
                     1)
                    65536))
                256)))

inspect an earlier assembler pass.

(%
   (+ (<< 0 26)
      (<< (% 0 32) 21)
      (<< (% 0 32) 16)
      (%
       (-
        (>> (- 4 $) 2) ;; this dollar sign is evaluating to zero. Why?
        1)
       65536))
   256)

In which pass is it evaluating to zero? The replace-symbols function is replacing the $ with the wrong symbol.

The problem was an extraneous pass in the assembler that should have been deleted. All tests are passing now. <2020-10-01 Thu 15:53>

Finishing porting beta.uasm to beta.lisp <2020-10-01 Thu 18:01> ok.

Emulator

Back end

Microcode

  • Read 4 bytes as a 32-bit little-endian uint.
  • disassemble instruction.
  • run through microcode interpreter.

IO. Web-server <=> SBCL.

At the moment the emulator will be running in SBCL, controlled from the web browser.

Front end

Display

Modes
  • fast mode where entire video buffer is fetched in one step
  • slow mode where each pixel is fetched one per step
Video Memory

Where should the video memory live?

Specs

how big should the display be? 320x240? That’s 2400 words for 1-bit color display. for 8-bit color we’re looking at 19200 words, or 76K.

  • How about 160x120 with each display pixel equal to 4x4 screen pixels. (* 160 120) = 19200 pixels 4 pixels per word. (/ 19200 4) = 4800 words.

OPTIONAL - Running on WASM

How to run common lisp on WASM?