brandy-1.20/0000755000175000017500000000000012163034777011717 5ustar colincolinbrandy-1.20/makefile.riscos0000644000175000017500000001273410675442512014723 0ustar colincolin# Makefile for brandy under RISC OS (using Norcroft tools) CC = cc LD = link CFLAGS = -c -Wc -IC: -g -throwback -DDEBUG CFLAGS2 = -c -Wc -IC: -throwback LDFLAGS = -debug LIBS = C:o.stubs OBJ = variables.o tokens.o riscos.o strings.o statement.o \ stack.o miscprocs.o mainstate.o lvalue.o keyboard.o iostate.o \ heap.o functions.o fileio.o evaluate.o errors.o emulate.o editor.o \ convert.o commands.o brandy.o assign.o SRC = variables.c tokens.c riscos.c strings.c statement.c \ stack.c miscprocs.c mainstate.c lvalue.c keyboard.c iostate.c \ heap.c functions.c fileio.c evaluate.c errors.c emulate.c editor.c \ convert.c commands.c brandy.c assign.c brandy: $(OBJ) $(LD) $(LDFLAGS) -o brandy $(OBJ) $(LIBS) # Build VARIABLES.C VARIABLES_C = common.h target.h basicdefs.h \ variables.h evaluate.h tokens.h \ stack.h heap.h errors.h \ miscprocs.h screen.h lvalue.h variables.o: $(VARIABLES_C) variables.c $(CC) $(CFLAGS) variables.c # Build TOKENS.C TOKENS_C = common.h target.h basicdefs.h \ tokens.h miscprocs.h convert.h \ errors.h tokens.o: $(TOKENS_C) tokens.c $(CC) $(CFLAGS) tokens.c # Build RISCOS.C RISCOS_C = common.h target.h basicdefs.h \ errors.h scrcommon.h screen.h \ keyboard.h riscos.o: $(RISCOS_C) riscos.c $(CC) $(CFLAGS) riscos.c # Build STRINGS.C STRINGS_C = common.h target.h basicdefs.h \ strings.h heap.h errors.h strings.o: $(STRINGS_C) strings.c $(CC) $(CFLAGS) strings.c # Build STATEMENT.C STATEMENT_C = common.h target.h basicdefs.h \ tokens.h commands.h stack.h \ heap.h errors.h editor.h \ miscprocs.h variables.h evaluate.h \ screen.h fileio.h strings.h \ iostate.h mainstate.h assign.h \ statement.h statement.o: $(STATEMENT_C) statement.c $(CC) $(CFLAGS) statement.c # Build STACK.C STACK_C = common.h target.h basicdefs.h \ stack.h miscprocs.h strings.h \ tokens.h errors.h stack.o: $(STACK_C) stack.c $(CC) $(CFLAGS) stack.c # Build MISCPROCS.C MISCPROCS_C = common.h target.h basicdefs.h \ tokens.h errors.h keyboard.h \ screen.h miscprocs.h miscprocs.o: $(MISCPROCS_C) miscprocs.c $(CC) $(CFLAGS) miscprocs.c # Build MAINSTATE.C MAINSTATE_C = common.h target.h basicdefs.h \ tokens.h variables.h stack.h \ heap.h strings.h errors.h \ statement.h evaluate.h convert.h \ miscprocs.h editor.h emulate.h \ screen.h lvalue.h fileio.h \ mainstate.h mainstate.o: $(MAINSTATE_C) mainstate.c $(CC) $(CFLAGS) mainstate.c # Build LVALUE.C LVALUE_C = common.h target.h basicdefs.h \ tokens.h evaluate.h stack.h \ errors.h variables.h miscprocs.h \ lvalue.h lvalue.o: $(LVALUE_C) lvalue.c $(CC) $(CFLAGS) lvalue.c # Build KEYBOARD.C KEYBOARD_C = common.h target.h basicdefs.h \ errors.h keyboard.h screen.h keyboard.o: $(KEYBOARD_C) keyboard.c $(CC) $(CFLAGS) keyboard.c # Build IOSTATE.C IOSTATE_C = common.h target.h basicdefs.h \ tokens.h stack.h strings.h \ errors.h miscprocs.h evaluate.h \ convert.h emulate.h fileio.h \ screen.h lvalue.h statement.h \ iostate.h iostate.o: $(IOSTATE_C) iostate.c $(CC) $(CFLAGS) iostate.c # Build HEAP.C HEAP_C = common.h target.h basicdefs.h \ heap.h target.h errors.h \ miscprocs.h heap.o: $(HEAP_C) heap.c $(CC) $(CFLAGS) heap.c # Build FUNCTIONS.C FUNCTIONS_C = common.h target.h basicdefs.h \ tokens.h variables.h strings.h \ convert.h stack.h errors.h \ evaluate.h keyboard.h screen.h \ emulate.h miscprocs.h fileio.h \ functions.h functions.o: $(FUNCTIONS_C) functions.c $(CC) $(CFLAGS) functions.c # Build FILEIO.C FILEIO_C = common.h target.h basicdefs.h \ errors.h fileio.h strings.h fileio.o: $(FILEIO_C) fileio.c $(CC) $(CFLAGS) fileio.c # Build EVALUATE.C EVALUATE_C = common.h target.h basicdefs.h \ tokens.h variables.h lvalue.h \ strings.h stack.h errors.h \ evaluate.h statement.h miscprocs.h \ functions.h evaluate.o: $(EVALUATE_C) evaluate.c $(CC) $(CFLAGS) evaluate.c # Build ERRORS.C ERRORS_C = common.h target.h basicdefs.h \ errors.h stack.h fileio.h keyboard.h \ tokens.h screen.h miscprocs.h errors.o: $(ERRORS_C) errors.c $(CC) $(CFLAGS) errors.c # Build EMULATE.C EMULATE_C = common.h target.h errors.h \ basicdefs.h target.h emulate.h \ screen.h emulate.o: $(EMULATE_C) emulate.c $(CC) $(CFLAGS) emulate.c # Build EDITOR.C EDITOR_C = common.h target.h basicdefs.h \ errors.h variables.h heap.h \ tokens.h strings.h miscprocs.h \ stack.h fileio.h editor.o: $(EDITOR_C) editor.c $(CC) $(CFLAGS) editor.c # Build CONVERT.C CONVERT_C = common.h target.h basicdefs.h \ convert.h errors.h miscprocs.h convert.o: $(CONVERT_C) convert.c $(CC) $(CFLAGS) convert.c # Build COMMANDS.C COMMANDS_C = common.h target.h basicdefs.h \ miscprocs.h tokens.h statement.h \ variables.h editor.h errors.h \ heap.h stack.h strings.h \ evaluate.h screen.h keyboard.h commands.o: $(COMMANDS_C) commands.c $(CC) $(CFLAGS) commands.c # Build BRANDY.C BRANDY_C = common.h target.h basicdefs.h \ tokens.h errors.h heap.h \ editor.h commands.h statement.h \ fileio.h emulate.h keyboard.h \ screen.h miscprocs.h brandy.o: $(BRANDY_C) brandy.c $(CC) $(CFLAGS) brandy.c # Build ASSIGN.C ASSIGN_C = common.h target.h basicdefs.h \ target.h tokens.h heap.h \ stack.h strings.h variables.h \ errors.h miscprocs.h editor.h \ evaluate.h lvalue.h statement.h \ assign.h fileio.h emulate.h assign.o: $(ASSIGN_C) assign.c $(CC) $(CFLAGS) assign.c recompile: $(CC) $(CFLAGS) $(SRC) $(LD) $(LDFLAGS) $(OBJ) $(LIBS) -o brandy clean: wipe o.* ~CF~R~V wipe brandy ~CF~R~V wipe map ~CF~R~V nodebug: $(CC) $(CFLAGS2) $(SRC) $(LD) $(OBJ) $(LIBS) -o brandy -sym map squeeze brandy all: brandy brandy-1.20/makefile.bcc0000644000175000017500000002223110675442512014141 0ustar colincolin# Makefile for brandy under DOS (for Borland BCC compiler) CC = bcc32 LD = bcc32 CFLAGS = -c -n$(SRCDIR) -O2 -WC -DTARGET_BCC32 LDFLAGS = LIBS = SRCDIR = src OBJ = $(SRCDIR)/variables.obj $(SRCDIR)/tokens.obj $(SRCDIR)/textonly.obj \ $(SRCDIR)/strings.obj $(SRCDIR)/statement.obj $(SRCDIR)/stack.obj \ $(SRCDIR)/miscprocs.obj $(SRCDIR)/mainstate.obj $(SRCDIR)/lvalue.obj \ $(SRCDIR)/keyboard.obj $(SRCDIR)/iostate.obj $(SRCDIR)/heap.obj \ $(SRCDIR)/functions.obj $(SRCDIR)/fileio.obj $(SRCDIR)/evaluate.obj \ $(SRCDIR)/errors.obj $(SRCDIR)/emulate.obj $(SRCDIR)/editor.obj \ $(SRCDIR)/convert.obj $(SRCDIR)/commands.obj $(SRCDIR)/brandy.obj \ $(SRCDIR)/assign.obj SRC = $(SRCDIR)/variables.c $(SRCDIR)/tokens.c $(SRCDIR)/textonly.c \ $(SRCDIR)/strings.c $(SRCDIR)/statement.c $(SRCDIR)/stack.c \ $(SRCDIR)/miscprocs.c $(SRCDIR)/mainstate.c $(SRCDIR)/lvalue.c \ $(SRCDIR)/keyboard.c $(SRCDIR)/iostate.c $(SRCDIR)/heap.c \ $(SRCDIR)/functions.c $(SRCDIR)/fileio.c $(SRCDIR)/evaluate.c \ $(SRCDIR)/errors.c $(SRCDIR)/emulate.c $(SRCDIR)/editor.c \ $(SRCDIR)/convert.c $(SRCDIR)/commands.c $(SRCDIR)/brandy.c \ $(SRCDIR)/assign.c brandy: $(OBJ) $(LD) $(LDFLAGS) -ebrandy $(SRCDIR)/*.obj $(LIBS) # Build VARIABLES.C VARIABLES_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h $(SRCDIR)/tokens.h \ $(SRCDIR)/stack.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/variables.obj: $(VARIABLES_C) $(SRCDIR)/variables.c $(CC) $(CFLAGS) $(SRCDIR)/variables.c # Build TOKENS.C TOKENS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.h \ $(SRCDIR)/errors.h $(SRCDIR)/tokens.obj: $(TOKENS_C) $(SRCDIR)/tokens.c $(CC) $(CFLAGS) $(SRCDIR)/tokens.c # Build TEXTONLY.C TEXTONLY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/scrcommon.h $(SRCDIR)/screen.h \ $(SRCDIR)/keyboard.h $(SRCDIR)/textonly.obj: $(TEXTONLY_C) $(SRCDIR)/textonly.c $(CC) $(CFLAGS) $(SRCDIR)/textonly.c # Build STRINGS.C STRINGS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/strings.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/strings.obj: $(STRINGS_C) $(SRCDIR)/strings.c $(CC) $(CFLAGS) $(SRCDIR)/strings.c # Build STATEMENT.C STATEMENT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/commands.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/editor.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/screen.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h \ $(SRCDIR)/iostate.h $(SRCDIR)/mainstate.h $(SRCDIR)/assign.h \ $(SRCDIR)/statement.h $(SRCDIR)/statement.obj: $(STATEMENT_C) $(SRCDIR)/statement.c $(CC) $(CFLAGS) $(SRCDIR)/statement.c # Build STACK.C STACK_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/stack.h $(SRCDIR)/miscprocs.h $(SRCDIR)/strings.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/stack.obj: $(STACK_C) $(SRCDIR)/stack.c $(CC) $(CFLAGS) $(SRCDIR)/stack.c # Build MISCPROCS.C MISCPROCS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/miscprocs.obj: $(MISCPROCS_C) $(SRCDIR)/miscprocs.c $(CC) $(CFLAGS) $(SRCDIR)/miscprocs.c # Build MAINSTATE.C MAINSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/strings.h $(SRCDIR)/errors.h \ $(SRCDIR)/statement.h $(SRCDIR)/evaluate.h $(SRCDIR)/convert.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/fileio.h \ $(SRCDIR)/mainstate.h $(SRCDIR)/mainstate.obj: $(MAINSTATE_C) $(SRCDIR)/mainstate.c $(CC) $(CFLAGS) $(SRCDIR)/mainstate.c # Build LVALUE.C LVALUE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/evaluate.h $(SRCDIR)/stack.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/lvalue.h $(SRCDIR)/lvalue.obj: $(LVALUE_C) $(SRCDIR)/lvalue.c $(CC) $(CFLAGS) $(SRCDIR)/lvalue.c # Build KEYBOARD.C KEYBOARD_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.obj: $(KEYBOARD_C) $(SRCDIR)/keyboard.c $(CC) $(CFLAGS) $(SRCDIR)/keyboard.c # Build IOSTATE.C IOSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/convert.h $(SRCDIR)/emulate.h $(SRCDIR)/fileio.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/iostate.h $(SRCDIR)/iostate.obj: $(IOSTATE_C) $(SRCDIR)/iostate.c $(CC) $(CFLAGS) $(SRCDIR)/iostate.c # Build HEAP.C HEAP_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/heap.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/heap.obj: $(HEAP_C) $(SRCDIR)/heap.c $(CC) $(CFLAGS) $(SRCDIR)/heap.c # Build FUNCTIONS.C FUNCTIONS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/strings.h \ $(SRCDIR)/convert.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h \ $(SRCDIR)/emulate.h $(SRCDIR)/miscprocs.h $(SRCDIR)/fileio.h \ $(SRCDIR)/functions.h $(SRCDIR)/functions.obj: $(FUNCTIONS_C) $(SRCDIR)/functions.c $(CC) $(CFLAGS) $(SRCDIR)/functions.c # Build FILEIO.C FILEIO_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h $(SRCDIR)/fileio.obj: $(FILEIO_C) $(SRCDIR)/fileio.c $(CC) $(CFLAGS) $(SRCDIR)/fileio.c # Build EVALUATE.C EVALUATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/lvalue.h \ $(SRCDIR)/strings.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/statement.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/functions.h $(SRCDIR)/evaluate.obj: $(EVALUATE_C) $(SRCDIR)/evaluate.c $(CC) $(CFLAGS) $(SRCDIR)/evaluate.c # Build ERRORS.C ERRORS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/stack.h $(SRCDIR)/fileio.h \ $(SRCDIR)/tokens.h $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/errors.obj: $(ERRORS_C) $(SRCDIR)/errors.c $(CC) $(CFLAGS) $(SRCDIR)/errors.c # Build EMULATE.C EMULATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/basicdefs.h $(SRCDIR)/target.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/emulate.obj: $(EMULATE_C) $(SRCDIR)/emulate.c $(CC) $(CFLAGS) $(SRCDIR)/emulate.c # Build EDITOR.C EDITOR_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/heap.h \ $(SRCDIR)/tokens.h $(SRCDIR)/strings.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/stack.h $(SRCDIR)/fileio.h $(SRCDIR)/editor.obj: $(EDITOR_C) $(SRCDIR)/editor.c $(CC) $(CFLAGS) $(SRCDIR)/editor.c # Build CONVERT.C CONVERT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/convert.h $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.obj: $(CONVERT_C) $(SRCDIR)/convert.c $(CC) $(CFLAGS) $(SRCDIR)/convert.c # Build COMMANDS.C COMMANDS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/tokens.h $(SRCDIR)/statement.h \ $(SRCDIR)/variables.h $(SRCDIR)/editor.h $(SRCDIR)/errors.h \ $(SRCDIR)/heap.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.h $(SRCDIR)/commands.obj: $(COMMANDS_C) $(SRCDIR)/commands.c $(CC) $(CFLAGS) $(SRCDIR)/commands.c # Build BRANDY.C BRANDY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/heap.h \ $(SRCDIR)/editor.h $(SRCDIR)/commands.h $(SRCDIR)/statement.h \ $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/brandy.obj: $(BRANDY_C) $(SRCDIR)/brandy.c $(CC) $(CFLAGS) $(SRCDIR)/brandy.c # Build ASSIGN.C ASSIGN_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/target.h $(SRCDIR)/tokens.h $(SRCDIR)/heap.h \ $(SRCDIR)/stack.h $(SRCDIR)/strings.h $(SRCDIR)/variables.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/assign.h $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/assign.obj: $(ASSIGN_C) $(SRCDIR)/assign.c $(CC) $(CFLAGS) $(SRCDIR)/assign.c recompile: $(CC) $(CFLAGS) $(SRC) $(LIBS) -ebrandy nodebug: $(CC) $(CFLAGS2) $(SRC) $(LIBS) -ebrandy strip brandy clean: erase $(SRCDIR)/*.obj erase brandy.exe all: brandy brandy-1.20/examples/0000755000175000017500000000000010546536104013527 5ustar colincolinbrandy-1.20/examples/trees10000644000175000017500000000155610546536104014664 0ustar colincolinREM Example program to create a binary tree and display REM its contents in alphabetical order of the name : DIM name$(100),value%(100),left%(100),right%(100) next%=1 root%=0 FOR N%=1 TO 10 READ X$,X% PROCadd(X$,X%) NEXT PROCshow(root%) END : DATA red, 5, green, 10, yellow, 15, blue, 20, black, 25, white, 30 DATA orange, 35, pink, 40, cyan, 45, purple, 50 : : DEF PROCadd(name$,value%) name$(next%)=name$ value%(next%)=value% left%(next%)=0 right%(next%)=0 IF root%=0 THEN root%=1: next%=2: ENDPROC P%=root% done%=FALSE REPEAT IF name$0 THEN P%=left%(P%) ELSE left%(P%)=next%: done%=TRUE ELSE IF right%(P%)<>0 THEN P%=right%(P%) ELSE right%(P%)=next%: done%=TRUE ENDIF UNTIL done% next%+=1 ENDPROC : : DEF PROCshow(P%) IF left%(P%)<>0 THEN PROCshow(left%(P%)) PRINT name$(P%);TAB(20);value%(P%) IF right%(P%)<>0 THEN PROCshow(right%(P%)) ENDPROC brandy-1.20/examples/combsort0000644000175000017500000000234410546536104015305 0ustar colincolinREM This program compares a comb sort to a bubble sort : size%=2000 DIM table%(size%) PROCsetup4 PROCbubblesort PROCsetup4 PROCcombsort END : : DEF PROCsetup1 PRINT"Ascending order "; FOR I%=1 TO size% table%(I%)=I% NEXT ENDPROC : : DEF PROCsetup2 PRINT"Descending order "; FOR I%=1 TO size% table%(I%)=size%-I% NEXT ENDPROC : : DEF PROCsetup3 PRINT"Random order "; I%=RND(-65656) FOR I%=1 TO size% table%(I%)=RND(100000) NEXT ENDPROC : : DEF PROCsetup4 PRINT"Semi-ordered "; I%=RND(-18940606) N%=1 WHILE N%<=size% L%=RND(20)+1 IF N%+L%>size% THEN L%=size%-N% X%=RND(100000) FOR I%=1 TO L% table%(N%)=X% X%+=RND(100) N%+=1 NEXT ENDWHILE ENDPROC : : DEF PROCcheck FOR N%=1 TO size%-1 IF table%(N%)>table%(N%+1) THEN PRINT"Out of order at ";N% NEXT ENDPROC :: DEF PROCcombsort PRINT"Comb sort "; T=TIME gap%=size% REPEAT gap%=gap%/1.3: IF gap%<1 THEN gap%=1 switch%=FALSE FOR I%=1 TO size%-gap% J%=I%+gap% IF table%(I%)>table%(J%) THEN SWAP table%(I%),table%(J%): switch%=TRUE NEXT UNTIL NOT switch% AND gap%=1 PRINT TIME-T PROCcheck ENDPROC : : DEF PROCbubblesort PRINT"Bubble sort "; T=TIME H%=size%-1 REPEAT M%=0 FOR I%=1 TO H% IF table%(I%)>table%(I%+1) THEN SWAP table%(I%),table%(I%+1): M%=I% NEXT H%=M% UNTIL M%=0 PRINT TIME-T PROCcheck ENDPROC brandy-1.20/examples/hanoi0000644000175000017500000000067210546536104014555 0ustar colincolinREM This example program solves the "Towers of Hanoi" puzzle : INPUT "Number of discs? " number% steps% = 0 T = TIME PROChanoi("left", "middle", "right", number%) PRINT;steps%;" steps in ";(TIME-T)/100;" seconds" END : : DEF PROChanoi(from$, using$, to$, N%) IF N%=0 THEN ENDPROC PROChanoi(from$, to$, using$, N%-1) PRINT STRING$(N%, " ");"Move disc "; N%; " from "; from$; " to "; to$ steps%+=1 PROChanoi(using$, from$, to$, N%-1) ENDPROC brandy-1.20/examples/graphdemo0000644000175000017500000000107510546536104015423 0ustar colincolinREM NOTE: This program will only run using a version of the REM interpreter that supports graphics. : MODE 27 ORIGIN 640, 512 xlow = -10 xhigh = 10 ylow = -10 yhigh = 10 depth = 10 xscale = 30 yscale = 12 c = -4000 : FOR x = xlow TO xhigh MOVE xscale*(x+ylow), yscale*(ylow-x)+c/(x*x+ylow*ylow+depth) FOR y = ylow TO yhigh DRAW xscale*(x+y), yscale*(y-x)+c/(x*x+y*y+depth) NEXT NEXT FOR y = ylow TO yhigh MOVE xscale*(xlow+y), yscale*(y-xlow)+c/(xlow*xlow+y*y+depth) FOR x = xlow TO xhigh DRAW xscale*(x+y), yscale*(y-x)+c/(x*x+y*y+depth) NEXT NEXT END brandy-1.20/examples/tekdemo20000644000175000017500000000254210546536104015167 0ustar colincolinREM NOTE: This program will ONLY run in an xterm window under NetBSD and Linux. REM REM It uses the Tektronics graphics terminal emulation that xterm provides REM to draw a simple graph in the xterm 'Tek' window. : REM To run the program: REM 1) Load it in the normal way REM 2) Switch output to the xterm 'Tek' window REM 3) Run the program in the normal way REM 4) Switch output back to the xterm 'VT' window : REM To switch xterm between 'Tek' and 'vt' modes, press 'Ctrl' and the REM middle mouse button to bring up the xterm 'VT Options' menu. The REM last-but-one entry on this is 'Switch to Tek Mode'. Select this REM option to display the window 'tektronix(Tek)'. To switch back, REM press 'Ctrl' and the middle mouse button to display the 'Tek Options' REM menu. Select the option 'Switch to VT Mode' to return xterm to REM normal operation. : LIBRARY"examples/teklib" PROCmode(0) PROCorigin(1024, 750) xlow = -10 xhigh = 10 ylow = -10 yhigh = 10 depth = 8 xscale = 50 yscale = 20 c = -4000 : FOR x = xlow TO xhigh PROCmove(xscale*(x+ylow), yscale*(ylow-x)+c/(x*x+ylow*ylow+depth)) FOR y = ylow TO yhigh PROCdraw(xscale*(x+y), yscale*(y-x)+c/(x*x+y*y+depth)) NEXT NEXT FOR y = ylow TO yhigh PROCmove(xscale*(xlow+y), yscale*(y-xlow)+c/(xlow*xlow+y*y+depth)) FOR x = xlow TO xhigh PROCdraw(xscale*(x+y), yscale*(y-x)+c/(x*x+y*y+depth)) NEXT NEXT END brandy-1.20/examples/trees20000644000175000017500000000211310546536104014653 0ustar colincolinREM Example program to create a binary tree and display REM its contents in alphabetical order of the name. REM This is the same as 'trees1' but it uses indirection REM operators : DIM heap% 1000 heaptop% = heap% : REM 'struct' for a tree entry name%=0: value%=20: left%=24: right%=28: nodesize%=32 root% = 0 : FOR N%=1 TO 10 READ X$, X% PROCadd(X$, X%) NEXT PROCshow(root%) END : DATA red, 5, green, 10, yellow, 15, blue, 20, black, 25, white, 30 DATA orange, 35, pink, 40, cyan, 45, purple, 50 : : DEF PROCadd(name$, data%) LOCAL node% node% = FNalloc(nodesize%) $(node%+name%) = name$ node%!value% = data% node%!left% = 0 node%!right% = 0 IF root%=0 THEN root% = node%: ENDPROC P% = root% REPEAT IF name$<$(P%+name%) THEN IF P%!left%<>0 THEN P% = P%!left% ELSE P%!left% = node%: ENDPROC ELSE IF P%!right%<>0 THEN P% = P%!right% ELSE P%!right% = node%: ENDPROC ENDIF UNTIL FALSE ENDPROC : : DEF PROCshow(P%) IF P%!left%<>0 THEN PROCshow(P%!left%) PRINT $(P%+name%);TAB(20);P%!value% IF P%!right%<>0 THEN PROCshow(P%!right%) ENDPROC : : DEF FNalloc(size%) LOCAL P% P% = heaptop% heaptop%+=size% =P%brandy-1.20/examples/lands0000644000175000017500000000353310546536104014557 0ustar colincolinREM This program draws a simple fractal landscape and plots it REM using characters to represent different heights. The landscape REM can be changed by entering different values for seed% : S%=256 limit%=2 :REM 64 by 64 plot xlimit%=64 zlimit%=24 DIM Y%(S%,S%),filler$(16) filler$()=".", "_", "+", "%", "o", "$", "=", "U", "E", "B", "F", "O", "Q", "N", "M", "#", "@" : INPUT"Seed? " seed% CLS start=TIME T%=1024 DIV S%*limit%*2 K%=1024 DIV S% step%=limit%*2 S2%=S% DIV 2 Y%(0,0)=FNrandom(S%)-S2%-20 Y%(0,S%)=FNrandom(S%)-S2%-20 Y%(S%,0)=FNrandom(S%)-S2%-20 Y%(S%,S%)=FNrandom(S%)-S2%-20 PROClandscape(0,0,S%) COLOUR 7 PRINT'"Time=";TIME-start END : : DEF PROClandscape(X%,Z%,D%) LOCAL A%,XA%,ZA% A%=D%>>1 A2%=A%>>1 XA%=X%+A%: ZA%=Z%+A% XD%=X%+D%: ZD%=Z%+D% IF Y%(XA%,Z%)=0 THEN Y%(XA%,Z%)=(Y%(X%,Z%)+Y%(XD%,Z%)>>1)+FNrandom(A%)-A2% PROCcol2d(Y%(XA%,Z%)) IF Y%(X%,ZA%)=0 THEN Y%(X%,ZA%)=(Y%(X%,Z%)+Y%(X%,ZD%)>>1)+FNrandom(A%)-A2% PROCcol2d(Y%(X%,ZA%)) IF Y%(XA%,ZD%)=0 THEN Y%(XA%,ZD%)=(Y%(X%,ZD%)+Y%(XD%,ZD%)>>1)+FNrandom(A%)-A2% PROCcol2d(Y%(XA%,ZD%)) IF Y%(XD%,ZA%)=0 THEN Y%(XD%,ZA%)=(Y%(XD%,Z%)+Y%(XD%,ZD%)>>1)+FNrandom(A%)-A2% PROCcol2d(Y%(XD%,ZA%)) Y%(XA%,ZA%)=(Y%(X%,ZA%)+Y%(XD%,ZA%)+Y%(XA%,Z%)+Y%(XA%,ZD%)>>2)+FNrandom(A%)-A2% PROCcol2d(Y%(XA%,ZA%)) IF A%>limit% THEN PROClandscape(X%,Z%,A%) PROClandscape(XA%,Z%,A%) PROClandscape(X%,ZA%,A%) PROClandscape(XA%,ZA%,A%) ENDIF ENDPROC : : DEF PROCcol2d(P%) LOCAL xx%, zz% xx%=X% DIV step% IF xx%>=xlimit% THEN ENDPROC zz%=Z% DIV step% IF zz%>=zlimit% THEN ENDPROC IF P%<=0 THEN REM Sea IF P%<-100 THEN COLOUR 4 ELSE COLOUR 6 PRINT TAB(xx%, zz%);"~"; ELSE REM Land colour%=P% DIV 18 IF colour%=0 THEN COLOUR 3 ELSE COLOUR 2 PRINT TAB(xx%, zz%);filler$(colour%); ENDIF ENDPROC : : DEF FNrandom(range%) seed%=48271*(seed% MOD 44488)-3399*(seed% DIV 44488) IF seed%<0 THEN seed%+=&80000000 =seed% MOD range%+1 brandy-1.20/examples/tekdemo10000644000175000017500000000203710546536104015165 0ustar colincolinREM NOTE: This program will ONLY run in an xterm window under NetBSD and Linux. REM REM It uses the Tektronics graphics terminal emulation that xterm provides REM to draw a simple graph in the xterm 'Tek' window. : REM To run the program: REM 1) Load it in the normal way REM 2) Switch output to the xterm 'Tek' window REM 3) Run the program in the normal way REM 4) Switch output back to the xterm 'VT' window : REM To switch xterm between 'Tek' and 'vt' modes, press 'Ctrl' and the REM middle mouse button to bring up the xterm 'VT Options' menu. The REM last-but-one entry on this is 'Switch to Tek Mode'. Select this REM option to display the window 'tektronix(Tek)'. To switch back, REM press 'Ctrl' and the middle mouse button to display the 'Tek Options' REM menu. Select the option 'Switch to VT Mode' to return xterm to REM normal operation. : LIBRARY"examples/teklib" PROCmode(0) x%=0 PROCorigin(0, 768) PROCline(0, 0, 1800, 0) PROCline(0, -500, 0, 500) PROCmove(0, 0) FOR angle=0 TO 2*PI STEP PI/50 PROCdraw(x%, 500*SIN(angle)) x%+=16 NEXT END brandy-1.20/examples/dow0000644000175000017500000000140210546536104014240 0ustar colincolinDIM month$(12) month$()="", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" REPEAT INPUT"Enter date in the form dd,mm,yy: " dd%, mm%, yy% UNTIL dd%>=1 AND dd%<=31 AND mm%>=1 AND mm%<=12 IF yy%<=99 THEN IF yy%<70 THEN yy%+=2000 ELSE yy%+=1900 ENDIF IF mm%<3 THEN factor=365*yy%+dd%+31*(mm%-1)+(yy%-1) DIV 4-INT(0.75*INT(((yy%-1)/100)+1)) ELSE factor=365*yy%+dd%+31*(mm%-1)-INT(0.4*mm%+2.3)+INT(yy%/4)-INT(0.75*(yy% DIV 100+1)) ENDIF dow%=factor-factor DIV 7*7 PRINT month$(mm%);" ";dd%;", ";yy%;" is a "; CASE dow% OF WHEN 0: PRINT"Saturday" WHEN 1: PRINT"Sunday" WHEN 2: PRINT"Monday" WHEN 3: PRINT"Tuesday" WHEN 4: PRINT"Wednesday" WHEN 5: PRINT"Thursday" WHEN 6: PRINT"Friday" ENDCASE END brandy-1.20/examples/teklib0000644000175000017500000000457610546536104014740 0ustar colincolinREM NOTE: this library can only be used in an xterm session under REM Linux and NetBSD : REM This is a simple library that allows graphics to be plotted REM in a xterm window running under NetBSD or Linux using the REM Tektronics graphics terminal emulation that xterm offers. : REM The procedures and functions work in the same way that their REM Basic statement counterparts do. The Tektronics screen has REM a size of 1024 by 780 pixels. This library works in terms in REM RISC OS graphics units so the screen dimensions according to REM this code is 2048 graphics units by 1560. : : REM PROCmode initialises the variables used by the library and REM clears the graphics screen. It has to be called before any REM other procedure in this library : DEF PROCmode(M%) tek_gcx%=0 tek_gcy%=0 tek_originx%=0 tek_originy%=0 VDU 1, 27, 1, 12 ENDPROC : : REM PROCorigin sets the coordinates of the graphics origin : DEF PROCorigin(X%, Y%) tek_originx%=X% tek_originy%=Y% ENDPROC : : REM PROCclg clears the graphics screen : DEF PROCclg VDU 1, 27, 1, 12 ENDPROC : : REM PROCmove moves the graphics cursor to the coordinates given : DEF PROCmove(X%, Y%) tek_gcx%=(X%+tek_originx%) DIV 2 tek_gcy%=(Y%+tek_originy%) DIV 2 ENDPROC : : REM PROCdraw draws a line from the last graphics cursor position REM to the coordinates given, making them the new cursor position : DEF PROCdraw(X%, Y%) X%=(X%+tek_originx%) DIV 2 Y%=(Y%+tek_originy%) DIV 2 VDU 1, 29 VDU 1, (tek_gcy%>>5)+32, 1, (tek_gcy% AND 31)+96, 1, (tek_gcx%>>5)+32, 1, (tek_gcx% AND 31)+64 VDU 1,(Y%>>5)+32, 1,(Y% AND 31)+96, 1,(X%>>5)+32, 1,(X% AND 31)+64 VDU 1, 31 tek_gcx%=X% tek_gcy%=Y% ENDPROC : : REM PROCline draws a line from the coordinates (sx, sy) to (ex, ey). REM The graphics cursor position is set to (ex, ey) : DEF PROCline(sx%, sy%, ex%, ey%) sx%=(sx%+tek_originx%) DIV 2 sy%=(sy%+tek_originy%) DIV 2 ex%=(ex%+tek_originx%) DIV 2 ey%=(ey%+tek_originy%) DIV 2 VDU 1, 29 VDU 1, (sy%>>5)+32, 1, (sy% AND 31)+96, 1, (sx%>>5)+32, 1, (sx% AND 31)+64 VDU 1, (ey%>>5)+32, 1, (ey% AND 31)+96, 1, (ex%>>5)+32, 1, (ex% AND 31)+64 VDU 1, 31 tek_gcx%=ex% tek_gcy%=ey% ENDPROC : : REM PROCpoint plots a single point : DEF PROCpoint(X%, Y%) X%=(X%+tek_originx%) DIV 2 Y%=(Y%+tek_originy%) DIV 2 VDU 1, 29 VDU 1,(Y%>>5)+32, 1,(Y% AND 31)+96, 1,(X%>>5)+32, 1,(X% AND 31)+64 VDU 1,(Y%>>5)+32, 1,(Y% AND 31)+96, 1,(X%>>5)+32, 1,(X% AND 31)+64 VDU 1, 31 tek_gcx%=X% tek_gcy%=Y% ENDPROC brandy-1.20/examples/pastriang0000644000175000017500000000051610546536104015444 0ustar colincolinREM this program draws Pascal's triangle SIZE% = 12 DIM prev%(SIZE%), next%(SIZE%) next%() = 0 next%(0) = 1 FOR I%=0 TO SIZE%-1 PRINT TAB(35-3*I%);next%(0); IF I%>0 THEN FOR J%=1 TO I% next%(J%) = prev%(J%)+prev%(J%-1) PRINT RIGHT$(" "+STR$next%(J%), 6); NEXT ENDIF PRINT prev%() = next%() NEXT END brandy-1.20/examples/cricket0000644000175000017500000001527610546536104015111 0ustar colincolin 10REM This program is a simple cricket simulation 20REM It plays a test match between England and New Zealand 30REM The teams are from the 1999 New Zealand tour. 40: 50REM Press the space bar at the end of each innings to start 60REM the next one 70: 80pl=11: stroke%=15 90rev$=CHR$17+CHR$129+CHR$17+CHR$0 100norm$=CHR$17+CHR$0+CHR$17+CHR$129 110MODE 6 120OFF 130VDU 23,255,0,0,0,0,255,0,0,0 140DIM players_score%(2),inplay%(2),runs%(stroke%),skill(2),innings%(4),player$(11,2),bat(11,2),bowl(11,2),teams$(2),wk%(2),cap%(2) 150ps=0.23 160n=1: followon%=FALSE: needed%=100000000 170FOR I%=1 TO stroke% 180READ runs%(I%) 190NEXT 200FOR I%=1 TO 2 210READ teams$(I%) 220FOR J%=1 TO 11 230READ N$,b,bowl(J%,I%) 240player$(J%,I%)=N$ 250IF LEFT$(N$,1)="^" THEN wk%(I%)=J% 260IF LEFT$(N$,1)="*" THEN cap%(I%)=J% 270bat(J%,I%)=FNff(b) 280NEXT J%,I% 290batting%=RND(2) 300: 310REM -- Start of Innings -- 320: 330CLS 340PRINT TAB(7);teams$(batting%); 350IF n<3 THEN PRINT" - First Innings" ELSE PRINT" - Second Innings" 360overs%=0: facing%=1: wickets%=0: score%=0: nextin%=3: balls%=1: extras%=0 370VDU 31,3,13: PRINT"Extras": VDU 31,39,13,ASC"0" 380VDU 31,37,14: PRINT"ÿÿÿ" 390VDU 31,0,15: PRINT" Overs: 0.0 Wkts: 0 Total:" 400PRINT'"Fall of Wickets:" 410PRINT" 1 2 3 4 5 6 7 8 9 10" 420fall%=0 430inplay%(1)=1: skill(1)=bat(1,batting%): players_score%(1)=0 440inplay%(2)=2: skill(2)=bat(2,batting%): players_score%(2)=0 450VDU 31,0,2: PRINT" 1 ";player$(1,batting%);TAB(39);"0" 460VDU 31,0,3: PRINT" 2 ";player$(2,batting%);TAB(39);"0" 470VDU 17,1,31,2,2,62,17,3 480: 490REM -- Play loop -- 500: 510REM Change the +8 to +4500 to make game run in real time 520t2=TIME+8 530WHILE TIMEps THEN 1130 560IF RND(20)=1 THEN 1080 570IF RND(1)>skill(facing%) THEN 730 580S%=runs%(RND(stroke%)) 590players_score%(facing%)+=S% 600score%+=S% 610VDU 31,37,1+inplay%(facing%): PRINT;FNdec(players_score%(facing%),3) 620VDU 31,37,15: PRINT;FNdec(score%,3) 630IF(S% AND 1)=1 THEN 640VDU 31,2,1+inplay%(facing%),32 650facing%=3-facing% 660VDU 17,1,31,2,1+inplay%(facing%),62,17,3 670ENDIF 680IF score%>needed% THEN 1670 690GOTO 1130 700: 710REM -- Batsman out -- 720: 730howout%=RND(24)-2 740IF howout%<1 THEN 1080 750wickets%=wickets%+1 760fielders%=3-batting% 770o$=MID$("CCCCCCCCBBBBBBBLLLLLRS",howout%,1) 780VDU 31,2,1+inplay%(facing%),32 790VDU 31,13,inplay%(facing%)+1 800IF o$="R" THEN PRINT"Run out": GOTO 950 810REPEAT 820B%=RND(11) 830IF B%<6 AND RND(1)<0.8-overs%/200 THEN B%=RND(11) 840UNTIL RND(1)"C" THEN 920 860C%=RND(11) 870IF C%=B% AND RND(1)<0.5 THEN C%=RND(11) 880name$=player$(C%,fielders%) 890IF LEFT$(name$,1)="^" THEN name$=MID$(name$,2) 900IF C%=B% THEN PRINT"C.& "; ELSE PRINT"C.";name$;" "; 910GOTO 940 920IF o$="L" THEN PRINT"LBW "; 930IF o$="S" THEN PRINT"St.";MID$(player$(wk%(fielders%),fielders%),2) 940VDU 31,25,inplay%(facing%)+1: PRINT"B.";player$(B%,fielders%) 950VDU 31,24,15: PRINT;FNdec(wickets%,2) 960VDU 31,fall%,19: PRINT;FNdec(score%,3): fall%=fall%+4 970IF wickets%>9 THEN 1280 980REM 990REM -- New batsman -- 1000REM 1010players_score%(facing%)=0 1020inplay%(facing%)=nextin% 1030skill(facing%)=bat(nextin%,batting%) 1040VDU 31,0,nextin%+1: PRINT;FNdec(nextin%,2);" ";player$(nextin%,batting%): VDU 31,39,nextin%+1,ASC"0" 1050VDU 17,1,31,2,1+inplay%(facing%),62,17,3 1060nextin%=nextin%+1 1070GOTO 1130 1080extras%=extras%+1 1090score%=score%+1 1100balls%=balls%-1 1110VDU 31,37,13: PRINT;FNdec(extras%,3) 1120VDU 31,37,15: PRINT;FNdec(score%,3) 1130balls%=balls%+1 1140IF balls%<7 THEN 520 1150REM 1160REM -- New Over -- 1170REM 1180overs%=overs%+1 1190balls%=1 1200VDU 31,2,1+inplay%(facing%),32 1210facing%=3-facing% 1220VDU 17,1,31,2,1+inplay%(facing%),62,17,3 1230VDU 31,11,15: PRINT;FNdec(overs%,3);".0" 1240GOTO 520 1250REM 1260REM -- End of Innings -- 1270REM 1280VDU 31,13,inplay%(3-facing%)+1 1290PRINT"Not out"; 1300VDU 31,0,21 1310innings%(n)=score% 1320IF followon% THEN 1830 1330ON n GOTO 1340,1390,1570,1670 1340PRINT teams$(batting%);" first innings total=";score% 1350n=2 1360A%=GET 1370batting%=3-batting% 1380GOTO 330 1390diff%=innings%(2)-innings%(1) 1400IF diff%<-199 THEN 1520 1410IF diff%<0 THEN 1470 1420PRINT teams$(batting%);" lead by ";diff%;" on first innings" 1430n=3 1440A%=GET 1450batting%=3-batting% 1460GOTO 330 1470PRINT teams$(batting%);" trail by ";-diff%;" on first innings" 1480n=3 1490A%=GET 1500batting%=3-batting% 1510GOTO 330 1520PRINT teams$(batting%);" are forced to follow on ";-diff%;" runs behind" 1530n=4 1540followon%=TRUE 1550A%=GET 1560GOTO 330 1570needed%=innings%(1)+innings%(3)-innings%(2) 1580batting%=3-batting% 1590IF needed%<0 THEN 1640 1600PRINT teams$(batting%);" need ";needed%;" runs to win" 1610n=4 1620A%=GET 1630GOTO 330 1640PRINT teams$(batting%);" win by an innings and ";-needed%;" runs" 1650ON 1660END 1670VDU 31,0,21 1680IF needed%1 THEN PRINT"s"; 1800PRINT 1810ON 1820END 1830needed%=innings%(1)-innings%(2)-innings%(4) 1840IF needed%>0 THEN 1920 1850needed%=1-needed% 1860batting%=3-batting% 1870PRINT teams$(batting%);" need ";needed%;" runs to win" 1880n=4 1890followon%=FALSE 1900A%=GET 1910GOTO 330 1920batting%=3-batting% 1930PRINT teams$(batting%);" win by an innings and ";needed%;" runs" 1940ON 1950END 1960: 1970DEF FNdec(X%,W%)=RIGHT$(" "+STR$X%,W%) 1980DEF FNff(x)=(x+0.7)*0.45 1990DATA 1,1,1,1,1,2,2,2,2,3,3,3,4,4,6 2000: 2010: 2020DATA"England" 2030DATA"Stewart" ,1.40, 0 2040DATA"Butcher" ,1.40, 0.55 2050DATA"Hussain" ,1.40, 0 2060DATA"Thorpe" ,1.40, 0 2070DATA"Ramprakash" ,1.40, 0.55 2080DATA"Habib" ,1.40, 0 2090DATA"^Read" ,1.20, 0 2100DATA"Tudor" ,1.05, 0.70 2110DATA"Caddick" ,1.05, 0.7 2120DATA"Mullally" ,1.05, 0.68 2130DATA"Tuffnell" ,1.05, 0.7 2140: 2150: 2160DATA"New Zealand" 2170DATA"Horne" ,1.40, 0 2180DATA"Astle" ,1.40, 0 2190DATA"Fleming" ,1.40, 0 2200DATA"Twose" ,1.40, 0.65 2210DATA"McMillan" ,1.40, 0 2220DATA"^Parore" ,1.25, 0 2230DATA"Doull" ,1.20, 0.67 2240DATA"Cairns" ,1.15, 0.67 2250DATA"Nash" ,1.05, 0.67 2260DATA"Vettori" ,1.05, 0.67 2270DATA"Allott" ,1.05, 0.67 brandy-1.20/examples/tvtime0000644000175000017500000004257210546536104014774 0ustar colincolinREM This program is a simple adventure-type game. The object is to REM watch your favourite TV programme : PROCinit PROCdescribe REPEAT PROCread_line PROCparse_line PROCaction UNTIL finished% END : DEF PROCread_line REPEAT LINE INPUT "Ok " text$ UNTIL LEN text$>0 FOR N%=1 TO LEN text$ MID$(text$,N%,1) = FNtolower(MID$(text$,N%,1)) NEXT ENDPROC : : DEF FNtolower(ch$) = xlate$(ASC ch$) : : DEF FNfind_verb(word$) FOR N% = 1 TO verbcount% IF verb$(N%)=word$ THEN =N% NEXT =0 : : DEF FNfind_noun(word$) FOR N% = 1 TO nouncount% IF noun$(N%) = word$ THEN =N% NEXT =0 : : DEF FNextract LOCAL start% WHILE index%<=len% AND MID$(text$, index%, 1) = " ": index%+=1: ENDWHILE IF index%>len% THEN ="" start% = index% WHILE index%<=len% AND MID$(text$, index%, 1)<>" ": index%+=1: ENDWHILE =MID$(text$, start%, index%-start%) : : DEF PROCparse_line LOCAL len%, index% len% = LEN text$ index% = 1 verb$ = FNextract IF verb$="" THEN ENDPROC: REM Nothing on line IF FNfind_verb(verb$)=0 THEN PRINT"The verb '";verb$;"' is not known" noun$ = FNextract IF noun$="on" OR noun$="in" THEN noun$=FNextract IF noun$<>"" THEN IF FNfind_noun(noun$)=0 THEN PRINT"The word '";noun$;"' is not known": verb$ = "" ENDIF prep$ = FNextract IF prep$="" THEN ENDPROC IF INSTR("in into on onto to from", prep$) THEN noun2$ = FNextract IF noun2$="" THEN PRINT"Another noun is needed after '";prep$;"'": verb$="" ELSE IF FNfind_noun(noun2$)=0 THEN PRINT"The word '";noun2$;"' is not known": verb$ = "" ENDIF ENDIF ENDPROC : : DEF PROCdescribe LOCAL excount%, N%, done% PRINT "You are ";description$(location%); excount%=0 FOR N%=1 TO 4 IF exits%(location%, N%)<>0 THEN excount%+=1 NEXT PRINT". You can go "; done%=0 FOR N%=1 TO 4 IF exits%(location%, N%)<>0 THEN PRINT directions$(N%); done%+=1 IF done%=excount%-1 THEN PRINT" and "; ELSE IF done%<>excount% THEN PRINT", "; ENDIF ENDIF NEXT PRINT ENDPROC : : DEF PROCaction IF verb$="" THEN ENDPROC :REM No verb supplied - Nothing to do time%+=1 CASE verb$ OF WHEN "north", "n", "east", "e", "south", "s", "west", "w": PROCmove WHEN "open": PROCopen WHEN "close": PROCclose WHEN "unlock": PROCunlock WHEN "lock": PROClock WHEN "get", "take": PROCget WHEN "drop": PROCdrop WHEN "kick": PROCkick WHEN "switch", "turn": PROCswitch WHEN "screw", "attach": PROCattach WHEN "buy": PROCbuy WHEN "look": PROClook WHEN "examine": PROCexamine WHEN "watch": PROCwatch WHEN "inv", "invent": PROCinventory WHEN "save": PROCsave WHEN "restore": PROCrestore WHEN "quit": PROCquit WHEN "help": PROChelp ENDCASE ENDPROC : : REM FNart returns an indefinite article for the word 'word$' : DEF FNart(word$) IF word$="money" THEN ="some " IF INSTR("aeiou", LEFT$(word$, 1)) THEN ="an " ELSE ="a " : : DEF PROCnonoun PRINT verb$;" what?" ENDPROC : : DEF PROCnotpossible PRINT"You cannot ";verb$;" ";FNart(noun$);noun$ ENDPROC : : REM FNfind returns the index in the object tables of item 'item$' : DEF FNfind(item$) FOR N%=1 TO objcount% IF objname$(N%)=item$ THEN =N% NEXT REM Should never get here PRINT"??? Cannot find ";item$ STOP =0 : : REM FNishere returns TRUE if the item object% is either being carried REM by the player, is at this location or is on something at this location : DEF FNishere(object%) LOCAL where%, holder% where% = objloc%(object%) IF where%>=0 THEN =where%=player% OR where%=location% holder% = FNfind(objname$(-where%)) =objloc%(holder%)=player% OR objloc%(holder%)=location% : : DEF FNcarried(item$) LOCAL object% object% = FNfind(item$) =objloc%(object%)=player% : : REM PROCscan lists the items found at location or object 'where'. REM If where is -ve then the items in or on an object are being listed. REM IF it is +ve then the items at a location are being listed : DEF PROCscan(where%) LOCAL N%, count%, done% count%=0 FOR N%=1 TO objcount% IF objloc%(N%)=where% THEN count%+=1 NEXT IF count%=0 THEN IF where%<0 THEN PRINT"There is nothing special about the ";objname$(-where%) ELSE PRINT"There is nothing to see here" ENDIF ELSE done% = 0 PRINT"There is"; FOR N%=1 TO objcount% IF objloc%(N%)=where% THEN PRINT" ";FNart(objname$(N%));objname$(N%); done%+=1 IF done%=count%-1 THEN PRINT" and"; ELSE IF done%<>count% THEN PRINT","; ENDIF ENDIF NEXT IF where%<0 THEN PRINT" ";objprep$(-where%);" the ";objname$(-where%) ELSE PRINT" here" ENDIF ENDIF ENDPROC : : DEF PROCmove LOCAL newloc% direction% = INSTR("nesw", LEFT$(verb$, 1)): REM Only look at first letter of direction newloc% = exits%(location%, direction%) IF newloc%=0 THEN PRINT"You cannot move that way" ELSE CASE newloc% OF WHEN hall%: IF door_locked% THEN PRINT"The front door is locked" ELSE location% = newloc%: PROCdescribe WHEN lounge%: IF tv_stolen% THEN PROCfailed("When you enter the room you realise that the TV is missing. Somebody stole it whilst you were out.") ELSE location% = newloc%: PROCdescribe ENDIF WHEN shop%: REM Bad neighbourhood this - Leave your front door open and things get nicked IF NOT door_locked% THEN tv_stolen% = TRUE location% = newloc% PROCdescribe OTHERWISE location% = newloc% PROCdescribe ENDCASE ENDIF ENDPROC : : DEF PROCget LOCAL object%, N% IF noun$="" THEN PROCnonoun: ENDPROC object% = FNfind(noun$) IF objloc%(object%)=player% THEN PRINT"You are already carrying the ";noun$: ENDPROC IF NOT FNishere(object%) OR noun$="screwdriver" AND cupboard_closed% THEN PRINT"The ";noun$;" is not here": ENDPROC IF objsize%(object%)>maxsize% THEN PRINT"The ";noun$;" is too big and heavy to move": ENDPROC IF noun$="plug" AND location%=shop% THEN PROCfailed("A store detective spots you and you soon find yourself at the police station being charged with theft.") ELSE IF encumbrance%+objsize%(object%)>maxload% THEN PRINT"You are already carrying as much as you can": ENDPROC encumbrance%+=objsize%(object%) objloc%(object%) = player% PRINT"Done" ENDIF ENDPROC : : DEF PROCdrop LOCAL object% IF noun$="" THEN PROCnonoun: ENDPROC object% = FNfind(noun$) IF objloc%(object%)<>player% THEN PRINT"You are not carrying the ";noun$: ENDPROC encumbrance%-=objsize%(object%) objloc%(object%) = location% PRINT"Done" ENDPROC : : DEF PROCopen IF noun$="" THEN PROCnonoun: ENDPROC IF NOT FNishere(FNfind(noun$)) THEN PRINT"There is no ";noun$;" here": ENDPROC CASE noun$ OF WHEN "door": IF NOT door_locked% THEN PRINT"The front door is already open": ENDPROC IF NOT FNcarried("key") THEN PRINT"You do not have a key": ENDPROC door_locked% = FALSE PRINT"Done" WHEN "cupboard": IF cupboard_closed% THEN cupboard_closed% = FALSE: PRINT"Done" ELSE PRINT"The cupboard is already open" OTHERWISE PROCnotpossible ENDCASE ENDPROC : : DEF PROCclose IF noun$="" THEN PROCnonoun: ENDPROC IF NOT FNishere(FNfind(noun$)) THEN PRINT"There is no ";noun$;" here": ENDPROC CASE noun$ OF WHEN "door": IF door_locked% THEN PRINT"The front door is already closed": ELSE door_locked% = TRUE: PRINT"Done" WHEN "cupboard": IF cupboard_closed% THEN PRINT"The cupboard is already open" ELSE cupboard_closed% = TRUE: PRINT"Done" OTHERWISE PROCnotpossible ENDCASE ENDPROC : : DEF PROCunlock IF noun$="" THEN PROCnonoun: ENDPROC IF NOT FNishere(FNfind(noun$)) THEN PRINT"There is no ";noun$;" here": ENDPROC IF noun$<>"door" THEN PROCnotpossible: ENDPROC IF NOT door_locked% THEN PRINT"The front door is already open": ENDPROC IF NOT FNcarried("key") THEN PRINT"You do not have a key": ENDPROC door_locked% = FALSE PRINT"Done" ENDPROC : : DEF PROClock IF noun$="" THEN PROCnonoun: ENDPROC IF NOT FNishere(FNfind(noun$)) THEN PRINT"There is no ";noun$;" here": ENDPROC IF noun$<>"door" THEN PROCnotpossible: ENDPROC IF door_locked% THEN PRINT"The front door is already locked": ENDPROC IF NOT FNcarried("key") THEN PRINT"You do not have a key": ENDPROC door_locked% = TRUE PRINT"Done" ENDPROC : : DEF PROCkick LOCAL object% IF noun$="" THEN PROCnonoun: ENDPROC IF NOT FNishere(FNfind(noun$)) THEN PRINT"There is no ";noun$;" here": ENDPROC CASE noun$ OF WHEN "door": IF NOT door_locked% THEN PRINT"The front door is already open": ENDPROC PROCfailed("The door consists of a wood veneer over sheet steel. You break your toes and end up in hospital.") WHEN "key", "screwdriver", "plug": PRINT"The ";noun$;" flies through the air and lands in a place you cannot reach" object% = FNfind(noun$) encumbrance%-=objsize%(object%) objloc%(object%) = 0 WHEN "cupboard", "settee", "table", "tv": PROCfailed("Light foot + heavy "+noun$+" = broken toes. It's hospital for you.") OTHERWISE PROCnotpossible ENDCASE ENDPROC : : DEF PROCswitch LOCAL object% IF noun$="" THEN PROCnonoun: ENDPROC object% = FNfind(noun$) IF NOT FNishere(object%) THEN PRINT"There is no ";noun$;" here": ENDPROC IF noun$<>"tv" THEN PROCnotpossible IF NOT tv_off% THEN PRINT"The TV is already switched on" IF no_plug% THEN PRINT"Nothing happens when you switch on the TV": ENDPROC tv_off% = FALSE PROCfinish ENDPROC : : REM PROCattach handles the 'attach' verb. The only thing it allows REM is for the plug to be attached to the TV's mains lead : DEF PROCattach LOCAL object% IF noun$="" THEN PROCnonoun: ENDPROC IF NOT FNcarried(noun$) THEN PRINT"You are not carrying the ";noun$: ENDPROC IF noun$<>"plug" THEN PROCnotpossible IF NOT FNcarried("screwdriver") THEN PRINT"You do not have everything you need to do this": ENDPROC IF NOT FNishere(FNfind("tv")) THEN PRINT"There is no ";noun$;" here": ENDPROC no_plug% = FALSE object% = FNfind(noun$) encumbrance%-=objsize%(object%) objloc%(object%) = -tv% PRINT"Done" ENDPROC : : REM PROCbuy deals with the 'buy' verb. The only thing that can be REM bought is a plug at the electrical shop : DEF PROCbuy LOCAL object% IF noun$="" THEN PROCnonoun: ENDPROC IF location%<>shop% THEN PRINT"You cannot buy anything here": ENDPROC object% = FNfind(noun$) IF objloc%(object%)=player% THEN PRINT"You are already carrying the ";noun$: ENDPROC IF NOT FNishere(object%) THEN PRINT"The ";noun$;" is not here": ENDPROC IF NOT FNcarried("money") THEN PRINT"You do not have any money on you": ENDPROC PRINT"You pay the shop assistant for the ";noun$; IF objsize%(object%)>maxsize% THEN PRINT" but it is too large to carry away" ELSE objloc%(object%) = player% PRINT ENDIF objloc%(FNfind("money")) = 0 ENDPROC : : DEF PROCwatch LOCAL object% IF noun$="" THEN PROCnonoun: ENDPROC IF noun$<>"tv" THEN PROCnotpossible: ENDPROC object% = FNfind(noun$) IF NOT FNishere(object%) THEN PRINT"The ";noun$;" is not here": ENDPROC IF no_plug% THEN PRINT"The TV set does not appear to work": ENDPROC tv_off% = FALSE PROCfinish ENDPROC : : REM PROClook says what it as the current location : DEF PROClook PROCscan(location%) ENDPROC : : REM PROCexamine lets the player find out interesting things about objects : DEF PROCexamine LOCAL where%, object%, holder% IF noun$="" THEN PROCnonoun: ENDPROC object% = FNfind(noun$) where% = objloc%(object%) IF where%<>player% THEN IF where%>0 THEN IF where%<>location% THEN PRINT"There is no ";noun$;" here": ENDPROC ELSE REM Object is in or on something. Is that item at this location? holder% = FNfind(objname$(-where%)) where% = objloc%(holder%) IF where%<>player% AND where%<>location% THEN PRINT"There is no ";noun$;" here": ENDPROC ENDIF ENDIF CASE TRUE OF WHEN noun$="door": IF door_locked% THEN PRINT"The door is locked" ELSE PRINT"The door is open" WHEN noun$="cupboard": IF cupboard_closed% THEN PRINT"The cupboard door is closed" ELSE PROCscan(-object%) WHEN noun$="tv": IF no_plug% THEN PRINT"It is an ordinary TV but you notice that there is no plug on the mains lead" ELSE PRINT"The TV is switched "; IF tv_off% THEN PRINT "off" ELSE PRINT"on" ENDIF OTHERWISE PROCscan(-object%) ENDCASE ENDPROC : : DEF PROCinventory LOCAL N% IF encumbrance%=0 THEN PRINT"You are not carrying anything": ENDPROC PRINT"You are carrying:" FOR N%=1 TO objcount% IF objloc%(N%)=player% THEN PRINT" ";FNart(objname$(N%));objname$(N%) NEXT ENDPROC : : DEF PROCsave REPEAT INPUT "Name of game file: " filename$ UNTIL filename$<>"" F%=0 ON ERROR LOCAL PRINT"Could not create game file: ";REPORT$: IF F%<>0 THEN CLOSE#F%: ENDPROC ELSE ENDPROC F%=OPENOUT filename$ PRINT#F%,location%, encumbrance%, time%, door_locked%, cupboard_closed%, no_plug%, tv_off%, tv_stolen% FOR N%=1 TO objcount% PRINT#F%,objloc%(N%) NEXT CLOSE#F% PRINT"Done" ENDPROC : : DEF PROCrestore REPEAT INPUT "Name of game file to be restored: " filename$ UNTIL filename$<>"" F%=OPENIN filename$ IF F%=0 THEN PRINT"File '";filename$;"' not found": ENDPROC INPUT#F%,location%, encumbrance%, time%, door_locked%, cupboard_closed%, no_plug%, tv_off%, tv_stolen% FOR N%=1 TO objcount% INPUT#F%,objloc%(N%) NEXT CLOSE#F% PROCdescribe ENDPROC : : REM PROCfinish is called when the player completes the game : DEF PROCfinish IF time%>timelimit% THEN PROCfailed("Unfortunately you find that the news is on, which follows what you wanted to see.") ELSE PRINT"Done it! You settle back to enjoy your favourite programme" ENDIF finished% = TRUE ENDPROC : : DEF PROCfailed(message$) PRINT message$'"It looks like you have missed the TV programme. That's it, I'm afraid" finished% = TRUE ENDPROC : : DEF PROCquit PRINT"Goodbye" finished% = TRUE ENDPROC : : DEF PROChelp PRINT'"This is a little adventure-type game. The object is to watch" PRINT"your favourite TV programme." PRINT"The game is played by typing in commands. These are limited to" PRINT"two words at most, a verb which is sometimes followed by a noun." PRINT"Type 'quit' to leave the game"' ENDPROC : REM -------------------------------------------------------- : DEF PROCinit maxlocs% = 25 :REM Maximum number of locations allowed in game maxobjs% = 25 :REM Maximum number of objects allowed in game maxsize% = 10 :REM Size of largest object that can be carried maxload% = 10 :REM Maximum total load that can be carried : DIM location$(maxlocs%), description$(maxlocs%), exits%(maxlocs%, 4) DIM objname$(maxobjs%), objprep$(maxobjs%), objsize%(maxobjs%), objloc%(maxobjs%) DIM verb$(50), noun$(50) DIM xlate$(255), directions$(4) : FOR N% = 0 TO 255: xlate$(N%) = CHR$N%: NEXT X% = ASC"a"-ASC"A" FOR N% = ASC"A" TO ASC"Z": xlate$(N%) = CHR$(N%+X%): NEXT : directions$() = "", "north", "east", "south", "west" : finished% = FALSE time% = 0 location% = 1 encumbrance% = 0 : door_locked% = TRUE :REM Front door is locked cupboard_closed% = TRUE :REM Kitchen cupboard is closed no_plug% = TRUE :REM There is no plug on the TV tv_off% = TRUE :REM The TV is switched off tv_stolen% = FALSE :REM The TV has not been stolen yet timelimit% = 40 :REM TV programme is missed if time limit is exceeded : REM Directions north% = 1: east% = 2: south% = 3: west% = 4 : REM Location numbers road1% = 1: road2% = 2: garden1% = 3: garden2% = 4: doorstep% = 5 hall% = 6: kitchen% = 7: lounge% = 8: shop% = 9 player% = 999 : REM Object numbers door% = 1: key% = 2: money% = 3: box% = 4 plug% = 5: screwdriver% = 6: cupboard% = 7: settee% = 8: table% = 9 tv% = 10 : REM Read the vocabulary : verbcount% = 0 REPEAT verbcount%+=1 READ verb$(verbcount%) UNTIL verb$(verbcount%)="***" nouncount% = 0 REPEAT nouncount%+=1 READ noun$(nouncount%) UNTIL noun$(nouncount%)="***" : REM Read the map data : READ thisloc% WHILE thisloc%<>0 READ description$(thisloc%) FOR N% = 1 TO 4 READ direction%, destination% IF direction%<>0 THEN exits%(thisloc%, direction%) = destination% NEXT READ thisloc% ENDWHILE : REM Read object data and place objects at locations : objcount% = 0 READ object% WHILE object%<>0 READ objname$(object%), objprep$(object%), objsize%(object%), objloc%(object%) objcount%+=1 READ object% ENDWHILE : ENDPROC : REM ============================================================== : REM Vocabulary - Verbs : DATA north, n, east, e, south, s, west, w, open, close, lock, unlock DATA look, examine, watch, kick, switch, turn, screw, attach DATA get, take, drop, buy, inv, invent, save, restore, quit, help DATA *** : REM Vocabulary - Nouns : DATA door, key, money, box, plug, screwdriver, cupboard DATA settee, table, tv DATA *** : REM Locations and connections to other locations : DATA road1%, in the road outside your house DATA east%, road2%, south%, garden1%, 0, 0, 0, 0 DATA road2%, in the road outside the electrical shop DATA west%, road1%, south%, shop%, 0, 0, 0, 0 DATA garden1%,in your front garden by the front door DATA north%, road1%, south%, doorstep%, west%, garden2%, 0, 0 DATA garden2%, in the garden at the side of your house DATA east%, garden1%, 0, 0, 0, 0, 0, 0 DATA doorstep%, standing on the front doorstep DATA north%, garden1%, south%, hall%, 0, 0, 0, 0 DATA hall%, in the hall of your house DATA north%, doorstep%, south%, kitchen%, east%, lounge%, 0, 0 DATA kitchen%, in the kitchen DATA north%, hall%, 0, 0, 0, 0, 0, 0 DATA lounge%, in the lounge DATA west%, hall%, 0, 0, 0, 0, 0, 0 DATA shop%, in the electrical shop DATA north%, road2%, 0, 0, 0, 0, 0, 0 DATA 0 : REM Objects and their starting locations : REM Negative location numbers indicate that the object is placed REM in or on another object. 'xx' says that nothing can be put REM in or on that object, 'in' says it can hold things and 'on' REM says that things can be put on it : DATA key%, key, xx, 1, garden2% DATA door%, door, xx, 100, doorstep% DATA settee%, settee, on, 100, lounge% DATA table%, table, on, 100, lounge% DATA money%, money, xx, 1, -table% DATA tv%, tv, xx, 100, lounge% DATA cupboard%, cupboard, in, 100, kitchen% DATA screwdriver%, screwdriver, xx, 1, -cupboard% DATA box%, box, in, 100, shop% DATA plug%, plug, xx, 1, -box% DATA 0 brandy-1.20/examples/cmdline0000644000175000017500000000065110546536104015067 0ustar colincolinREM This program uses the ARGC and ARGV$ functions to display what was REM passed to the program on the command line : REM ARGV$ 0 is the name of the interpreter or an empty string REM ARGV$ 1 onwards are the parameters REM ARGC returns the index of the highest parameter : count% = ARGC IF count%=0 THEN PRINT"No parameters supplied" ELSE PRINT"Parameters:" FOR N%=1 TO count% PRINT;N%;TAB(5);ARGV$(N%) NEXT ENDIF brandy-1.20/examples/sieve0000644000175000017500000000075410546536104014573 0ustar colincolinREM Sieve of Eratosthenes Prime Number Program : size%=10000 iterations%=10 : DIM flags%(size%) : T=TIME PRINT;iterations%;" iterations." FOR C%=1 TO iterations% PRINT"Doing ";C% count%=0 flags%()=TRUE FOR I%=0 TO size% IF flags%(I%) THEN prime%=I%+I%+3 K%=I%+prime% WHILE K%<=size% flags%(K%)=FALSE K%+=prime% ENDWHILE count%+=1 ENDIF NEXT NEXT PRINT"There are ";count%;" primes" PRINT"Time taken=";(TIME-T)/100;" seconds" END brandy-1.20/examples/README0000644000175000017500000000151010546536103014403 0ustar colincolinThe example programs are as follows: cmdline Reads parameters from the command line used to start the interpreter combsort Compares a comb sort and a bubble sort cricket Simulates a game of cricket dow Prints the day of the week for the given date graphdemo Plots a graph hanoi Solves the 'Ttowers of Hanoi' puzzle hex Solves the 'hex' puzzle lands Plots a simple fractal landscape pastriang Draws Pascal's triangle sieve Sieve of Eratosthenes tekdemo1 Graphics demo using the Tektronics terminal emulation in xterm under NetBSD and Linux tekdemo2 Graphics demo using the Tektronics terminal emulation in xterm under NetBSD and Linux teklib Library of procedures used by the two Tektronics demo programs trees1 Create a binary tree trees2 Create a binary tree using indirection operators tvtime A simple adventure game brandy-1.20/examples/hex0000644000175000017500000000720310546536104014240 0ustar colincolinREM Work out solutions to the "hex" problem. The idea here REM is to find all the solutions to a magic square where the REM numbers 1 to 19 have to be arranged in a hex pattern REM so that all the straight lines add up to 38 thus: REM REM xx xx xx REM xx xx xx xx REM xx xx xx xx xx REM xx xx xx xx REM xx xx xx : threesize%=200 : DIM jval%(threesize%), kval%(threesize%), nextpos%(threesize%) DIM xlistpos%(19), used%(19), ring%(19), checks%(6,3), does%(6) : T=TIME checks%(1,1)=8: checks%(1,2)=12: checks%(1,3)=18 checks%(2,1)=2: checks%(2,2)=10: checks%(2,3)=18 checks%(3,1)=4: checks%(3,2)=12: checks%(3,3)=13 checks%(4,1)=6: checks%(4,2)=10: checks%(4,3)=17 checks%(5,1)=2: checks%(5,2)=6: checks%(5,3)=14 checks%(6,1)=4: checks%(6,2)=8: checks%(6,3)=16 does%(1)=17 does%(2)=13 does%(3)=14 does%(4)=16 does%(5)=15 does%(6)=15 nosol%=0 num%=0 FOR I%=1 TO 19 used%(I%)=FALSE xlistpos%(I%)=0 NEXT : FOR I%=3 TO 19 FOR J%=1 TO 19 IF I%<>J% THEN FOR K%=3 TO 19 IF (K%<>J%) AND (K%<>I%) AND (I%+J%+K%=38) THEN num%+=1 next%=num% jval%(next%)=J% kval%(next%)=K% nextpos%(next%)=xlistpos%(I%) xlistpos%(I%)=next% ENDIF NEXT ENDIF NEXT NEXT PRINT FNdec(num%,3);" number groups generated" : FOR I%=3 TO 19 P%=xlistpos%(I%) used%(I%)=TRUE WHILE P%<>0 J%=jval%(P%) K%=kval%(P%) used%(J%)=TRUE used%(K%)=TRUE ring%(1)=I% ring%(2)=J% curr%=2 PROCfillin(K%) used%(J%)=FALSE used%(K%)=FALSE P%=nextpos%(P%) ENDWHILE used%(I%)=FALSE NEXT PRINT"There are";FNdec(nosol%,3);" solutions" PRINT"Time taken: ";(TIME-T)/100;" seconds" END : : DEF FNdec(X%,W%)=RIGHT$(" "+STR$X%,W%) : : DEF PROCblockin(target%) LOCAL total%, poss%, I% IF target%>5 THEN IF (38-ring%(4)-ring%(8)-ring%(16))=ring%(15) THEN poss%=1 WHILE used%(poss%) poss%+=1 ENDWHILE IF (38-ring%(11)-ring%(18)-ring%(15)-ring%(5))=poss% THEN ring%(19)=poss% nosol%+=1 PRINT"Solution no.";FNdec(nosol%,3)'' PRINT" ";FNdec(ring%(1),2);FNdec(ring%(2),4);FNdec(ring%(3),4) PRINT" ";FNdec(ring%(12),2);FNdec(ring%(13),4);FNdec(ring%(14),4);FNdec(ring%(4),4) PRINT" ";FNdec(ring%(11),2);FNdec(ring%(18),4);FNdec(ring%(19),4);FNdec(ring%(15),4);FNdec(ring%(5),4) PRINT" ";FNdec(ring%(10),2);FNdec(ring%(17),4);FNdec(ring%(16),4);FNdec(ring%(6),4) PRINT" ";FNdec(ring%(9),2);FNdec(ring%(8),4);FNdec(ring%(7),4)'' ENDIF ENDIF ELSE total%=38 FOR I%=1 TO 3 total%=total%-ring%(checks%(target%,I%)) NEXT IF (total%>0) AND (total%<20) THEN IF NOT used%(total%) THEN used%(total%)=TRUE ring%(does%(target%))=total% PROCblockin(target%+1) used%(total%)=FALSE ENDIF ENDIF ENDIF ENDPROC : DEF PROCfillin(pi%) LOCAL I%, pj%, pk%, pos1%, ptr% ptr%=xlistpos%(pi%) WHILE ptr%<>0 pj%=jval%(ptr%) pk%=kval%(ptr%) IF NOT used%(pj%) AND NOT used%(pk%) THEN used%(pj%)=TRUE used%(pk%)=TRUE ring%(curr%+curr%-1)=pi% ring%(curr%+curr%)=pj% curr%+=1 IF curr%<7 THEN PROCfillin(pk%) used%(pk%)=FALSE used%(pj%)=FALSE curr%-=1 ELSE IF curr%=6 THEN IF NOT used%(pj%) AND pk%=ring%(1) THEN used%(pj%)=TRUE ring%(11)=pi% ring%(12)=pj% FOR I%=1 TO 19 IF NOT used%(I%) THEN ring%(18)=I% used%(I%)=TRUE PROCblockin(1) used%(I%)=FALSE ENDIF NEXT used%(pj%)=FALSE ENDIF ENDIF ENDIF ptr%=nextpos%(ptr%) ENDWHILE ENDPROC brandy-1.20/makefile.djgpp0000644000175000017500000002317710675442512014530 0ustar colincolin# Makefile for brandy under DOS (using gcc and DJGPP) CC = gcc LD = gcc CFLAGS = -march=i586 -c -g -DDEBUG CFLAGS2 = -march=i586 -O2 -fomit-frame-pointer LDFLAGS = LIBS = -lm SRCDIR = src OBJ = $(SRCDIR)/variables.o $(SRCDIR)/tokens.o $(SRCDIR)/textonly.o \ $(SRCDIR)/strings.o $(SRCDIR)/statement.o $(SRCDIR)/stack.o \ $(SRCDIR)/miscprocs.o $(SRCDIR)/mainstate.o $(SRCDIR)/lvalue.o \ $(SRCDIR)/keyboard.o $(SRCDIR)/iostate.o $(SRCDIR)/heap.o \ $(SRCDIR)/functions.o $(SRCDIR)/fileio.o $(SRCDIR)/evaluate.o \ $(SRCDIR)/errors.o $(SRCDIR)/emulate.o $(SRCDIR)/editor.o \ $(SRCDIR)/convert.o $(SRCDIR)/commands.o $(SRCDIR)/brandy.o \ $(SRCDIR)/assign.o SRC = $(SRCDIR)/variables.c $(SRCDIR)/tokens.c $(SRCDIR)/textonly.c \ $(SRCDIR)/strings.c $(SRCDIR)/statement.c $(SRCDIR)/stack.c \ $(SRCDIR)/miscprocs.c $(SRCDIR)/mainstate.c $(SRCDIR)/lvalue.c \ $(SRCDIR)/keyboard.c $(SRCDIR)/iostate.c $(SRCDIR)/heap.c \ $(SRCDIR)/functions.c $(SRCDIR)/fileio.c $(SRCDIR)/evaluate.c \ $(SRCDIR)/errors.c $(SRCDIR)/emulate.c $(SRCDIR)/editor.c \ $(SRCDIR)/convert.c $(SRCDIR)/commands.c $(SRCDIR)/brandy.c \ $(SRCDIR)/assign.c brandy: $(OBJ) $(LD) $(LDFLAGS) -o brandy $(OBJ) $(LIBS) # Build VARIABLES.C VARIABLES_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h $(SRCDIR)/tokens.h \ $(SRCDIR)/stack.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/variables.o: $(VARIABLES_C) $(SRCDIR)/variables.c $(CC) $(CFLAGS) $(SRCDIR)/variables.c -o $(SRCDIR)/variables.o # Build TOKENS.C TOKENS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.h \ $(SRCDIR)/errors.h $(SRCDIR)/tokens.o: $(TOKENS_C) $(SRCDIR)/tokens.c $(CC) $(CFLAGS) $(SRCDIR)/tokens.c -o $(SRCDIR)/tokens.o # Build TEXTONLY.C TEXTONLY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/scrcommon.h $(SRCDIR)/screen.h \ $(SRCDIR)/keyboard.h $(SRCDIR)/textonly.o: $(TEXTONLY_C) $(SRCDIR)/textonly.c $(CC) $(CFLAGS) $(SRCDIR)/textonly.c -o $(SRCDIR)/textonly.o # Build STRINGS.C STRINGS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/strings.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/strings.o: $(STRINGS_C) $(SRCDIR)/strings.c $(CC) $(CFLAGS) $(SRCDIR)/strings.c -o $(SRCDIR)/strings.o # Build STATEMENT.C STATEMENT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/commands.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/editor.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/screen.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h \ $(SRCDIR)/iostate.h $(SRCDIR)/mainstate.h $(SRCDIR)/assign.h \ $(SRCDIR)/statement.h $(SRCDIR)/statement.o: $(STATEMENT_C) $(SRCDIR)/statement.c $(CC) $(CFLAGS) $(SRCDIR)/statement.c -o $(SRCDIR)/statement.o # Build STACK.C STACK_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/stack.h $(SRCDIR)/miscprocs.h $(SRCDIR)/strings.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/stack.o: $(STACK_C) $(SRCDIR)/stack.c $(CC) $(CFLAGS) $(SRCDIR)/stack.c -o $(SRCDIR)/stack.o # Build MISCPROCS.C MISCPROCS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/miscprocs.o: $(MISCPROCS_C) $(SRCDIR)/miscprocs.c $(CC) $(CFLAGS) $(SRCDIR)/miscprocs.c -o $(SRCDIR)/miscprocs.o # Build MAINSTATE.C MAINSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/strings.h $(SRCDIR)/errors.h \ $(SRCDIR)/statement.h $(SRCDIR)/evaluate.h $(SRCDIR)/convert.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/fileio.h \ $(SRCDIR)/mainstate.h $(SRCDIR)/mainstate.o: $(MAINSTATE_C) $(SRCDIR)/mainstate.c $(CC) $(CFLAGS) $(SRCDIR)/mainstate.c -o $(SRCDIR)/mainstate.o # Build LVALUE.C LVALUE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/evaluate.h $(SRCDIR)/stack.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/lvalue.h $(SRCDIR)/lvalue.o: $(LVALUE_C) $(SRCDIR)/lvalue.c $(CC) $(CFLAGS) $(SRCDIR)/lvalue.c -o $(SRCDIR)/lvalue.o # Build KEYBOARD.C KEYBOARD_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.o: $(KEYBOARD_C) $(SRCDIR)/keyboard.c $(CC) $(CFLAGS) $(SRCDIR)/keyboard.c -o $(SRCDIR)/keyboard.o # Build IOSTATE.C IOSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/convert.h $(SRCDIR)/emulate.h $(SRCDIR)/fileio.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/iostate.h $(SRCDIR)/iostate.o: $(IOSTATE_C) $(SRCDIR)/iostate.c $(CC) $(CFLAGS) $(SRCDIR)/iostate.c -o $(SRCDIR)/iostate.o # Build HEAP.C HEAP_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/heap.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/heap.o: $(HEAP_C) $(SRCDIR)/heap.c $(CC) $(CFLAGS) $(SRCDIR)/heap.c -o $(SRCDIR)/heap.o # Build FUNCTIONS.C FUNCTIONS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/strings.h \ $(SRCDIR)/convert.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h \ $(SRCDIR)/emulate.h $(SRCDIR)/miscprocs.h $(SRCDIR)/fileio.h \ $(SRCDIR)/functions.h $(SRCDIR)/functions.o: $(FUNCTIONS_C) $(SRCDIR)/functions.c $(CC) $(CFLAGS) $(SRCDIR)/functions.c -o $(SRCDIR)/functions.o # Build FILEIO.C FILEIO_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h $(SRCDIR)/fileio.o: $(FILEIO_C) $(SRCDIR)/fileio.c $(CC) $(CFLAGS) $(SRCDIR)/fileio.c -o $(SRCDIR)/fileio.o # Build EVALUATE.C EVALUATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/lvalue.h \ $(SRCDIR)/strings.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/statement.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/functions.h $(SRCDIR)/evaluate.o: $(EVALUATE_C) $(SRCDIR)/evaluate.c $(CC) $(CFLAGS) $(SRCDIR)/evaluate.c -o $(SRCDIR)/evaluate.o # Build ERRORS.C ERRORS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/stack.h $(SRCDIR)/fileio.h \ $(SRCDIR)/tokens.h $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/errors.o: $(ERRORS_C) $(SRCDIR)/errors.c $(CC) $(CFLAGS) $(SRCDIR)/errors.c -o $(SRCDIR)/errors.o # Build EMULATE.C EMULATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/basicdefs.h $(SRCDIR)/target.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/emulate.o: $(EMULATE_C) $(SRCDIR)/emulate.c $(CC) $(CFLAGS) $(SRCDIR)/emulate.c -o $(SRCDIR)/emulate.o # Build EDITOR.C EDITOR_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/heap.h \ $(SRCDIR)/tokens.h $(SRCDIR)/strings.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/stack.h $(SRCDIR)/fileio.h $(SRCDIR)/editor.o: $(EDITOR_C) $(SRCDIR)/editor.c $(CC) $(CFLAGS) $(SRCDIR)/editor.c -o $(SRCDIR)/editor.o # Build CONVERT.C CONVERT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/convert.h $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.o: $(CONVERT_C) $(SRCDIR)/convert.c $(CC) $(CFLAGS) $(SRCDIR)/convert.c -o $(SRCDIR)/convert.o # Build COMMANDS.C COMMANDS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/tokens.h $(SRCDIR)/statement.h \ $(SRCDIR)/variables.h $(SRCDIR)/editor.h $(SRCDIR)/errors.h \ $(SRCDIR)/heap.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.h $(SRCDIR)/commands.o: $(COMMANDS_C) $(SRCDIR)/commands.c $(CC) $(CFLAGS) $(SRCDIR)/commands.c -o $(SRCDIR)/commands.o # Build BRANDY.C BRANDY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/heap.h \ $(SRCDIR)/editor.h $(SRCDIR)/commands.h $(SRCDIR)/statement.h \ $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/brandy.o: $(BRANDY_C) $(SRCDIR)/brandy.c $(CC) $(CFLAGS) $(SRCDIR)/brandy.c -o $(SRCDIR)/brandy.o # Build ASSIGN.C ASSIGN_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/target.h $(SRCDIR)/tokens.h $(SRCDIR)/heap.h \ $(SRCDIR)/stack.h $(SRCDIR)/strings.h $(SRCDIR)/variables.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/assign.h $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/assign.o: $(ASSIGN_C) $(SRCDIR)/assign.c $(CC) $(CFLAGS) $(SRCDIR)/assign.c -o $(SRCDIR)/assign.o recompile: $(CC) $(CFLAGS) $(SRC) $(LIBS) -o brandy nodebug: $(CC) $(CFLAGS2) $(SRC) $(LIBS) -o brandy strip brandy check: $(CC) $(CFLAGS) -Wall $(SRC) $(LIBS) -o brandy clean: rm $(SRCDIR)/*.o brandy all: brandy brandy-1.20/makefile.text0000644000175000017500000002432612163033227014376 0ustar colincolin# Makefile for brandy under NetBSD and Linux CC = gcc LD = gcc CFLAGS += -g -DDEBUG -DNO_SDL CFLAGS2 = -O2 -DNO_SDL LDFLAGS = LIBS = -lm SRCDIR = src OBJ = $(SRCDIR)/variables.o $(SRCDIR)/tokens.o \ $(SRCDIR)/strings.o $(SRCDIR)/statement.o $(SRCDIR)/stack.o \ $(SRCDIR)/miscprocs.o $(SRCDIR)/mainstate.o $(SRCDIR)/lvalue.o \ $(SRCDIR)/keyboard.o $(SRCDIR)/iostate.o $(SRCDIR)/heap.o \ $(SRCDIR)/functions.o $(SRCDIR)/fileio.o $(SRCDIR)/evaluate.o \ $(SRCDIR)/errors.o $(SRCDIR)/emulate.o $(SRCDIR)/editor.o \ $(SRCDIR)/convert.o $(SRCDIR)/commands.o $(SRCDIR)/brandy.o \ $(SRCDIR)/assign.o TEXTONLYOBJ = $(SRCDIR)/textonly.o SIMPLETEXTOBJ = $(SRCDIR)/simpletext.o SRC = $(SRCDIR)/variables.c $(SRCDIR)/tokens.c \ $(SRCDIR)/strings.c $(SRCDIR)/statement.c $(SRCDIR)/stack.c \ $(SRCDIR)/miscprocs.c $(SRCDIR)/mainstate.c $(SRCDIR)/lvalue.c \ $(SRCDIR)/keyboard.c $(SRCDIR)/iostate.c $(SRCDIR)/heap.c \ $(SRCDIR)/functions.c $(SRCDIR)/fileio.c $(SRCDIR)/evaluate.c \ $(SRCDIR)/errors.c $(SRCDIR)/emulate.c $(SRCDIR)/editor.c \ $(SRCDIR)/convert.c $(SRCDIR)/commands.c $(SRCDIR)/brandy.c \ $(SRCDIR)/assign.c TEXTONLYSRC = $(SRCDIR)/textonly.c SIMPLETEXTSRC = $(SRCDIR)/simpletext.c all: tbrandy sbrandy tbrandy: $(OBJ) $(TEXTONLYOBJ) $(LD) $(LDFLAGS) -o tbrandy $(OBJ) $(TEXTONLYOBJ) $(LIBS) sbrandy: $(OBJ) $(SIMPLETEXTOBJ) $(LD) $(LDFLAGS) -o sbrandy $(OBJ) $(SIMPLETEXTOBJ) $(LIBS) # Build VARIABLES.C VARIABLES_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h $(SRCDIR)/tokens.h \ $(SRCDIR)/stack.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/variables.o: $(VARIABLES_C) $(SRCDIR)/variables.c $(CC) $(CFLAGS) $(SRCDIR)/variables.c -c -o $(SRCDIR)/variables.o # Build TOKENS.C TOKENS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.h \ $(SRCDIR)/errors.h $(SRCDIR)/tokens.o: $(TOKENS_C) $(SRCDIR)/tokens.c $(CC) $(CFLAGS) $(SRCDIR)/tokens.c -c -o $(SRCDIR)/tokens.o # Build TEXTONLY.C GSDL_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/scrcommon.h $(SRCDIR)/screen.h $(SRCDIR)/textonly.o: $(GSDL_C) $(SRCDIR)/textonly.c $(CC) $(CFLAGS) $(SRCDIR)/textonly.c -c -o $(SRCDIR)/textonly.o # Build SIMPLETEXT.C $(SRCDIR)/simpletext.o: $(GSDL_C) $(SRCDIR)/simpletext.c $(CC) $(CFLAGS) $(SRCDIR)/simpletext.c -c -o $(SRCDIR)/simpletext.o # Build GEOM.C GEOM_C = $(SRCDIR)/target.h $(SRCDIR)/geom.o: $(GEOM_C) $(SRCDIR)/geom.c $(CC) $(CFLAGS) $(SRCDIR)/geom.c -c -o $(SRCDIR)/geom.o # Build STRINGS.C STRINGS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/strings.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/strings.o: $(STRINGS_C) $(SRCDIR)/strings.c $(CC) $(CFLAGS) $(SRCDIR)/strings.c -c -o $(SRCDIR)/strings.o # Build STATEMENT.C STATEMENT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/commands.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/editor.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/screen.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h \ $(SRCDIR)/iostate.h $(SRCDIR)/mainstate.h $(SRCDIR)/assign.h \ $(SRCDIR)/statement.h $(SRCDIR)/statement.o: $(STATEMENT_C) $(SRCDIR)/statement.c $(CC) $(CFLAGS) $(SRCDIR)/statement.c -c -o $(SRCDIR)/statement.o # Build STACK.C STACK_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/stack.h $(SRCDIR)/miscprocs.h $(SRCDIR)/strings.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/stack.o: $(STACK_C) $(SRCDIR)/stack.c $(CC) $(CFLAGS) $(SRCDIR)/stack.c -c -o $(SRCDIR)/stack.o # Build MISCPROCS.C MISCPROCS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/miscprocs.o: $(MISCPROCS_C) $(SRCDIR)/miscprocs.c $(CC) $(CFLAGS) $(SRCDIR)/miscprocs.c -c -o $(SRCDIR)/miscprocs.o # Build MAINSTATE.C MAINSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/strings.h $(SRCDIR)/errors.h \ $(SRCDIR)/statement.h $(SRCDIR)/evaluate.h $(SRCDIR)/convert.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/fileio.h \ $(SRCDIR)/mainstate.h $(SRCDIR)/mainstate.o: $(MAINSTATE_C) $(SRCDIR)/mainstate.c $(CC) $(CFLAGS) $(SRCDIR)/mainstate.c -c -o $(SRCDIR)/mainstate.o # Build LVALUE.C LVALUE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/evaluate.h $(SRCDIR)/stack.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/lvalue.h $(SRCDIR)/lvalue.o: $(LVALUE_C) $(SRCDIR)/lvalue.c $(CC) $(CFLAGS) $(SRCDIR)/lvalue.c -c -o $(SRCDIR)/lvalue.o # Build KEYBOARD.C KEYBOARD_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.o: $(KEYBOARD_C) $(SRCDIR)/keyboard.c $(CC) $(CFLAGS) $(SRCDIR)/keyboard.c -c -o $(SRCDIR)/keyboard.o # Build IOSTATE.C IOSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/convert.h $(SRCDIR)/emulate.h $(SRCDIR)/fileio.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/iostate.h $(SRCDIR)/iostate.o: $(IOSTATE_C) $(SRCDIR)/iostate.c $(CC) $(CFLAGS) $(SRCDIR)/iostate.c -c -o $(SRCDIR)/iostate.o # Build HEAP.C HEAP_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/heap.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/heap.o: $(HEAP_C) $(SRCDIR)/heap.c $(CC) $(CFLAGS) $(SRCDIR)/heap.c -c -o $(SRCDIR)/heap.o # Build FUNCTIONS.C FUNCTIONS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/strings.h \ $(SRCDIR)/convert.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h \ $(SRCDIR)/emulate.h $(SRCDIR)/miscprocs.h $(SRCDIR)/fileio.h \ $(SRCDIR)/functions.h $(SRCDIR)/functions.o: $(FUNCTIONS_C) $(SRCDIR)/functions.c $(CC) $(CFLAGS) $(SRCDIR)/functions.c -c -o $(SRCDIR)/functions.o # Build FILEIO.C FILEIO_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h $(SRCDIR)/fileio.o: $(FILEIO_C) $(SRCDIR)/fileio.c $(CC) $(CFLAGS) $(SRCDIR)/fileio.c -c -o $(SRCDIR)/fileio.o # Build EVALUATE.C EVALUATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/lvalue.h \ $(SRCDIR)/strings.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/statement.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/functions.h $(SRCDIR)/evaluate.o: $(EVALUATE_C) $(SRCDIR)/evaluate.c $(CC) $(CFLAGS) $(SRCDIR)/evaluate.c -c -o $(SRCDIR)/evaluate.o # Build ERRORS.C ERRORS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/stack.h $(SRCDIR)/fileio.h \ $(SRCDIR)/tokens.h $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/errors.o: $(ERRORS_C) $(SRCDIR)/errors.c $(CC) $(CFLAGS) $(SRCDIR)/errors.c -c -o $(SRCDIR)/errors.o # Build EMULATE.C EMULATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/basicdefs.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/keyboard.h $(SRCDIR)/emulate.o: $(EMULATE_C) $(SRCDIR)/emulate.c $(CC) $(CFLAGS) $(SRCDIR)/emulate.c -c -o $(SRCDIR)/emulate.o # Build EDITOR.C EDITOR_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/heap.h \ $(SRCDIR)/tokens.h $(SRCDIR)/strings.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/stack.h $(SRCDIR)/fileio.h $(SRCDIR)/editor.o: $(EDITOR_C) $(SRCDIR)/editor.c $(CC) $(CFLAGS) $(SRCDIR)/editor.c -c -o $(SRCDIR)/editor.o # Build CONVERT.C CONVERT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/convert.h $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.o: $(CONVERT_C) $(SRCDIR)/convert.c $(CC) $(CFLAGS) $(SRCDIR)/convert.c -c -o $(SRCDIR)/convert.o # Build COMMANDS.C COMMANDS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/tokens.h $(SRCDIR)/statement.h \ $(SRCDIR)/variables.h $(SRCDIR)/editor.h $(SRCDIR)/errors.h \ $(SRCDIR)/heap.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.h $(SRCDIR)/commands.o: $(COMMANDS_C) $(SRCDIR)/commands.c $(CC) $(CFLAGS) $(SRCDIR)/commands.c -c -o $(SRCDIR)/commands.o # Build BRANDY.C BRANDY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/heap.h \ $(SRCDIR)/editor.h $(SRCDIR)/commands.h $(SRCDIR)/statement.h \ $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/brandy.o: $(BRANDY_C) $(SRCDIR)/brandy.c $(CC) $(CFLAGS) $(SRCDIR)/brandy.c -c -o $(SRCDIR)/brandy.o # Build ASSIGN.C ASSIGN_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/target.h $(SRCDIR)/tokens.h $(SRCDIR)/heap.h \ $(SRCDIR)/stack.h $(SRCDIR)/strings.h $(SRCDIR)/variables.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/assign.h $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/assign.o: $(ASSIGN_C) $(SRCDIR)/assign.c $(CC) $(CFLAGS) $(SRCDIR)/assign.c -c -o $(SRCDIR)/assign.o trecompile: $(CC) $(CFLAGS) $(SRC) $(TEXTONLYSRC) $(LIBS) -o tbrandy srecompile: $(CC) $(CFLAGS) $(SRC) $(SIMPLETEXTSRC) $(LIBS) -o sbrandy tnodebug: $(CC) $(CFLAGS2) $(SRC) $(TEXTONLYSRC) $(LIBS) -o tbrandy strip tbrandy snodebug: $(CC) $(CFLAGS2) $(SRC) $(SIMPLETEXTSRC) $(LIBS) -o sbrandy strip sbrandy tcheck: $(CC) $(CFLAGS) -Wall -O2 $(SRC) $(TEXTONLYSRC) $(LIBS) -o tbrandy scheck: $(CC) $(CFLAGS) -Wall -O2 $(SRC) $(SIMPLETEXTSRC) $(LIBS) -o sbrandy clean: rm -f $(SRCDIR)/*.o tbrandy sbrandy brandy-1.20/makefile.mingw0000644000175000017500000002322412161325744014535 0ustar colincolin# Makefile for brandy under DOS (using gcc and MINGW) CC = gcc LD = gcc CFLAGS = -march=i586 -c -g -DDEBUG CFLAGS2 = -march=i586 -O2 -fomit-frame-pointer LDFLAGS = LIBS = -lm SRCDIR = src OBJ = $(SRCDIR)/variables.o $(SRCDIR)/tokens.o $(SRCDIR)/textonly.o \ $(SRCDIR)/strings.o $(SRCDIR)/statement.o $(SRCDIR)/stack.o \ $(SRCDIR)/miscprocs.o $(SRCDIR)/mainstate.o $(SRCDIR)/lvalue.o \ $(SRCDIR)/keyboard.o $(SRCDIR)/iostate.o $(SRCDIR)/heap.o \ $(SRCDIR)/functions.o $(SRCDIR)/fileio.o $(SRCDIR)/evaluate.o \ $(SRCDIR)/errors.o $(SRCDIR)/emulate.o $(SRCDIR)/editor.o \ $(SRCDIR)/convert.o $(SRCDIR)/commands.o $(SRCDIR)/brandy.o \ $(SRCDIR)/assign.o SRC = $(SRCDIR)/variables.c $(SRCDIR)/tokens.c $(SRCDIR)/textonly.c \ $(SRCDIR)/strings.c $(SRCDIR)/statement.c $(SRCDIR)/stack.c \ $(SRCDIR)/miscprocs.c $(SRCDIR)/mainstate.c $(SRCDIR)/lvalue.c \ $(SRCDIR)/keyboard.c $(SRCDIR)/iostate.c $(SRCDIR)/heap.c \ $(SRCDIR)/functions.c $(SRCDIR)/fileio.c $(SRCDIR)/evaluate.c \ $(SRCDIR)/errors.c $(SRCDIR)/emulate.c $(SRCDIR)/editor.c \ $(SRCDIR)/convert.c $(SRCDIR)/commands.c $(SRCDIR)/brandy.c \ $(SRCDIR)/assign.c brandy: $(OBJ) $(LD) $(LDFLAGS) -o brandy $(OBJ) $(LIBS) # Build VARIABLES.C VARIABLES_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h $(SRCDIR)/tokens.h \ $(SRCDIR)/stack.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/variables.o: $(VARIABLES_C) $(SRCDIR)/variables.c $(CC) $(CFLAGS) $(SRCDIR)/variables.c -o $(SRCDIR)/variables.o # Build TOKENS.C TOKENS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.h \ $(SRCDIR)/errors.h $(SRCDIR)/tokens.o: $(TOKENS_C) $(SRCDIR)/tokens.c $(CC) $(CFLAGS) $(SRCDIR)/tokens.c -o $(SRCDIR)/tokens.o # Build TEXTONLY.C TEXTONLY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/scrcommon.h $(SRCDIR)/screen.h \ $(SRCDIR)/keyboard.h $(SRCDIR)/textonly.o: $(TEXTONLY_C) $(SRCDIR)/textonly.c $(CC) $(CFLAGS) $(SRCDIR)/textonly.c -o $(SRCDIR)/textonly.o # Build STRINGS.C STRINGS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/strings.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/strings.o: $(STRINGS_C) $(SRCDIR)/strings.c $(CC) $(CFLAGS) $(SRCDIR)/strings.c -o $(SRCDIR)/strings.o # Build STATEMENT.C STATEMENT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/commands.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/editor.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/screen.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h \ $(SRCDIR)/iostate.h $(SRCDIR)/mainstate.h $(SRCDIR)/assign.h \ $(SRCDIR)/statement.h $(SRCDIR)/statement.o: $(STATEMENT_C) $(SRCDIR)/statement.c $(CC) $(CFLAGS) $(SRCDIR)/statement.c -o $(SRCDIR)/statement.o # Build STACK.C STACK_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/stack.h $(SRCDIR)/miscprocs.h $(SRCDIR)/strings.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/stack.o: $(STACK_C) $(SRCDIR)/stack.c $(CC) $(CFLAGS) $(SRCDIR)/stack.c -o $(SRCDIR)/stack.o # Build MISCPROCS.C MISCPROCS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/miscprocs.o: $(MISCPROCS_C) $(SRCDIR)/miscprocs.c $(CC) $(CFLAGS) $(SRCDIR)/miscprocs.c -o $(SRCDIR)/miscprocs.o # Build MAINSTATE.C MAINSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/strings.h $(SRCDIR)/errors.h \ $(SRCDIR)/statement.h $(SRCDIR)/evaluate.h $(SRCDIR)/convert.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/fileio.h \ $(SRCDIR)/mainstate.h $(SRCDIR)/mainstate.o: $(MAINSTATE_C) $(SRCDIR)/mainstate.c $(CC) $(CFLAGS) $(SRCDIR)/mainstate.c -o $(SRCDIR)/mainstate.o # Build LVALUE.C LVALUE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/evaluate.h $(SRCDIR)/stack.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/lvalue.h $(SRCDIR)/lvalue.o: $(LVALUE_C) $(SRCDIR)/lvalue.c $(CC) $(CFLAGS) $(SRCDIR)/lvalue.c -o $(SRCDIR)/lvalue.o # Build KEYBOARD.C KEYBOARD_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.o: $(KEYBOARD_C) $(SRCDIR)/keyboard.c $(CC) $(CFLAGS) $(SRCDIR)/keyboard.c -o $(SRCDIR)/keyboard.o # Build IOSTATE.C IOSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/convert.h $(SRCDIR)/emulate.h $(SRCDIR)/fileio.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/iostate.h $(SRCDIR)/iostate.o: $(IOSTATE_C) $(SRCDIR)/iostate.c $(CC) $(CFLAGS) $(SRCDIR)/iostate.c -o $(SRCDIR)/iostate.o # Build HEAP.C HEAP_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/heap.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/heap.o: $(HEAP_C) $(SRCDIR)/heap.c $(CC) $(CFLAGS) $(SRCDIR)/heap.c -o $(SRCDIR)/heap.o # Build FUNCTIONS.C FUNCTIONS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/strings.h \ $(SRCDIR)/convert.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h \ $(SRCDIR)/emulate.h $(SRCDIR)/miscprocs.h $(SRCDIR)/fileio.h \ $(SRCDIR)/functions.h $(SRCDIR)/functions.o: $(FUNCTIONS_C) $(SRCDIR)/functions.c $(CC) $(CFLAGS) $(SRCDIR)/functions.c -o $(SRCDIR)/functions.o # Build FILEIO.C FILEIO_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h $(SRCDIR)/fileio.o: $(FILEIO_C) $(SRCDIR)/fileio.c $(CC) $(CFLAGS) $(SRCDIR)/fileio.c -o $(SRCDIR)/fileio.o # Build EVALUATE.C EVALUATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/lvalue.h \ $(SRCDIR)/strings.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/statement.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/functions.h $(SRCDIR)/evaluate.o: $(EVALUATE_C) $(SRCDIR)/evaluate.c $(CC) $(CFLAGS) $(SRCDIR)/evaluate.c -o $(SRCDIR)/evaluate.o # Build ERRORS.C ERRORS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/stack.h $(SRCDIR)/fileio.h \ $(SRCDIR)/tokens.h $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/errors.o: $(ERRORS_C) $(SRCDIR)/errors.c $(CC) $(CFLAGS) $(SRCDIR)/errors.c -o $(SRCDIR)/errors.o # Build EMULATE.C EMULATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/basicdefs.h $(SRCDIR)/target.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/emulate.o: $(EMULATE_C) $(SRCDIR)/emulate.c $(CC) $(CFLAGS) $(SRCDIR)/emulate.c -o $(SRCDIR)/emulate.o # Build EDITOR.C EDITOR_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/heap.h \ $(SRCDIR)/tokens.h $(SRCDIR)/strings.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/stack.h $(SRCDIR)/fileio.h $(SRCDIR)/editor.o: $(EDITOR_C) $(SRCDIR)/editor.c $(CC) $(CFLAGS) $(SRCDIR)/editor.c -o $(SRCDIR)/editor.o # Build CONVERT.C CONVERT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/convert.h $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.o: $(CONVERT_C) $(SRCDIR)/convert.c $(CC) $(CFLAGS) $(SRCDIR)/convert.c -o $(SRCDIR)/convert.o # Build COMMANDS.C COMMANDS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/tokens.h $(SRCDIR)/statement.h \ $(SRCDIR)/variables.h $(SRCDIR)/editor.h $(SRCDIR)/errors.h \ $(SRCDIR)/heap.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.h $(SRCDIR)/commands.o: $(COMMANDS_C) $(SRCDIR)/commands.c $(CC) $(CFLAGS) $(SRCDIR)/commands.c -o $(SRCDIR)/commands.o # Build BRANDY.C BRANDY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/heap.h \ $(SRCDIR)/editor.h $(SRCDIR)/commands.h $(SRCDIR)/statement.h \ $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/brandy.o: $(BRANDY_C) $(SRCDIR)/brandy.c $(CC) $(CFLAGS) $(SRCDIR)/brandy.c -o $(SRCDIR)/brandy.o # Build ASSIGN.C ASSIGN_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/target.h $(SRCDIR)/tokens.h $(SRCDIR)/heap.h \ $(SRCDIR)/stack.h $(SRCDIR)/strings.h $(SRCDIR)/variables.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/assign.h $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/assign.o: $(ASSIGN_C) $(SRCDIR)/assign.c $(CC) $(CFLAGS) $(SRCDIR)/assign.c -o $(SRCDIR)/assign.o recompile: $(CC) $(CFLAGS) $(SRC) $(LIBS) -o brandy nodebug: $(CC) $(CFLAGS2) $(SRC) $(LIBS) -o brandy strip brandy.exe check: $(CC) $(CFLAGS) -Wall $(SRC) $(LIBS) -o brandy clean: del /q $(SRCDIR)\*.o del /q brandy.exe all: brandy brandy-1.20/COPYING0000644000175000017500000004310610546535642012756 0ustar colincolin GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. brandy-1.20/makefile0000644000175000017500000002315712163032760013415 0ustar colincolin# Makefile for brandy under NetBSD and Linux CC = gcc LD = gcc CFLAGS += -g -DDEBUG -I/usr/include/SDL -DUSE_SDL CFLAGS2 = -O2 -I/usr/include/SDL -DUSE_SDL LDFLAGS = LIBS = -lm -lSDL SRCDIR = src OBJ = $(SRCDIR)/variables.o $(SRCDIR)/tokens.o $(SRCDIR)/graphsdl.o \ $(SRCDIR)/strings.o $(SRCDIR)/statement.o $(SRCDIR)/stack.o \ $(SRCDIR)/miscprocs.o $(SRCDIR)/mainstate.o $(SRCDIR)/lvalue.o \ $(SRCDIR)/keyboard.o $(SRCDIR)/iostate.o $(SRCDIR)/heap.o \ $(SRCDIR)/functions.o $(SRCDIR)/fileio.o $(SRCDIR)/evaluate.o \ $(SRCDIR)/errors.o $(SRCDIR)/emulate.o $(SRCDIR)/editor.o \ $(SRCDIR)/convert.o $(SRCDIR)/commands.o $(SRCDIR)/brandy.o \ $(SRCDIR)/assign.o $(SRCDIR)/geom.o SRC = $(SRCDIR)/variables.c $(SRCDIR)/tokens.c $(SRCDIR)/graphsdl.c \ $(SRCDIR)/strings.c $(SRCDIR)/statement.c $(SRCDIR)/stack.c \ $(SRCDIR)/miscprocs.c $(SRCDIR)/mainstate.c $(SRCDIR)/lvalue.c \ $(SRCDIR)/keyboard.c $(SRCDIR)/iostate.c $(SRCDIR)/heap.c \ $(SRCDIR)/functions.c $(SRCDIR)/fileio.c $(SRCDIR)/evaluate.c \ $(SRCDIR)/errors.c $(SRCDIR)/emulate.c $(SRCDIR)/editor.c \ $(SRCDIR)/convert.c $(SRCDIR)/commands.c $(SRCDIR)/brandy.c \ $(SRCDIR)/assign.c $(SRCDIR)/geom.c brandy: $(OBJ) $(LD) $(LDFLAGS) -o brandy $(OBJ) $(LIBS) # Build VARIABLES.C VARIABLES_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h $(SRCDIR)/tokens.h \ $(SRCDIR)/stack.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/variables.o: $(VARIABLES_C) $(SRCDIR)/variables.c $(CC) $(CFLAGS) $(SRCDIR)/variables.c -c -o $(SRCDIR)/variables.o # Build TOKENS.C TOKENS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.h \ $(SRCDIR)/errors.h $(SRCDIR)/tokens.o: $(TOKENS_C) $(SRCDIR)/tokens.c $(CC) $(CFLAGS) $(SRCDIR)/tokens.c -c -o $(SRCDIR)/tokens.o # Build GRAPHSDL.C GSDL_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/scrcommon.h $(SRCDIR)/screen.h $(SRCDIR)/graphsdl.o: $(GSDL_C) $(SRCDIR)/graphsdl.c $(CC) $(CFLAGS) $(SRCDIR)/graphsdl.c -c -o $(SRCDIR)/graphsdl.o # Build GEOM.C GEOM_C = $(SRCDIR)/target.h $(SRCDIR)/geom.o: $(GEOM_C) $(SRCDIR)/geom.c $(CC) $(CFLAGS) $(SRCDIR)/geom.c -c -o $(SRCDIR)/geom.o # Build STRINGS.C STRINGS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/strings.h $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/strings.o: $(STRINGS_C) $(SRCDIR)/strings.c $(CC) $(CFLAGS) $(SRCDIR)/strings.c -c -o $(SRCDIR)/strings.o # Build STATEMENT.C STATEMENT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/commands.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/errors.h $(SRCDIR)/editor.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/variables.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/screen.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h \ $(SRCDIR)/iostate.h $(SRCDIR)/mainstate.h $(SRCDIR)/assign.h \ $(SRCDIR)/statement.h $(SRCDIR)/statement.o: $(STATEMENT_C) $(SRCDIR)/statement.c $(CC) $(CFLAGS) $(SRCDIR)/statement.c -c -o $(SRCDIR)/statement.o # Build STACK.C STACK_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/stack.h $(SRCDIR)/miscprocs.h $(SRCDIR)/strings.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/stack.o: $(STACK_C) $(SRCDIR)/stack.c $(CC) $(CFLAGS) $(SRCDIR)/stack.c -c -o $(SRCDIR)/stack.o # Build MISCPROCS.C MISCPROCS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/miscprocs.o: $(MISCPROCS_C) $(SRCDIR)/miscprocs.c $(CC) $(CFLAGS) $(SRCDIR)/miscprocs.c -c -o $(SRCDIR)/miscprocs.o # Build MAINSTATE.C MAINSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/stack.h \ $(SRCDIR)/heap.h $(SRCDIR)/strings.h $(SRCDIR)/errors.h \ $(SRCDIR)/statement.h $(SRCDIR)/evaluate.h $(SRCDIR)/convert.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/fileio.h \ $(SRCDIR)/mainstate.h $(SRCDIR)/mainstate.o: $(MAINSTATE_C) $(SRCDIR)/mainstate.c $(CC) $(CFLAGS) $(SRCDIR)/mainstate.c -c -o $(SRCDIR)/mainstate.o # Build LVALUE.C LVALUE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/evaluate.h $(SRCDIR)/stack.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/lvalue.h $(SRCDIR)/lvalue.o: $(LVALUE_C) $(SRCDIR)/lvalue.c $(CC) $(CFLAGS) $(SRCDIR)/lvalue.c -c -o $(SRCDIR)/lvalue.o # Build KEYBOARD.C KEYBOARD_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.o: $(KEYBOARD_C) $(SRCDIR)/keyboard.c $(CC) $(CFLAGS) $(SRCDIR)/keyboard.c -c -o $(SRCDIR)/keyboard.o # Build IOSTATE.C IOSTATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/evaluate.h \ $(SRCDIR)/convert.h $(SRCDIR)/emulate.h $(SRCDIR)/fileio.h \ $(SRCDIR)/screen.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/iostate.h $(SRCDIR)/iostate.o: $(IOSTATE_C) $(SRCDIR)/iostate.c $(CC) $(CFLAGS) $(SRCDIR)/iostate.c -c -o $(SRCDIR)/iostate.o # Build HEAP.C HEAP_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/heap.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/heap.o: $(HEAP_C) $(SRCDIR)/heap.c $(CC) $(CFLAGS) $(SRCDIR)/heap.c -c -o $(SRCDIR)/heap.o # Build FUNCTIONS.C FUNCTIONS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/strings.h \ $(SRCDIR)/convert.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/keyboard.h $(SRCDIR)/screen.h \ $(SRCDIR)/emulate.h $(SRCDIR)/miscprocs.h $(SRCDIR)/fileio.h \ $(SRCDIR)/functions.h $(SRCDIR)/functions.o: $(FUNCTIONS_C) $(SRCDIR)/functions.c $(CC) $(CFLAGS) $(SRCDIR)/functions.c -c -o $(SRCDIR)/functions.o # Build FILEIO.C FILEIO_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/fileio.h $(SRCDIR)/strings.h $(SRCDIR)/fileio.o: $(FILEIO_C) $(SRCDIR)/fileio.c $(CC) $(CFLAGS) $(SRCDIR)/fileio.c -c -o $(SRCDIR)/fileio.o # Build EVALUATE.C EVALUATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/variables.h $(SRCDIR)/lvalue.h \ $(SRCDIR)/strings.h $(SRCDIR)/stack.h $(SRCDIR)/errors.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/statement.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/functions.h $(SRCDIR)/evaluate.o: $(EVALUATE_C) $(SRCDIR)/evaluate.c $(CC) $(CFLAGS) $(SRCDIR)/evaluate.c -c -o $(SRCDIR)/evaluate.o # Build ERRORS.C ERRORS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/stack.h $(SRCDIR)/fileio.h \ $(SRCDIR)/tokens.h $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/errors.o: $(ERRORS_C) $(SRCDIR)/errors.c $(CC) $(CFLAGS) $(SRCDIR)/errors.c -c -o $(SRCDIR)/errors.o # Build EMULATE.C EMULATE_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/errors.h \ $(SRCDIR)/basicdefs.h $(SRCDIR)/emulate.h \ $(SRCDIR)/screen.h $(SRCDIR)/keyboard.h $(SRCDIR)/emulate.o: $(EMULATE_C) $(SRCDIR)/emulate.c $(CC) $(CFLAGS) $(SRCDIR)/emulate.c -c -o $(SRCDIR)/emulate.o # Build EDITOR.C EDITOR_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/errors.h $(SRCDIR)/variables.h $(SRCDIR)/heap.h \ $(SRCDIR)/tokens.h $(SRCDIR)/strings.h $(SRCDIR)/miscprocs.h \ $(SRCDIR)/stack.h $(SRCDIR)/fileio.h $(SRCDIR)/editor.o: $(EDITOR_C) $(SRCDIR)/editor.c $(CC) $(CFLAGS) $(SRCDIR)/editor.c -c -o $(SRCDIR)/editor.o # Build CONVERT.C CONVERT_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/convert.h $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/convert.o: $(CONVERT_C) $(SRCDIR)/convert.c $(CC) $(CFLAGS) $(SRCDIR)/convert.c -c -o $(SRCDIR)/convert.o # Build COMMANDS.C COMMANDS_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/miscprocs.h $(SRCDIR)/tokens.h $(SRCDIR)/statement.h \ $(SRCDIR)/variables.h $(SRCDIR)/editor.h $(SRCDIR)/errors.h \ $(SRCDIR)/heap.h $(SRCDIR)/stack.h $(SRCDIR)/strings.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/screen.h $(SRCDIR)/keyboard.h $(SRCDIR)/commands.o: $(COMMANDS_C) $(SRCDIR)/commands.c $(CC) $(CFLAGS) $(SRCDIR)/commands.c -c -o $(SRCDIR)/commands.o # Build BRANDY.C BRANDY_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/tokens.h $(SRCDIR)/errors.h $(SRCDIR)/heap.h \ $(SRCDIR)/editor.h $(SRCDIR)/commands.h $(SRCDIR)/statement.h \ $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/keyboard.h \ $(SRCDIR)/screen.h $(SRCDIR)/miscprocs.h $(SRCDIR)/brandy.o: $(BRANDY_C) $(SRCDIR)/brandy.c $(CC) $(CFLAGS) $(SRCDIR)/brandy.c -c -o $(SRCDIR)/brandy.o # Build ASSIGN.C ASSIGN_C = $(SRCDIR)/common.h $(SRCDIR)/target.h $(SRCDIR)/basicdefs.h \ $(SRCDIR)/target.h $(SRCDIR)/tokens.h $(SRCDIR)/heap.h \ $(SRCDIR)/stack.h $(SRCDIR)/strings.h $(SRCDIR)/variables.h \ $(SRCDIR)/errors.h $(SRCDIR)/miscprocs.h $(SRCDIR)/editor.h \ $(SRCDIR)/evaluate.h $(SRCDIR)/lvalue.h $(SRCDIR)/statement.h \ $(SRCDIR)/assign.h $(SRCDIR)/fileio.h $(SRCDIR)/emulate.h $(SRCDIR)/assign.o: $(ASSIGN_C) $(SRCDIR)/assign.c $(CC) $(CFLAGS) $(SRCDIR)/assign.c -c -o $(SRCDIR)/assign.o recompile: $(CC) $(CFLAGS) $(SRC) $(LIBS) -o brandy nodebug: $(CC) $(CFLAGS2) $(SRC) $(LIBS) -o brandy strip brandy check: $(CC) $(CFLAGS) -Wall -O2 $(SRC) $(LIBS) -o brandy clean: rm -f $(SRCDIR)/*.o brandy all: brandy brandy-1.20/READ.ME0000644000175000017500000000244312163034777012660 0ustar colincolinBrandy 1.20 --------------- This version uses the SDL graphics library. The file docs/history lists what has been done. Files ----- docs Documentation examples Some sample programs COPYING Copy of GPL src Directory containing source code makefile Makefile to recompile program under NetBSD and Linux makefile.text Makefile to compile text mode versions makefile.riscos Makefile for AMU to recompile under RISC OS makefile.djgpp Makefile for text only version for DOS using DJGPP makefile.bcc Makefile for the DOS version using Borland C The program is distributed under the terms of the GNU GPL. Brandy is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Brandy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Brandy; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. brandy-1.20/src/0000755000175000017500000000000012163032760012474 5ustar colincolinbrandy-1.20/src/convert.c0000644000175000017500000001275110546536104014332 0ustar colincolin/* ** This file is part of the Brandy Basic V Interpreter. ** Copyright (C) 2000, 2001, 2002, 2003, 2004 David Daniels ** ** Brandy is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2, or (at your option) ** any later version. ** ** Brandy is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Brandy; see the file COPYING. If not, write to ** the Free Software Foundation, 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** ** This file contains functions that convert numbers between ** character and binary format */ #include #include #include "common.h" #include "target.h" #include "convert.h" #include "errors.h" #include "miscprocs.h" /* ** 'todigit' converts the character 'x' to its numeric equivalent */ int todigit(char x) { if (x>='0' && x<='9') return x-'0'; if (x>='A' && x<='F') return x-'A'+10; if (x>='a' && x<='f') return x-'a'+10; return 0; } #define INTCONV (MAXINTVAL/10) /* ** 'tonumber' converts the character string starting at 'cp' to binary. ** It handles integer and floating point values, including numbers ** expressed in hexadecimal and binary. It returns a pointer to the ** character after the last one used in the number or 'NIL' if an error ** was detected. The value is returned at either 'floatvalue' or ** 'intvalue' depending on the type of the number. 'isinteger' says ** which it is. In the event of an error, 'intvalue' is used to return ** an error number */ char *tonumber(char *cp, boolean *isinteger, int32 *intvalue, float64 *floatvalue) { int32 value; static float64 fpvalue, fltdiv; boolean isint, isneg, negexp; int digits, exponent; value = 0; digits = 0; cp = skip_blanks(cp); /* Ignore leading white space characters */ switch (*cp) { case '&': /* Hex value */ cp++; while (isxdigit(*cp)) { digits++; value = (value<<4)+todigit(*cp); cp++; } if (digits==0) { *intvalue = WARN_BADHEX; /* Bad hexadecimal constant */ cp = NIL; } else { *intvalue = value; *isinteger = TRUE; } break; case '%': /* Binary value */ cp++; while (*cp=='0' || *cp=='1') { digits++; value = (value<<1)+(*cp-'0'); cp++; } if (digits==0) { *intvalue = WARN_BADBIN; /* Bad binary constant */ cp = NIL; } else { *intvalue = value; *isinteger = TRUE; } break; default: /* Integer or floating point value */ isint = TRUE; isneg = *cp=='-'; /* Deal with any sign first */ if (*cp=='+' || *cp=='-') cp++; while (*cp>='0' && *cp<='9') { digits = 0; /* Used to count the number of digits before the '.' */ if (isint && value>=INTCONV) { isint = FALSE; fpvalue = TOFLOAT(value); } if (isint) value = value*10+(*cp-'0'); else { fpvalue = fpvalue*10.0+TOFLOAT(*cp-'0'); } digits++; cp++; } if (!isint && *cp!='.' && *cp!='E' && fpvalue<=TOFLOAT(MAXINTVAL)) { /* Convert back to integer */ value = TOINT(fpvalue); isint = TRUE; } if (*cp=='.') { /* Number contains a decimal point */ if (isint) { isint = FALSE; fpvalue = TOFLOAT(value); } fltdiv = 1.0; cp++; while (*cp>='0' && *cp<='9') { fpvalue = fpvalue*10.0+TOFLOAT(*cp-'0'); fltdiv = fltdiv*10.0; cp++; } fpvalue = fpvalue/fltdiv; } /* ** Deal with an exponent. Note one trick here: if the 'E' is followed by another ** letter it is assumed that the 'E' is part of a word that follows the number, ** that is, there is not really an exponent here */ if (toupper(*cp)=='E' && !isalpha(*(cp+1))) { /* Number contains an exponent */ if (isint) { isint = FALSE; fpvalue = value; } exponent = 0; cp++; negexp = *cp=='-'; if (*cp=='+' || *cp=='-') cp++; while (*cp>='0' && *cp<='9' && exponent<=MAXEXPONENT) { exponent = exponent*10+(*cp-'0'); cp++; } if (negexp) { if (exponent-digits<=MAXEXPONENT) exponent = -exponent; else { /* If value<1E-308, set value to 0 */ exponent = 0; fpvalue = 0; } } else if (exponent+digits-1>MAXEXPONENT) { /* Crude check for overflow on +ve exponent */ *intvalue = WARN_EXPOFLO; cp = NIL; exponent = 0; } fpvalue = fpvalue*pow(10.0, exponent); } *isinteger = isint; if (isint) *intvalue = (isneg ? -value : value); else { *floatvalue = (isneg ? -fpvalue : fpvalue); } } return cp; } /* ** 'itob' formats the value 'value' as a binary number at 'dest'. ** It returns a count of the number of characters in the formatted ** number. 'width' gives the minimum field width, but this is not ** used at present */ int itob(char *dest, int32 value, int32 width) { int count, n; char temp[sizeof(int32)*8]; for (n=0; n>1; } n = sizeof(int32)*8-1; while (n>0 && temp[n]=='0') n--; count = n+1; while (n>=0) { *dest = temp[n]; dest++; n--; } *dest = NUL; return count; } brandy-1.20/src/keyboard.c0000644000175000017500000014604512161325744014457 0ustar colincolin/* ** This file is part of the Brandy Basic V Interpreter. ** Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 David Daniels ** and Copyright (C) 2006, 2007 Colin Tuckley ** ** Brandy is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2, or (at your option) ** any later version. ** ** Brandy is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Brandy; see the file COPYING. If not, write to ** the Free Software Foundation, 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** ** This file contains the keyboard handling routines. ** ** When running under operating systems other than RISC OS the ** interpreter uses its own keyboard handling functions to ** provide both line editing and a line recall feature */ /* ** Colin Tuckley December 2006: ** Rewrite to use SDL library Event handling. */ /* ** Crispian Daniels August 20th 2002: ** Included Mac OS X target in conditional compilation. */ #include #include #include "common.h" #include "target.h" #include "basicdefs.h" #include "errors.h" #include "keyboard.h" #include "screen.h" #ifdef USE_SDL #include "SDL.h" Uint32 waitkey_callbackfunc(Uint32 interval, void *param) { SDL_Event event; SDL_UserEvent userevent; userevent.type = SDL_USEREVENT; userevent.code = 0; userevent.data1 = NULL; userevent.data2 = NULL; event.type = SDL_USEREVENT; event.user = userevent; SDL_PushEvent(&event); return(0); /* cancel the timer */ } #endif #ifdef TARGET_RISCOS /* ================================================================= */ /* ================= RISC OS versions of functions ================= */ /* ================================================================= */ #include "kernel.h" #include "swis.h" /* ** 'emulate_get' emulates the Basic function 'get' */ int32 emulate_get(void) { return _kernel_osrdch(); } /* ** 'emulate_inkey' does the hard work for the Basic 'inkey' function */ int32 emulate_inkey(int32 arg) { _kernel_oserror *oserror; /* Use OS_Byte 129 to obtain the info */ _kernel_swi_regs regs; regs.r[0] = 129; /* Use OS_Byte 129 for this */ regs.r[1] = arg & BYTEMASK; regs.r[2] = (arg>>BYTESHIFT) & BYTEMASK; oserror = _kernel_swi(OS_Byte, ®s, ®s); if (oserror != NIL) error(ERR_CMDFAIL, oserror->errmess); if (arg >= 0) { /* +ve argument = read keyboard with time limit */ if (regs.r[2] == 0) /* Character was read successfully */ return (regs.r[1]); else if (regs.r[2] == 0xFF) /* Timed out */ return -1; else { error(ERR_CMDFAIL, "C library has missed an escape event"); } } else { /* -ve argument */ if (regs.r[1] == 0xFF) return -1; else { return regs.r[1]; } } return 0; /* Not needed, but it keeps the Acorn C compiler happy */ } /* ** 'emulate_readline' reads a line from the keyboard. It returns 'true' ** if the call worked successfully or 'false' if 'escape' was pressed. ** The data input is stored at 'buffer'. Up to 'length' characters can ** be read. A 'null' is added after the last character. The reason for ** using this function in preference to 'fgets' under RISC OS is that ** 'fgets' does not use 'OS_ReadLine' and therefore bypasses the command ** line history and other features that might be available via this SWI ** call. */ readstate emulate_readline(char buffer[], int32 length) { _kernel_oserror *oserror; _kernel_swi_regs regs; int32 carry; regs.r[0] = TOINT(&buffer[0]); regs.r[1] = length-1; /* -1 to allow for a NULL to be added at the end in all cases */ regs.r[2] = 0; /* Allow any character to be input */ regs.r[3] = 255; oserror = _kernel_swi_c(OS_ReadLine, ®s, ®s, &carry); if (oserror != NIL) error(ERR_CMDFAIL, oserror->errmess); if (carry != 0) /* Carry is set - 'escape' was pressed */ buffer[0] = NUL; else { buffer[regs.r[1]] = NUL; /* Number of characters read is returned in R1 */ } return carry == 0 ? READ_OK : READ_ESC; } /* * set_fn_string - Define a function key string */ void set_fn_string(int key, char *string, int length) { printf("Key = %d String = '%s'\n", key, string); } boolean init_keyboard(void) { return TRUE; } void end_keyboard(void) { } #else /* ==================================================================== */ /* DOS/Linux/NetBSD/FreeBSD/MacOS/OpenBSD/AmigaOS versions of functions */ /* ==================================================================== */ #include #if defined(TARGET_LINUX) | defined(TARGET_NETBSD) | defined(TARGET_MACOSX)\ | defined(TARGET_DJGPP) | defined(TARGET_FREEBSD) | defined(TARGET_OPENBSD)\ | defined(TARGET_AMIGA) & defined(__GNUC__)\ | defined(TARGET_GNUKFREEBSD) | defined(TARGET_GNU) #include #include #include #include #include #endif #if defined(TARGET_WIN32) | defined(TARGET_BCC32) | defined(TARGET_MINGW) #include #endif #ifdef TARGET_DJGPP #include #include #endif /* ASCII codes of various useful characters */ #define CTRL_A 1 #define CTRL_B 2 #define CTRL_C 3 #define CTRL_D 4 #define CTRL_E 5 #define CTRL_F 6 #define CTRL_H 8 #define CTRL_K 0x0B #define CTRL_N 0x0E #define CTRL_P 0x10 #define CTRL_U 0x15 #define ESCAPE 0x1B #define DEL 0x7F /* ** Following are the key codes given in the RISC OS PRMs for the various ** special keys of interest to this program. RISC OS sequences for these ** keys consists of a NUL followed by one of these values. They are used ** internally when processing the keys. The key codes returned by foreign ** operating systems are mapped on to these values where possible. */ #define HOME 0x1E #define CTRL_HOME 0x1E #define END 0x8B #define CTRL_END 0xAB #define UP 0x8F #define CTRL_UP 0xAF #define DOWN 0x8E #define CTRL_DOWN 0xAE #define LEFT 0x8C #define CTRL_LEFT 0xAC #define RIGHT 0x8D #define CTRL_RIGHT 0xAD #define PGUP 0x9F #define CTRL_PGUP 0xBF #define PGDOWN 0x9E #define CTRL_PGDOWN 0xBE #define INSERT 0xCD #define CTRL_INSERT 0xED #define DELETE 0x7F #define CTRL_DELETE 0x7F /* Function key codes */ #define KEY_F1 0x81 #define SHIFT_F1 0x91 #define CTRL_F1 0xA1 #define KEY_F2 0x82 #define SHIFT_F2 0x92 #define CTRL_F2 0xA2 #define KEY_F3 0x83 #define SHIFT_F3 0x93 #define CTRL_F3 0xA3 #define KEY_F4 0x84 #define SHIFT_F4 0x94 #define CTRL_F4 0xA4 #define KEY_F5 0x85 #define SHIFT_F5 0x95 #define CTRL_F5 0xA5 #define KEY_F6 0x86 #define SHIFT_F6 0x96 #define CTRL_F6 0xA6 #define KEY_F7 0x87 #define SHIFT_F7 0x97 #define CTRL_F7 0xA7 #define KEY_F8 0x88 #define SHIFT_F8 0x98 #define CTRL_F8 0xA8 #define KEY_F9 0x89 #define SHIFT_F9 0x99 #define CTRL_F9 0xA9 #define KEY_F10 0xCA #define SHIFT_F10 0xDA #define CTRL_F10 0xEA #define KEY_F11 0xCB #define SHIFT_F11 0xDB #define CTRL_F11 0xEB #define KEY_F12 0xCC #define SHIFT_F12 0xDC #define CTRL_F12 0xEC /* ** Operating system version number returned by 'INKEY'. These values ** are made up */ #if defined(TARGET_NETBSD) #define OSVERSION 0xFE #elif defined(TARGET_WIN32) | defined(TARGET_BCC32) | defined(TARGET_MINGW) #define OSVERSION 0xFC #elif defined(TARGET_BEOS) #define OSVERSION 0xFB #elif defined(TARGET_DJGPP) #define OSVERSION 0xFA #elif defined(TARGET_LINUX) #define OSVERSION 0xF9 #elif defined(TARGET_MACOSX) #define OSVERSION 0xF8 #elif defined(TARGET_FREEBSD) #define OSVERSION 0xF7 #elif defined(TARGET_OPENBSD) #define OSVERSION 0xF6 #elif defined(TARGET_AMIGA) #define OSVERSION 0xF5 #elif defined(TARGET_GNUKFREEBSD) #define OSVERSION 0xF4 #elif defined(TARGET_GNU) #define OSVERSION 0xF3 #else #error Target operating system is either not defined or not supported #endif #define INKEYMAX 0x7FFF /* Maximum wait time for INKEY */ #define WAITIME 10 /* Time to wait in centiseconds when dealing with ANSI key sequences */ #define HISTSIZE 1024 /* Size of command history buffer */ #define MAXHIST 20 /* Maximum number of entries in history list */ #define FN_KEY_COUNT 15 /* Number of function keys supported (0 to FN_KEY_COUNT) */ static int32 place, /* Offset where next character will be added to buffer */ highplace, /* Highest value of 'place' (= number of characters in buffer) */ histindex, /* Index of next entry to fill in in history list */ highbuffer, /* Index of first free character in 'histbuffer' */ recalline; /* Index of last line recalled from history display */ static boolean enable_insert; /* TRUE if keyboard input code is in insert mode */ static char histbuffer[HISTSIZE]; /* Command history buffer */ static int32 histlength[MAXHIST]; /* Table of sizes of entries in history buffer */ /* function key strings */ static struct {int length; char *text;} fn_key[FN_KEY_COUNT]; /* ** holdcount and holdstack are used when decoding ANSI key sequences. If a ** sequence is read that does not correspond to an ANSI sequence the ** characters are stored here so that they can be returned by future calls ** to 'emulate_get'. Note that this is a *stack* not a queue */ static int32 holdcount; /* Number of characters held on stack */ static int32 holdstack[8]; /* Hold stack - Characters waiting to be passed back via 'get' */ /* ** fn_string and fn_string_count are used when expanding a function ** key string. Effectively input switches to the string after a ** function key with a string associated with it is pressed */ static char *fn_string; /* Non-NULL if taking chars from a function key string */ static int fn_string_count; /* Count of characters left in function key string */ #if defined(TARGET_LINUX) | defined(TARGET_NETBSD) | defined(TARGET_MACOSX)\ | defined(TARGET_FREEBSD) |defined(TARGET_OPENBSD) | defined(TARGET_AMIGA) & defined(__GNUC__)\ | defined(TARGET_GNUKFREEBSD) | defined(TARGET_GNU) static struct termios origtty; /* Copy of original keyboard parameters */ static int32 keyboard; /* File descriptor for keyboard */ #endif /* The following functions are common to all operating systems */ /* ** 'push_key' adds a key to the held key stack */ static void push_key(int32 ch) { holdcount++; holdstack[holdcount] = ch; } /* ** pop_key - Remove a key from the held key stack */ static int32 pop_key(void) { return holdstack[holdcount--]; } /* ** purge_keys - Flattens the holding stack */ void purge_keys(void) { holdcount = 0; } /* ** set_fn_string - Define a function key string */ void set_fn_string(int key, char *string, int length) { if (fn_key[key].text != NIL) free(fn_key[key].text); fn_key[key].length = length; fn_key[key].text = malloc(length); if (fn_key[key].text != NIL) memcpy(fn_key[key].text, string, length); } /* ** switch_fn_string - Called to switch input to a function ** key string. It returns the first character of the string */ static int32 switch_fn_string(int32 key) { int32 ch; if (fn_key[key].length == 1) return *fn_key[key].text; fn_string = fn_key[key].text; fn_string_count = fn_key[key].length - 1; ch = *fn_string; fn_string++; return ch; } /* ** read_fn_string - Called when input is being taken from a ** function key string, that is, fn_string is not NULL. It ** returns the next character in the string. */ static int32 read_fn_string(void) { int32 ch; ch = *fn_string; fn_string++; fn_string_count--; if (fn_string_count == 0) fn_string = NIL; /* Last character read */ return ch; } /* * is_fn_key - Returns the function key number if the RISC OS * key code passed to it is one for a function key. This is used * when checking for function key strings, so shifted and CTRL'ed * function keys are of no interest */ static int32 is_fn_key(int32 key) { if (key >= KEY_F1 && key <= KEY_F9) return key - KEY_F1 + 1; if (key >= KEY_F10 && key <= KEY_F12) return key - KEY_F10 + 10; /* Not a function key */ return 0; } #if defined(TARGET_LINUX) | defined(TARGET_NETBSD) | defined(TARGET_MACOSX)\ | defined(TARGET_FREEBSD) | defined(TARGET_OPENBSD) | defined(TARGET_AMIGA) & defined(__GNUC__)\ | defined(TARGET_GNUKFREEBSD) | defined(TARGET_GNU) /* ----- Linux-, *BSD- and MACOS-specific keyboard input functions ----- */ /* ** 'waitkey' is called to wait for up to 'wait' centiseconds for ** keyboard input. It returns 'true' if there is a character available ** */ static boolean waitkey(int wait) { fd_set keyset; struct timeval waitime; #ifdef USE_SDL SDL_Event ev; SDL_TimerID timer_id; /* set up timer if wait time not zero */ if (wait != 0) timer_id = SDL_AddTimer(wait*10, waitkey_callbackfunc, 0); while ( 1 ) { /* * First check for SDL events */ while (SDL_PollEvent(&ev) > 0) switch(ev.type) { case SDL_USEREVENT: return 0; /* timeout expired */ case SDL_KEYDOWN: switch(ev.key.keysym.sym) { case SDLK_RSHIFT: /* ignore non-character keys */ case SDLK_LSHIFT: case SDLK_RCTRL: case SDLK_LCTRL: case SDLK_RALT: case SDLK_LALT: break; default: SDL_PushEvent(&ev); /* we got a char - push the event back and say we found one */ return 1; break; } break; case SDL_QUIT: exit_interpreter(EXIT_SUCCESS); break; } /* * Then for stdin keypresses */ FD_ZERO(&keyset); FD_SET(keyboard, &keyset); waitime.tv_sec = waitime.tv_usec = 0; if ( select(1, &keyset, NIL, NIL, &waitime) > 0 ) return 1; if (wait == 0) return 0; /* return after one check if wait time = 0 */ } #else FD_ZERO(&keyset); FD_SET(keyboard, &keyset); waitime.tv_sec = wait/100; /* Convert wait time to seconds and microseconds */ waitime.tv_usec = wait%100*10000; return select(1, &keyset, NIL, NIL, &waitime) > 0; #endif } /* ** 'read_key' reads the next character from the keyboard ** or gets the next keypress from the SDL event queue */ int32 read_key(void) { int errcode; byte ch = 0; #ifdef USE_SDL SDL_Event ev; fd_set keyset; struct timeval waitime; while (ch == 0) { /* ** First check the SDL event Queue */ if (SDL_PollEvent(&ev)) switch(ev.type) { case SDL_KEYDOWN: switch(ev.key.keysym.sym) { case SDLK_RSHIFT: /* ignored keys */ case SDLK_LSHIFT: case SDLK_RCTRL: case SDLK_LCTRL: case SDLK_RALT: case SDLK_LALT: break; case SDLK_LEFT: push_key(LEFT); return NUL; case SDLK_RIGHT: push_key(RIGHT); return NUL; case SDLK_UP: push_key(UP); return NUL; case SDLK_DOWN: push_key(DOWN); return NUL; case SDLK_HOME: return HOME; case SDLK_END: push_key(END); return NUL; case SDLK_PAGEUP: push_key(PGUP); return NUL; case SDLK_PAGEDOWN: push_key(PGDOWN); return NUL; case SDLK_INSERT: push_key(INSERT); return NUL; case SDLK_ESCAPE: return ESCAPE; case SDLK_F1: case SDLK_F2: case SDLK_F3: case SDLK_F4: case SDLK_F5: case SDLK_F6: case SDLK_F7: case SDLK_F8: case SDLK_F9: ch = KEY_F1 + ev.key.keysym.sym - SDLK_F1; if (ev.key.keysym.mod & KMOD_SHIFT) ch += 0x10; if (ev.key.keysym.mod & KMOD_CTRL) ch += 0x20; push_key(ch); return NUL; case SDLK_F10: case SDLK_F11: case SDLK_F12: ch = KEY_F10 + ev.key.keysym.sym - SDLK_F10; if (ev.key.keysym.mod & KMOD_SHIFT) ch += 0x10; if (ev.key.keysym.mod & KMOD_CTRL) ch += 0x20; push_key(ch); return NUL; default: ch = ev.key.keysym.unicode; return ch; } break; case SDL_QUIT: exit_interpreter(EXIT_SUCCESS); break; } /* ** Then check stdin */ FD_ZERO(&keyset); FD_SET(keyboard, &keyset); waitime.tv_sec = waitime.tv_usec = 0; /* Zero wait time */ if ( select(1, &keyset, NIL, NIL, &waitime) > 0 ) { errcode = read(keyboard, &ch, 1); if (errcode < 0) { /* read() returned an error */ if (errno == EINTR) error(ERR_ESCAPE); /* Assume Ctrl-C was pressed */ error(ERR_BROKEN, __LINE__, "keyboard"); /* Otherwise roll over and die */ } else return ch; } /* If we reach here then nothing happened and so we should sleep */ SDL_Delay(10); } #else errcode = read(keyboard, &ch, 1); if (errcode < 0) { /* read() returned an error */ if (errno == EINTR) error(ERR_ESCAPE); /* Assume Ctrl-C was pressed */ error(ERR_BROKEN, __LINE__, "keyboard"); /* Otherwise roll over and die */ } #endif return ch; } /* ** 'decode_sequence' reads a possible ANSI escape sequence and attempts ** to decode it, converting it to a RISC OS key code. It returns the first ** character of the key code (a null) if the sequence is recognised or ** the first character of the sequence read if it cannot be identified. ** Note that the decoding is incomplete as the function only deals ** with keys of interest to it. Note also that it deals with both Linux ** and NetBSD key sequences, for example, the one for 'F1' under Linux ** is 1B 5B 5B 41 and for NetBSD it is 1B 4F 50. It should also be noted ** that the range of keys that can be decoded is a long way short of the ** key combinations possible. Lastly, the same ANSI sequences are used for ** more than one key, for example, F11 and shift-F1 both return the same ** code. ** ** States: ** 1 ESC read 2 ESC 'O' 3 ESC '[' ** 4 ESC '[' '1' 5 ESC '[' '2' 6 ESC '[' '3' ** 7 ESC '[' '4' 8 ESC '[' '5' 9 ESC '[' '6' ** 10 ESC '[' '[' ** 11 ESC '[' '1' '1' 12 ESC '[' '1' '2' 13 ESC '[' '1' '3' ** 14 ESC '[' '1' '4' 15 ESC '[' '1' '5' 16 ESC '[' '1' '7' ** 17 ESC '[' '1' '8' 18 ESC '[' '1' '9' ** 19 ESC '[' '2' '0' 20 ESC '[' '2' '1' 21 ESC '[' '2' '3' ** 12 ESC '[' '2' '4' 23 ESC '[' '2' '5' 24 ESC '[' '2' '6' ** 25 ESC '[' '2' '8' 26 ESC '[' '2' '9' ** 27 ESC '[' '3' '1' 28 ESC '[' '3' '2' 29 ESC '[' '3' '3' ** 30 ESC '[' '3' '4' ** ** This code cannot deal with the 'alt' key sequences that KDE passes ** through. alt-home, for example, is presented as ESC ESC '[' 'H' and ** as 'ESC ESC' is not a recognised sequence the function simply passes ** on the data as supplied. ** ** Note: there seem to be some NetBSD escape sequences missing here */ static int32 decode_sequence(void) { int state, newstate; int32 ch; boolean ok; static int32 state2key [] = { /* Maps states 11 to 24 to function key */ KEY_F1, KEY_F2, KEY_F3, KEY_F4, /* [11..[14 */ KEY_F5, KEY_F6, KEY_F7, KEY_F8, /* [15..[19 */ KEY_F9, KEY_F10, KEY_F11, KEY_F12, /* [20..[24 */ SHIFT_F3, SHIFT_F4, SHIFT_F5, SHIFT_F6, /* [25..[29 */ SHIFT_F7, SHIFT_F8, SHIFT_F9, SHIFT_F10 /* [31..[34 */ }; static int statelbno[] = {4, 5, 6, 7, 8, 9}; /* ** The following tables give the next machine state for the character ** input when handling the ESC '[' '1', ESC '[' '2' and ESC '[' '3' ** sequences */ static int state1[] = {11, 12, 13, 14, 15, 0, 16, 17, 18}; /* 1..9 */ static int state2[] = {19, 20, 0, 21, 22, 23, 24, 0, 25, 26}; /* 0..9 */ static int state3[] = {27, 28, 29, 30}; /* 1..4 */ state = 1; /* ESC read */ ok = TRUE; while (ok && waitkey(WAITIME)) { ch = read_key(); switch (state) { case 1: /* ESC read */ if (ch == 'O') /* ESC 'O' */ state = 2; else if (ch == '[') /* ESC '[' */ state = 3; else { /* Bad sequence */ ok = FALSE; } break; case 2: /* ESC 'O' read */ if (ch >= 'P' && ch <= 'S') { /* ESC 'O' 'P'..'S' */ push_key(ch - 'P' + KEY_F1); /* Got NetBSD F1..F4. Map to RISC OS F1..F4 */ return NUL; /* RISC OS first char of key sequence */ } else { /* Not a known key sequence */ ok = FALSE; } break; case 3: /* ESC '[' read */ switch (ch) { case 'A': /* ESC '[' 'A' - cursor up */ push_key(UP); return NUL; case 'B': /* ESC '[' 'B' - cursor down */ push_key(DOWN); return NUL; case 'C': /* ESC '[' 'C' - cursor right */ push_key(RIGHT); return NUL; case 'D': /* ESC '[' 'D' - cursor left */ push_key(LEFT); return NUL; case 'F': /* ESC '[' 'F' - 'End' key */ push_key(END); return NUL; case 'H': /* ESC '[' 'H' - 'Home' key */ return HOME; case '1': case '2': case '3': case '4': case '5': case '6': /* ESC '[' '1'..'6' */ state = statelbno[ch - '1']; break; case '[': /* ESC '[' '[' */ state = 10; break; default: ok = FALSE; } break; case 4: /* ESC '[' '1' read */ if (ch >= '1' && ch <= '9') { /* ESC '[' '1' '1'..'9' */ newstate = state1[ch - '1']; if (newstate == 0) /* Bad character */ ok = FALSE; else { state = newstate; } } else if (ch == '~') /* ESC '[' '1 '~' - 'Home' key */ return HOME; else { ok = FALSE; } break; case 5: /* ESC '[' '2' read */ if (ch >= '0' && ch <= '9') { /* ESC '[' '2' '0'..'9' */ newstate = state2[ch - '0']; if (newstate == 0) /* Bad character */ ok = FALSE; else { state = newstate; } } else if (ch == '~') { /* ESC '[' '2' '~' - 'Insert' key */ push_key(INSERT); return NUL; } else { ok = FALSE; } break; case 6: /* ESC '[' '3' read */ if (ch >= '1' && ch <= '4') { /* ESC '[' '3' '1'..'4' */ newstate = state3[ch - '1']; if (newstate == 0) /* Bad character */ ok = FALSE; else { state = newstate; } } else if (ch == '~') return CTRL_H; /* ESC '[' '3' '~' - 'Del' key */ else { ok = FALSE; } break; case 7: /* ESC '[' '4' read */ if (ch == '~') { /* ESC '[' '4' '~' - 'End' key */ push_key(END); return NUL; } ok = FALSE; break; case 8: /* ESC '[' '5' read */ if (ch == '~') { /* ESC '[' '5' '~' - 'Page up' key */ push_key(PGUP); return NUL; } ok = FALSE; break; case 9: /* ESC '[' '6' read */ if (ch == '~') { /* ESC '[' '6' '~' - 'Page down' key */ push_key(PGDOWN); return NUL; } ok = FALSE; break; case 10: /* ESC '[' '[' read */ if (ch >= 'A' && ch <= 'E') { /* ESC '[' '[' 'A'..'E' - Linux F1..F5 */ push_key(ch - 'A' + KEY_F1); return NUL; } ok = FALSE; break; case 11: case 12: case 13: case 14: /* ESC '[' '1' '1'..'4' */ case 15: case 16: case 17: case 18: /* ESC '[' '1' '5'..'9' */ case 19: case 20: /* ESC '[' '2' '0'..'1' */ case 21: case 22: case 23: case 24: /* ESC '[' '2' '3'..'6' */ case 25: case 26: /* ESC '[' '2' '8'..'9' */ case 27: case 28: case 29: case 30: /* ESC '[' '3' '1'..'4' */ if (ch == '~') { push_key(state2key[state - 11]); return NUL; } ok = FALSE; } } /* ** Incomplete or bad sequence found. If it is bad then 'ok' will be set to ** 'false'. If incomplete, 'ok' will be 'true'. 'ch' will be undefined ** in this case. */ if (!ok) push_key(ch); switch (state) { case 1: /* ESC read */ return ESCAPE; case 2: /* ESC 'O' read */ push_key('O'); return ESCAPE; case 3: /* ESC '[' read */ break; case 4: case 5: case 6: case 7: case 8: case 9: /* ESC '[' '1'..'6' read */ push_key('1' + state - 4); break; case 10: /* ESC '[' '[' read */ push_key('['); break; case 11: case 12: case 13: case 14: case 15: /* ESC '[' '1' '1'..'5' read */ push_key(1 + state - 11); push_key('1'); break; case 16: case 17: case 18: /* ESC '[' '1' '7'..'9' read */ push_key('7' + state - 16); push_key('1'); break; case 19: case 20: /* ESC '[' '2' '0'..'1' read */ push_key('0' + state - 19); push_key('2'); break; case 21: case 22: case 23: case 24: /* ESC '[' '2' '3'..'6' read */ push_key('3' + state - 21); push_key('2'); break; case 25: case 26: /* ESC '[' '2' '8'..'9' read */ push_key('8' + state - 25); push_key('2'); case 27: case 28: case 29: case 30: /* ESC '[' '3' '1'..'4' */ push_key('1' + state - 27); push_key(3); } push_key('['); return ESCAPE; } /* ** 'emulate_get' emulates the Basic function 'get'. It is also the ** input routine used when reading a line from the keyboard */ int32 emulate_get(void) { byte ch; int32 key, fn_keyno; #ifndef USE_SDL int32 errcode; #endif if (basicvars.runflags.inredir) error(ERR_UNSUPPORTED); /* Not reading from the keyboard */ /* * Check if characters are being taken from a function * key string and if so return the next one */ if (fn_string != NIL) return read_fn_string(); if (holdcount > 0) return pop_key(); /* Return character from hold stack if one is present */ #ifdef USE_SDL ch = read_key(); #else errcode = read(keyboard, &ch, 1); if (errcode < 0) { if(errno == EINTR) error(ERR_ESCAPE); /* Assume CTRL-C has been pressed */ error(ERR_BROKEN, __LINE__, "keyboard"); } #endif ch = ch & BYTEMASK; if (ch != ESCAPE) return ch; /* * Either ESC was pressed or it marks the start of an ANSI * escape sequence for a function key, cursor key or somesuch. * Try to make sense of what follows. If function key was * pressed, check to see if there is a function key string * associated with it and return the first character of * the string otherwise return a NUL. (The next character * returned will be the RISC OS key code in this case) */ key = decode_sequence(); if (key != NUL) return key; /* NUL found. Check for function key */ key = pop_key(); fn_keyno = is_fn_key(key); if (fn_keyno == 0) { /* Not a function key - Return NUL then key code */ push_key(key); return NUL; } /* Function key hit. Check if there is a function key string */ if (fn_key[fn_keyno].text == NIL) { /* No string is defined for this key */ push_key(key); return NUL; } /* * There is a function key string. Switch input to string * and return the first character */ return switch_fn_string(fn_keyno); } /* ** 'emulate_inkey' emulates the Basic function 'inkey'. Only the 'timed wait' ** and 'OS version' flavours of the function are supported. ** Note that the behaviour of the RISC OS version of INKEY with a +ve argument ** appears to be undefined if the wait exceeds 32767 centiseconds. */ int32 emulate_inkey(int32 arg) { if (arg >= 0) { /* Timed wait for a key to be hit */ if (basicvars.runflags.inredir) error(ERR_UNSUPPORTED); /* There is no keyboard to read */ if (arg > INKEYMAX) arg = INKEYMAX; /* Wait must be in range 0..32767 centiseconds */ if (waitkey(arg)) return emulate_get(); /* Fetch the key if one is available */ else { return -1; /* Otherwise return -1 to say that nothing arrived in time */ } } else if (arg == -256) /* Return version of operating system */ return OSVERSION; else { /* Check is a specific key is being pressed */ error(ERR_UNSUPPORTED); /* Check for specific key is unsupported */ } return 0; } #endif #if defined(TARGET_DJGPP) | defined(TARGET_WIN32) | defined(TARGET_BCC32) | defined(TARGET_MINGW) /* ----- DJGPP/WIN32/DOS keyboard input functions ----- */ /* ** This table gives the mapping from DOS extended key codes to the RISC OS ** equivalents documented in the PRMs for special keys such as 'insert' ** and the function keys. ** ** Under DOS, the special keys, for example, 'Home', 'Page Up', 'F1' and so ** forth, appear as a two byte sequence where the first byte is an escape ** character and the second denotes the key. The escape character for DJGPP ** is always a null. The LCC-WIN32 version of 'getch' uses the value 0xE0 ** for keys such as 'Home' but zero for the function keys. It also uses zero ** for the 'alt' versions of the keys. Only unshifted, control- or alt- ** versions of the specials keys can be detected by this code */ static byte dostable [] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0xCA, 0x45, 0x46, 0x1E, 0x8F, 0x9F, 0x4A, 0x8C, 0x4C, 0x8D, 0x4E, 0x8B, 0x8E, 0x9E, 0xCD, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xDA, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xEA, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0xAC, 0xAD, 0xAB, 0xBE, 0x1E, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0xBF, 0xCB, 0xCC, 0xDB, 0xDC, 0xEB, 0xEC, 0x8B, 0x8C, 0xAF, 0x8E, 0x8F, 0x90, 0xAE, 0xED, 0x7F, 0x94, 0x95, 0x96, 0x97, 0x98, 0x00, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; #endif #if defined(TARGET_WIN32) | defined(TARGET_BCC32) | defined(TARGET_MINGW) /* ** 'emulate_get' deals with the Basic function 'get' */ int32 emulate_get(void) { int32 ch, fn_keyno; if (basicvars.runflags.inredir) error(ERR_UNSUPPORTED); /* There is no keyboard to read */ /* * Check if characters are being taken from a function * key string and if so return the next one */ if (fn_string != NIL) return read_fn_string(); if (holdcount > 0) return pop_key(); /* Return held character if one is present */ ch = getch(); if (ch == NUL || ch == 0xE0) { /* DOS escape characters */ ch = dostable[getch()]; if (ch == HOME) return HOME; /* Special case - 'Home' is only one byte */ /* Check for RISC OS function key */ fn_keyno = is_fn_key(ch); if (fn_keyno == 0) { /* Not a function key - Return NUL then key code */ push_key(ch); return NUL; } /* Function key hit. Check if there is a function key string */ if (fn_key[fn_keyno].text == NIL) { /* No string is defined for this key */ push_key(ch); return NUL; } /* * There is a function key string. Switch input to string * and return the first character */ return switch_fn_string(fn_keyno); } return ch & BYTEMASK; } /* ** 'emulate_inkey' emulates the Basic function 'inkey'. Only the 'OS ** version' flavour of the function are supported */ int32 emulate_inkey(int32 arg) { if (arg >= 0) { /* Timed wait for a key to be hit */ if (arg > INKEYMAX) arg = INKEYMAX; /* Wait must be in range 0..32767 centiseconds */ error(ERR_UNSUPPORTED); } else if (arg == -256) /* Return version of operating system */ return OSVERSION; else { /* Check is a specific key is being pressed */ error(ERR_UNSUPPORTED); /* Check for specific key is unsupported */ } return 0; } #endif #ifdef TARGET_DJGPP #define EXTENDCHAR 0x100 /* Extended keys have codes >= 0x100 */ /* ** 'emulate_get' deals with the Basic function 'get' */ int32 emulate_get(void) { int32 ch, fn_keyno; if (basicvars.runflags.inredir) error(ERR_UNSUPPORTED); /* There is no keyboard to read */ /* * Check if characters are being taken from a function * key string and if so return the next one */ if (fn_string != NIL) return read_fn_string(); /* * Normal keyboard input */ if (holdcount > 0) return pop_key(); /* Return held character if one is present */ ch = getxkey(); if (ch >= EXTENDCHAR) { /* DOS function key or other extended key */ ch = dostable[ch & BYTEMASK]; if (ch == HOME) return HOME; /* Special case - 'Home' is only one byte */ /* Check for RISC OS function key */ fn_keyno = is_fn_key(ch); if (fn_keyno == 0) { /* Not a function key - Return NUL then key code */ push_key(ch); return NUL; } /* Function key hit. Check if there is a function key string */ if (fn_key[fn_keyno].text == NIL) { /* No string is defined for this key */ push_key(ch); return NUL; } /* * There is a function key string. Switch input to string * and return the first character */ return switch_fn_string(fn_keyno); } return ch & BYTEMASK; } /* ** 'emulate_inkey' emulates the Basic function 'inkey'. Only the 'timed wait' ** and 'OS version' flavours of the function are supported */ int32 emulate_inkey(int32 arg) { if (arg >= 0) { /* Timed wait for a key to be hit */ if (basicvars.runflags.inredir) error(ERR_UNSUPPORTED); /* There is no keyboard to read */ if (arg > INKEYMAX) arg = INKEYMAX; /* Wait must be in the range 0..32767 centiseconds */ if (holdcount > 0) return pop_key(); /* There is a character waiting so return that */ if (kbhit()) return emulate_get(); /* There is an unread key waiting */ while (arg > 0) { /* Wait for 'arg' centiseconds, checking the keyboard every centisecond */ delay(10); /* Wait 10 milliseconds */ if (kbhit()) return emulate_get(); /* Return a key if one is now available */ arg--; } return -1; /* Timeout - Return -1 to indicate that nothing was read */ } else if (arg == -256) /* Return version of operating system */ return OSVERSION; else { /* Check is a specific key is being pressed */ error(ERR_UNSUPPORTED); /* Check for specific key is unsupported */ } return 0; } #endif #ifdef TARGET_BEOS int32 emulate_get(void) { error(ERR_UNSUPPORTED); return 0; } int32 emulate_inkey(int32 arg) { error(ERR_UNSUPPORTED); return 0; } #endif #ifdef TARGET_AMIGA #ifndef __AMIGADATE__ #define __AMIGADATE__ "("__DATE__")" #endif const char *VERsion = "$VER: Brandy 1.19 "__AMIGADATE__" $"; #ifdef __SASC long __stack = 67000; /* ** 'read_key' reads the next character from the keyboard */ int32 read_key(void) { byte ch; ch = getchar(); /* if (errno == EINTR) error(ERR_ESCAPE); / * Assume Ctrl-C was pressed */ return ch; } int32 emulate_get(void) { /* error(ERR_UNSUPPORTED);*/ return read_key(); } int32 emulate_inkey(int32 arg) { error(ERR_UNSUPPORTED); return 0; } boolean init_keyboard(void) { rawcon(1); return TRUE; } void end_keyboard(void) { rawcon(0); } #endif #endif /* ** 'display' outputs the given character 'count' times ** special case for VDU_CURBACK because it doesn't ** work if echo is off */ static void display(int32 what, int32 count) { if ( what != VDU_CURBACK) echo_off(); while (count > 0) { emulate_vdu(what); count--; } if ( what != VDU_CURBACK) echo_on(); } /* ** 'remove_history' removes entries from the command history buffer. ** The first 'count' entries are deleted. The function also takes ** care of updating 'highbuffer' and 'histindex' */ static void remove_history(int count) { int n, freed; freed = 0; for (n = 0; n < count; n++) freed+=histlength[n]; if (count < histindex) { /* Not deleting everything - Move entries down */ memmove(histbuffer, &histbuffer[freed], highbuffer-freed); for (n = count; n < histindex; n++) histlength[n-count] = histlength[n]; } highbuffer-=freed; histindex-=count; } /* ** 'add_history' adds an entry to the command history buffer. ** The new command is added to the end of the buffer. If there is not ** enough room for it, one or more commands are removed from the front ** of the buffer to make space for it. Also, if the maximum number of ** entries has been reached, an entry is dropped off the front of the ** buffer. ** 'cmdlen' is the length of the command. It does not include the NULL ** at the end */ static void add_history(char command[], int32 cmdlen) { int32 wanted, n, freed; if (highbuffer+cmdlen >= HISTSIZE) { /* There is not enough room at the end of the buffer */ wanted = highbuffer+cmdlen-HISTSIZE+1; /* +1 for the NULL at the end of the command */ /* ** Figure out how many commands have to be removed from the buffer to make ** room for the new one. Scan from the start of the history list adding up ** the lengths of the commands in the history buffer until the total equals ** or exceeds the number of characters required. Entries from 0 to n-1 have ** to be deleted. */ freed = 0; n = 0; do { freed += histlength[n]; n++; } while (n < histindex && freed < wanted); remove_history(n); } else if (histindex == MAXHIST) { /* History list is full */ remove_history(1); /* Delete the first entry */ } memmove(&histbuffer[highbuffer], command, cmdlen+1); histlength[histindex] = cmdlen+1; highbuffer += cmdlen+1; histindex += 1; } static void init_recall(void) { recalline = histindex; } static void recall_histline(char buffer[], int updown) { int n, start, count; if (updown < 0) { /* Move backwards in history list */ if (recalline == 0) return; /* Already at start of list */ recalline -= 1; } else { /* Move forwards in history list */ if (recalline == histindex) return; /* Already at end of list */ recalline += 1; } if (recalline == histindex) /* Moved to last line */ buffer[0] = NUL; else { start = 0; for (n = 0; n < recalline; n++) start += histlength[n]; strcpy(buffer, &histbuffer[start]); } display(VDU_CURBACK, place); /* Move cursor to start of old line */ place = strlen(buffer); if (place > 0) emulate_vdustr(buffer, place); count = highplace - place; /* Find difference in old and new line lengths */ if (count > 0) { /* Some of the old line is still visible */ display(' ', count); display(VDU_CURBACK, count); } highplace = place; } /* ** 'shift_down' moves all the characters in the buffer down by one ** overwriting the character at 'offset'. It also redraws the line on ** the screen, leaving the cursor at the postion of 'offset' */ static void shift_down(char buffer[], int32 offset) { int32 count; count = highplace-offset; /* Number of characters by which to move cursor */ highplace--; echo_off(); while (offset < highplace) { buffer[offset] = buffer[offset+1]; emulate_vdu(buffer[offset]); offset++; } emulate_vdu(DEL); echo_on(); display(VDU_CURBACK, count); /* Move cursor back to correct position */ } /* ** 'shift_up' moves the text from 'offset' along by one character to ** make room for a new character, rewriting the line on the screen as ** well. It leaves the cursor at the screen position for the new ** character. The calling routine has to check that there is room ** for another character */ static void shift_up(char buffer[], int32 offset) { int32 n; if (offset == highplace) return; /* Appending char to end of line */ n = highplace; while (n >= offset+1) { buffer[n] = buffer[n-1]; n--; } echo_off(); emulate_vdu(DEL); /* Where new character goes on screen */ n = offset+1; while (n <= highplace) { emulate_vdu(buffer[n]); n++; } echo_on(); while (n > offset) { /* Put cursor back where it should be */ emulate_vdu(VDU_CURBACK); n--; } highplace++; /* Bump up 'last character' index */ } /* ** 'emulate_readline' reads a line from the keyboard. It returns 'true' ** if the call worked successfully or 'false' if 'escape' was pressed. ** The data input is stored at 'buffer'. Up to 'length'-1 characters ** can be read. A 'null' is added after the last character. 'buffer' ** can be prefilled with characters if required to allow existing text ** to be edited. ** ** This function uses only the most basic facilities of the underlying ** OS to carry out its task (which counts as everything under DOS) so ** much of this code is ugly. ** ** The function provides both DOS and Unix style line editing facilities, ** for example, both 'HOME' and control 'A' move the cursor to the start ** of the line. It is also possible to recall the last line entered. ** ** There is a problem with LCC-WIN32 running under Windows 98 in that the ** extended key codes for the cursor movement keys (insert, left arrow ** and so on) are not returned correctly by 'getch()'. In theory they ** should appear as a two byte sequence of 0xE0 followed by the key code. ** Only the 0xE0 is returned. This appears to be a bug in the C runtime ** library. */ readstate emulate_readline(char buffer[], int32 length) { int32 ch, lastplace; if (basicvars.runflags.inredir) { /* There is no keyboard to read - Read fron file stdin */ char *p; p = fgets(buffer, length, stdin); if (p == NIL) { /* Call failed */ if (ferror(stdin)) error(ERR_READFAIL); /* I/O error occured on stdin */ buffer[0] = NUL; /* End of file */ return READ_EOF; } return READ_OK; } highplace = strlen(buffer); if (highplace > 0) emulate_vdustr(buffer, highplace); place = highplace; lastplace = length-2; /* Index of last position that can be used in buffer */ init_recall(); do { ch = emulate_get(); watch_signals(); /* Let asynchronous signals catch up */ if ((ch == ESCAPE) || basicvars.escape) return READ_ESC; /* Check if the escape key has been pressed and bail out if it has */ switch (ch) { /* Normal keys */ case CR: case LF: /* End of line */ emulate_vdu('\r'); emulate_vdu('\n'); buffer[highplace] = NUL; if (highplace > 0) add_history(buffer, highplace); break; case CTRL_H: case DEL: /* Delete character to left of cursor */ if (place > 0) { emulate_vdu(VDU_CURBACK); place--; shift_down(buffer, place); } break; case CTRL_D: /* Delete character under the cursor */ if (place < highplace) shift_down(buffer, place); break; case CTRL_K: /* Delete from cursor position to end of line */ display(DEL, highplace-place); /* Clears characters after cursor */ display(VDU_CURBACK, highplace-place); /* Now move cursor back */ highplace = place; break; case CTRL_U: /* Delete whole input line */ display(VDU_CURBACK, place); /* Move cursor to start of line */ display(DEL, highplace); /* Overwrite text with blanks */ display(VDU_CURBACK, highplace); /* Move cursor back to start of line */ highplace = place = 0; break; case CTRL_B: /* Move cursor left */ if (place > 0) { emulate_vdu(VDU_CURBACK); place--; } break; case CTRL_F: /* Move cursor right */ if (place < highplace) { emulate_vdu(buffer[place]); /* It does the job */ place++; } break; case CTRL_P: /* Move backwards one entry in the history list */ recall_histline(buffer, -1); break; case CTRL_N: /* Move forwards one entry in the history list */ recall_histline(buffer, 1); break; case CTRL_A: /* Move cursor to start of line */ display(VDU_CURBACK, place); place = 0; break; case CTRL_E: /* Move cursor to end of line */ echo_off(); while (place < highplace) { emulate_vdu(buffer[place]); /* It does the job */ place++; } echo_on(); break; case HOME: /* Move cursor to start of line */ display(VDU_CURBACK, place); place = 0; break; case NUL: /* Function or special key follows */ ch = emulate_get(); /* Fetch the key details */ switch (ch) { case END: /* Move cursor to end of line */ echo_off(); while (place < highplace) { emulate_vdu(buffer[place]); /* It does the job */ place++; } echo_on(); break; case UP: /* Move backwards one entry in the history list */ recall_histline(buffer, -1); break; case DOWN: /* Move forwards one entry in the history list */ recall_histline(buffer, 1); break; case LEFT: /* Move cursor left */ if (place > 0) { emulate_vdu(VDU_CURBACK); place--; } break; case RIGHT: /* Move cursor right */ if (place < highplace) { emulate_vdu(buffer[place]); /* It does the job */ place++; } break; case DELETE: /* Delete character at the cursor */ if (place < highplace) shift_down(buffer, place); break; case INSERT: /* Toggle between 'insert' and 'overwrite' mode */ enable_insert = !enable_insert; set_cursor(enable_insert); /* Change cursor if in graphics mode */ break; default: emulate_vdu(VDU_BEEP); /* Bad character - Ring the bell */ } break; default: if (ch < ' ' && ch != TAB) /* Reject any other control character except tab */ emulate_vdu(VDU_BEEP); else if (highplace == lastplace) /* No room left in buffer */ emulate_vdu(VDU_BEEP); else { /* Add character to buffer */ if (enable_insert) shift_up(buffer, place); buffer[place] = ch; emulate_vdu(ch); place++; if (place > highplace) highplace = place; } } } while (ch != CR && ch != LF); return READ_OK; } /* Initialise keyboard emulation */ #if defined(TARGET_WIN32) | defined(TARGET_BCC32) | defined(TARGET_MINGW) boolean init_keyboard(void) { int n; for (n = 0; n < FN_KEY_COUNT; n++) fn_key[n].text = NIL; fn_string_count = 0; fn_string = NIL; holdcount = 0; histindex = 0; highbuffer = 0; enable_insert = TRUE; set_cursor(enable_insert); return TRUE; } void end_keyboard(void) { } #elif defined(TARGET_DJGPP) /* ** 'init_keyboard' initialises the keyboard code and checks if ** stdin is connected to the keyboard or not. If it is then the ** keyboard code uses BDOS-level keyboard function to read the ** individual keys. If stdin is not connected to the keyboard ** then standard C functions are used instead. The assumption ** here is that stdin is most likely taking input from a file. */ boolean init_keyboard(void) { struct termios tty; int errcode, keyboard, n; for (n = 0; n < FN_KEY_COUNT; n++) fn_key[n].text = NIL; fn_string_count = 0; fn_string = NIL; holdcount = 0; histindex = 0; highbuffer = 0; enable_insert = TRUE; set_cursor(enable_insert); /* ** Check to see if stdin is attached to a keyboard */ keyboard = fileno(stdin); errcode = tcgetattr(keyboard, &tty); if (errcode == 0) return TRUE; /* Keyboard being used */ /* ** tcgetattr() returned an error. If the error is ENOTTY then ** stdin does not point at a keyboard and so the program does ** simple reads from stdin rather than use the custom keyboard ** code. If the error is not ENOTTY then something has gone ** wrong so we abort the program */ if (errno != ENOTTY) return FALSE; /* tcgetattr() returned an error we cannot handle */ basicvars.runflags.inredir = TRUE; /* tcgetattr() returned ENOTTY - Use normal C functions to read input */ return TRUE; } void end_keyboard(void) { } #elif defined(TARGET_LINUX) | defined(TARGET_NETBSD) | defined(TARGET_MACOSX)\ | defined(TARGET_FREEBSD) | defined(TARGET_OPENBSD) | defined(TARGET_AMIGA) & defined(__GNUC__)\ | defined(TARGET_GNUKFREEBSD) | defined(TARGET_GNU) /* ** 'init_keyboard' initialises the keyboard code. It checks to ** see if stdin is connected to a keyboard. If it is then the ** function changes stdin to use unbuffered I/O so that the ** individual key presses can be read. This is not done if ** stdin is pointing elsewhere as it is assumed that input is ** most likely being taken from a file. */ boolean init_keyboard(void) { struct termios tty; int n, errcode; for (n = 0; n < FN_KEY_COUNT; n++) fn_key[n].text = NIL; fn_string_count = 0; fn_string = NIL; holdcount = 0; histindex = 0; highbuffer = 0; enable_insert = TRUE; set_cursor(enable_insert); /* ** Set up keyboard for unbuffered I/O */ keyboard = fileno(stdin); errcode = tcgetattr(keyboard, &tty); if (errcode < 0) { /* Could not obtain keyboard parameters */ if (errno != ENOTTY) return FALSE; /* tcgetattr() returned an error we cannot handle */ /* ** The error returned by tcgetattr() was ENOTTY (not a typewriter). ** This says that stdin is not associated with a keyboard. The ** most probable cause is that input is being taken from a file. ** Input is therefore read using fgets() instead of a character ** at a time using read(). This means that the command line editor ** and history facilities as well as functions like GET and INKEY ** will not be available but if input truly is from a file then ** this will not be a problem. */ basicvars.runflags.inredir = TRUE; return TRUE; } origtty = tty; /* Preserve original settings for later */ #ifdef TARGET_LINUX tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH); #else tty.c_lflag &= ~(ECHONL|NOFLSH); #endif tty.c_lflag &= ~(ICANON|ECHO); tty.c_iflag &= ~(ICRNL|INLCR); tty.c_cflag |= CREAD; tty.c_cc[VTIME] = 1; tty.c_cc[VMIN] = 1; errcode = tcsetattr(keyboard, TCSADRAIN, &tty); if (errcode < 0) return FALSE; /* Could not set up keyboard in the way desired */ return TRUE; } void end_keyboard(void) { (void) tcsetattr(keyboard, TCSADRAIN, &origtty); } #endif #endif brandy-1.20/src/emulate.c0000644000175000017500000007665612161325744014325 0ustar colincolin/* ** This file is part of the Brandy Basic V Interpreter. ** Copyright (C) 2000, 2001, 2002, 2003, 2004 David Daniels ** ** Brandy is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2, or (at your option) ** any later version. ** ** Brandy is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Brandy; see the file COPYING. If not, write to ** the Free Software Foundation, 59 Temple Place - Suite 330, ** Boston, MA 02111-1307, USA. ** ** ** This is one the files that contains functions that emulate ** some features of RISC OS such as the VDU drivers. The others ** are fileio.c, keyboard.c, textonly.c, textgraph.c and ** riscos.c All OS-specific items should be put in these files. ** ** Some of the functions provided in here are not supported on ** any operating system other than RISC OS and in general using ** any of these in a program will result in an error. However, ** some of the features are cosmetic in that they do materially ** affect how the program runs, for example, the colours on the ** screen. There is a command line option, -ignore, that will ** allow the use of these features to be silently ignored rather ** than flagging them and bringing the program to a halt. The ** results might not look pretty but the program will run. */ /* ** Crispian Daniels August 20th 2002: ** Included Mac OS X target in conditional compilation. */ #include #include #include #include #include #include #include "common.h" #include "target.h" #include "errors.h" #include "basicdefs.h" #include "emulate.h" #include "screen.h" #include "keyboard.h" #ifdef TARGET_RISCOS #include "kernel.h" #include "swis.h" #endif #ifdef TARGET_DJGPP #include "dos.h" #endif #if defined(TARGET_UNIX) || defined(TARGET_MACOSX) #include #include #include #endif #ifdef USE_SDL void sdlchar(char); #endif /* Address range used to identify emulated calls to the BBC Micro MOS */ #define LOW_MOS 0xFFCE #define HIGH_MOS 0xFFF7 /* Emulated BBC MOS calls */ #define BBC_OSWRCH 0xFFEE #define BBC_OSBYTE 0xFFF4 static time_t startime; /* Adjustment subtracted in 'TIME' */ /* =================================================================== */ /* ======= Emulation functions common to all operating systems ======= */ /* =================================================================== */ /* ** 'emulate_mos' provides an emulation of some of the BBC Micro ** MOS calls emulated by the Acorn interpreter */ static int32 emulate_mos(int32 address) { int32 areg, xreg; areg = basicvars.staticvars[A_PERCENT].varentry.varinteger; xreg = basicvars.staticvars[X_PERCENT].varentry.varinteger; switch (address) { case BBC_OSBYTE: /* Emulate OSBYTE 0 */ if (areg==0 && xreg!=0) return MACTYPE; /* OSBYTE 0 - Return machine type */ error(ERR_UNSUPPORTED); break; case BBC_OSWRCH: /* Emulate OSWRCH - Output a character */ emulate_vdu(areg); return areg; break; default: error(ERR_UNSUPPORTED); } return 0; } /* ** 'emulate_call' deals with the Basic 'CALL' statement. This is ** unsupported except to provide limited support for the BBC MOS ** calls supported by the Acorn interpreter */ void emulate_call(int32 address, int32 parmcount, int32 parameters []) { if (parmcount==0 && address>=LOW_MOS && address<=HIGH_MOS) emulate_mos(address); else { error(ERR_UNSUPPORTED); } } /* ** 'emulate_usr' deals with the Basic function 'USR'. It ** provides some limited support for the BBC MOS calls ** emulated by USR in the Acorn interpreter (where the ** called address is in the range 0xFFF4 to 0xFFC5) */ int32 emulate_usr(int32 address) { if (address>=LOW_MOS && address<=HIGH_MOS) return emulate_mos(address); error(ERR_UNSUPPORTED); return 0; } /* =================================================================== */ /* ================== RISC OS versions of functions ================== */ /* =================================================================== */ #ifdef TARGET_RISCOS /* OS_Word and OS_Byte calls used */ #define WRITE_PALETTE 12 /* OS_Word call number to set palette entry */ #define CONTROL_MOUSE 21 /* OS_Word call number to control the mouse pointer */ #define SELECT_MOUSE 106 /* OS_Byte call number to select a mouse pointer */ #define XBIT 0x20000 /* Mask for 'X' bit in SWI numbers */ /* Processor flag bits used in emulate_sys() */ #define OVERFLOW_FLAG 1 #define CARRY_FLAG 2 #define ZERO_FLAG 4 #define NEGATIVE_FLAG 8 /* ** 'emulate_time' is called to deal with the Basic pseudo-variable ** 'TIME' to return its current value. Under RISC OS, the C function ** 'clock' returns the current value of the centisecond clock, which ** is just what we want */ int32 emulate_time(void) { return clock()-startime; } /* ** 'emulate_setime' handles assignments to the Basic pseudo variable 'TIME'. ** As adjusting 'TIME' is frowned upon the code emulates the effects ** of doing this */ void emulate_setime(int32 time) { startime = clock()-time; } /* ** 'emulate_setimedol' is called to handle assignments to the Basic ** pseudo variable 'TIME$'. This is used to set the computer's clock. ** It does not seem to be worth the effort of parsing the string, nor ** does it seem worth rejecting the assignment so this code just ** quietly ignores it */ void emulate_setimedol(char *time) { } /* ** 'emulate_mouse_on' turns on the mouse pointer */ void emulate_mouse_on(int32 pointer) { (void) _kernel_osbyte(SELECT_MOUSE, 1, 0); /* R1 = 1 = select mouse pointer 1 */ } /* ** 'emulate_mouse_off' turns off the mouse pointer */ void emulate_mouse_off(void) { (void) _kernel_osbyte(SELECT_MOUSE, 0, 0); /* R1 = 0 = do not show the mouse pointer */ } /* ** 'emulate_mouse_to' moves the mouse pointer to position (x,y) on the screen */ void emulate_mouse_to(int32 x, int32 y) { struct {byte call_number, x_lsb, x_msb, y_lsb, y_msb;} osword_parms; osword_parms.call_number = 3; /* OS_Word 21 call 3 sets the mouse position */ osword_parms.x_lsb = x & BYTEMASK; osword_parms.x_msb = x>>BYTESHIFT; osword_parms.y_lsb = y & BYTEMASK; osword_parms.y_msb = y>>BYTESHIFT; (void) _kernel_osword(CONTROL_MOUSE, TOINTADDR(&osword_parms)); } /* ** 'emulate_mouse_step' defines the mouse movement multipliers */ void emulate_mouse_step(int32 xmult, int32 ymult) { struct {byte call_number, xmult, ymult;} osword_parms; osword_parms.call_number = 2; /* OS_Word 21 call 2 defines the mouse movement multipliers */ osword_parms.xmult = xmult; osword_parms.ymult = ymult; (void) _kernel_osword(CONTROL_MOUSE, TOINTADDR(&osword_parms)); } /* ** 'emulate_mouse_colour' sets one of the colours used for the mouse pointer */ void emulate_mouse_colour(int32 colour, int32 red, int32 green, int32 blue) { struct {byte ptrcol, mode, red, green, blue;} osword_parms; osword_parms.ptrcol = colour; osword_parms.mode = 25; /* Setting mouse pointer colour */ osword_parms.red = red; osword_parms.green = green; osword_parms.blue = blue; (void) _kernel_osword(WRITE_PALETTE, TOINTADDR(&osword_parms)); } /* ** 'emulate_mouse_rectangle' defines the mouse bounding box */ void emulate_mouse_rectangle(int32 left, int32 bottom, int32 right, int32 top) { struct { byte call_number, left_lsb, left_msb, bottom_lsb, bottom_msb, right_lsb, right_msb, top_lsb, top_msb; } osword_parms; osword_parms.call_number = 1; /* OS_Word 21 call 1 defines the mouse bounding box */ osword_parms.left_lsb = left & BYTEMASK; /* Why didn't Acorn provide a nice, clean SWI */ osword_parms.left_msb = left>>BYTESHIFT; /* for this call? */ osword_parms.bottom_lsb = bottom & BYTEMASK; osword_parms.bottom_msb = bottom>>BYTESHIFT; osword_parms.right_lsb = right & BYTEMASK; osword_parms.right_msb = right>>BYTESHIFT; osword_parms.top_lsb = top & BYTEMASK; osword_parms.top_msb = top>>BYTESHIFT; (void) _kernel_osword(CONTROL_MOUSE, TOINTADDR(&osword_parms)); } /* ** 'emulate_mouse' returns the current position of the mouse */ void emulate_mouse(int32 values[]) { _kernel_oserror *oserror; _kernel_swi_regs regs; oserror = _kernel_swi(OS_Mouse, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); values[0] = regs.r[0]; /* Mouse X coordinate is in R0 */ values[1] = regs.r[1]; /* Mouse Y coordinate is in R1 */ values[2] = regs.r[2]; /* Mouse button state is in R2 */ values[3] = regs.r[3]; /* Timestamp is in R3 */ } /* ** 'emulate_adval' emulates the Basic function 'ADVAL' which returns ** either the number of entries free in buffer 'x' or the current ** value of the A/D convertor depending on whether x<0 (free entries) ** or x>=0 (A/D convertor reading) */ int32 emulate_adval(int32 x) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = 128; /* Use OS_Byte 128 for this */ regs.r[1] = x; oserror = _kernel_swi(OS_Byte, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); return regs.r[1]+(regs.r[2]<errmess); } /* ** 'emulate_sound_off' handles the Basic 'SOUND OFF' statement */ void emulate_sound_off(void) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = 1; /* Turn off the sound system */ oserror = _kernel_swi(Sound_Enable, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); } /* ** 'emulate_sound' handles the Basic 'SOUND' statement. ** Note that this code ignores the 'delay' parameter */ void emulate_sound(int32 channel, int32 amplitude, int32 pitch, int32 duration, int32 delay) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = channel; regs.r[1] = amplitude; regs.r[2] = pitch; regs.r[3] = duration; oserror = _kernel_swi(Sound_Enable, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); } /* ** 'emulate_beats' emulates the Basic statement 'BEATS' */ void emulate_beats(int32 barlength) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = barlength; oserror = _kernel_swi(Sound_QBeat, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); } /* ** 'emulate_beatfn' emulates the Basic functions 'BEAT' and 'BEATS', both ** of which appear to return the same information */ int32 emulate_beatfn(void) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = 0; oserror = _kernel_swi(Sound_QBeat, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); return regs.r[0]; } /* ** 'emulate_tempo' emulates the Basic statement 'TEMPO' */ void emulate_tempo(int32 x) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = x; oserror = _kernel_swi(Sound_QTempo, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); } /* ** 'emulate_tempofn' emulates the Basic function 'TEMPO' */ int32 emulate_tempofn(void) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = 0; oserror = _kernel_swi(Sound_QTempo, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); return regs.r[0]; } /* **'emulate_voice' attaches the voice named to a voice channel */ void emulate_voice(int32 channel, char *name) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = channel; regs.r[1] = TOINT(name); oserror = _kernel_swi(Sound_AttachNamedVoice, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); } /* ** 'emulate_voices' handles the Basic statement 'VOICES' which ** is define to set the number of voice channels to be used */ void emulate_voices(int32 count) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = count; /* Number of voice channels to usse */ regs.r[1] = 0; regs.r[2] = 0; regs.r[3] = 0; regs.r[4] = 0; oserror = _kernel_swi(Sound_Configure, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); } void emulate_stereo(int32 channel, int32 position) { _kernel_oserror *oserror; _kernel_swi_regs regs; regs.r[0] = channel; regs.r[1] = position; oserror = _kernel_swi(Sound_Stereo, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); } /* ** 'read_monotonic' returns the current value of the monotonic ** timer */ static int32 read_monotonic(void) { _kernel_oserror *oserror; _kernel_swi_regs regs; oserror = _kernel_swi(OS_ReadMonotonicTime, ®s, ®s); if (oserror!=NIL) error(ERR_CMDFAIL, oserror->errmess); return regs.r[0]; /* Value of timer is returned in R0 */ } /* ** 'emulate_waitdelay' emulate the Basic statement 'WAIT