The following is a article posted to comp.sys.acorn.programmer by Matthias Seifert (my markup, headers trimmed) which describes the memory controller identification code used by Linloader to assist in machine identification.
From: M.Seifert@t-online.de (Matthias Seifert)
Newsgroups: comp.sys.acorn.programmer
Subject: Re: Identifying a Risc PC?
Date: Fri, 02 Apr 1999 07:51:25 +0200
Organization: Software Evolutions
Message-ID: <48ec4ce873M.Seifert@t-online.de>
Timothy Baldwin <tim@reinhouse.freeserve.co.uk> wrote:
> In message <48eb4be1b8M.Seifert@t-online.de>
> M.Seifert@t-online.de (Matthias Seifert) wrote:
> > Timothy Baldwin <tim@reinhouse.freeserve.co.uk> wrote:
> > > How can a RISC OS (C + assembler) program tell between a Risc PC and
> > > some future RISC OS system?
> >
> > I would simply check if an IOMD is present and if so, which type it is
> > (i.e. IOMD20/21 in a RPC or the 'embedded' IOMDs of ARM7500 and
> > ARM7500+).
> How?
First you have to check the RISC OS version as RISC OS 2 has a bug in the
SWI "OS_ReadSysInfo" which crashes the machine if you call this SWI with
anything but 0 in R0.
Then you call the SWI "OS_ReadSysInfo" 2. The bits 16 to 23 of returned
register R0 tell you which memory control chip is present (0=MEMC, 1=IOMD).
If you want to know _which_ type of IOMD is present, you have to check
this directly (as there are no OS commands to do so). For this you first
need the base address of the IOMD which you can get in two ways:
1) You simply assume that it is &03200000 as is stated in the PRM, TRM
and even in the datasheets of ARM7500(FE) (if this isn't the case you
can be pretty sure that many programs will get in trouble with this
hardware)
2) You write a 'fake' device driver which receives the base adress of the
IOC in R3 when called
I would use method 1. ;-)
Now you read the IOMD chip ID which you find at offset &94 (low byte) and
&98 (high byte). (This doesn't work if the processor is in USR mode.)
The complete code may look something like:
STMFD R13!,{R1-R4,R14}
MOV R0,#129 ;
MOV R1,#0 ;
MOV R2,#&ff ;
SWI "OS_Byte" ; Read OS identifier (R1), corrupts R0 and R2
CMP R1,#&A3 ; Is it at least RISC OS 3?
MOVLT R0,#0 ; No -> must be MEMC
BLT Finished ;
MOV R0,#2 ;
SWI "XOS_ReadSysInfo" ; Read system info, returns values in R0-R4
MOVVS R0,#0 ; An error occured (don't know how, but if
BVS Finished ; so, I would say that we found a MEMC...)
MOV R0,R0,LSR #16 ;
AND R0,R0,#&FF ; 0 = MEMC, 1 = IOMD
TEQ R0,#1 ; Is it an IOMD?
BNE Finished ; No -> exit
MOV R4,PC ; Get actual processor mode (assumes that ARM is in
; 26 bit mode)
TST R4,#%11 ; (assumes that ARM is in 26 bit mode)
SWIEQ "OS_EnterOS" ; Change into SVC mode if needed
MOV R1,#&03200000 ; Base address of IOMD
LDRB R2,[R1,#&94] ; Low byte of IOMD ID
ORR R0,R0,R2,LSL #16
LDRB R2,[R1,#&98] ; High byte of IOMD ID
ORR R0,R0,R2,LSL #24
TST R4,#%11 ;
TEQEQP R4,#0 ; Return to original processor mode if needed
; (assumes that ARM is in 26 bit mode)
Finished
LDMFD R13!,{R1-R4,PC}
Possible results in R0 (AFAIK):
&00000000: MEMC
&5B980001: embedded IOMD of ARM7500
&AA7C0001: embedded IOMD of ARM7500FE
&D4E70001: IOMD of Risc PC
&00000002: Future type of memory controller
&00000003: Future type of memory controller
..
&000000FF: Future type of memory controller
--
_ _ | Acorn Risc PC, StrongARM @ 287 MHz
| | | _, _|__|_ |) ' _, , | 130 Mbyte RAM, ~30 Gbyte HD
| | | / | | | |/\ | / | / \ | ------------------------------------
| | |_/\/|_/|_/|_/| |/|/\/|_/ \/ | http://www.deutschlandwetter.de