What CPU is BASIC running on

From BeebWiki
Jump to: navigation, search

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.

Assembler

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:

 DIMA%-1:P%=A%:!A%=0:[OPT 0:NOP:]:A%=!A%:REM IFA%<0:A%=P%?-1

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

Memory limits

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 or ?&FFF7=&4C
 Z80         ?&FFF7=&C3
 6809        ?&FFF7=&7E
 PDP11       ?&FFF7=&26 or within Unix stack frame
 80x86       within program memory
 32016       within program memory
 68000       within program memory
 ARM         within program memory

See also

WikiSysop (talk) 13:04, 8 March 2015 (UTC)