;*******************************************************************************
; Title:	CmndBASIC
; Author:	Paul Clifford
; Copyright:	(C) Paul Clifford 2001
;		Converted to ObjAsm source code by Philip Ludlam
; Version:	0.06, 23 February 2003
;
;*******************************************************************************
; 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 APARTICULAR 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
;
;*******************************************************************************


		TTL	> CmndBASIC

		GET	OSLib:oslib.hdr.OS
		GET	OSLib:oslib.hdr.OSModule
		GET	AsmLib2:hdr.Regs
		GET	AsmLib2:hdr.Macros


program_block_size	*	&1000

match			*	&0
program			*	&4
position		*	&8
line_number		*	&C
command			*	&10
workspace		*	0

command_start		*	command + 13
command_end		*	command_start + 9


		AREA	|!!!Module$$Header|, CODE, READONLY

		ENTRY

		DCD	application
		DCD	initialise
		DCD	finalise
		DCD	0
		DCD	title
		DCD	help
		DCD	commands
		DCD	0
		DCD	0
		DCD	0
		DCD	0
		DCD	0
		DCD	flags

BASIC_entry	DOSIGNATURE
		ADD	r1, lr, #72
		STR	r1, [r0, #match]
		MOV	pc, lr

BASIC_program
		; The "TokenAddr" program, which calls the BASIC_entry code above (module
		; start + 52) to extract the address of the MATCH routine

		; When decoded it is:
		; SYS30,18,"CommandBASIC"TO,,,B%,A%:CALLB%+52
		; (SYS 30 is a call to OS_Module)
		DCD	&2a0a000d
		DCD	&303399c8
		DCD	&2c38312c
		DCD	&6d6f4322
		DCD	&646e616d
		DCD	&49534142
		DCD	&2cb82243
		DCD	&25422c2c
		DCD	&3a25412c
		DCD	&2b2542d6
		DCD	&ff0d3235
BASIC_program_end

flags
		DCD	1				; 32-bit compatible.

title
		DCB	"CommandBASIC"
		DCB	0
help
		DCB	"CommandBASIC\t0.06 (23 February 2003)  Paul Clifford"
		DCB	0
		ALIGN

application	DOSIGNATURE
		LDR	r12, [r12, #0]
		ADD	r0, r12, #command
		SWI	XOS_CLI
		SWI	OS_Exit

initialise	DOSIGNATURE
		STMFD	r13!, {r7-r11, lr}
		MOV	r0, #6
		MOV	r3, #workspace
		ADD	r3, r3, #&30
		SWI	XOS_Module
		LDMVSFD r13!, {r7-r11, pc}
		STR	r2, [r12, #0]
		MOV	r12, r2

					; Initialise the workspace variables
		MOV	r0, #0
		STR	r0, [r12, #program]
		STR	r0, [r12, #position]
		STR	r0, [r12, #line_number]

					; Setup the command buffer to call the
					; BASIC initialisation code
		ADR	r0, BASIC_quit
		LDMIA	r0, {r2-r4}
		ADD	r1, r12, #command
		STMIA	r1!, {r2-r4}
		MOV	r0, #"@"
		STR	r0, [r1], #1
		ADR	r0, BASIC_program
		MOV	r2, #9
		SWI	XOS_ConvertHex8
		BVS	initialise_error
		MOV	r0, #","
		STRB	r0, [r1], #1
		ADR	r0, BASIC_program_end
		MOV	r2, #9
		SWI	XOS_ConvertHex8
		LDMVCFD r13!, {r7-r11, pc}

initialise_error	DOSIGNATURE
		MOV	r7, r0
		MOV	r0, #7
		MOV	r2, r12
		SWI	XOS_Module
		MOV	r0, r7
		SetV
		LDMFD	r13!, {r7-r11, lr}

BASIC_quit	DOSIGNATURE
		DCB	"BASIC -quit "
		;	"@000"
		;	"0000"
		;	"0,00"
		;	"0000"
		;	"00.."

finalise	DOSIGNATURE
		STMFD	r13!, {r7-r11, lr}
		LDR	r12, [r12, #0]
		LDR	r2, [r12, #program]
		MOV	r0, #7
		CMP	r2, #0
		SWINE	OS_Module
		MOV	r2, r12
		SWI	OS_Module
		ClearV
		LDMFD	r13!, {r7-r11, pc}

commands	DOSIGNATURE
		DCB	"[", 0
		ALIGN
		DCD	command_line
		DCD	0 + (255 << 16)
		DCD	syntax_line
		DCD	help_line

		DCB	"]", 0
		ALIGN
		DCD	command_run
		DCD	0 + (255 << 16)
		DCD	syntax_run
		DCD	help_run

		DCD	0

help_line
		DCB	"*[ tokenises and adds a BASIC statement to memory."
		DCB	13

syntax_line
		DCB	"Syntax: *[ [line of BASIC]"
		DCB	0

help_run
		DCB	"*] executes the program after optionally adding a final statement."
		DCB	13

syntax_run
		DCB	"Syntax: *] [line of BASIC]"
		DCB	0
		ALIGN

command_line	DOSIGNATURE
		LDR	r12, [r12, #0]
		TEQ	r1, #0
		MOVEQ	pc, lr

command_line_entry	DOSIGNATURE
		STMFD	r13!, {r0, r7-r11, lr}
		LDR	r2, [r12, #program]
		CMP	r2, #0
		BNE	command_line_check_space
		MOV	r0, #6
		MOV	r3, #program_block_size
		SWI	XOS_Module
		ADDVS	r13, r13, #4
		LDMVSFD r13!, {r7-r11, pc}
		STR	r2, [r12, #program]

command_line_check_space	DOSIGNATURE
		LDR	r0, [r2, #-4]	; size of block
		LDR	r1, [r12, #position]
		SUB	r0, r0, r1
		CMP	r0, #260 + 4 ; + 4 to leave room for the &ff end byte
		BGE	command_line_tokenise
		MOV	r0, #13
		MOV	r3, #program_block_size
		SWI	XOS_Module
		ADDVS	r13, r13, #4
		LDMVSFD r13!, {r7-r11, pc}
		STR	r2, [r12, #program]

command_line_tokenise	DOSIGNATURE
		LDR	r1, [r13, #0]
		MOV	r0, r1

command_line_find_terminator	DOSIGNATURE
		LDRB	r2, [r0], #1
		CMP	r2, #32
		BGE	command_line_find_terminator
		MOV	r2, #13
		STRB	r2, [r0, #-1]
		BL	tokenise_string
		LDMFD	r13!, {r0, r7-r11, pc}

command_run	DOSIGNATURE
		STMFD	r13!, {r7-r11, lr}
		LDR	r12, [r12, #0]
		CMP	r1, #0
		BLGT	command_line_entry		; enters line (if any)
							; Got a program to run?
		LDR	r0, [r12, #program]
		CMP	r0, #0
		LDMEQFD r13!, {r7-r11, pc}
							; Calculate end address
		LDR	r8, [r12, #position]
		ADD	r8, r0, r8
		ADD	r8, r8, #1
							; Mark the end of the program
							; (and increase the end address)
		MOV	r1, #255
		STRB	r1, [r8], #1
							; Reset the write position and
							; line number for the next use
		MOV	r1, #0
		STR	r1, [r12, #position]
		STR	r1, [r12, #line_number]
							; Build the appropriate
							; "BASIC -quit ..." command
		ADD	r1, r12, #command_start
		MOV	r2, #9
		SWI	OS_ConvertHex8
		MOV	r0, #","
		STRB	r0, [r1, #0]
		MOV	r0, r8
		ADD	r1, r12, #command_end
		MOV	r2, #9
		SWI	OS_ConvertHex8
							; Jump into our application
							; entry point
		MOV	r0, #2
		ADR	r1, title
		SWI	XOS_Module
							; If it goes wrong...
		MOV	r8, r0
		MOV	r0, #7
		LDR	r2, [r12, #program]
		SWI	XOS_Module
		MOVVC	r2, #0
		STRVC	r2, [r12, #program]
		MOV	r0, r8
		SetV
		LDMFD	r13!, {r7-r11, lr}

tokenise_string	DOSIGNATURE
						; r1 = string to be tokenised
		STMFD	r13!, {r0-r5, lr}
		LDR	r2, [r12, #program]
		LDR	r6, [r12, #position]
		ADD	r6, r2, r6
		MOV	r2, #13
		STRB	r2, [r6, #0]
		LDR	r2, [r12, #line_number]
		ADD	r2, r2, #1
		STR	r2, [r12, #line_number]
		STRB	r2, [r6, #2]
		MOV	r2, r2, lsr #8
		STRB	r2, [r6, #1]
		ADD	r2, r6, #4
		MOV	r3, #0
		MOV	r4, #0
		MOV	lr, pc
		LDR	pc, [r12, #match]
		SUB	r2, r2, r6
		SUB	r2, r2, #1
		LDR	r0, [r12, #position]
		ADD	r0, r0, r2
		STR	r0, [r12, #position]
		STRB	r2, [r6, #3]
		LDMFD	r13!, {r0-r5, pc}

licence		DCB	" PC, 2003. Licence: GPL."
		ALIGN

		END
