changeset 3086:83bf26264aa6

Added brainfuck interpreter
author boisy@tee-boy.com
date Sat, 03 Oct 2015 14:50:37 -0500
parents a9311007b1b2
children a938d0f26711
files 3rdparty/packages/brainfuck/ReadMe 3rdparty/packages/brainfuck/b.asm 3rdparty/packages/brainfuck/bf.asm 3rdparty/packages/brainfuck/defsfile 3rdparty/packages/brainfuck/donothing.bf 3rdparty/packages/brainfuck/helloworld.bf 3rdparty/packages/brainfuck/inout.bf 3rdparty/packages/brainfuck/makefile 3rdparty/packages/makefile
diffstat 9 files changed, 665 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/ReadMe	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,8 @@
+Brainfuck is a dead-simple, Turing complete computer language.
+This is a dead-simple interpreter for the language. It takes a single parameter: the name of the source file.
+
+e.g.
+
+brainfuck helloworld.bf
+
+Learn more about Brainfuck here: https://en.wikipedia.org/wiki/Brainfuck
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/b.asm	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,379 @@
+********************************************************************
+* NGU - The "Next Great Utility"
+*
+* $Id$
+*
+* NGU is a template for writing utilities under OS-9/6809. It has
+* robust option handling and is littered with comments to help you
+* write your own utilities.
+*
+* NGU uses a two-pass method for parsing the command line.  On the
+* first pass, dash options are processed and internal flags are set
+* accordingly.  As the options are processed, they are cleared to
+* spaces so that they won't be present on the second pass.
+*
+*  e.g.
+*       1st pass:   ngu -x foo1 -y foo2 -t=bar1 -ab
+*       2nd pass:   ngu    foo1    foo2
+*
+* For the second pass, NGU parses the remaining arguments, which don't
+* begin with -. Presumably these are filenames or other names that are to be
+* processed.
+*
+* Features:
+*    - Written for 6809 and 6309 processors in fast, compact
+*      assembly language.
+*
+*    - Both options and files can be specified anywhere
+*      on the command line
+*          (i.e ngu -a test1 -b test2 -c=foo)
+*
+*    - Multiple options can be combined behind one dash:
+*          (i.e ngu -ab test1 -c=foo test2 test3)
+*
+*    - Several useful assembly routines are provided for
+*      copying strings and determining string length.
+*
+* Limitations:
+*    - Only single character option names can be processed.
+*      Multi-character option names (i.e. -delete) aren't supported.
+*
+*    - The current file counter is one byte, counting a maximum
+*      of 255 files.
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2003/01/11  Boisy G. Pitre
+* Put your development info here.
+
+         nam   NGU
+         ttl   The "Next Great Utility"
+
+         ifp1
+         use   defsfile
+         endc
+
+* Here are some tweakable options
+DOHELP   set   1	1 = include help info
+STACKSZ  set   128	estimated stack size in bytes
+PARMSZ   set   256	estimated parameter size in bytes
+COPTSIZ  set   64	max size of C option's parameter
+
+* Module header definitions
+tylg     set   Prgrm+Objct   
+atrv     set   ReEnt+rev
+rev      set   $00
+edition  set   1
+
+         mod   eom,name,tylg,atrv,start,size
+
+* Your utility's static storage vars go here
+         org   0
+* These vars are used by the base template and shouldn't be removed
+parmptr  rmb   2	pointer to our command line params
+bufptr   rmb   2	pointer to user expandable buffer
+bufsiz   rmb   2	size of user expandable buffer
+filecnt  rmb   1
+* These vars are used for this example, it will probably change for you
+gota     rmb   1
+gotb     rmb   1
+coptflg  rmb   1	1 = this option has been processed once already
+cleartop equ   .	everything up to here gets cleared at start
+copt     rmb   COPTSIZ	buffer for what follows after -c=
+* Next is a user adjustable buffer with # modifier on command line.
+* Some utilities won't need this flexibility, some will.
+* Currently set up to be larger for Level 2 than Level 1
+* Note: this buffer must come just before the stack
+         IFGT  Level-1
+bigbuff  rmb   8*1024		8K default buffer for Level 2
+         ELSE
+bigbuff  rmb   512		512 byte default buffer for Level 1
+         ENDC
+* Finally the stack for any PSHS/PULS/BSR/LBSRs that we might do
+         rmb   STACKSZ+PARMSZ
+size     equ   .
+
+* The utility name and edition goes here
+name     fcs   /NGU/
+         fcb   edition
+
+* Place constant strings here
+         IFNE  DOHELP
+HlpMsg   fcb   C$LF
+         fcc   /Use: NGU [<opts>] <path> [<path>] [<opts>]/
+         fcb   C$LF
+         fcc   /   -a    option 1/
+         fcb   C$LF
+         fcc   /   -b    option 2/
+         fcb   C$LF
+         fcc   /   -c=f  option 3/
+         fcb   C$LF
+CR       fcb   C$CR
+HlpMsgL  equ   *-HlpMsg
+         ENDC
+UnkOpt   fcc   /unknown option: /
+UnkOptL  equ   *-UnkOpt
+
+* Here's how registers are set when this process is forked:
+*
+*   +-----------------+  <--  Y          (highest address)
+*   !   Parameter     !
+*   !     Area        !
+*   +-----------------+  <-- X, SP
+*   !   Data Area     !
+*   +-----------------+
+*   !   Direct Page   !
+*   +-----------------+  <-- U, DP       (lowest address)
+*
+*   D = parameter area size
+*  PC = module entry point abs. address
+*  CC = F=0, I=0, others undefined
+
+* The start of the program is here.
+* Before any command line processing is done, we clear out
+* our static memory from U to cleartop, then determine the
+* size of our data area (minus the stack).
+start    pshs  u,x		save registers for later
+         leax  <cleartop,u	point to end of area to zero out
+         IFNE  H6309
+         subr  u,x		subtract U from X
+         tfr   x,w		and put X in W
+         clr   ,-s		put a zero on the stack
+         tfm   s,u+		and use TFM to clear starting at U
+         leas  1,s		clean up the stack
+         ELSE
+         pshs   x		save end pointer on stack
+clrnxt   clr   ,u+		clear out
+         cmpu  ,s		done?
+         bne   clrnxt		branch if not
+         leas  2,s		else clear stack
+         ENDC
+         puls  x,u		and restore our earlier saved registers
+         leay  bigbuff,u	point Y to copy buffer offset in U
+         stx   <parmptr		save parameter pointer
+         sty   <bufptr		save pointer to buffer
+         tfr   s,d		place top of stack in D
+         IFNE  H6309
+         subr  y,d
+         ELSE
+         pshs  y		save Y on stack
+         subd  ,s++		get size of space between copybuf and X
+         ENDC
+         subd  #STACKSZ+PARMSZ	subtract out our stack/param size
+         std   <bufsiz		size of our buffer
+
+* At this point we have determined our buffer space and saved pointers
+* for later use.  Now we will parse the command line for options that
+* begin with a dash.
+* Note that X will NOT point to a space, but to either a CR (if no
+* parameters were passed) or the first non-space character of the
+* parameter.
+* Here we merely grab the byte at X into A and test for end of line,
+* exiting if so.  Utilities that don't require arguments should
+* comment out the following three lines.
+         lda   ,x         	get first char
+         cmpa  #C$CR		CR?
+         lbeq  ShowHelp		if so, no parameters... show help and exit
+GetChar  lda   ,x+		get next character on cmd line
+         cmpa  #C$CR		CR?
+         lbeq  DoNGU		if so, do whatever this utility does
+         cmpa  #'-		is it an option?
+         beq   GetDash		if so, process it
+         inc   <filecnt         else must be a non-option argument (file)
+         lbsr  SkipNSpc         move past the argument
+ChkDash  lbsr  SkipSpcs         and any following spaces
+         bra   GetChar          start processing again
+GetDash  clr   -1,x		and wipe out the dash from the cmd line
+GetDash2 ldd   ,x+		load option char and char following
+         ora   #$20		make lowercase
+IsItA    cmpa  #'a		is it this option?
+         bne   IsItB		branch if not
+         inc   <gota
+         bra  FixCmdLn
+IsItB    cmpa  #'b		is it this option?
+         bne   IsItC		branch if not
+         inc   <gotb
+         bra   FixCmdLn
+IsItC    cmpa  #'c		is it this option?
+         bne   BadOpt		branch if not
+         tst   <coptflg		was this option already specified?
+         bne   BadOpt		show help if so
+         cmpb  #'=		2nd char =?
+         lbne  ShowHelp		show help if not
+         inc   <coptflg		else tag this option as parsed
+*         ldb   #C$SPAC		get space
+         clr   -$01,x		write over c
+         clr   ,x+		and = sign, inc X to dest dir
+* check for valid char after -c=
+         lda   ,x
+         lbeq  ShowHelp         
+         cmpa  #C$SPAC
+         lbeq  ShowHelp         
+         cmpa  #C$CR
+         lbeq  ShowHelp         
+         leay  <copt,u		point Y to parameber buffer
+         tfr   y,d		transfer Y to D
+         addd  #COPTSIZ
+         pshs  b,a		save updated ptr value
+L0339    lda   ,x		get byte at X
+         clr   ,x+		store nul byte at X and inc
+         sta   ,y+		save loaded byte at Y and inc
+         cmpy  ,s		are we at end?
+         beq   L035D		branch if so (buffer too small)
+         tsta			else is char in A a nul byte?
+         beq   L0350		branch if so
+         cmpa  #C$SPAC		a space?
+         beq   L0350		branch if so
+         cmpa  #C$CR		cr?
+         bne   L0339		get next byte if not
+L0350    leax  -1,x
+         sta   ,x		restore previous A
+         leas  $02,s		kill stack
+         lbra  ChkDash
+L035D    leas  $02,s
+         ldb   #$BF		else buffer size too small
+         orcc  #Carry
+         lbra  Exit
+FixCmdLn clr   -$01,x		and wipe out option character
+         cmpb  #'0
+         lblt  ChkDash		start dash option processing again
+         lbra  GetDash		possibly another option following?
+
+* We branch here if we encounter an unknown option character
+* A = bad option character
+BadOpt   leax  UnkOpt,pcr
+         ldy   #UnkOptL
+         ldb   #C$CR
+         pshs  d		save bad option and CR on stack
+         lda   #$02		stderr
+         os9   I$Write
+         leax  ,s		point X at option char on stack
+         os9   I$WritLn		print option and CR
+         puls  d		clean up stack
+         lbra  ShowHelp
+
+
+* At this point options are processed.
+* We load X with our parameter pointer and go down the command line
+* looking at each file to process (options have been wiped out with
+* spaces)
+*
+* Note, the following two instructions may not be needed, depending on
+* if your utility requires a non-option on the command line.
+DoNGU    tst   <filecnt		we should have at least one file on cmdline
+         lbeq  ShowHelp		if not, exit with error
+         ldx   <parmptr		get our parameter pointer
+DoLoop   lbsr  SkipSpcs		skip any leading spaces
+         cmpa  #C$CR		end of parameters?
+         beq   ExitOk		if so, end the utility
+         pshs  x		save pointer to arg
+         bsr   ProcFile		process file at X
+         puls  x		get arg pointer
+         lbsr  SkipNSpc         skip the argument we just processed
+         bra   DoLoop
+
+* This routine processes one file at a time.
+* Entry: X = ptr to argument on the command line.
+* On exit, X can point to the argument or past it.
+* Note that there are NO leading spaces.
+* They have been skipped by the caller.
+* The following code just echos the command line argument, followed
+* by a carriage return.
+ProcFile 
+         pshs  x		save ptr
+         lda   #$01		standard output
+         bsr   StrLen		get length of argument in Y
+         puls  x		recover ptr
+         os9   I$Write		write name out
+         leax  CR,pcr		point to carriage return
+         os9   I$WritLn		write it out
+         rts
+
+ShowHelp equ   *
+         IFNE  DOHELP
+         leax  >HlpMsg,pcr	point to help message
+         ldy   #HlpMsgL		get length
+         lda   #$02		std error
+         os9   I$WritLn 	write it
+         ENDC
+ExitOk   clrb  			clear carry
+Exit     os9   F$Exit   	and exit
+
+* This routine counts the number of non-whitespace characters
+* starting at X
+*
+* Entry:
+*   X = ptr to string (space, nul byte or CR terminated)
+* Exit:
+*   Y = length of string
+*   X = ptr to byte after string
+StrLen   pshs  a
+         ldy   #$0000
+StrLenLp lda   ,x+
+         beq   StrLenEx
+         cmpa  #C$SPAC
+         beq   StrLenEx
+         cmpa  #C$CR
+         beq   StrLenEx
+         leay  1,y
+         bra   StrLenLp
+StrLenEx puls  a,pc
+
+* This routine copies a string of text from X to Y until
+* a whitespace character or CR is encountered
+*
+* Entry:
+*   X = ptr to src string
+*   Y = ptr to dest string
+* Exit:
+*   D = number of bytes copied
+*   X = ptr to byte after original string
+*   Y = ptr to byte after copied string
+StrCpy   pshs  u
+         ldu   #$0000
+CopyFnLp lda   ,x+
+         beq   CopyFnEx
+         cmpa  #C$SPAC
+         beq   CopyFnEx
+         cmpa  #C$CR
+         beq   CopyFnEx
+         sta   ,y+
+         leau  1,u
+         bra   CopyFnLp
+CopyFnEx tfr   u,d
+         puls  u,pc
+
+* This routine skip over spaces and nul bytes
+*
+* Entry:
+*   X = ptr to data to parse
+* Exit:
+*   X = ptr to first non-whitespace char
+*   A = non-whitespace char
+SkipSpcs lda   ,x+
+         beq   SkipSpcs
+         cmpa  #C$SPAC
+         beq   SkipSpcs
+         leax  -1,x
+         rts
+
+* This routine skips over everything but spaces, nul bytes and CRs
+*
+* Entry:
+*   X = ptr to data to parse
+* Exit:
+*   X = ptr to first whitespace char
+*   A = whitespace char
+SkipNSpc lda   ,x+
+         beq   EatOut
+         cmpa  #C$SPAC
+         beq   EatOut
+         cmpa  #C$CR
+         bne   SkipNSpc
+EatOut   leax  -1,x
+         rts
+
+         emod
+eom      equ   *
+         end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/bf.asm	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,177 @@
+********************************************************************
+* bf - Brainfuck Language Interpreter
+*
+* $Id$
+*
+* This is a simple interpreter for the Brainfuck language:
+* https://en.wikipedia.org/wiki/Brainfuck
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2015/10/02  Boisy G. Pitre
+* Created.
+*
+
+        ifp1
+	use	defsfile
+	endc
+
+tylg	set	Prgrm+Objct
+atrv	set	ReEnt+rev
+rev	set	$00
+edition	set	1
+
+	mod	eom,name,tylg,atrv,start,size
+
+pSize	equ	12000
+dSize   equ     3000
+
+        org     0
+pmem	rmb	pSize
+dmem	rmb	dSize
+stack	rmb	200
+size	equ	.
+
+name	fcs	/bfp/
+	fcb	edition
+
+* initialize interpreter
+* clear program memory
+start
+	lda	#READ.
+	os9	I$Open
+	lbcs	error
+	ldy	#pSize
+	leax	pmem,u
+	os9	I$Read
+	lbcs	error
+	os9	I$Close
+	tfr	y,d		nul terminate program string in memory
+	clr	d,x
+
+	leay	dmem,u
+	ldd	#dSize
+clrloop clr	,y+
+	subd	#$0001
+	bne	clrloop
+	leay	dmem,u
+	bra	parse
+
+ptrInc 
+	leay	1,y
+	bra	parse
+
+ptrDec
+	leay    -1,y
+	bra	parse
+
+dataInc
+	inc	,y
+	bra	parse
+
+dataDec
+	dec	,y
+	bra	parse
+
+putChar
+	pshs    d,x,y
+	lda	#1
+	tfr     y,x
+	ldy     #1
+	os9	I$Write
+	puls	d,x,y,pc
+
+getChar
+	pshs    d,x,y
+	clra
+	tfr     y,x
+	ldy     #1
+	os9	I$Read
+	puls	d,x,y,pc
+	
+
+brOpen	lda	#1
+	pshs	a
+	tst	,y
+	bne	brOpenBye
+brOpenDo
+	lda	,x+
+	cmpa	#'[
+	bne	brOpenCkClose
+	inc	,s
+	bra	brOpenDoTest
+brOpenCkClose
+	cmpa	#']
+	bne	brOpenDoTest
+	dec	,s
+brOpenDoTest
+	tst	,s
+	bne	brOpenDo
+brOpenBye
+	puls	a,pc
+
+brClose
+	clr	,-s
+brCloseDo
+	lda	,-x
+	cmpa	#'[
+	bne	brCloseCkClose
+	inc	,s
+	bra	brCloseDoCont
+brCloseCkClose
+	cmpa	#']
+	bne	brCloseDoCont
+	dec	,s
+brCloseDoCont
+	tst	,s
+	bne	brCloseDo
+	puls    a,pc
+
+* X = Brainfuck program pointer (nul byte terminates)
+* Y = Brainfuck data pointer
+parse
+	lda	,x+
+	beq	parseEnd
+	cmpa	#'>
+	bne	a1
+	leay	1,y
+	bra	parse
+a1	cmpa	#'<
+	bne	a2
+	leay	-1,y
+	bra	parse
+a2	cmpa	#'+
+	bne	a3
+	inc	,y
+	bra	parse
+a3	cmpa	#'-
+	bne	a4
+	dec	,y
+	bra	parse
+a4	cmpa	#'.
+	bne	a5
+	bsr	putChar
+	bra	parse
+a5	cmpa	#',
+	bne	a6
+	bsr	getChar
+	bra	parse
+a6	cmpa	#'[
+	bne	a7
+	bsr	brOpen
+	bra	parse
+a7	cmpa	#']
+	bne	parse			unrecognized character -- keep parsing
+	bsr	brClose	
+	bra	parse
+
+
+parseEnd
+	clrb
+error
+	os9	F$Exit
+
+	EMOD
+eom	EQU	*
+	END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/defsfile	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,2 @@
+         use   os9.d   
+         use   scf.d   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/donothing.bf	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,2 @@
+[ This program does nothing. ]
+[,.]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/helloworld.bf	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,44 @@
+[ This program prints "Hello World!" and a newline to the screen, its
+  length is 106 active command characters. [It is not the shortest.]
+
+  This loop is a "comment loop", a simple way of adding a comment
+  to a BF program such that you don't have to worry about any command
+  characters. Any ".", ",", "+", "-", "<" and ">" characters are simply
+  ignored, the "[" and "]" characters just have to be balanced. This
+  loop and the commands it contains are ignored because the current cell
+  defaults to a value of 0; the 0 value causes this loop to be skipped.
+]
++++++ +++               Set Cell #0 to 8
+[
+    >++++               Add 4 to Cell #1; this will always set Cell #1 to 4
+    [                   as the cell will be cleared by the loop
+        >++             Add 2 to Cell #2
+        >+++            Add 3 to Cell #3
+        >+++            Add 3 to Cell #4
+        >+              Add 1 to Cell #5
+        <<<<-           Decrement the loop counter in Cell #1
+    ]                   Loop till Cell #1 is zero; number of iterations is 4
+    >+                  Add 1 to Cell #2
+    >+                  Add 1 to Cell #3
+    >-                  Subtract 1 from Cell #4
+    >>+                 Add 1 to Cell #6
+    [<]                 Move back to the first zero cell you find; this will
+                        be Cell #1 which was cleared by the previous loop
+    <-                  Decrement the loop Counter in Cell #0
+]                       Loop till Cell #0 is zero; number of iterations is 8
+
+The result of this is:
+Cell No :   0   1   2   3   4   5   6
+Contents:   0   0  72 104  88  32   8
+Pointer :   ^
+
+>>.                     Cell #2 has value 72 which is 'H'
+>---.                   Subtract 3 from Cell #3 to get 101 which is 'e'
++++++++..+++.           Likewise for 'llo' from Cell #3
+>>.                     Cell #5 is 32 for the space
+<-.                     Subtract 1 from Cell #4 for 87 to give a 'W'
+<.                      Cell #3 was set to 'o' from the end of 'Hello'
++++.------.--------.    Cell #3 for 'rl' and 'd'
+>>+.                    Add 1 to Cell #5 gives us an exclamation point
+>++.                    And finally a newline from Cell #6
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/inout.bf	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,2 @@
+[ This program takes one byte of input and immediately outputs it. ]
+,.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/packages/brainfuck/makefile	Sat Oct 03 14:50:37 2015 -0500
@@ -0,0 +1,50 @@
+include $(NITROS9DIR)/rules.mak
+
+DSK	= brainfuck.dsk
+
+# NitrOS-9
+H6309		= $(AFLAGS) -DH6309=1
+# Non-NitrOS-9
+M6809		= $(AFLAGS)
+
+DEPENDS		= ./makefile
+
+TEXTFILES	= ReadMe inout.bf helloworld.bf donothing.bf
+OBJS		= bf
+ALLOBJS		= $(OBJS)
+
+all:	banner $(ALLOBJS) $(DEPENDS)
+
+banner:
+	@$(ECHO) "**************************************************"
+	@$(ECHO) "*                                                *"
+	@$(ECHO) "*                    Brainfuck                   *"
+	@$(ECHO) "*                                                *"
+	@$(ECHO) "**************************************************"
+
+bf: bf.asm
+	$(AS) $(ASOUT)$@ $< $(H6309)
+
+clean: dskclean
+	$(RM) $(ALLOBJS)
+
+dsk: $(DSK)
+
+$(DSK): all
+	$(RM) $@
+	$(OS9FORMAT_SS35) $@ -n"brainfuck"
+	$(MAKDIR) $@,CMDS
+	$(OS9COPY) $(ALLOBJS) $@,CMDS
+	$(OS9ATTR_EXEC) $(foreach file,$(ALLOBJS),$@,CMDS/$(file))
+	$(CPL) $(TEXTFILES) $@,.
+	$(OS9ATTR_TEXT) $(foreach file,$(TEXTFILES),$@,$(file))
+
+dskcopy: $(DSK)
+	$(CP) $(DSK) $(DSKDIR)
+
+dskclean:
+	$(RM) $(DSK)
+
+info:
+	@$(ECHO) "*** brainfuck ***"
+	@$(ECHO) $(DSK)
--- a/3rdparty/packages/makefile	Sun Jul 26 10:39:02 2015 +0200
+++ b/3rdparty/packages/makefile	Sat Oct 03 14:50:37 2015 -0500
@@ -1,6 +1,6 @@
 include $(NITROS9DIR)/rules.mak
 
-dirs	= arcadepak basic09 deskmate3 cc fsim2 koronis kyumgai mm multivue os9l2bbs pacos9 raakatu rof sierra subsim uucpbb
+dirs	= arcadepak basic09 brainfuck deskmate3 cc fsim2 koronis kyumgai mm multivue os9l2bbs pacos9 raakatu rof sierra subsim uucpbb
 
 # Make all components
 all: