; > Startup ; BBC BASIC for the pdp11 ; (C)J.G.Harston 1988, 1989, 2005, 2006 ; Program header and BASIC startup, etc. ; 24-May-2006 v0.10 Added skeleton error handler ; 28-Jan-2008 v0.11 ; This source uses the 'ADR label,dst' pseudo-opcode ; The assembler needs to expand this into: ; MOV pc,dst // ADD #label-$,dst ORG 0 ; Position independant code EQUW &0107 ; Magic number &o000407, also branch to Startup EQUW CodeEnd-Startup ; size of text EQUW &0000 ; size of initialised data EQUW BasicEnd-CodeEnd ; size of uninitialised data EQUW &0000 ; size of symbol data EQUW &0000 ; entry point EQUW &0000 ; not used EQUW &0001 ; no relocation info ; ORG 0 ; Position independant code .Startup ; On entry, R0-R5=0, SP=>stack, R7=Startup ; Environment: R7=>Bottom of memory ; R6=>Top of memory ; When run on Unix, ; R6=>pointers to command line parameter strings, ; terminated with 0 ; parameter strings ; When run in BBC environment, ; R5=&0BBC ; ; Normally, header will not have been loaded ; and memory will be mapped so Startup=&0000 ; ; Loader clears system variables. This means that ; CALL Startup does not replicate running the code. ; For CALL Startup (CALL 0) to re-enter BASIC as ; though run from disk, Startup needs to clear system ; variables, as done by the system loader. ; ;ADR SV_VARS,r0 ; r0=>start of system variable area ;MOV #(SV_SIZE-2)/2,r1 ; Size of system variable area ;MOV #&090A,(r0)+ ; @%=&90A ; Loader clears data area ;.StartClear ;MOV #&0000,(r0)+ ; Clear system variable area ;DEC r1 ; Clears all resident and dynamic variables ;BNE StartClear ; r0=bottom of memory ;ADR BasicEnd,r0 ; r0=bottom of memory ;MOV sp,r1 ; r1=top of memory jsr PC,IO_Init ; Initialise I/O, find memory limits mov r0,SV_MEMBOT ; Initialise bottom of memory mov r0,SV_PAGE ; Put initial PAGE at bottom of memory mov #&FF0D,(r0) ; 'NEW' the program add #2,r0 mov r0,SV_TOP ; TOP=end of empty program mov r0,SV_LOMEM ; LOMEM=TOP mov r0,SV_VAREND ; VAREND=TOP mov r1,SV_MEMTOP ; Initialise top of memory mov r1,SV_HIMEM ; Put initial HIMEM at top of memory mov r1,SV_STACK ; Clear BASIC's stack mov r1,sp ; Put stack at top of memory mov #&090A,SV_VARS ; @%=&90A adr StartupCopyright-1,r0 ; Get location of (C) message mov r0,SV_FAULT ; Point REPORT to it movb #&FF,SV_OPTIONS ; Set options to &FF jsr pc,IO_CommandLine ; any command line params? eg filename beq StartupNull ; LEN(filename)=0, quiet startup jmp ChainStartup ; Jump to do CHAIN "filename" .StartupNull jsr pc,PrintInline ; .StartupMessage EQUS "PDP11 BBC BASIC IV Version 0.12 [Integer only]",13 .StartupCopyright EQUS "(C) Copyright J.G.Harston 1989,2005-2008",13 EQUB 0 ALIGN ; ; Immediate mode ; -------------- .Immediate clr SV_AUTO ; Clear AUTO line .ImmediateLoop mov SV_HIMEM,SP ; Put system stack at top of memory jsr pc,IO_AckEsc ; Ack. any pending Escape mov #ASC">",r0 jsr pc,IO_WRCH ; print ">" prompt clr SV_ONERR ; Cancel ON ERROR mov SV_AUTO,SV_LINE ; Get current line to AUTO line beq ImmNotAuto ; No AUTO line mov r0,-(sp) jsr pc,PrintLineNumber ; Output r0 as line number mov (sp),r0 mov SV_STEP,r1 ; Get AUTO STEP bic #&FF00,r1 ; Ensure 8-bit value add r1,r0 ; Add STEP to AUTO line bcs errTooBig ; Run out of line numbers mov r0,SV_AUTO ; Store updated AUTO line mov #ASC" ",r0 jsr pc,IO_WRCH ; Print a space .ImmNotAuto ADR SV_STRING,r1 ; Point to string buffer JSR PC,IO_ReadLine ; Read a line of input clrb SV_COUNT ; Zero COUNT adr SV_STRING,r5 ; Point to string buffer ;;jsr pc,ReadLineNumber ; r4=line number (CC) or zero (CS) ;;bcs ImmNoLineNum ; No line number entered ;;mov r4,SV_LINE ; Set current input line number .ImmNoLineNum ; r5=>start or line or after line number ; Tokenise entered line ; --------------------- adr SV_INPUT,r4 ; r4=>dest in input buffer jsr pc,Tokenise ; Tokenise from r5 to r4 ; On exit, r0,r1,r2,r3=corrupted, r4=>dest , r5=>source inc r4 ; Step past movb #&FF,(r4) ; Put &FF after ; ; nb, need line length later on ; ;adr SV_INPUT,r5 ;jsr pc,Debug_DumpLine ; mov SV_LINE,r0 ; Get line number bne ImmLineNum ; Line number, enter line adr SV_INPUT,r5 ; Point BASIC pointer to line jmp Execute ; No line number, execute line ; .ImmLineNum ; jsr pc,PrintInline equs "Insert line",13,0 align ; ; save various registers ;jsr pc,FindTOP ; Check for Bad Program ;jsr pc,LineFind ; Find where to put line number ;bne ImmLineEnter ;jsr pc,LineDelete ; Delete existing line ;.ImmLineEnter ; restore various registers ;beq ImmediateLoop ; No line to enter, jump back for another ;add #4,r2 ; r2=line length++++ ; Check if enough room ; insert space for new line ; insert new line ;jsr pc,SetTOP ; Put program terminator at end br ImmediateLoop ; Go back for another line .errTooBig jsr pc,Error equb 20,"Too big",0 align