What CPU is BASIC running on
Sometimes a program needs to know what CPU the BASIC program is running on, for example if it needs to know the CPC-specific layout of the memory, such as where BASIC's string buffer is.
This is different from knowing what machine a program is running on which can be found with OSBYTE 0 and INKEY-256. 6502 BASIC II could be running on RISC OS via 65Tube, ARM BASIC V could be running on a BBC B via the ARM CoProcessor. In each of these cases, OSBYTE 0 or INKEY-256 would not give the answer looked for.
It is a bit fiddly to easily determine the CPU, several tests have to be done over-riding earlier tests.
A%=0:X%=1:os%=((USR&FFF4)AND&FF00)DIV256:cpu%=0:A%=-1 IF os%=32:IF HIMEM>&FFFF:cpu%=86 IF HIMEM>&FFFF:IF PAGE>&8000:IF PAGE<&FFFF:cpu%=44 IF PAGE<&20000:IF HIMEM<&20001:DIM A%-1:!A%=0:P%=A%:[OPT 0:NOP:]:A%=!A% IF A%=&EA:cpu%=65 ELSE IF A%=&00:cpu%=80 ELSE IF A%=&12:cpu%=09 IF A%=&A0:cpu%=11 ELSE IF A%=&90:cpu%=86
This leaves cpu% set to a value representing the CPU the BASIC is running on:
65 - 6502 or 65816 80 - Z80 44 - ARM 86 - 80x86 11 - PDP11 9 - 6809
It fails to give a correct result on the 32016 or 68000.
Almost all versions of BBC BASIC include an inline assembler. A simple test is to assemble a NOP instruction and see what opcode is output.
DIM A% -1 :REM Use the top of the heap P%=A% :REM Point assembler to the top of the heap !A%=0 :REM Clear to zero [OPT 0 \ Turn off assembler listing, must include a space NOP \ Assemble a NOP ] :REM End of assembly A%=!A% :REM Fetch the opcode output
This can be crunched to the following:
Unfortunately, some BBC BASICs don't have an assembler (32016 and 68000) and some don't recognise the NOP mnemonic (most versions of ARM). A% will be set to the following:
6502 &EA 65816 &EA Z80 &00 6809 &12 PDP11 &A0 80x86 &90 32016 error 68000 error ARM error or &E1A00000
Testing BASIC's memory limits can be a partial test for the CPU that BASIC is running on. It is a simple way to determine if BASIC is running in a 16-bit memory map, as all of BASIC's memory pointers will be in the first 64K of memory.
This isn't infallible, as Bas128 runs in main memory and puts the BASIC memory space in sideways RAM between virtual addresses &10000 and &20000, and 65816 BASIC has the program in the first 64K of memory, but variables in extended memory starting at &10000.
CPU Possible values for PAGE LOMEM HIMEM 6502 &0800-&F700 &0800-&F7FF &0800-&F800 6502 Bas128 &10000 &10000-&1FFFF &20000 65816 &0800-&FF00 &0800-&FFFFFF &0800-&FFFFFF Z80 &0100-&FF00 &0100-&FFFF &0100-&FF00 6809 &0100-&FF00 &0100-&FFFF &0100-&FF00 PDP11 &0100-&FF00 &0100-&FFFF &0100-&FF00 80x86 small &0900-&FF00 &0100-&FFFF &0900-&10000 80x86 large &0900-&FFFFFF &0100-&FFFFFF &0900-&FFFFFF 32016 &4000-&FFFFFF &4000-&FFFFFF &4000-&FFFFFF 68000 &0E00-&FFFFFF &0E00-&FFFFFF &0E00-&FFFFFF ARM &8000-&FFFFFF &8000-&FFFFFF &8000-&FFFFFF Windows &100000-&FFFFFF &100000-&FFFFFF &100000-&FFFFFF
Jump block entries
On some platforms the MOS entry block at &FFxx can be examined to see what JUMP opcodes the system is using, and from this determine the CPU being used.
6502/65816 ?&FFF7=&6C 6502/65816 ?&FFF7=&4C Z80 ?&FFF7=&C3 6809 ?&FFF7=&7E PDP11 ?&FFF7=&26 PDP11 within Unix stack frame 80x86 within program memory 32016 within program memory 68000 within program memory ARM within program memory
Jgh 23:33, 21 December 2013 (GMT)