Update README.md

This commit is contained in:
David Schmenk 2014-04-29 19:51:48 -07:00
parent d2083d19a1
commit 1c96bcf3c8

View File

@ -15,72 +15,72 @@ PLASMA takes an approach that uses the best of all the above implementations to
The PLASMA low level operations are defined as: The PLASMA low level operations are defined as:
OP | Description |OP | Description
----------------------------------------- -----------------------------------------
ZERO | push zero on the stack |ZERO | push zero on the stack
DROP | drop top stack value |DROP | drop top stack value
DUP | duplicate top stack value |DUP | duplicate top stack value
OVER | duplicate next from top stack value |OVER | duplicate next from top stack value
SWAP | swap two topmost stack values |SWAP | swap two topmost stack values
ADD | add top two values, leave result on top |ADD | add top two values, leave result on top
SUB | subtract next from top from top, leave result on top |SUB | subtract next from top from top, leave result on top
MUL | multiply two topmost stack values, leave result on top |MUL | multiply two topmost stack values, leave result on top
DIV | divide next from top by top, leave result on top |DIV | divide next from top by top, leave result on top
MOD | divide next from top by top, leave remainder on top |MOD | divide next from top by top, leave remainder on top
INCR | increment top of stack |INCR | increment top of stack
DECR | decrement top of stack |DECR | decrement top of stack
NEG | negate top of stack |NEG | negate top of stack
COMP | compliment top of stack |COMP | compliment top of stack
BAND | bit wise AND top two values, leave result on top |BAND | bit wise AND top two values, leave result on top
IOR | bit wise inclusive OR top two values, leave result on top |IOR | bit wise inclusive OR top two values, leave result on top
XOR | bit wise exclusive OR top two values, leave result on top |XOR | bit wise exclusive OR top two values, leave result on top
NOT | logical NOT of top of stack |NOT | logical NOT of top of stack
LOR | logical OR top two values, leave result on top |LOR | logical OR top two values, leave result on top
LAND | logical AND top two values, leave result on top |LAND | logical AND top two values, leave result on top
SHL | shift left next from top by top, leave result on top |SHL | shift left next from top by top, leave result on top
SHR | shift right next from top by top, leave result on top |SHR | shift right next from top by top, leave result on top
IDXB | add top of stack to next from top, leave result on top |IDXB | add top of stack to next from top, leave result on top
IDXW | add 2X top of stack to next from top, leave result on top |IDXW | add 2X top of stack to next from top, leave result on top
LAA | load absolute address |LAA | load absolute address
LLA | load local address from frame offset |LLA | load local address from frame offset
CB | constant byte |CB | constant byte
CW | constant word |CW | constant word
LB | load byte from top of stack address |LB | load byte from top of stack address
LW | load word from top of stack address |LW | load word from top of stack address
LLB | load byte from frame offset |LLB | load byte from frame offset
LLW | load word from frame offset |LLW | load word from frame offset
LAB | load byte from absolute address |LAB | load byte from absolute address
LAW | load word from absolute address |LAW | load word from absolute address
SB | store top of stack byte into next from top address |SB | store top of stack byte into next from top address
SW | store top of stack word into next from top address |SW | store top of stack word into next from top address
SLB | store top of stack into local byte at frame offset |SLB | store top of stack into local byte at frame offset
SLW | store top of stack into local word at frame offset |SLW | store top of stack into local word at frame offset
SAB | store top of stack into byte at absolute address |SAB | store top of stack into byte at absolute address
SAW | store top of stack into word at absolute address |SAW | store top of stack into word at absolute address
DLB | duplicate top of stack into local byte at frame offset |DLB | duplicate top of stack into local byte at frame offset
DLW | duplicate top of stack into local word at frame offset |DLW | duplicate top of stack into local word at frame offset
DAB | duplicate top of stack into byte at absolute address |DAB | duplicate top of stack into byte at absolute address
DAW | duplicate top of stack into word at absolute address |DAW | duplicate top of stack into word at absolute address
BRGT | branch next from top greater than top |BRGT | branch next from top greater than top
BRLT | branch next from top less than top |BRLT | branch next from top less than top
BREQ | branch next from top equal to top |BREQ | branch next from top equal to top
BRNE | branch next from top not equal to top |BRNE | branch next from top not equal to top
ISEQ | if next from top is equal to top, set top true |ISEQ | if next from top is equal to top, set top true
ISNE | if next from top is not equal to top, set top true |ISNE | if next from top is not equal to top, set top true
ISGT | if next from top is greater than top, set top true |ISGT | if next from top is greater than top, set top true
ISLT | if next from top is less than top, set top true |ISLT | if next from top is less than top, set top true
ISGE | if next from top is greater than or equal to top, set top true |ISGE | if next from top is greater than or equal to top, set top true
ISLE | if next from top is less than or equal to top, set top true |ISLE | if next from top is less than or equal to top, set top true
BRFLS | branch if top of stack is zero |BRFLS | branch if top of stack is zero
BRTRU | branch if top of stack is non-zero |BRTRU | branch if top of stack is non-zero
BRNCH | branch to address |BRNCH | branch to address
CALL | sub routine call with stack parameters |CALL | sub routine call with stack parameters
ICAL | sub routine call to indirect address on stack top with stack parameters |ICAL | sub routine call to indirect address on stack top with stack parameters
ENTER | allocate frame size and copy stack parameters to local frame |ENTER | allocate frame size and copy stack parameters to local frame
LEAVE | deallocate frame and return from sub routine call |LEAVE | deallocate frame and return from sub routine call
RET | return from sub routine call |RET | return from sub routine call
PUSH | push top to call stack |PUSH | push top to call stack
PULL | pull from call stack |PULL | pull from call stack
##PLASMA Compiler/Assembler ##PLASMA Compiler/Assembler
@ -192,51 +192,50 @@ Expressions are algebraic. Data is free-form, but all operations on the evaluat
More complex expressions can be built up using algebraic unary and binary operations. More complex expressions can be built up using algebraic unary and binary operations.
OP | Unary Operation |OP | Unary Operation
-------------------------- |--------------------------
^ | byte pointer |^ | byte pointer
* | word pointer |* | word pointer
@ | address of |@ | address of
- | negate |- | negate
# | bitwise compliment |# | bitwise compliment
! | logical NOT |! | logical NOT
OP | Binary Operation |OP | Binary Operation
--------------------------- |---------------------------
* | multiply |* | multiply
/ | divide |/ | divide
% | modulo |% | modulo
+ | add |+ | add
- | subtract |- | subtract
<< | shift left |<< | shift left
>> | shift right |>> | shift right
& | bitwise AND |& | bitwise AND
| | bitwise OR || | bitwise OR
^ | bitwise XOR |^ | bitwise XOR
== | equals |== | equals
<> | not equal |<> | not equal
>= | greater than or equal |>= | greater than or equal
> | greater than |> | greater than
<= | less than or equal |<= | less than or equal
< | less than |< | less than
OR | logical OR |OR | logical OR
AND | logical AND |AND | logical AND
Statements are built up from expressions and control flow keywords. Simplicity of syntax took precedence over flexibility and complexity. The simplest statement is the basic assignment using =. Statements are built up from expressions and control flow keywords. Simplicity of syntax took precedence over flexibility and complexity. The simplest statement is the basic assignment using =.
<code> ```
byte numchars byte numchars
numchars = 0 numchars = 0
</code> ```
Expressions can be built up with constants, variables, function calls, addresses, and pointers/arrays. Comparison operators evaluate to 0 or -1 instead of the more traditional 0 or 1. The use of -1 allows binary operations to be applied to other non-zero values and still retain a non-zero result. Any conditional tests check only for zero and non-zero values. Expressions can be built up with constants, variables, function calls, addresses, and pointers/arrays. Comparison operators evaluate to 0 or -1 instead of the more traditional 0 or 1. The use of -1 allows binary operations to be applied to other non-zero values and still retain a non-zero result. Any conditional tests check only for zero and non-zero values.
Control structures affect the flow of control through the program. There are conditional and looping constructs. The most widely used is probably the if/elsif/else/fin construct. Control structures affect the flow of control through the program. There are conditional and looping constructs. The most widely used is probably the if/elsif/else/fin construct.
<code> ```
if ^pushbttn3 < 128 if ^pushbttn3 < 128
if key == $C0 if key == $C0
key = $D0 ; P key = $D0 ; P
elsif key == $DD elsif key == $DD
@ -244,15 +243,15 @@ if ^pushbttn3 < 128
elsif key == $DE elsif key == $DE
key = $CE ; N key = $CE ; N
fin fin
else else
key = key ? $E0 key = key ? $E0
fin fin
</code> ```
The when/is/otherwise/merge statement is similar to the if/elsif/else/fin construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. However only the 'when' value is compared against a list of expressions. The expressions do not need to be constants, they can be any valid expression. The list of expressions is evaluated in order, so for efficiency sake, place the most common cases earlier in the list. The when/is/otherwise/merge statement is similar to the if/elsif/else/fin construct except that it is more efficient. It selects one path based on the evaluated expressions, then merges the code path back together at the end. However only the 'when' value is compared against a list of expressions. The expressions do not need to be constants, they can be any valid expression. The list of expressions is evaluated in order, so for efficiency sake, place the most common cases earlier in the list.
<code> ```
when keypressed when keypressed
is keyarrowup is keyarrowup
cursup cursup
is keyarrowdown is keyarrowdown
@ -271,59 +270,59 @@ when keypressed
redraw redraw
otherwise otherwise
bell bell
wend wend
</code> ```
The most common looping statement is the for/next construct. The most common looping statement is the for/next construct.
<code> ```
for xscan = 0 to 19 for xscan = 0 to 19
(scanptr):[xscan] = val (scanptr):[xscan] = val
next next
</code> ```
The for/next statement will efficiently increment or decrement a variable form the starting value to the ending value. The increment/decrement amount can be set with the step option after the ending value; the default is one. If the ending value is less than the starting value, use downto instead of to to progress in the negative direction. Only use positive step values. The to or downto will add or subtract the step value appropriately. The for/next statement will efficiently increment or decrement a variable form the starting value to the ending value. The increment/decrement amount can be set with the step option after the ending value; the default is one. If the ending value is less than the starting value, use downto instead of to to progress in the negative direction. Only use positive step values. The to or downto will add or subtract the step value appropriately.
<code> ```
for i = heapmapsz - 1 downto 0 for i = heapmapsz - 1 downto 0
if sheapmap.[i] <> $FF if sheapmap.[i] <> $FF
mapmask = szmask mapmask = szmask
fin fin
next next
</code> ```
while/loop statements will continue looping as long as the while expression is non-zero. while/loop statements will continue looping as long as the while expression is non-zero.
<code> ```
while !(mask & 1) while !(mask & 1)
addr = addr + 16 addr = addr + 16
mask = mask >> 1 mask = mask >> 1
loop loop
</code> ```
Lastly, the repeat/until statement will continue looping as long as the until expression is zero. Lastly, the repeat/until statement will continue looping as long as the until expression is zero.
<code> ```
repeat repeat
txtbuf = read(refnum, @txtbuf + 1, maxlnlen) txtbuf = read(refnum, @txtbuf + 1, maxlnlen)
numlines = numlines + 1 numlines = numlines + 1
until txtbuf == 0 or numlines == maxlines until txtbuf == 0 or numlines == maxlines
</code> ```
Runtime #Runtime
PLASMA includes a very minimal runtime that nevertheless provides a great deal of functionality to the system. Two system calls are provided to access native 6502 routines (usually in ROM) and ProDOS. PLASMA includes a very minimal runtime that nevertheless provides a great deal of functionality to the system. Two system calls are provided to access native 6502 routines (usually in ROM) and ProDOS.
call6502(aReg, xReg, yReg, statusReg, addr) returns a pointer to a four byte structure containing the A,X,Y and STATUS register results. call6502(aReg, xReg, yReg, statusReg, addr) returns a pointer to a four byte structure containing the A,X,Y and STATUS register results.
<code> ```
const xreg = 1 const xreg = 1
const getlin = $FD6A const getlin = $FD6A
numchars = (call6502(0, 0, 0, 0, getlin)).xreg ; return char count in X reg numchars = (call6502(0, 0, 0, 0, getlin)).xreg ; return char count in X reg
prodos(cmd, params)calls ProDOS, returning the status value. prodos(cmd, params)calls ProDOS, returning the status value.
def read(refnum, buff, len) def read(refnum, buff, len)
byte params[8] byte params[8]
params.0 = 4 params.0 = 4
@ -332,24 +331,24 @@ def read(refnum, buff, len)
params:4 = len params:4 = len
perr = prodos($CA, @params) perr = prodos($CA, @params)
return params:6 return params:6
end end
</code> ```
cout(char), prstr(string), prstrz(stringz) are handy utility routines for printing to the standard Apple II COUT routine. cout(char), prstr(string), prstrz(stringz) are handy utility routines for printing to the standard Apple II COUT routine.
<code> ```
cout('.') cout('.')
byte okstr[] = "OK" byte okstr[] = "OK"
prstr(@okstr) prstr(@okstr)
</code> ```
memset(val16, addr, len) will fill memory with a 16 bit value. memcpy(srcaddr, dstaddr, len) will copy memory from one address to another, taking care to copy in the proper direction. memset(val16, addr, len) will fill memory with a 16 bit value. memcpy(srcaddr, dstaddr, len) will copy memory from one address to another, taking care to copy in the proper direction.
<code> ```
byte nullstr[] = "" byte nullstr[] = ""
memset(@nullstr, strlinbuf, maxfill * 2) ; fill line buff with pointer to null string memset(@nullstr, strlinbuf, maxfill * 2) ; fill line buff with pointer to null string
memcpy(strptr + ofst + 1, scrnptr, numchars) memcpy(strptr + ofst + 1, scrnptr, numchars)
</code> ```
#Implementation Details #Implementation Details