From ef58031f43f2350b1ce4602f978f97d8a9f9c915 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 May 2014 19:55:02 -0700 Subject: [PATCH 01/10] Update User Manual.md --- Docs/Tutorials/PLASMA/User Manual.md | 142 +++++++++++++++++++++++++-- 1 file changed, 133 insertions(+), 9 deletions(-) diff --git a/Docs/Tutorials/PLASMA/User Manual.md b/Docs/Tutorials/PLASMA/User Manual.md index 24a55492..dd1dc998 100644 --- a/Docs/Tutorials/PLASMA/User Manual.md +++ b/Docs/Tutorials/PLASMA/User Manual.md @@ -317,24 +317,148 @@ myobject_class:delete(an_obj) Function definitions in PLASMA is what really seperates PLASMA from a low level language like assembly, or even a language like FORTH. ### Expressions +Exressions are comprised of operators and operations. Operator precedence follows address, arithmatic, binary, and logical from highest to lowest. Parantheses can be used to force operations to happen in a specific order. -### Control Flow +#### Address Operators +Address operators can work on any value, i.e. anything can be an address. Parentheses can be used to get the value from a variable, then use that as an address to dereference for any of the post-operators. + +| OP | Pre-Operation | +|:----:|---------------------| +| ^ | byte pointer +| * | word pointer +| @ | address of + +| OP | Post-Operation | +|:----:|---------------------| +| . | byte type override +| : | word type override +| [] | array index +| () | functional call + +#### Arithmetic, Bitwise, and Logical Operators +| OP | Unary Operation | +|:----:|---------------------| +| - | negate +| ~ | bitwise compliment +| NOT | logical NOT +| ! | logical NOT (alternate) + +| OP | Binary Operation | +|:----:|----------------------| +| * | multiply +| / | divide +| % | modulo +| + | add +| - | subtract +| << | shift left +| >> | shift right +| & | bitwise AND +| ^ | bitwise XOR +| | | bitwise OR +| == | equals +| <> | not equal +| >= | greater than or equal +| > | greater than +| <= | less than or equal +| < | less than +| OR | logical OR +| AND | logical AND + +### Statements +PLASMA definitions are a list of statements the carry out the algorithm. Statements are generally assignment or control flow in nature. + +#### Assignment +Assignments evaluate an expression and save the result into memory. They can be very simple or quite complex. A simple example: +``` +byte a +a = 0 +``` +##### Empty Assignments +An assignment doesn't even have to save the expression into memory, although the expression will be avaluated. This can be useful when referencing hardware that responds just to being accessed. On the Apple II, the keyboard is read from location $C000, then the strobe, telling the hardware to prepare for another keypress is cleared by just reading the address $C010. In PLASMA, this looks like: +``` +byte keypress + +keypress = ^$C000 ; read keyboard +^$C010 ; read keyboard strobe, throw away value +``` + +#### Control Flow PLASMA implements most of the control flow that most higher level languages provide. It may do it in a slightly different way, though. One thing you won't find in PLASMA is GOTO - there are other ways around it. -#### RETURN +##### CALL +Function calls are the easiest ways to pass control to another function. Function calls can be part of an expression, or be all by itself - the same as an empty assignment statement. -#### IF/ELSIF/ELSE/FIN +##### RETURN +`RETURN` will exit the current definition. An optional value can be returned, however, if a value isn't specified a default of zero will be returned. All definitions return a value, regardless of whether it used or not. -#### WHEN/IS/OTHERWISE/WEND +##### IF/[ELSIF]/[ELSE]/FIN +The common `IF` test can have optional `ELSIF` and/or `ELSE` clauses. Any expression that is evaluated to non-zero is treated as TRUE, zero is treated as FALSE. -#### FOR/NEXT +##### WHEN/IS/[OTHERWISE]/WEND +The complex test case is handled with `WHEN`. Basically a `IF`, `ELSIF`, `ELSE` list of comparisons, it is gernerally more efficient. The `IS` value can be any expression. It is evaluated and tested for equality to the `WHEN` value. +``` +when key + is 'A' + ; handle A character + is 'B' + ; handle B character +``` +... +``` + is 'Z' + ; handle Z character + otherwise + ; Not a known key +wend +``` +With a little "Yoda-Speak", some fairly complex test can be made: +``` +const FALSE = 0 +const TRUE = NOT FALSE -#### WHILE/LOOP +byte a -#### REPEAT/UNTIL +when TRUE + is (a <= 10) + ; 10 or less + is (a > 10) AND (a < 20) + ; between 10 and 20 + is (a >= 20) + ; 20 or greater +wend +``` -## Dynamic Heap Memory Allocation -Memory allocation isn't technically part of the PLASMA specification, but it plays such an integral part of the PLASMA environment that is is covered here. +##### FOR [STEP]/NEXT +Iteration over a range is handled with the `FOR`/`NEXT` loop. When iterating from a smaller to larger value, the `TO` construct is used; when iterating from larger to smaller, the `DOWNTO` construct is used. +``` +for a = 1 to 10 + ; do something with a +next + +for a = 10 downto 1 + ; do something else with a +next +``` +An optional stepping value can be used to change the default iteration step from 1 to something else. Always use a positive value; when iterating using `DOWNTO`, the step value will be subtracted from the current value. + +##### WHILE/LOOP +For loops that test at the top of the loop, use `WHILE`. The loop will run zero or more times. +``` +a = c ; Who knows what c could be +while a < 10 + ; do something + a = b * 2 ; b is something special, I'm sure +loop +``` +##### REPEAT/UNTIL +For loops that always run at least once, use the `REPEAT` loop. +``` +repeat + update_cursor +until keypressed +``` +##### BREAK +To exit early from one of the looping constructs, the `BREAK` statement will break out of it immediately and resume control immediately following the bottom of the loop. ## Advanced Topics There are some things about PLASMA that aren't necessary to know, but can add to it's effectiveness in a tight situation. Usually you can just code along, and the system will do a pretty reasonable job of carrying out your task. However, a little knowledge in the way to implement small assembly language routines or some coding practices just might be the ticket. From ee4597734cc11e389c9dbad2cae3677c82009a7a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 May 2014 20:03:04 -0700 Subject: [PATCH 02/10] Update User Manual.md --- Docs/Tutorials/PLASMA/User Manual.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Docs/Tutorials/PLASMA/User Manual.md b/Docs/Tutorials/PLASMA/User Manual.md index dd1dc998..c4e25db0 100644 --- a/Docs/Tutorials/PLASMA/User Manual.md +++ b/Docs/Tutorials/PLASMA/User Manual.md @@ -157,11 +157,11 @@ Excaped characters, like the `\n` above are replaces with the Carriage Return ch | Escaped Char | ASCII Value |:------------:|------------ -| \n | NL +| \n | LF | \t | TAB | \r | CR | \\\\ | \ -| \\0 | 0 +| \\0 | NUL ### Words Words, 16 bit signed values, are the native sized quanta of PLASMA. All calculations, parameters, and return values are words. @@ -389,13 +389,13 @@ PLASMA implements most of the control flow that most higher level languages prov Function calls are the easiest ways to pass control to another function. Function calls can be part of an expression, or be all by itself - the same as an empty assignment statement. ##### RETURN -`RETURN` will exit the current definition. An optional value can be returned, however, if a value isn't specified a default of zero will be returned. All definitions return a value, regardless of whether it used or not. +`return` will exit the current definition. An optional value can be returned, however, if a value isn't specified a default of zero will be returned. All definitions return a value, regardless of whether it used or not. ##### IF/[ELSIF]/[ELSE]/FIN -The common `IF` test can have optional `ELSIF` and/or `ELSE` clauses. Any expression that is evaluated to non-zero is treated as TRUE, zero is treated as FALSE. +The common `if` test can have optional `elsif` and/or `else` clauses. Any expression that is evaluated to non-zero is treated as TRUE, zero is treated as FALSE. ##### WHEN/IS/[OTHERWISE]/WEND -The complex test case is handled with `WHEN`. Basically a `IF`, `ELSIF`, `ELSE` list of comparisons, it is gernerally more efficient. The `IS` value can be any expression. It is evaluated and tested for equality to the `WHEN` value. +The complex test case is handled with `when`. Basically a `if`, `elsifF`, `else` list of comparisons, it is gernerally more efficient. The `is` value can be any expression. It is evaluated and tested for equality to the `when` value. ``` when key is 'A' @@ -428,8 +428,8 @@ when TRUE wend ``` -##### FOR [STEP]/NEXT -Iteration over a range is handled with the `FOR`/`NEXT` loop. When iterating from a smaller to larger value, the `TO` construct is used; when iterating from larger to smaller, the `DOWNTO` construct is used. +##### FOR TO,DOWNTO [STEP]/NEXT +Iteration over a range is handled with the `for`/`next` loop. When iterating from a smaller to larger value, the `to` construct is used; when iterating from larger to smaller, the `downto` construct is used. ``` for a = 1 to 10 ; do something with a @@ -439,10 +439,10 @@ for a = 10 downto 1 ; do something else with a next ``` -An optional stepping value can be used to change the default iteration step from 1 to something else. Always use a positive value; when iterating using `DOWNTO`, the step value will be subtracted from the current value. +An optional stepping value can be used to change the default iteration step from 1 to something else. Always use a positive value; when iterating using `downto`, the step value will be subtracted from the current value. ##### WHILE/LOOP -For loops that test at the top of the loop, use `WHILE`. The loop will run zero or more times. +For loops that test at the top of the loop, use `while`. The loop will run zero or more times. ``` a = c ; Who knows what c could be while a < 10 @@ -451,14 +451,14 @@ while a < 10 loop ``` ##### REPEAT/UNTIL -For loops that always run at least once, use the `REPEAT` loop. +For loops that always run at least once, use the `repeat` loop. ``` repeat update_cursor until keypressed ``` ##### BREAK -To exit early from one of the looping constructs, the `BREAK` statement will break out of it immediately and resume control immediately following the bottom of the loop. +To exit early from one of the looping constructs, the `break` statement will break out of it immediately and resume control immediately following the bottom of the loop. ## Advanced Topics There are some things about PLASMA that aren't necessary to know, but can add to it's effectiveness in a tight situation. Usually you can just code along, and the system will do a pretty reasonable job of carrying out your task. However, a little knowledge in the way to implement small assembly language routines or some coding practices just might be the ticket. From 6b9402ec3e44db59e0060a62b00d129486b70f02 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 May 2014 20:04:11 -0700 Subject: [PATCH 03/10] Update User Manual.md --- Docs/Tutorials/PLASMA/User Manual.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Tutorials/PLASMA/User Manual.md b/Docs/Tutorials/PLASMA/User Manual.md index c4e25db0..9fb06053 100644 --- a/Docs/Tutorials/PLASMA/User Manual.md +++ b/Docs/Tutorials/PLASMA/User Manual.md @@ -428,7 +428,7 @@ when TRUE wend ``` -##### FOR TO,DOWNTO [STEP]/NEXT +##### FOR \ [STEP]/NEXT Iteration over a range is handled with the `for`/`next` loop. When iterating from a smaller to larger value, the `to` construct is used; when iterating from larger to smaller, the `downto` construct is used. ``` for a = 1 to 10 From 2d63a62367ba452875544416120d5c3e5b922089 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 May 2014 20:09:29 -0700 Subject: [PATCH 04/10] Update User Manual.md --- Docs/Tutorials/PLASMA/User Manual.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Docs/Tutorials/PLASMA/User Manual.md b/Docs/Tutorials/PLASMA/User Manual.md index 9fb06053..3a0c79b2 100644 --- a/Docs/Tutorials/PLASMA/User Manual.md +++ b/Docs/Tutorials/PLASMA/User Manual.md @@ -45,6 +45,9 @@ make hello for the **make** program to build all the dependencies and run the module. ## Organization of a PLASMA Source File +### Character Case +All identifiers and reserved words are case insensitive. Case is only significant inside character constants and strings. Imported and exported symbols are always promoted to upper case when resolved. Because some Apple IIs only work easily with uppercase, the eases the chance of mismatched symbol names. + ### Comments Comments are allowed throughout a PLASMA source file. The format follows that of an assembler: they begin with a `;` and comment out the rest of the line: From 3146598bc692e80be3b2bb5ec7d85ee0fcf86325 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 May 2014 20:24:37 -0700 Subject: [PATCH 05/10] Update User Manual.md --- Docs/Tutorials/PLASMA/User Manual.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Docs/Tutorials/PLASMA/User Manual.md b/Docs/Tutorials/PLASMA/User Manual.md index 3a0c79b2..da25778b 100644 --- a/Docs/Tutorials/PLASMA/User Manual.md +++ b/Docs/Tutorials/PLASMA/User Manual.md @@ -467,9 +467,19 @@ To exit early from one of the looping constructs, the `break` statement will bre There are some things about PLASMA that aren't necessary to know, but can add to it's effectiveness in a tight situation. Usually you can just code along, and the system will do a pretty reasonable job of carrying out your task. However, a little knowledge in the way to implement small assembly language routines or some coding practices just might be the ticket. ### Native Assembly Functions -Assembly code in PLASMA is implemented strictly as a pass-through to the assembler. No syntax checking, or checking at all, is made. All assembly routines *must* come after all data has been declared, and before any PLASMA function definitions. +Assembly code in PLASMA is implemented strictly as a pass-through to the assembler. No syntax checking, or checking at all, is made. All assembly routines *must* come after all data has been declared, and before any PLASMA function definitions. Native assemlbly functions can't see PLASMA labels and definitions, so they are pretty much relegated to leaf functions. Lasltly, PLASMA modules are relocatable, but labels inside assembly functions don't get flagged for fixups. The assembly code must use all relative branches and only accessing data/code at a fixed address. Data passed in on the PLASMA evalution stack is readily accessed with the X register and the zero page address of the ESTK. The X register must be properly saved, incremented, and/or decremented to remain consistent with the rest of PLASMA. Parameters are "popped" off the evaluation stack with `INX`, and the return value is "pushed" with `DEX`. ### Code Optimizations +#### Functions Without Parameters Or Local Variables +Certain simple functions that don't take parameters or use local variables will skip the Frame Stack Entry/Leave setup. That can speed up the function significantly. The following could be a very useful function: +``` +def keypress + while ^$C000 < 128 + loop + ^$C010 + return ^$C000 +end +``` #### Return Values PLASMA always returns a value from a function, even if you don't supply one. Probably the easiest optimization to make in PLASMA is to cascade a return value if you don't care about the value you return. This only works if the last thing you do before returning from your routine is calling another definition. You would go from: ``` From 1365c449533b6d3e8ad38be91f0e711240e1e2cc Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 May 2014 20:26:44 -0700 Subject: [PATCH 06/10] Update User Manual.md --- Docs/Tutorials/PLASMA/User Manual.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Tutorials/PLASMA/User Manual.md b/Docs/Tutorials/PLASMA/User Manual.md index da25778b..b7360662 100644 --- a/Docs/Tutorials/PLASMA/User Manual.md +++ b/Docs/Tutorials/PLASMA/User Manual.md @@ -488,7 +488,7 @@ def mydef calldef(10) ; call some other def end ``` -PLASMA will effectively add a RETURN 0 to the end of your function, as well as add code to ignore the result of `calldef(10)`. As long as you don't care about the return value from `mydef`, you can save some code bytes with: +PLASMA will effectively add a RETURN 0 to the end of your function, as well as add code to ignore the result of `calldef(10)`. As long as you don't care about the return value from `mydef` or want to use its return as the return value fromyour function (cascade the return), you can save some code bytes with: ``` def mydef ; do some stuff From 5ad39d689763e956399233ac9a008316b32aa10e Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 May 2014 20:33:47 -0700 Subject: [PATCH 07/10] Remove extraneous files and get better coverage from testlib & test --- PLASMA/src/class.pla | 31 --------- PLASMA/src/hgr1.pla | 21 ------ PLASMA/src/hgr1test.pla | 127 ---------------------------------- PLASMA/src/makefile | 29 ++------ PLASMA/src/rod.pla | 84 ---------------------- PLASMA/src/samplib.s | 150 ---------------------------------------- PLASMA/src/test.pla | 54 ++++++++------- PLASMA/src/testcls.pla | 32 --------- PLASMA/src/testlib.pla | 18 +++-- 9 files changed, 47 insertions(+), 499 deletions(-) delete mode 100755 PLASMA/src/class.pla delete mode 100644 PLASMA/src/hgr1.pla delete mode 100644 PLASMA/src/hgr1test.pla delete mode 100644 PLASMA/src/rod.pla delete mode 100755 PLASMA/src/samplib.s delete mode 100755 PLASMA/src/testcls.pla diff --git a/PLASMA/src/class.pla b/PLASMA/src/class.pla deleted file mode 100755 index d5c7b43a..00000000 --- a/PLASMA/src/class.pla +++ /dev/null @@ -1,31 +0,0 @@ -; -; Declare all imported modules and their data/functions. -; -import stdlib - predef putc, puts -end -import testcls - word print - const dec = 0 - const hex = 2 -end - -byte spaces[] = " " - -def putln - putc($0D) -end - -def printnums - word i - i = 10000 - repeat - print:dec(i) - puts(@spaces) - print:hex(i) - putln - i = i / 10 - until i == 0 -end -printnums -done diff --git a/PLASMA/src/hgr1.pla b/PLASMA/src/hgr1.pla deleted file mode 100644 index 41f41149..00000000 --- a/PLASMA/src/hgr1.pla +++ /dev/null @@ -1,21 +0,0 @@ -import STDLIB - predef memset - ; - ; System flags: memory allocator screen holes. - ; - const restxt1 = $0001 - const restxt2 = $0002 - const reshgr1 = $0004 - const reshgr2 = $0008 - const resxhgr1 = $0010 - const resxhgr2 = $0020 -end - -sysflags reshgr1 ; Reserve HGR page 1 - -memset($2000, $2000, 0) ; Clear HGR page 1 -^$C054 -^$C052 -^$C057 -^$C050 -done \ No newline at end of file diff --git a/PLASMA/src/hgr1test.pla b/PLASMA/src/hgr1test.pla deleted file mode 100644 index 86adc87d..00000000 --- a/PLASMA/src/hgr1test.pla +++ /dev/null @@ -1,127 +0,0 @@ -import STDLIB - predef memset, memcpy, getc, heapalloc, heapmark, heaprelease -end -import HGR1 -end - -const view_height = 64 ; scan count of ground view -const fix_bits = 8 ; number of fixed point bits -; -; Hardware addresses -; -const speaker=$C030 -const showgraphics=$C050 -const showtext=$C051 -const showfull=$C052 -const showmix=$C053 -const showpage1=$C054 -const showpage2=$C055 -const showlores=$C056 -const showhires=$C057 -const keyboard=$C000 -const keystrobe=$C010 -const hgr1=$2000 -const hgr2=$4000 -const page1=0 -const page2=1 -word hgrpage[] = hgr1, hgr2 -word hgrscan[] = $0000,$0400,$0800,$0C00,$1000,$1400,$1800,$1C00 -word = $0080,$0480,$0880,$0C80,$1080,$1480,$1880,$1C80 -word = $0100,$0500,$0900,$0D00,$1100,$1500,$1900,$1D00 -word = $0180,$0580,$0980,$0D80,$1180,$1580,$1980,$1D80 -word = $0200,$0600,$0A00,$0E00,$1200,$1600,$1A00,$1E00 -word = $0280,$0680,$0A80,$0E80,$1280,$1680,$1A80,$1E80 -word = $0300,$0700,$0B00,$0F00,$1300,$1700,$1B00,$1F00 -word = $0380,$0780,$0B80,$0F80,$1380,$1780,$1B80,$1F80 -word = $0028,$0428,$0828,$0C28,$1028,$1428,$1828,$1C28 -word = $00A8,$04A8,$08A8,$0CA8,$10A8,$14A8,$18A8,$1CA8 -word = $0128,$0528,$0928,$0D28,$1128,$1528,$1928,$1D28 -word = $01A8,$05A8,$09A8,$0DA8,$11A8,$15A8,$19A8,$1DA8 -word = $0228,$0628,$0A28,$0E28,$1228,$1628,$1A28,$1E28 -word = $02A8,$06A8,$0AA8,$0EA8,$12A8,$16A8,$1AA8,$1EA8 -word = $0328,$0728,$0B28,$0F28,$1328,$1728,$1B28,$1F28 -word = $03A8,$07A8,$0BA8,$0FA8,$13A8,$17A8,$1BA8,$1FA8 -word = $0050,$0450,$0850,$0C50,$1050,$1450,$1850,$1C50 -word = $00D0,$04D0,$08D0,$0CD0,$10D0,$14D0,$18D0,$1CD0 -word = $0150,$0550,$0950,$0D50,$1150,$1550,$1950,$1D50 -word = $01D0,$05D0,$09D0,$0DD0,$11D0,$15D0,$19D0,$1DD0 -word = $0250,$0650,$0A50,$0E50,$1250,$1650,$1A50,$1E50 -word = $02D0,$06D0,$0AD0,$0ED0,$12D0,$16D0,$1AD0,$1ED0 -word = $0350,$0750,$0B50,$0F50,$1350,$1750,$1B50,$1F50 -word = $03D0,$07D0,$0BD0,$0FD0,$13D0,$17D0,$1BD0,$1FD0 -word hcolor[] = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF -; -; def draw_scan(d8p8, scanptr) -; -asm draw_scan - !SOURCE "plvm02zp.inc" -WFIXL = $80 -WFIXH = $81 -WINT = $82 -PIX = $83 - LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - LDA ESTKL+1,X - STA WFIXL - STA WFIXH - LDA ESTKH+1,X - LSR - STA WINT - ROR WFIXH - ROR WFIXL - LDA #$FF - SEC - SBC WFIXL - STA WFIXL - LDA #$FF - SBC WFIXH - STA WFIXH - LDA #$FF - SBC WINT - STA WINT - LDY #$01 - STY PIX - DEY -- EOR ESTKH+1,X - LSR - BCC + - LDA PIX - ORA (TMP),Y - STA (TMP),Y -+ ASL PIX - BPL + - LDA #$01 - STA PIX - INY - CPY #36 - BEQ ++ -+ LDA ESTKL+1,X - CLC - ADC WFIXL - STA WFIXL - LDA ESTKH+1,X - ADC WFIXH - STA WFIXH - LDA #$00 - ADC WINT - STA WINT - BNE - - BEQ - -++ INX - RTS -end -def draw_ground(page) - byte ip - - for ip = 1 to view_height - draw_scan((127 << fix_bits) / ip, hgrpage[page] + hgrscan[ip + 191 - view_height] + 2) - next -end - -draw_ground(page1) -getc -^showpage1 -^showtext -done \ No newline at end of file diff --git a/PLASMA/src/makefile b/PLASMA/src/makefile index da8c6353..078b048d 100755 --- a/PLASMA/src/makefile +++ b/PLASMA/src/makefile @@ -22,7 +22,7 @@ TXTTYPE = .TXT #SYSTYPE = \#ff0000 #TXTTYPE = \#040000 -all: $(PLASM) $(PLVM) $(PLVM02) $(CMD) TESTLIB ROD.REL +all: $(PLASM) $(PLVM) $(PLVM02) $(CMD) TESTLIB clean: -rm *.o *~ *.a *.SYM *.SYS *.REL TESTLIB $(PLASM) $(PLVM) @@ -44,39 +44,20 @@ $(CMD): cmd.pla cmdstub.s $(PLVM) $(PLASM) acme --setpc 8192 -o $(CMD) cmdstub.s TESTLIB: testlib.pla $(PLVM) $(PLASM) - ./$(PLASM) -AM < testlib.pla > testlib.a + m4 < testlib.pla |./$(PLASM) -AM > testlib.a acme --setpc 4094 -o TESTLIB testlib.a test: test.pla TESTLIB $(PLVM) $(PLASM) - ./$(PLASM) -AM < test.pla > test.a + m4 < test.pla | ./$(PLASM) -AM > test.a acme --setpc 4094 -o TEST.REL test.a ./$(PLVM) TEST.REL -TESTCLS: testcls.pla $(PLVM) $(PLASM) - ./$(PLASM) -AM < testcls.pla > testcls.a - acme --setpc 4094 -o TESTCLS testcls.a - -class: class.pla TESTCLS $(PLVM) $(PLASM) - ./$(PLASM) -AM < class.pla > class.a - acme --setpc 4094 -o CLASS.REL class.a - ./$(PLVM) CLASS.REL - debug: test.pla TESTLIB $(PLVM) $(PLASM) - ./$(PLASM) -AM < test.pla > test.a + m4 < test.pla | ./$(PLASM) -AM > test.a acme --setpc 4094 -o TEST.REL test.a ./$(PLVM) -s TEST.REL MAIN hello: hello.pla $(PLVM) $(PLASM) - ./$(PLASM) -AM < hello.pla > hello.a + m4 < hello.pla | ./$(PLASM) -AM > hello.a acme --setpc 4094 -o HELLO.REL hello.a ./$(PLVM) HELLO.REL - -ROD.REL: rod.pla $(PLVM) $(PLASM) - ./$(PLASM) -AM < rod.pla > rod.a - acme --setpc 4094 -o ROD.REL rod.a - -HGR1: hgr1.pla hgr1test.pla $(PLVM) $(PLASM) - ./$(PLASM) -AM < hgr1test.pla > hgr1test.a - acme --setpc 4094 -o HGR1TEST.REL hgr1test.a - ./$(PLASM) -AM < hgr1.pla > hgr1.a - acme --setpc 4094 -o HGR1 hgr1.a diff --git a/PLASMA/src/rod.pla b/PLASMA/src/rod.pla deleted file mode 100644 index e54412c3..00000000 --- a/PLASMA/src/rod.pla +++ /dev/null @@ -1,84 +0,0 @@ -import STDLIB - predef romcall, puts -end -const speaker=$C030 -const showgraphics=$C050 -const showtext=$C051 -const showfull=$C052 -const showmix=$C053 -const TRUE=$FFFF -const FALSE=$0000 -const showpage1=$C054 -const showpage2=$C055 -const showlores=$C056 -const showhires=$C057 -const keyboard=$C000 -const keystrobe=$C010 -const hgr1=$2000 -const hgr2=$4000 -const page1=0 -const page2=1 -byte exitmsg[] = "PRESS ANY KEY TO EXIT.\n" -byte goodbye[] = "THAT'S ALL FOLKS!\n" -byte i, j, k, w, fmi, fmk, color - -def textmode - romcall(0, 0, 0, 0, $FB39) -end -def home - romcall(0, 0, 0, 0, $FC58) -end -def gotoxy(x, y) - ^($24) = x - romcall(y, 0, 0, 0, $FB5B) -end -def grmode - romcall(0, 0, 0, 0, $FB40) - ^showlores -end -def grcolor(color) - romcall(color, 0, 0, 0, $F864) -end -def grplot(x, y) - romcall(y, 0, x, 0, $F800) -end -def colors - while TRUE - for w = 3 to 50 - for i = 1 to 19 - for j = 0 to 19 - k = i + j - color = (j * 3) / (i + 3) + i * w / 12 - fmi = 40 - i - fmk = 40 - k - romcall(color, 0, 0, 0, $F864) ;grcolor(color); - romcall(k, 0, i, 0, $F800) ;grplot(i, k); - romcall(i, 0, k, 0, $F800) ;grplot(k, i); - romcall(fmk, 0, fmi, 0, $F800) ;grplot(fmi, fmk); - romcall(fmi, 0, fmk, 0, $F800) ;grplot(fmk, fmi); - romcall(fmi, 0, k, 0, $F800) ;grplot(k, fmi); - romcall(k, 0, fmi, 0, $F800) ;grplot(fmi, k); - romcall(fmk, 0, i, 0, $F800) ;grplot(i, fmk); - romcall(i, 0, fmk, 0, $F800) ;grplot(fmk, i); - if ^keyboard >= 128 - ^keystrobe - return - fin - next - next - next - loop -end - - -grmode() -gotoxy(10,22) -puts(@exitmsg) -colors() -textmode() -home() -puts(@goodbye) -while ^keyboard < 128 -loop -^keystrobe -done \ No newline at end of file diff --git a/PLASMA/src/samplib.s b/PLASMA/src/samplib.s deleted file mode 100755 index 8f837e96..00000000 --- a/PLASMA/src/samplib.s +++ /dev/null @@ -1,150 +0,0 @@ -; -; Sample PLASMA library. -; -!TO "samplib.bin", PLAIN -* = $1000 -; -; DATA/CODE SEGMENT -; -_SEGBEGIN - !WORD _SEGEND-_SEGBEGIN ; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT -; -; MODULE HEADER -; - !WORD $DA7E ; MAGIC # - !WORD _SUBSEG ; BYTECODE SUB-SEGMENT - !WORD _INIT ; BYTECODE INIT ROUTINE -; -; MODULE DEPENDENCY LIST -; NOTE: DCI = PSUEDO OP FOR ASCII STRING WITH HI BIT SET EXCEPT LAST CHAR -; - ;DCI "STDLIB" - !CT "hi.ascii" - !TX "STDLI" - !CT RAW - !TX 'B' - ;DCI "FILEIO" - !CT "hi.ascii" - !TX "FILEI" - !CT RAW - !TX 'O' - !BYTE 0 -; -; NATIVE CODE + GLOBAL DATA -; -COUNT !WORD 0 -INCCNT -FIXUP1 INC COUNT - BNE XINIT -FIXUP2 INC COUNT+1 -XINIT RTS -; -; BYTECODE SUB-SEGMENT -; -_SUBSEG -MYFUNC !BYTE $58, $01, $16 ; ENTER 1,16 - !BYTE $66, $02 ; LLW 2 - !BYTE $2A, $01 ; CB 1 - !BYTE $54 ; CALL EXTERN(1) "OPEN" -FIXUP4 !WORD $0000 - !BYTE $6E, $04 ; DLW 4 - !BYTE $54 ; CALL EXTERN(3) "READ" -FIXUP5 !WORD $0000 - !BYTE $30 ; DROP - !BYTE $66, $04 ; LLW 4 - !BYTE $54 ; CALL EXTERN(2) ; "CLOSE" -FIXUP6 !WORD $0000 - !BYTE $30 ; DROP - !BYTE $6A ; LAW COUNT -FIXUP7 !WORD $0000 - !BYTE $54 ; CALL INCNT -FIXUP8 !WORD $0000 - !BYTE $5A ; LEAVE -_INIT - !BYTE $5C ; RET -; -; END OF CODE/DATA + BYTECODE SEGMENT -; -_SEGEND -; -; BYTCODE FUNCTION DICTIONARY -; - !BYTE $A1 ; FIXUP FLAGS - !WORD MYFUNC ; FIXUP OFFSET - !BYTE $00 ; FIXUP LO BYTE (OF HI BYTE)/IMPORT INDEX -; -; RE-LOCATION DICTIONARY (FIXUP TABLE) -; - !BYTE $81 ; FIXUP FLAGS - !WORD FIXUP1+1 ; FIXUP OFFSET - !BYTE $00 ; FIXUP LO BYTE (OF HI BYTE)/IMPORT INDEX - !BYTE $81 - !WORD FIXUP2+1 - !BYTE $00 - !BYTE $91 ; IMPORT FIXUP - !WORD FIXUP4 - !BYTE $01 ; IMPORT INDEX 1 - !BYTE $91 - !WORD FIXUP5 - !BYTE $03 - !BYTE $91 - !WORD FIXUP6 - !BYTE $02 - !BYTE $81 - !WORD FIXUP7 - !BYTE $00 - !BYTE $81 - !WORD FIXUP8 - !BYTE $00 - !BYTE 0 ; END OF RLD -; -; EXTERNAL/ENTRY SYMBOL DIRECTORY -;; -; IMPORT TABLE -; -IMPTBL ;DCI "OPEN" ; EXTERNAL SYMBOL NAME - !CT "hi.ascii" - !TX "OPE" - !CT RAW - !TX 'N' - !BYTE $10 ; EXTERNAL SYMBOL FLAG - !WORD 1 ; SYMBOL INDEX - ;DCI "CLOSE" - !CT "hi.ascii" - !TX "CLOS" - !CT RAW - !TX 'E' - !BYTE $10 - !WORD 2 - ;DCI "READ" - !CT "hi.ascii" - !TX "REA" - !CT RAW - !TX 'D' - !BYTE $10 - !WORD 3 - ;DCI "MEMSET" - !CT "hi.ascii" - !TX "MEMSE" - !CT RAW - !TX 'T' - !BYTE $10 - !WORD 4 -; -; EXPORT TABLE -; -EXPTBL ;DCI "INCNT" ; ENTRY SYMBOL NAME - !CT "hi.ascii" - !TX "INCN" - !CT RAW - !TX 'T' - !BYTE $08 ; ENTRY SYMBOL FLAG - !WORD INCCNT ; OFFSET - ;DCI "MYFUNC" - !CT "hi.ascii" - !TX "MYFUN" - !CT RAW - !TX 'C' - !BYTE $08 - !WORD MYFUNC - !BYTE 0 ; END OF ESD diff --git a/PLASMA/src/test.pla b/PLASMA/src/test.pla index 8116fbe0..edd14f53 100755 --- a/PLASMA/src/test.pla +++ b/PLASMA/src/test.pla @@ -1,45 +1,55 @@ ; ; Declare all imported modules and their data/functions. ; -import stdlib - predef cls, gotoxy, viewport, puts, putc, getc -end -import testlib - predef puti, putnl -end -const mainentry = 2 -; -; Predeclare any functions called before defined. -; -predef ascii, main +include(stdlib.plh) +include(testlib.plh) + ; ; Declare all global variables for this module. ; + byte hello[] = "Hello, world.\n" -word defptr = @ascii, @main -word struct[] = 1, 10, 100 +word struct[] = 1, 10, 100, 1000, 10000 +byte spaces[] = " " + ; ; Define functions. ; + +def tens(start) + word i + i = start + repeat + print:hex(i) + puts(@spaces) + print:dec(i) + print:newln() + i = i / 10 + until i == 0 +end + def ascii byte i - for i = 32 to 127 + i = 32 + while i < 128 putc(i) - next + i = i + 1 + loop end def nums(range) word i - for i = -10 to range + for i = range downto -range step range/10 puti(i) - putnl + putln next end export def main(range) cls - nums(range) + nums(*range) + tens(*range*10) viewport(12, 12, 16, 8) ascii viewport(0, 0, 40, 24) @@ -47,11 +57,5 @@ export def main(range) puts(@hello) end -export def indirect - word mainptr - mainptr = @main - return defptr:mainentry(struct:2) -end - -indirect +main(@struct:6) done diff --git a/PLASMA/src/testcls.pla b/PLASMA/src/testcls.pla deleted file mode 100755 index e2ae4d68..00000000 --- a/PLASMA/src/testcls.pla +++ /dev/null @@ -1,32 +0,0 @@ -; -; Declare all imported modules and their data/functions. -; -import stdlib - predef putc -end -predef puti, puth -export word print[] = @puti, @puth -byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' -; -; Define functions. -; -def puti(i) - if i < 0 - putc('-') - i = -i - fin - if i < 10 - putc(i + '0') - else - puti(i / 10) - putc(i % 10 + '0') - fin -end -def puth(h) - putc('$') - putc(valstr[(h >> 12) & $0F]) - putc(valstr[(h >> 8) & $0F]) - putc(valstr[(h >> 4) & $0F]) - putc(valstr[ h & $0F]) -end -done diff --git a/PLASMA/src/testlib.pla b/PLASMA/src/testlib.pla index 3ecde6bc..93ee08c1 100755 --- a/PLASMA/src/testlib.pla +++ b/PLASMA/src/testlib.pla @@ -1,13 +1,21 @@ ; ; Declare all imported modules and their data/functions. ; -import stdlib - predef cls, gotoxy, puts, putc -end +include(stdlib.plh) +predef puti, puth, putln +export word print[] = @puti, @puth, @putln +byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' byte loadstr[] = "testlib loaded!" ; ; Define functions. ; +def puth(h) + putc('$') + putc(valstr[(h >> 12) & $0F]) + putc(valstr[(h >> 8) & $0F]) + putc(valstr[(h >> 4) & $0F]) + putc(valstr[ h & $0F]) +end export def puti(i) if i < 0 putc('-') @@ -20,10 +28,10 @@ export def puti(i) putc(i % 10 + '0') fin end -export def putnl +export def putln putc($0D) end puts(@loadstr) -putnl +putln done From b41e759bc3ed2d5a2f2a89caa564853d39ba536a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 May 2014 20:43:37 -0700 Subject: [PATCH 08/10] Clean up test case a little --- PLASMA/src/test.pla | 4 ++-- PLASMA/src/testlib.pla | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/PLASMA/src/test.pla b/PLASMA/src/test.pla index edd14f53..ab98933e 100755 --- a/PLASMA/src/test.pla +++ b/PLASMA/src/test.pla @@ -1,5 +1,5 @@ ; -; Declare all imported modules and their data/functions. +; Include all imported modules and their data/functions. ; include(stdlib.plh) @@ -22,7 +22,7 @@ def tens(start) i = start repeat print:hex(i) - puts(@spaces) + print:str(@spaces) print:dec(i) print:newln() i = i / 10 diff --git a/PLASMA/src/testlib.pla b/PLASMA/src/testlib.pla index 93ee08c1..29c2a052 100755 --- a/PLASMA/src/testlib.pla +++ b/PLASMA/src/testlib.pla @@ -1,14 +1,22 @@ ; -; Declare all imported modules and their data/functions. +; Include all imported modules and their data/functions. ; + include(stdlib.plh) + +; +; Module data. +; + predef puti, puth, putln -export word print[] = @puti, @puth, @putln +export word print[] = @puti, @puth, @putln, @puts, @putc byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' byte loadstr[] = "testlib loaded!" + ; ; Define functions. ; + def puth(h) putc('$') putc(valstr[(h >> 12) & $0F]) @@ -16,6 +24,7 @@ def puth(h) putc(valstr[(h >> 4) & $0F]) putc(valstr[ h & $0F]) end + export def puti(i) if i < 0 putc('-') @@ -28,6 +37,7 @@ export def puti(i) putc(i % 10 + '0') fin end + export def putln putc($0D) end From 934a7eaed6d30f59e554cf25ce3a805ab4e501f8 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 May 2014 20:55:12 -0700 Subject: [PATCH 09/10] Create headers and use m4 to include them --- PLASMA/src/stdlib.plh | 16 ++++++++++++++++ PLASMA/src/testlib.plh | 9 +++++++++ 2 files changed, 25 insertions(+) create mode 100644 PLASMA/src/stdlib.plh create mode 100644 PLASMA/src/testlib.plh diff --git a/PLASMA/src/stdlib.plh b/PLASMA/src/stdlib.plh new file mode 100644 index 00000000..2307526b --- /dev/null +++ b/PLASMA/src/stdlib.plh @@ -0,0 +1,16 @@ +import stdlib + predef cls, gotoxy, viewport, putc, puts, getc, gets, syscall, romcall + predef heapmark, heapallocallign, heapalloc, heaprelease, heapavail + predef memset, memcpy, memxcpy + predef isugt, isuge, isult, isule + predef exec + ; + ; System flags: memory allocator screen holes. + ; + const restxt1 = $0001 + const restxt2 = $0002 + const reshgr1 = $0004 + const reshgr2 = $0008 + const resxhgr1 = $0010 + const resxhgr2 = $0020 +end diff --git a/PLASMA/src/testlib.plh b/PLASMA/src/testlib.plh new file mode 100644 index 00000000..a2e244ad --- /dev/null +++ b/PLASMA/src/testlib.plh @@ -0,0 +1,9 @@ +import testlib + predef puti, putln + word print + const dec = 0 + const hex = 2 + const newln = 4 + const str = 6 + const char = 8 +end From 1d0907311e4d719a5ce14d5de3d88e4e6989e89a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 May 2014 22:03:55 -0700 Subject: [PATCH 10/10] Update User Manual.md --- Docs/Tutorials/PLASMA/User Manual.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Tutorials/PLASMA/User Manual.md b/Docs/Tutorials/PLASMA/User Manual.md index b7360662..aae197bb 100644 --- a/Docs/Tutorials/PLASMA/User Manual.md +++ b/Docs/Tutorials/PLASMA/User Manual.md @@ -25,7 +25,7 @@ Three tools are required to build and run this program: **plasm**, **acme**, and ``` ./plasm -AM < hello.pla > hello.a -acme --setpc 4096 -o HELLO.REL hello.a +acme --setpc 4094 -o HELLO.REL hello.a ./plvm HELLO.REL ```