Skip to content

Latest commit

 

History

History
664 lines (586 loc) · 19.7 KB

plan.org

File metadata and controls

664 lines (586 loc) · 19.7 KB

b4 implementation plan

– b4vm

– debugger

show labels in the debugger

  • defs could always be line-aligned (just leave spaces) and we could have a comment on the left

read/write individual bytes

rb/wb ri/wi

– stacks and registers are all 32 bits – but the main content can be bytes

– READ byte VS READ value (4 bytes) – -> s-eq? wants to read a byte at a time -> eol flag could just be a byte.

– but: we also want to write registers

[3/3] make the debug display easier to see

explicit ‘call’ op

use high bits for ops

switch ram to bytes

[2/2] add ‘step over’, ‘run to cursor’ in debugger

  • [X] ‘step over’ is only for calls. just move the cursor to the next active cell, and then ‘run to cursor’
  • [X] ‘run to cursor’ should move to next active cell, and then sets a breakpoint

show a prettier version of the return stack (with labels)

[ ] show a stack somewhere

show name for calls

[ ] show the label

allow setting breakpoints

source-level assembly language debugger

– b4a assembler

add !var and @var to assembler

b4a repl

you should be able to execute assembly language instructions directly (in the vm implementation itself)

  • maybe even show exactly how it’s getting assembled underneath
  • run opcodes directly
  • show stacks
  • show ram

have assembler use si, hop, h0 if possible

stacks are still cell-based

assembler plan

  • b4a should extend b3a with:
    • labels
    • special control words ( { } | [ ] .data .code )
    • call and $addr syntax
  • eventually, write b4a in b3a

b4a spec [runs on the b4 vm, so has a stack, etc]

  • immediate need: dictionary
  • adds labels
  • allow both decimal and hex numbers
  • .data to allow building raw binary data
    • counted strings
  • .code to make it nice to write forth-like code
    • auto-call functions
    • add ‘si’ or ‘li’ before chars, numbers
  • .dict to define a dictionary entry
  • structured programming constructs:
    • .if .th .el .ef .en
    • .wh .do .od
    • .fr .nx

use the new 2-char b4 opcodes

allow character literals with ‘x

macros for dictionary entries

maybe .xxx is label and :xxx is dictionary entry?

export binary numbers padded to proper size

implement enough of minno to allow in-band debug signals

only show debug messages when given a flag

escape the control codes in the output in debug mode

– bios

get a string match working

implement number parser

implement number printer

memory allocator

– interpreter (b4th? b4i?)

add dictionary entries for all non-control-flow ops

[2/4] implement the forth interpreter

[4/4] implement a forth-style dictionary

implement headers manually

implement ‘words’

implement ‘word?’ (s-a)

  • find definition
    • get last entry address
    • while entry address != 0 do:
      • use offset to find string
      • compare entry to goal string
      • if match, then leave address of value on stack
    • if entry = 0, say ‘not found’

interpreter word (exec)

complier words

  • if compiling:
    • write ‘call’ + address

defining words

’:’ defines new word

  • creates new entry
  • reads token for name
  • copies token to heap
  • turns on the compiler

’;’ emits return and turns off the compiler

dictionary entry format

  • prev: addr
  • hash: (optional single cell with 32-bit hash/crc)
  • word: str with len
  • data: the data or value

create new entry:

  • last @ ,
  • here @ last !
  • str,

‘str,’ copies a string

  • args: start, length
  • duplicate and write the length
  • copy the string

copy tokens to token buffer

  • read name
  • write name

look up and execute a single word

  • last
  • e-nm (“lb 4 ad”)
  • s-eq uses “inc” (“lb 1 ad”)
  • find (currently “word?”)

number/base

quote

repeatedly load tokens from input buffer

line editor

“calculator mode” (send ascii chars)

  • copy input bytes to buffer
  • let enter trigger word

read tokens from input buffer instead of keyboard

– implementations

[3/3] bring turbo vm in sync with j version

use hex numbers only in turbo b4a

pas: flags to configure loading bios

pas: include bios in the executable

– unclear

allow defining aliases up front in a table

– lessons

operations on state: simple calculator

  • visual ‘buttons’ that do the work
  • number buttons: multiply by base and add digit
  • clear, inc, dec?

sequence:

visual virtual machine

no-op, breakpoints

(so we can see the cursor moving)

place opcodes in the cells directly

repetition:

  • simple counter
  • implement addition, multiplication

conditionals

  • show jumping over some code
  • show ‘else’ using [a?] [b?] [c?] [d?]
  • so consider this instead: [ c ? a | b ]
  • now: [ c0 ? a | [ c1 ? b ] ]
  • so just allow ‘elif’

library mode to edit the input buffer directly

– ancient tasks from retro days

[4/9] implement io devices

port 1 : keyboard

port 2 : character generator

extend character generator with ability to change bitmap font

port 3 : force video update ( optional and not needed here )

[10/10] port 4 : file i/o

io op 1 | … -> 0 | save image

io op 2 | filename -> 0 | include a file

io op -1 | filename, mode -> handle | Open a file

io op -2 | handle -> flag | Read a byte from a file

io op -3 | character, handle -> flag | Write a byte to a file

io op -4 | handle -> flag | Close a file

io op -5 | handle -> offset | Return current location in file

io op -6 | offset, handle -> flag | Seek a new location in file

io op -7 | handle -> size | Return the size of a file

io op -8 | filename -> flag | Delete a file.

[0/1] port 5 : vm query

query op 10 | implement environment variables

http://www.freepascal.org/docs-html/rtl/sysutils/getenvironmentvariable.html

[0/8] port 6 : canvas

[#A] figure out the basic sdl / aggpas / ptckvm pipeline.

canvas op 1 | n- | set color for drawing operations

canvas op 2 | xy- | draw a pixel at coordinates x, y

canvas op 3 | xyhw- | rectangle

canvas op 4 | xyhw- | filled rect

canvas op 5 | xyh- | draw a vertical line of height (h) starting at x, y

canvas op 6 | xyw- | draw a horizontal line of width (w) starting at x, y

canvas op 7 | xyw- | draw a circle of width (w) starting at x, y

canvas op 8 | xyw- | draw a filled circle of width (w) starting at x, y

[0/2] port 7 : mouse

mouse op 1 | push mx, push my

mouse op 2 | push mb ( button state : 1 bit per button )

port 8 : enhanced text output

[0/1] show user-defined words in the debugger

procedure to walk the dictionary and extract details

define a record structure to hold the word

populate the fields

[0/12] exercise vm with more ngaro assembly programs

square : draw a square

color : draw the palette

click : click screen to change color

keys : press any key to change color

hello : show the word hello

caps : letters on screen (uppercase)

shift : captital letters / shift key

color : colored text input

read : read a file from disk

write : write a file to disk

port pixel.hex to pixel.nga

NOTE Just use the syntax retro gives when you type see

Retro 11.0 (1309798464)

ok  see ok
1423 nop
1424 nop
1425 lit   4
1427 @
1428 call  167
1429 0;
1430 drop
1431 call  421
1432 lit   54
1434 call  443
1435 ;

ok

memory manager to allow sharing pascal and retro data

{ � todo : custom memmory manager
  http://www.freepascal.org/docs-html/prog/progsu160.html#x205-2180008.4.4
}

{ retro's file format conventions ( see image/kernel.rx in retro source ) }
  type rx_header = class
		     prev, wordclass : int32;
		     docptr : ^ansistring;
		     xt     : ^ansistring; { h.xt = @h.code }
		     token  : ansistring;
		     code   : ansistring;
		   end;
  const
    rx_last  = 2;
    rx_xtofs = ;

– ancient wishlist

NOTE on contributing to this project

these are things that are off the critical path (for now)

[#A] is easy, [#B] medium, [#C] advanced

i could use help with the main tasklist, too, but:

usually discover i need something out of order
probably best to chat on freenode/#b4 if you want to work on main tasklist

licensing issues

  • if you contribute / port something, make sure license is MIT/ ISC compatible (retroforth license is ISC)
  • freepascal code has a tendency to use MPL/LGPL style. I’m okay with that, too.

WANT relational database (b4 has tiny relational database)

[#C] b-tree or b+-tree implementation

[#A] codd’s 8 relational operators

There is psuedocode for all 8 here:

http://science.kennesaw.edu/~mguimara/3310/RA_SQL.htm

WANT port of gamesketchlib to b4

I made the java/processing game library at http://gamesketchlib.org/ and will try to follow the same design patterns as I work on this system.

WANT python bytecode -> ngaro translator

[#A] research step : match up the two sets of bytecode

ngaro only has 30 instructions, python has around the same. There is much overlap, and in forth-like languages, it’s very easy to translate things like this.

So it’s possible that at least some python code should be able to run here.

The first step would be to compile a table that compares and contrasts the two sets of bytecode:

python dis module and the opcode section in ngaro-vm reference

?? pending above step, add new primitives to let us run python

probably the most dynamic aspects of python will not run well, but simpler python code probably can.

WANT modfile player.

I would really really like a modfile player for retro sounds and music. (don’t know what modfiles are? see http://modarchive.org/ )

[13:04] <dom96> I always wanted to compete in Ludum Dare. Sadly, nowadays there isn’t enough time. [13:05] <tangentstorm> http://web.archive.org/web/20080704164939/http://turcanator.tangentcode.com/ [13:05] <tangentstorm> this is a midi sequencer i wrote in pygame… i would love it if someone took that and turned it into the music engine for this system. [13:06] <tangentstorm> not the graphics part… but the time/synchronization code for the music events [13:07] <tangentstorm> to make something like this: http://www.photonstorm.com/flod

WANT render org-files to something more readable.

github makes org-code ugly

[#A] org itself does better job… make me a macro?

WANT standalone org-babel-tangle (preferably in pascal)

IDEA interface IDebuggable ?

It would probably have like a .tostring, plus menu options?

Not really sure what would be included in the interface, but I had the debugger in one section of my org-file for ngaro.pas.org, and then it got spread out.

IDEA ramdisk / image layout

things that need to be in ram somewhere early:

the first 256 cells are reserved for registers

they also leave room for 256 ngaro-style opcodes

(these may be device-specific opcodes, too)

first eight bytes should be magic # : utf-16 for the four corners

lookup the code points
the bios needs to fit in the next 512 bytes

map disk pages to ram (probably 4k blocks)

maybe give blocks a negative number to indicate system/hardware?
this makes sense, as we may have multiple machines in one image
btree for where things are laid out in memory

maybe a version number / hash for the interpreter config?

primary console video ram

the basic 256-character font (codepoints + 16 bytes)

the registers / stack for each machine

paging system

ngaro wants ram to be laid out in a specific way

the paging system would emulate contiguous ram

basically just like the processor does

WANT clarify interfaces between the modules

module io : high level input/output abstraction

module io_nw - network

module iokb - keyboard

module iohd - hard drive

module ioss - sound system

module iovm - interface to the vm itself

module ioip - interprocess communication

module vm : the virtual machine

module vt : virtual terminal

module ui : text widgets

module sg : scenegraph

IDEA create a simple game in pascal. translate to assembly. (mastermind?)

– b4th –

license and header

# b4th : a bootstrapped forth-like environment
# --------------------------------------------------------------
# <<isc-license>>
# --------------------------------------------------------------

layout of the image

header

<<b4:header>
JMP: --begin-- # jump over the data block
<<data>>
<<bios>>
:--begin--
<<boot>>
<<main>>

SECT data - the data block

Overview of the data block.

# -- DATA ------------------------------------------------------
<<data:end>

We will use the first 256-cell block (1KB) to hold global variables and system buffers.

Since the VM treats any number that is not an opcode as a call to a routine, this means the first 256 numbers can be used as opcodes. The default implementation requires only 30 opcodes, which leaves users plenty of room to add new opcodes if they want to experiment.

End data block.

Now, tell the assembler to pad the rest of the 256-cell block with zeros.

� # <- http://en.wikipedia.org/wiki/End_Transmission_Block_character

SECT bios - basic input/output system

# -- BIOS ------------------------------------------------------
:bios

SECT boot - the boot process

# -- BOOT --( boot process )------------------------------------

SECT main - main loop

#name: main
# -- MAIN --( the main loop of the system )---------------------
:mainloop
JMP: mainloop

describe the stack machine’s algorithm

simple flowchart

capture this with “ifso/else” syntax

NOTE . create an assembler via stepwise refinement

write an assembler in pascal-like psuedocode

show how to translate that psuedocode to instructions

NOTE . block usage policy

I’m thinking for now, I would follow the colorforth convention of putting documentation in the odd numbered blocks and source code in the even numbered blocks. Some blocks would also be binary blocks used by the kernel.

In fact, I could just stipulate that up front: the first 16KB are reserved for the system, input buffer, memory map, etc… So code would start at $10.

NOTE . block map

NOTE . core variables

NOTE . core listener

NOTE . hex assembler

NOTE . bootstrap system

NOTE . core compiler

def , (comma)

NOTE . dictionary routines

find a word in the dictionary

simple hash function

build a forth

identify the branch/jump opcodes

start with an infinite loop

break the loop

break on any key

Not really a loop at all, unless asking for a key blocks the cpu. An async version might check a specific port for a signal.

read the key

emit corresponding character to the screen

wait for specific key (C-c ? Esc ?)

accept a word

create a buffer

pack the string

lookup word in dictionary

traverse the chain

compare to ram

obtain the code and type fields

execute the code