Z80CONV and Z80TAIL Version 1.26 ================================ J.G.Harston - jgh@mdfs.net 70 Camm Street, Walkley, Sheffield S6 3TR http://mdfs.net/BBCBasic/Z80Basic Introduction ============ Z80Conv and Z80Tail are conversion programs to modify BBC BASIC on the Acorn Z80 second processor to use the standard BBC file I/O instead of CP/M. They also allow Z80 BBC BASIC to be blown into an EPROM. These programs are for the Acorn Z80 second processor 1.20 and Richard Russell's Z80 BBC BASIC version 2.20. There is a rarely-encountered Z80 second processor ROM version 2.00. The conversion has not been tested on this. Z80 BBC BASIC is copyright Richard Russell (http://www.rtrussell.co.uk). Richard has given permission for Z80 BBC BASIC to be freely distributed, as long as he is acknowledged. Consequently, this distribution includes BBC BASIC (Z80) for the Z80 Tube running CP/M and the converted Z80 BBC BASIC for the Z80 Tube using BBC I/O. You can use the file Z80ROM straight away by loading it into a sideways ROM bank or blowing it into an EPROM and plugging it into your machine. The full original CPMTube distribution is available at http://mdfs.net/Software/BBCBasic/CPMTube.zip Conversion ========== To convert an Acorn Z80 CoProcessor CP/M version of Z80 BBC BASIC, you have to do the following: * Copy Z80CONV and Z80TAIL onto a blank non-CPM disk (eg DFS). * Turn on your Z80 and boot up CP/M. * Enter Z80 BBC BASIC by running BBCBASIC.COM. * Using RDACORN.BBC, load Z80CONV and save it on a CP/M disk. * LOAD the Z80CONV.BBC program. * Now take out the CP/M disk, and place the non-CPM disk in the drive. * Enter RUN to run the Z80CONV.BBC program. This will modify the BASIC interpreter in memory and create a ROM header. These will be saved in two files to disk, Z80BAS and Z80R1. (The file Z80BAS can be run from disk as a CPM .COM file.) * Turn off your Z80 and press CTRL-Break. * CHAIN the Z80TAIL program. This will create the 6502 part of the ROM including the disassembly routine, saving them in a file Z80R2. It then loads in all three files, joining them together and creating a fourth file, Z80ROM. This is the ROM image containing Z80 BBC BASIC modified to use normal BBC file I/O. You now have a ROM image Z80ROM which can be loaded into sideways RAM or blown into an EPROM and installed permanently in your machine. Also included with Z80CONV and Z80TAIL are D1, showing how to call the disassembler, D2, which lists all the Z80 functions, and MONITOR, a simple disassembler program. Changes in Z80 BBC BASIC ======================== This is a complete list of all the features in the modified Z80 BBC BASIC. Modified commands ----------------- LOAD, CHAIN Loads the file into memory with OSFILE &FF, and then changes it to Z80 format. It checks if file begins with a CR byte, as a BASIC file should have, and doesn't convert it if it doesn't. SAVE If there is sufficient space between the top of the variable space and the bottom of the stack, then a modified copy of the program is created in 6502 format, and then saved with OSFILE &00. Otherwise, first, if the filing system number returned by OSARGS &00,&00 is larger than 3, indicating not TAPE or ROM, then a dummy file is saved of sufficient length for the program, to ensure no 'Can't Extend' errors. Then the program is saved to disk using OPENOUT and BPUT, rearranging the order of the bytes of the program as they are sent to save it in 6502 format. The saved file has load address &FFFFFB00 and execution address &FFFF0000. This means it will be recognised as file-typed as a BASIC file by RISC OS. SAVE with no filename will use a filename after a '>' in a REM statement in the first line of the program, eg 10 REM >Prog1. OPENIN Uses OSFIND &40 to open a file for input. OPENOUT Uses OSFIND &80 to open a file for output. OPENUP Uses OSFIND &C0 to open a file for update. CLOSE Uses OSFIND &00 to close a file. =PTR#n Uses OSARGS 0 to read the file pointer. PTR#n= Uses OSARGS 1 to set the file pointer. =EXT#n Uses OSARGS 2 to read the file extent. =EOF#n Uses OSBYTE &7F to read the end-of-file status. BGET Uses OSBGET to read a byte from a file. BPUT Uses OSBPUT to write a byte to a file. INPUT# Uses OSBGET to read the bytes from the file, and reorders them into the Z80 format. PRINT# Uses OSBPUT to write the bytes to the file, reordered into the 6502 format. OSCLI and * commands Sends directly to OSCLI. INPUT No longer outputs a space after the question mark. This makes it the same as 6502 BBC BASIC. END No longer closes files when a program ends, or an error occurs, or an END command executed. RESTORE When an error occurs in 6502 BBC BASIC, the DATA pointer is restored. In Z80 BBC BASIC, the data pointer is not restored. A RESTORE statement should be included in error handlers if needed. New commands/functions ---------------------- TIME$= Sends a text string to OSWORD &0F to set a real-time clock, if supported. =TIME$ Requests a text string using OSWORD &0E,0 to read a real-time clock. If no string is returned, then =TIME$ returns a null string. EXT#n=v Uses OSARGS 3 to write the file extent on complying filing systems. =REPORT$ Returns the string of the last error message. =END Returns the address of the end of the variable storage. This is the same as the following function: DEFFNend:LOCAL A%:DIM A%-1:=A% Memory Locations ---------------- Zero page memory locations &0040 to &00FF are available to the user. This means that you can stick to the range &0070 to &008F to be compatible with programs running in the 6502 environment for such things as calling operating system calls, eg: !&70=USR &FFF4 On entry to BASIC, any command line parameter to the *BASIC command is stored at &0081-&00FF with &0080 holding the string length. This can be fetched with: ?(&81+?&80)=13:cmd$=$&81 If the command *Basic BinToHex code hexdmp is used, then cmd$ will be set to "BinToHex code hexdmp". &F010-&F27F can be used for transient Z80 code *commands. Such transient code must not have a ROM header, or it will become the current foreground application. When calling OSARGS from the 6502, Y% holds zero or the channel number for the operation, and X% holds an offset to a zero page location for the data. When calling from the Z80, X% and Y% are put into HL to point to the memory area, and E% holds the channel number. This is all ok, as for most of the OSARGS calls, you would use the build-in functions and commands PTR and EXT. However, the calls which have the channel number set to zero (Y% in 6502, E% in Z80) have to be done manually. The most common of these is finding out the filing system number, OSARGS 0,0. To do this, the following should be used: DEFFNfs:LOCAL A%,E%,Y%:=USR&FFDA AND&FF The LOCAL statement sets A%, E% and Y% all to zero. This will work in both Z80 and 6502 environments. In the 6502, the channel in in Y%, and E% is ignored, and in the Z80, the channel is in E%, and with this call Y% is ignored. Similarly, with the zero channel calls that return information in memory, the zero page locations should be used, with E% and Y% set to zero, and X% pointing to the location, as in the following function to read the free space on an HADFS disk: DEFFNfree_space:LOCAL A%,E%,X%,Y%,!&70 A%=5:E%=0:X%=&70:Y%=0:A%=USR&FFDA AND&FF IF A%<>5 THEN =!&70 ELSE =0 From the 6502, Y% is set to 0 to indicate a zero channel operation, and X% always refers to a zero page location. From the Z80, E% is set to 0 to indicate a zero channel operation, and Y% set to zero makes X% point to a zero page location. Identifying Program Environment ------------------------------- When using BBC BASIC it is useful to determine what environment the program is running in as different environments may have different filename conventions and different I/O capabilities, etc. The BASIC interpreter type can be tested with ?(TOP-3). This will return 0 for Richard Russell Z80/80x86/SDL BASIC and non-zero otherwise. This allows a program to modify its behaviour, for instance: IF ?(TOP-3)=0 THEN REPORT ELSE PRINT:REPORT If the program knows it is running Z80 BBC BASIC, the environment can be determined by examining and using the BDOS call at location &0005. If ?&0005=&C3 (a JP opcode), then the program is running in a CP/M environment or the BBC I/O environment. Otherwise it is running in another Z80 environment, such as the NC100 or Z88. If ?5=&C3, then call 5 with C%=12, L%=0 and H%=0 to read the CP/M version number. If the returned value is zero, then Z80 BBC BASIC is running in a BBC I/O environment, else it is running in a CP/M environment. The BBC I/O host environment is found by calling OSBYTE 0 as usual with A%=0:X%=1:os%=(USR&FFF4) AND &FF00) DIV 256. Modifications to the Z80 Tube MOS ================================= The OSWORD length tables are modified so that OSWORD &0E and OSWORD &0F work correctly. The OSCLI call uses a temporary stack. Previously, when selecting a language, the user's stack was overwritten, so preventing correct execution. OSBYTE &84, to read the top of memory returns the value in &0006/&0007, which points to the top of memory. If a *command causes machine code to be entered, if the code does not have a ROM header the Z80 Tube MOS enters it with the stack is unbalanced, and a POP is needed before returning otherwise a crash will occur. When BBC BASIC is running, code is entered with the stack balanced. The code can tell how it has been called by checking the Zero flag. If the stack is unbalanced, the zero flag is clear (NZ); if it is balanced, the zero flag is set (Z). If code needs to be able to run in either case it should start with the following two instructions: JR Z,P%+3:POP AF:\ Balance stack Code that starts with a ROM header is entered correctly. Note that this applies to the v1.20 Z80 Tube MOS code. The v2.00 Z80 Tube MOS enters raw code with the stack balanced, but still with the flags set to NZ. To be compatible with the v2.00 Z80 Tube MOS a better test is needed. Two bytes of zero page are used as a PCtoHL routine to provide a LD HL,PC instruction and a HLtoPC routine to provide a CALL (HL) instruction. These are &000E and &000F, and are used in the following way from assembly language: 10 REM Outside the assembler 20 PCtoHL=&E:HLtoPC=&F : 100 [ 110 \ Enter the assembler : 150 CALL PCtoHL :\ LD HL,PC 160 .label :\ HL will have the value of this label : 200 LD HL,routine 210 CALL HLtoPC :\ CALL (HL) PCtoHL allows routines to know where in memory they are executing, and so can make writing relocatable routines easier. HLtoPC allows the calling of routines with calculated addresses without having to set up a return address on the stack beforehand. The actual routine at &000E is the following: 000E E1 POP HL :\ Get return address 000F E9 JP (HL) :\ Jump to return address and can be recreated with: LD HL,&E9E1 LD (&E),HL Routines provided in the ROM image ================================== Language selection ------------------ On reset, the Z80 BBC BASIC ROM checks if the Tube is active, and examines the coprocessor to see if it is a Z80. If it is, then it removes the 'language' bit from the ROM type table for all ROMs that do not contain Z80 code, indicated by the bottom nybble being 8. This means that no non-Z80 ROMs can be entered as a language when the Z80 BBC BASIC ROM is present and the Z80 second processor is turned on. Also, the *FX189 value which contains the ROM number of the ROM selected by the *BASIC command is changed to &80+ROM number so the Z80 BBC BASIC ROM can intercept it, but you can still find which ROM contains BASIC. You can append a filename to the *BASIC command to CHAIN that file on entry, eg: *BASIC Menu1 You can also place a single option on the command line which is ignored, eg: *BASIC -quit Menu1 Any parameters after any option are copied to &80-&FF so the CHAINed BASIC program can fetch them. With the Z80 second processor turned off, Z80 BBC BASIC is disabled as a language and non-Z80 language ROMs are left alone. If the Z80 BBC BASIC ROM is selected as a language (eg with *FX142) when in a 6502 environment (ie the Z80 is turned off), then a warning is printed and another language entered, usually 6502 BBC BASIC. OSWORD 190 - Disassembly routine -------------------------------- Z80 BBC BASIC, as all versions of BBC BASIC, contains an in-line assembler for the processor that it runs on. To complement this, in the spare space at the end of the ROM are the disassembly routines for the Z80 and 8080/8085 processors from the DisAssembly ROM. The disassembly is in standard Zilog mnemonics, the 8080/8085 is also in Zilog mnemonics, not the deeply nasty Intel mnemonics. To call the disassembly routine, use the following OSWORD call: On entry: A=190, XY points to control block: Control block XY+0 &10 - Length of entry control block XY+1 &20 - Length of exit control block XY+2 Processor number XY+3 Flag (default zero) XY+4 \ XY+5 \ Address of instruction XY+6 / XY+7 / XY+8 \ XY+9 \ Bytes of instruction to be XY+10 / disassembled XY+11/ On exit: A,X,Y may be corrupted. Control block XY+0 XY+1 XY+2 Disassembly status flag XY+3 Number of bytes disassembled XY+4 Text string of disassembled instruction, : terminated by a CR (value 13). : XY+31 Maximum length of string 28 characters. You send the routine the address of the disassembly, and also the four bytes that are at that address for it to disassemble. This simplifies the routine so that it does not have to attempt to read the bytes directly from memory itself. In the returned control block, XY+3 contains the actual number of bytes disassembled, and so is the value by which to increase the address pointer to disassemble the next instruction. The status byte at XY+2 holds flags about the disassembly, the top bit always being used to indicate if the instructions could be disassembled or not. If b7=0, it was a valid instruction. If b7=1, it could not be disassembled, and the returned text string is the processor's equivalent of "EQUB &nn". If b6=1 the disassembled instruction is the end of a routine such as an unconditional jump. The bottom six bits are used by different disassembly routines for different purposes. In the entry control block, XY+2 holds the processor control number. Numbers allocated so far are: 0 reserved 44 ARM 2 6502 48 80486 8 8008 58 80586 9 8009 65 6502/65C02/6512 11 pdp11 68 68x00 series 12 65C12 80 Z80, Zilog mnemonics 18 80186 85 8080/8085, Zilog mnemonics 28 80286 86 80x86 series 30 oggin 89 INS8900 32 32016 94 9440 series 38 80386 99 9900 A simple disassembly program would be the following: 10 REM Disassembly test program 1 20 REM By J.G.Harston 30 DIM ctrl% 32:X%=ctrl%:Y%=X% DIV 256 40 INPUT "Address: &"A$:Addr%=EVAL("&"+A$) 50 A%=190:REPEAT 60 !X%=&2010:X%?2=80 :REM Z80 70 X%!4=Addr% :REM Address 80 X%!8=!Addr% :REM Data at the address 90 CALL &FFF1 100 PRINT;~Addr%;" "; 110 FOR Z%=Addr% TO Addr%-1+X%?3 120 PRINT;~?Z%;" ";:NEXT 130 PRINTTAB(20);$(X%+4) 140 IF (X%?2 AND 64) THEN PRINT 150 Addr%=Addr%+X%?3 160 UNTIL0 The Z80 disassembly routine (type number 80) returns the following information in the status byte: b7 could not be disassembled b6 instruction is unconditional RET, JP or JR. b5-b2 unused, zero b1 Instruction not on the 8080/8085 b0 Unofficial instruction The Z80 disassembly routine recognises the unofficial instructions using the index registers as 8-bit register pairs, labelling them IXL, IXH, IYL and IYH, and the Shift Left and Set instructions CB30 to CB38. The 8080/8085 disassembly routine (type number 85) returns the following information in the status byte: b7 could not be disassembled b6 instruction is unconditional RET or JP b5-b0 unused, zero When calling from the Z80, the XY address is held in the HL register. Calling from BBC BASIC, this is transparent, as you still use X% and Y% anyway. OSBYTE 90 - General ------------------- All the ROMs that I write conform to my ROM selection standard that allows interrogation of the ROMs in a uniform manner. This is the OSBYTE 90 call, used to enable and disable the ROM, and to ask for status information about it. The arrangement of the OSBYTE 90 call is: On entry: A=90 X=ID number, or zero Y=call number On exit: A=90 X=b7-b6 ROM status, b5-b0 other specific info. Y=other info. All ROMs respond to X=0, Y=0 on entry (*FX90,0 or just *FX90) by displaying their ID number and their name, eg: >*FX90 6: Harston ADFS 9: Z80 BASIC With X set to non-zero, it is a specific call to a particular ROM, with Y containing the call number. All ROMs respond to calls with Y=0 to enable the ROM, Y=1 to disable to ROM and Y=255 to request the ROM's status, eg: >*FX90,9,1 will disable the ROM with program ID 9, ie Z80 BASIC. On return from calls 0, 1 and 255, the top two bits of X hold information about whether the ROM is present, and whether it is enabled or not. Bit 7 holds if the ROM is enabled or disabled, and bit 6 holds if the ROM is actually present of not. This is summarised as: X=11xxxxxx ROM not present X=10xxxxxx ROM present, but disabled X=0yxxxxxx ROM present and enabled If the ROM is enabled (ie bit 7 is zero), then it must also be present, so bit 6 is an implied zero. This allows bit 6 to be used to return information on other things. The other six bits of X can be used to return specific information about the ROM. The top two bits of X hold the status of the ROM before the call, so if the ROM is disabled, and you enable it with Y=0, then X will return %10xxxxxx. When calling from a second processor using the OSBYTE call, the Y register is ignored and zero is used instead for calls below OSBYTE &80. This means that if you use a call with Y=255 to read the status, and it returns saying that the ROM was disabled, the ROM will actually have been enabled, because Y=0 has been used instead. To get round this, use something like: A%=90:X%=number:Y%=255:S%=(USR&FFF4 AND&FF00)DIV256 IF (S% AND &C0)=&80 THEN OSCLI "FX90,"+STR$(number)+",1" This will re-disable a ROM found to be actually disabled. Some of the program IDs that I have used so far are: 1: CharROM - character set ROM 2: NewMOS 3: 4: 5: Games Auto Boot ROM 6: HADFS - Harston Advanced Disk Filing System 7: Z80 Emulator - Emulates a Z80 CPU 8: 9: Z80 BASIC - Z80 BBC BASIC with BBC file I/O 10: 11: Dissem ROM - Various disassembly routines 16: NFS Front end If anyone else wants to adhere to this method for a ROM that they are writing, write to me, and I will assign you a number and give you the routine I use for service call 7 to provide the OSBYTE 90 call. OSBYTE 90 - in Z80 BBC BASIC ---------------------------- Z80 BBC BASIC has program ID 9, and by default, the ROM is enabled. To disable it, you can use *FX90,9,1. You cannot use OSBYTE 90 with X%=9 and Y%=1 from the second processor because the low numbered calls do not pass the Y parameter, and instead substitute a 0, so you must use the *FX call. *FX90,9,0 is used to enable the ROM. The ROM will re-enable itself on a power-on reset or a memory-clear reset. The bottom six bits of X are used by Z80 BBC BASIC when it starts up to see if it is a Break selection or a *BASIC selection. After Z80 BBC BASIC is started, the bottom six bits of X do not hold anything valid. When called from the I/O processor, Y is returned holding the ROM number of Z80 BBC BASIC. From the Z80, the X and Y values are taken from the L and H registers, respectively. When making a call to the MOS routines at &FFxx, H and L are set from Y% and X%, respectively. History ======= 01-03-2009 1.26 Reset checks for second processor type after Tube startup, so works with ARM CoPro. 29-03-2006 1.25 LOAD no longer depends on the returned length from OSFILE. 23-11-2003 1.24 Spare space within code compacted to help with Spectrum converson. 14-07-1997 1.23 Variable names rewritten, program reordered in code order. 15-04-1997 1.22 Filing calls use common external control block, EXT#= added. 03-03-1997 1.21 Tidyer coding structure. Language only enabled if Z80 coprocessor. Runs on Master better. 27-02-1997 1.20 Module-compliant ROM header. *BASIC works again, calls OSGBPB &80. 23-02-1997 1.19 Errors don't do CLOSE#0. *BASIC no longer works - provides OSGBPB &80, but calls OSGBPB &09. 16-06-1993 1.18 LOAD checks for non-BASIC. &F000 set to: RET:RET:RET:JP &FFB9:DEFB &E8:DEFB 0:DEFB 3:DEFM "BASIC":DEFB 0:DEFB 0 23-05-1991 1.17 PRINT# corrected. 16-04-1991 1.?? *BASIC can take a filename. Provides OSGBPB &09 to pass command line to language. BASICROM set to &FF to pass *BASIC command direct to ROM. Version number in *HELP message. ??-??-1991 1.?? Disables non-Z80 languages if CoPro present. If entered as 6502 code, dispays warning and selects an alternative ROM. Sets BASICROM to &FF. ??-??-1990 1.00 BBC BASIC uses BBC I/O. ROM code provides disassembly routines. No version number in *HELP list. Sets BASICROM number, entered with MOS's *BASIC command. &000E/F set. Calls OSGBPB &09 on startup to find command line. &F000 set to: JP &FFB9:JP &FFB9:DEFB &E8:DEFB 0:DEFB 3:DEFM "BASIC":DEFB 0:DEFB 0 Acorn Z80 Tube MOS Entry Points =============================== As well as the standard MOS entry points which are documented in Appendix J and the CP/M manual, and listed in the Z80 BBC BASIC manual, there exists some other very useful entry points. This is a complete list of them. Most of them should really only be called from Z80 assembly language, and not from BASIC. ESCFLG &FF80 Escape flag TERMFLG &FF81 TERM flag FAULT &FF82 Fault pointer DEF_ERR &FF84 Address of default error handler PR_OUT &FF9E Print a character to OSWRCH or TERMOUT On entry: A = character to be printed On exit: with TERM set to OSWRCH: all registers preserved. with TERM set to TERMOUT: C is corrupted HL is corrupted after sending ESC &3F (clear to end of screen) or ESC &40 (clear to end of line) Calling this routine either calls the OSWRCH code, or the TERMOUT code, depending on the setting of TERM. Altering TERM alters the address field of this entry to point to the required code. When TERM is set to TERMOUT, the following ESCape sequences are obeyed: ESC, &3D ('='), Y, X move cursor to X-32,Y-32 ESC, &3E ('>'), C, C ... 0 print characters C-32, until C=0 ESC, &3F ('?') clear to end of screen ESC, &40 ('@') clear to end of line Any other ESC, char sequence is ignored. ESC ? and ESC @ only work correctly in 80 column screen modes INIT_FF &FFA1 Set up OSWORD &FF in host On entry: - On exit: HL, DE, B, A are corrupted Calling this routine sets up the code to handle OSWORD &FF (block transfer) in the host processor. It is called by the TUBE OS on startup, and should not be called again, as then the vector daisy-chaining will end in a loop. The Z80 BBC BASIC ROM initialisation removes this call by putting a RET opcode at location &FFA1. M_OSWD_7F &FFA4 Multiple OSWORD &7F call On entry: HL points to the OSWORD &7F control block On exit: A holds the result byte from (HL+10). A=0 means ok. B, C, DE are corrupted. This routine tries to access a disk drive. The call is made up to 40 times before giving up and returning with the failure result byte in A. Every ten unsuccessful attempts, the routine tries to seek to track zero, sector zero on the drive being accessed, before continuing to attempt to access the drive. If the routine succeeds, then zero is returned in the A register, otherwise A holds the disk error number. LD_CCP &FFA7 Load CCP and BDOS On entry: - On exit: A holds zero if successful. BC, DE, HL are corrupted. This routine is called to reload the CCP. The default routine loads the Acorn CP/M CCP and BDOS from the disk in drive zero, using the code of the multiple OSWORD &7F call detailed above. If a disk error occurs, the error 'Disk fault', number 0 is generated. The memory loaded is: Track 0, sectors 8 and 9 loaded to &D400 to &D5FF Track 1, sectors 0 to 9 loaded to &D600 to &DFFF Track 2, sectors 0 to 9 loaded to &E000 to &E9FF In effect, the routine loads sectors 0/8 to 2/9 to memory &D400 to &E9FF. The Acorn BIOS calls this on a soft CPM reset to reload the CCP. PR_HEX &FFAA Print A in hex On entry: A = value to be printed On exit: A is corrupted This routine prints out the A register in hexadecimal to two digits and leading zeros. This routine is overwritten by the Acorn BIOS in CPM. PR2HEX &FFAD Print HL in hex On entry: HL = value to be printed On exit: A is corrupted This routine prints out the HL register in hexadecmial to four digits and leading zeros. This routine is overwritten by the Acorn BIOS in CPM. USERINT &FFB0 User interupt routine On entry: - On exit: - This call is made if an unrecognised interupt occurs. By default it just points to a RET instruction. Any routine that intercepts this call MUST preserve ALL registers. PR_TEXT &FFB3 Print in-line text On entry: - On exit: - This routine prints out the text following the call to OSASCI. The text should be terminated with a zero byte, which also gets printed, eg: CALL PR_TEXT DEFM "HELLO THERE":NOP \ continue here This routine is overwritten by the Acorn BIOS in CPM. PRNT_C &FFB6 Send C to TERMOUT On entry: C = character to be printed On exit: A is corrupted HL is corrupted after sending ESC &3F and ESC &40 Calling this routine prints the character in the C register using TERMOUT. See the description of PR_OUT at address &FF9E. CLI_COM &FFB9 Enter CLI processor No entry parameters No exit from call Calling this routine enters the CLI processor. This presents a '*' prompt and sends all input to OSCLI. RST_38 &FFBC Default error jump On entry: - On exit: - The default error jump code to initialise locations &0038 to &003A with. Enters the default error handler which displays the error message and then enters the CLI processor. INIT_ERR &FFBF Initialise default error code On entry: - On exit: - Copies the default error jump code at &FFBC to locations &0038 to &003A. SEEK_0 &FFC2 Seek track zero On entry: A=drive? On exit: - Temporarily sets SP to &FF80 and does an OSWORD &7F to seek track zero of drive 0. KBD_TST &FFC5 Reads status of keyboard input On entry: - On exit: A holds &00 if no characters pending A holds &FF if there are input characters pending This routine tests if there are any characters waiting to be read, either in the input buffer, or from a soft key expansion. A returns &00 if there are no characters pending, or &FF if there are. TERM &FFC8 Read or set the TERM status On entry: A read or set parameter On exit: A holds the old TERM status, or preserved if invalid parameter HL is corrupted, or preserved if A holds an invalid parameter The calls sets whether the PR_OUT routine at address &FF9E calls OSWRCH or TERM_OUT. The entry values for A are: A=0 Set PR_OUT to do OSWRCH A=1 Set PR_OUT to do TERM_OUT A=&FF Read current setting If A does not hold one of these values, then the routine does nothing. OSWRD2 &FFCB Do an OSWORD call, reading the control block to DE On entry: A is the OSWORD call number HL points to the control block DE points to where to receive the returned control block On exit: - This call does a standard OSWORD call, but the returned control block is put into the memory pointed to by DE. The following entry points are the standard BBC entries: OSFIND &FFCE Open or close a file OSGBPB &FFD1 Multiple byte file access OSBPUT &FFD4 Put a byte to a file OSBGET &FFD7 Get a byte from a file OSARGS &FFDA Read or set file arguments OSFILE &FFDD Load or save file OSRDCH &FFE0 Input a character OSASCI &FFE3 Print a character, with CR converted to LF,CR OSNEWL &FFE7 Print a LF,CR sequence OSWRCH &FFEE Print a character OSWORD &FFF1 Do an OSWORD call OSBYTE &FFF4 Do an OSBYTE call OSCLI &FFF7 Interpret a command The following three addresses hold system vectors: BRKV &FFFA Address of error handler EVENTV &FFFC Address of event handler INTV &FFFE Address of primary interupt handler Entry points into BBC BASIC =========================== BBC BASIC has some entry points at its start in page 1 (as with many other Z80 programs). This is a full list of them. &100 Startup. &103 Return to command entry prompt - do END. &106 Give 'Escape' error. &109 Report error. A=err num, text follows the call. &10C Print inline text after call (same as PR_TEXT). &10F Print text from HL until 0 byte. &112 Check program and set TOP. &115 Clear variables - do CLEAR. &118 Execute program in memory - do RUN. &11B Do OSCLI of string pointed to by HL. &11E Read a byte from a file - do A=BGET#H. &121 Write a byte to a file - do BPUT#H,A. &124 Check EOF of a file - do Z=EOF#E. &127 Close all files - do CLOSE#0.