Archimedes Podule Loaders ~~~~~~~~~~~~~~~~~~~~~~~~~ Name: 0310071 Version: 0.02 History: 0.01: Undated : started. 0.02: 15-Feb-89: updated for release on SID CONTENTS 1. About this document 2. Podule identity 2.1 Podule identity space 2.2 Podule identity low byte 2.2.1 Podule presence 2.2.2 ID field 2.2.3 Acorn conformance bit 2.3 Identification extension 2.4 Country code 2.5 Manufacturer code 2.6 Product type code 2.7 FIQ and IRQ status 2.8 Interrupt status pointers 3. Chunk directory structure 3.1 Operating system identity byte 4. Binding a ROM image 5. Code space 6. Writing a loader 6.1 Registers 6.2 Entry points 6.3 Initialisation 6.4 Errors 6.5 Example 6.6 Loading the loader 7. Example BASIC program for joining ROMs 8. Interfaces 1. About this document This document has been written for Original Equipment Manufacturers (OEMs), and describes how to generate ROMs for Podules. It includes information about the format of Loaders and how to write them; how the Podule Manager expects to see Podule space structured; and how the MOS uses the Podule Manager to load Modules from Podules. It is expected that readers of this document have read the specification A SERIES PODULES, have a working knowledge of ARM assembler and BBC BASIC V, and a good understanding of the general principles underlying the Arthur Operating System. 2. Podule Identity Each Podule must be capable of identifying itself to the host operating system, which it does by means of the Podule Identity (PI). It consists of at least one byte (the low byte) of which bits 3 to 7 carry PI information, and is usually followed by several more bytes. The PI is read by a synchronous read of address 0 of the Podule space. 2.1 Podule identity space The Podule identity space starts at Podule address 0 and extends into the Podule space as required. The minimum PI, which all Podules must support, is a single readable byte at address 0, called the PI low byte. Most Podules will support an extended PI, consisting of eight bytes starting from address 0. The PI (whether extended or not) must appear at the bottom of the Podule space, from address zero upwards after reset. It does not however have to remain readable at all times, so it can be in a paged address space so long as the Podule is set to page zero on reset. Refer to sections 4.2.2 and 4.3.1. of A SERIES PODULES. This has the effect that the PI, including the Podule present bit, is only valid after reset until the Podule driver is installed. The first 16 bytes of the Podule identity space is assumed to be bytewide only. The space after this may be 8, 16 or, in the future, 32 bits wide. Bits 2 and 3 in byte 1 of the extended PI (W0, W1) indicate the width of the data (if any) which follows. If the PI is included in a ROM which is 16 or 32 bits wide, then only the lowest byte in each half-word or word must be used for the first 16 (half) words. Current versions of the Arthur Podule Manager only support the 8 bit wide mode. 2.2 Podule Identity low byte The low byte of the PI is as follows: 7 6 5 4 3 2 1 0 +-----+-----+-----+-----+-----+-----+-----+-----+ | A |ID[3]|ID[2]|ID[1]|ID[0]| FIQ | P | IRQ | +-----+-----+-----+-----+-----+-----+-----+-----+ IRQ = 0 : not requesting IRQ ) see text = 1 : requesting IRQ ) P = 0 : Podule is present FIQ = 0 : not requesting FIQ ) see text = 1 : requesting FIQ ) ID[3:0] = 0 : extended PI <> 0 : ID field A = 0 : Acorn conformant Podule = 1 : non-conformant Podule 2.2.1 Podule presence The Arthur operating system has to know if there are any Podules present. Normally BD[1] is pulled high by a weak pullup. Reading the low byte of the PI will therefore read a 1 on this bit unless a Podule is present. All Podules must have bit 1 LOW in the low byte of the PI. 2.2.2 ID field There are 4 bits in the low byte of the PI (BD[3:6]) which may be used for Podule identification. These should only be used for the very simplest of Podules or temporarily during development. Most Podules should implement the extended PI which eliminates the possibility of Podule IDs clashing. When an extended PI is used, all four bits in the ID field of the low byte PI must be zero. 2.2.3 Acorn conformance bit The most significant bit in the low byte of the PI must be zero for Podules that conform to this Acorn specification. 2.3 Identification extension If the ID field of the low byte of the PI is zero, then the PI is extended. This means that the next seven bytes of the PI will be read by the operating system. The extended PI starts at the bottom of the Podule space, and consists of eight bytes as defined on the next page. If bit 0 of byte 1 is not set then the extended PI is just eight bytes long. If bit 0 of byte 1 (CD) is set, then a Chunk Directory follows the Interrupt Status Pointers. 7 6 5 4 3 2 1 0 +-----+-----+-----+-----+-----+-----+-----+-----+ | C[7]| C[6]| C[5]| C[4]| C[3]| C[2]| C[1]| C[0]| 1CH +-----+-----+-----+-----+-----+-----+-----+-----+ |M[15]|M[14]|M[13]|M[12]|M[11]|M[10]| M[9]| M[8]| 18H +-----+-----+-----+-----+-----+-----+-----+-----+ | M[7]| M[6]| M[5]| M[4]| M[3]| M[2]| M[1]| M[0]| 14H +-----+-----+-----+-----+-----+-----+-----+-----+ |P[15]|P[14]|P[13]|P[12]|P[11]|P[10]| P[9]| P[8]| 10H +-----+-----+-----+-----+-----+-----+-----+-----+ | P[7]| P[6]| P[5]| P[4]| P[3]| P[2]| P[1]| P[0]| 0CH +-----+-----+-----+-----+-----+-----+-----+-----+ | R | R | R | R | R | R | R | R | 08H +-----+-----+-----+-----+-----+-----+-----+-----+ | R | R | R | R | W[1]| W[0]| IS | CD | 04H +-----+-----+-----+-----+-----+-----+-----+-----+ | A | 0 | 0 | 0 | 0 | F | 0 | I | 00H +-----+-----+-----+-----+-----+-----+-----+-----+ A = 0 : Acorn conformant Podule = 1 : non-conformant Podule F = 0 : not requesting FIQ ) see text = 1 : requesting FIQ ) I = 0 : not requesting IRQ ) see text = 1 : requesting IRQ ) R = 0 : mandatory at present = 1 : reserved for future use CD = 0 : no Chunk Directory follows = 1 : Chunk Directory follows Interrupt Status IS = 0 : Interrupt Status appears in low byte PI = 1 : Interrupt Status has been relocated W[1:0] = 0 : 8-bit code follows after byte 15 of ID = 1 : 16-bit code follows after byte 15 of ID = 2 : 32-bit code follows after byte 15 of ID = 3 : reserved C[7:0] = : Country M[15:0] = : Manufacturer P[15:0] = : Product Type 2.4 Country code Every Podule should have a code for the country of origin. The current allocation of country codes is as follows: Country name Code Value UK 0 Italy 4 Spain 5 France 6 Germany 7 Portugal 8 Greece 10 Sweden 11 Finland 12 Denmark 14 Norway 15 Iceland 16 Canada 17 Turkey 20 Consult Acorn for further allocation of codes. 2.5 Manufacturer code Every Podule should have a code for manufacturer. The current allocation of manufacturer codes is as follows: Manufacturer Code Value Acorn UK 0 Acorn USA 1 Olivetti 2 Watford 3 Computer Concepts 4 Intelligent Interfaces 5 Caman Systems 6 Armadillo 7 Soft Option 8 Wild Vision 9 Anglo Computers 10 Resource 11 Allied Interactive 12 Musbury Consultants 13 Cambridge Ring Consultants 14 A and G Electronics 15 Space Tech 16 Consult Acorn for further allocation of codes. 2.6 Product type code Every Podule type must have a unique number allocated to it. The current allocation of Podule type codes is as follows: Product type Code Value Host Tube 0 Parasite Tube 1 SCSI 2 Ethernet 3 IBM Disc 4 RAM/ROM 5 BBC IO 6 Modem 7 Teletext 8 CDROM 9 IEEE 488 10 Hard Disc 11 ESDI 12 SMD 13 Laser Printer 14 Scanner 15 Fast Ring 16 VME Bus 17 PROM Programmer 18 MIDI 19 Mono VPU 20 Frame Grabber 21 Sound Sampler 22 Video Digitiser 23 GenLock 24 CODEC Sampler 25 Image Analyser 26 Analogue Input 27 CD Sound Sampler 28 6 MIPS Signal Processor 29 12 MIPS Signal Processor 30 33 MIPS Signal Processor 31 Touch Screen 32 Transputer Link # 33 Interactive Video 34 Laser Scanner 35 Transputer Link #2 36 VMEBus 37 Tape Streamer 38 Laser Test 39 Colour Digitiser 40 Weather Satellite 41 Consult Acorn for further allocation of codes. 2.7 FIQ and IRQ status If bit 1 in byte 1 of the extended PI (IS) is not set, then the interrupt status bits have not been relocated within the Podule address space. In this case the FIQ and IRQ status bits must appear as bits 2 and 0 respectively in the low byte of the PI. Podules which cannot generate interrupts must drive these bits to zero. If bit 0 in byte 1 of the extended PI (CD) is not set either, then the Interrupt Status Pointers do not need to be defined, as the operating system will not read them. If CD is set, then the Interrupt Status Pointers should be defined to point to the respective bits in the PI low byte. If bit 1 of byte 1 of the extended PI (IS) is set, then the interrupt status bits have been relocated within the Podule space. In this case the Interrupt Status Pointers must be defined as described in section 4.4 of A SERIES PODULES. If both IRQ and FIQ sources are provided by a Podule, then a separate status bit must exist for each type of interrupt source, though the two status bits may appear at the same address. Refer to section 4.4. 2.8 Interrupt status pointers If bit 1 of byte 1 of the extended PI (IS) is set, then the address of the FIQ and IRQ status bits must be provided in the eight bytes which follow the extended PI, even if the two status bits are at address 0. There are two sets of 4-byte numbers as detailed below, each consisting of a 3-byte address field and a 1-byte position mask field. The latter defines which bit within the status byte refers to the status bit. It should consist of 1 'one' and 7 'zeros'. The other bits may be 'don't cares'. If the Podule does not provide one of these interrupt sources, then the respective position mask should consist of 8 'zeros'. If bit 0 of byte 1 of the extended PI (CD) is set, then bit 1 of byte 1 of the extended PI (IS) must be set and hence the addresses must be present. Note that these eight bytes are always assumed to be bytewide. Only the lowest byte in each word should be used. After byte 15 (address 40H upwards), wider words may be used, according to the setting of W[1] and W[0] in the extended ID. See section 4.3 of A SERIES PODULES. The 24-bit address field allows for an absolute byte address with an offset from 3000000H to be defined. Hence the cycle speed to access the status register can be included in the address (encoded by bits 19 and 20). Bits 14 and 15 should be zero. +-------------------+ 40H | IRQ Status Bit | | Address (24 bits) | +-------------------+ 34H | IRQ Status Bit | | Position Mask | +-------------------+ 30H | FIQ Status Bit | | Address (24 bits) | +-------------------+ 24H | FIQ Status Bit | | Position Mask | +-------------------+ 20H The previous paragraphs explain the system of Podule identification. You do not need to use all of these features on all Podules, and the implementation depends on the needs and complexity of the Podule in question. ALL Podules must implement at least the simplest form of Podule identification. Synchronous cycles are used by the operating system to read and write any locations within the PI space (to simplify the design of synchronous Podules). 3. Chunk Directory structure If bit 0 of byte 1 of the extended PI (CD) is set, then following the Interrupt Status Pointers is a directory of Chunks of data and/or code stored in the ROM. The lengths and types of these Chunks and the manner in which they are loaded is variable, so after the eight bytes of Interrupt Status Pointers there follow a number of entries in the Chunk Directory. The Chunk Directory entries are eight bytes long and all follow the same format. There may be any number of these entries. This list of entries is terminated by a block of four bytes of zeros. Note that from here on the definition is in terms of bytes. +-------------------+ n+8 | Start address | | 4 Bytes (32 bits) | +-------------------+ n+4 | Size in bytes : | 3 Bytes (24 bits) | +-------------------+ n+1 | Operating System | | Identity Byte | +-------------------+ n 3.1 Operating System Identity Byte The Operating System Identity Byte forms the first byte of the Chunk Directory entry, and determines the type of data which appears in the Chunk to which the Chunk Directory refers. It is defined as follows: 7 6 5 4 3 2 1 0 +-----+-----+-----+-----+-----+-----+-----+-----+ |OS[3]|OS[2]|OS[1]|OS[0]| D[3]| D[2]| D[1]| D[0]| +-----+-----+-----+-----+-----+-----+-----+-----+ OS[3] = 0 reserved OS[3] = 1 mandatory at present OS[2:0] = 0 Acorn Operating System #0 Arthur D[3:0] = 0 Loader 1 Relocatable Module 2 BBC ROM 3 Sprite 4-15 Reserved 1-5 reserved D[3:0] = 0-15 reserved 6 manufacturer defined D[3:0] = 0-15 manufacturer specific 7 device data D[3:0] = 0 link (for 0, the object pointed to is another directory) 1 serial number 2 date of manufacture 3 modification status 4 place of manufacture 5 description 6 part number (for 1-6, the data in the pointed-to location contains the ASCII string of the information) 7-14 reserved 15 empty chunk Those Chunks with OS[0:2] = 7, are operating system independent and are always treated as ASCII strings terminated with a zero byte. They are not intended to be read by programs, but rather inspected by users. It is expected that even minimum Podules will have an entry for D[0:3] = 5 (description), and it is this string which is printed out by the command *Podules. 4. Binding a ROM image For the ROM to be read by the Podule Manager it must conform to the specification, even if only minimally. The simplest way to generate ROM images is to use a BASIC program to combine the various parts togther and to compute the header and Chunk Directory structure. Such a program is shown at the end of this application note. The ouput of such a program is a file suitable for programming into a PROM or an EPROM. This then forms the basis of storing software and data in Podules. However, there is an obvious drawback in that the Podule space is only 4 kbytes (at word boundaries), and so its usefulness is limited as it stands. To allow Podules to accomodate more than this 4 kbytes an extension of the addressing capability is used. This extension is called the Code Space. 5. Code Space The Code Space is an abstracted address space that is accessed in a Podule independent way via a software interface. It is a large linear address space that randomly addressable to a byte boundary. This will typically be used for driver code for the Podule, and will be downloaded into system memory by the operating system before it is used. The manner in which this memory is accessed is variable and so it is accessed via a LOADER. 6. Writing a loader The purpose of the loader is to present to the Podule Manager a simple interface that allows the reading (and writing) of the Code Space on a particular Podule. The usual case is a ROM paged to appear in 2 kbyte pages at the bottom of the Podule space, with the page address stored in a latch. This then permits the Podule Manager to load software (Relocatable Modules) or data from a Podule without having to know how that particular Podule's hardware is arranged. The loader is a simple piece of relocatable code with four entry points and clearly defined entry and exit conditions. The format of the loader is optimised for ease of implementation and small code size rather than anything else. 6.1 Registers The register usage is the same for each of the four entry points. Input/Output Comments ------------ -------- R0 Write/Read data Treated as a byte R1 Address Must be preserved R2-R3 May be used R4-R9 Must be preserved R10 May be used R11 Hardware Hardware base address, must be preserved R12 Private, must be preserved R13 sp Stack pointer (FD), must be preserved R14 Return address; use BICS pc, lr, #V_bit R15 PC The exception to this is the CallLoader entry point where R0-R2 are the user's entry and exit data. 6.2 Entry points All code must be relocatable and position independent. It can be assumed that the code will be run in RAM in SVC mode. Origin + &00 Read a byte Origin + &04 Write a byte Origin + &08 Reset to initial state Origin + &0C SWI Podule_CallLoader 6.3 Initialisation The first call will be to Read address 0. 6.4 Errors Errors are returned in the usual way; V is set and R0 points at a word-aligned word containing the error number, which is followed by an optional error string, which in turn must be followed by a zero byte. ReadByte and WriteByte may be able to return errors like 'Bad address' if the device is not as big as the address given, or 'Bad write' if using read after write checks on the WriteByte call. If the CallLoader entry is not supported then don't return an error. If Reset fails then return an error. Since device drivers may well be short of space it will be possible to return an error with R0=0 and an error string from within the Podule manager will be used. Note that this is not encouraged, but is offered as a suggestion of last resort. Errors are returned to the caller by using ORRS pc, lr, #V_bit rather than the usual BICS exit. 6.5 Example 00 LEADR &FFFFFD00 ; Data 00 00003000 PageReg * &3000 00 0000000B PageSize * 11 ; Bits 00 EA00000B Origin B ReadByte 04 EA000019 B WriteByte 08 EA000001 B Reset 0C E3DEF201 BICS pc, lr, #V_bit 10 FFFFFFFF Page DCD -1 ; Variable 14 E59FA0E4 Reset LDR r10, =2_00000011111111111111000000000000 18 E00BA00A AND r10, r11, r10 ; Hardware address only 1C E28AAA03 ADD r10, r10, #PageReg 20 E3E02000 MOV r2, #-1 24 E50F201C STR r2, Page 28 E3A02000 MOV r2, #0 2C E4CA2000 STRB r2, [ r10 ] 30 E3DEF201 BICS pc, lr, #V_bit 34 E59F40C4 ReadByte LDR r4, =2_00000011111111111111000000000000 38 E00B4004 AND r4, r11, r4 ; Hardware address only 3C E284AA03 ADD r10, r4, #PageReg 40 E3510B3E CMP r1, #&F800 ; Last page 44 228F0060 ADRHS Error, ErrorATB 48 239EF201 ORRHSS pc, lr, #V_bit 4C E2812B02 ADD r2, r1, #1 :SHL: PageSize 50 E1A025C2 MOV r2, r2, ASR #PageSize 54 E51F304C LDR r3, Page 58 E1320003 TEQ r2, r3 5C 14CA2000 STRNEB r2, [ r10 ] 60 150F2058 STRNE r2, Page 64 E3C12BFE BIC r2, r1, #&7F :SHL: PageSize 68 E7D40102 LDRB r0, [ r4, r2, ASL #2 ] ; Word addressing 6C E3DEF201 BICS pc, lr, #V_bit 70 E28F0000 WriteByte ADR Error, ErrorNW 74 E39EF201 ORRS pc, lr, #V_bit 78 00000580 ErrorNW DCD ErrorNumber_NotWriteable A8 DCB ErrorString_NotWriteable A9 00 DCB 0 AA 00 00 ALIGN AC 00000584 ErrorATB DCD ErrorNumber_AddressTooBig BC DCB ErrorString_AddressTooBig BF 00 DCB 0 C0 END 6.6 Loading the Loader The loading of the Loader is performed automatically by the Podule Manager if it is ever asked to 'EnumerateChunk' a Chunk with a Loader in it. Since the MOS enumerates all Chunks from all Podules at a hard reset this is achieved by default. If no Loader is loaded then SWI Podule_EnumerateChunk will terminate on the zero at the end of the Chunk Directory in the Podule space. If, however, when the end of the Podule space Chunk Directory is reached a Loader has been loaded, then a second Chunk Directory, stored in the Code Space, will appear as a continuation of the original Chunk Directory. This second Chunk Directory is in exactly the same format as the original Chunk Directory. Addresses in the Code Space Chunk Directory refer to addresses in the Code Space. The Chunk Directory starts at address 0 (rather than address 16 as the one in Podule Space does). 7. Example BASIC program for joining ROMs 10 REM > &.arm.MidiAndI/O.MidiJoiner 20 REM Author : Arthur 30 REM Last edit : 06-Jan-87 40 PRINT"Joiner for Podule ROMs"'"Version 1.05." 50 PRINT"For Midi board.": DIM Buffer% 300, Block% 20 70 INPUT'"Enter name of output file : "OutName$ 75 H%=OPENOUT(OutName$) 80 IF H%=0 THEN PRINT"'";OutName$;"' not found.":END 90 ONERRORONERROROFF:CLOSE#H%:REPORT:PRINT" at line ";ERL:END 100 Device%=0:L%=TRUE:REPEAT 120 Max%=&800:REM Max% is the size of the normal area 130 Low%=&100:REM Low% is the size of the pseudo directory 140 Base%=0:REM The offset for file address calculations 150 Rom%=&4000:REM Rom% is the size of BBC ROMs 170 PROCByte(0):PROCHalf(3):PROCHalf(19):PROCHalf(0):PROCByte(0) 180 PROCByte(0):PROC3Byte(0):PROCByte(0):PROC3Byte(0) 190 IF PTR#H% <> 16 STOP 200 Bot%=PTR#H%:REM Bot% is where the directory grows from 210 Top%=Max%:REM Top% is where normal files decend from 230 INPUT"Enter filename of loader : "Loader$ 240 IF Loader$ <> "" THEN K%=FNAddFile( &80, Loader$ ) 250 IF K% ELSE PRINT"No room for loader.": PTR#H%=Bot%:PROCByte(0):CLOSE#H%:END 270 INPUTLINE'"Enter product description : "Dat$ 280 IF Dat$ <> "" THEN PROCAddString( &F5, Dat$ ) 300 PRINT:REPEAT 310 INPUT"Enter name of file to add : "File$ 320 IF File$ <> "" THEN T%=FNType( File$ ) ELSE T%=0 330 IF T%=0 ELSE K%=FNAddFile( T%, File$ ) 340 IF K% ELSE PRINT"No more room." 350 UNTIL (File$ = "") OR (K%=FALSE) 360 IF K% ELSE PTR#H%=Bot%:PROCByte(0):CLOSE#H%:END 370 IF L% PROCChange 390 INPUTLINE"Enter serial number : "Dat$ 400 IF Dat$ <> "" THEN PROCAddString( &F1, Dat$ ) 410 INPUTLINE"Enter modification status : "Dat$ 420 IF Dat$ <> "" THEN PROCAddString( &F3, Dat$ ) 430 INPUTLINE"Enter place of manufacture : "Dat$ 440 IF Dat$ <> "" THEN PROCAddString( &F4, Dat$ ) 450 INPUTLINE"Enter part number : "Dat$ 460 IF Dat$ <> "" THEN PROCAddString( &F6, Dat$ ) 480 Date$=TIME$ 490 Date$=MID$(Date$,5,2)+"-"+MID$(Date$,8,3)+"-"+MID$(Date$,14,2) 500 PROCAddString( &F2, Date$ ) 530 REM PROCHeader( &F0, Z%+W%*Rom%-Base%, 0 ):REM Link 550 PTR#H%=Bot%:PROCByte(0) 570 CLOSE#H%: END 590 DEF PROCByte(D%):BPUT#H%,D%:ENDPROC 610 DEF PROCHalf(D%):BPUT#H%,D%:BPUT#H%,D%DIV256:ENDPROC 630 DEF PROC3Byte(D%) 640 BPUT#H%,D%:BPUT#H%,D%DIV256:BPUT#H%,D%DIV65535:ENDPROC 660 DEF PROCWord(D%) 670 BPUT#H%,D%:BPUT#H%,D%DIV256:BPUT#H%,D%DIV65535 680 BPUT#H%,D%DIV16777216:ENDPROC 700 DEF PROCAddString( T%, S$ ) 710 S$=S$+CHR$0 720 IF L% THEN PROCAddNormalString ELSE PROCAddPsuedoString 730 ENDPROC 750 DEF PROCAddNormalString 760 IF Top%-Bot% < 10+LEN(S$) THEN STOP 770 PROCHeader( T%, Top%-LEN(S$)-Base%, LEN(S$) ) 780 Top%=Top%-LEN(S$):PTR#H%=Top%:FOR I%=1 TO LEN(S$) 790 BPUT#H%,ASC(MID$(S$,I%,1)):NEXTI%:ENDPROC 810 DEF PROCAddPsuedoString 820 IF Max%+Low%-Bot% < 9 THEN STOP 830 PROCHeader( T%, Top%-Base%, LEN(S$) ) 840 PTR#H%=Top%:FOR I%=1 TO LEN(S$) 850 BPUT#H%,ASC(MID$(S$,I%,1)):NEXTI% 860 Top%=Top%+LEN(S$):ENDPROC 880 DEF PROCHeader( Type%, Address%, Size% ) 890 PTR#H%=Bot% 900 PROCByte( Type% ) 910 PROC3Byte( Size% ) 920 PROCWord( Address% ) 930 Bot%=Bot%+8:ENDPROC 950 DEF FNAddFile( T%, N$ ) 960 F%=OPENIN( N$ ) 970 IF F%=0 THEN PRINT"File '";N$;"' not found.":=FALSE 980 S%=EXT#F% 990 IF L% THEN =FNAddNormalFile ELSE =FNAddPsuedoFile 1010 DEF FNAddNormalFile 1020 E%=S%+9-(Top%-Bot%) 1030 IF E%>0 THEN PRINT"Oversize by ";E%;" bytes."': PROCChange:=FNAddPsuedoFile 1040 PROCHeader( T%, Top%-S%-Base%, S% ) 1050 Top%=Top%-S%:PTR#H%=Top%:FOR I%=1 TO S% 1060 BPUT#H%,BGET#F%:NEXTI%:CLOSE#F%:=TRUE 1080 DEF FNAddPsuedoFile 1090 IF Max%+Low%-Bot% < 9 THEN =FALSE 1100 PROCHeader( T%, Top%-Base%, S% ) 1110 PTR#H%=Top% 1120 FOR I%=1 TO S%:BPUT#H%,BGET#F%:NEXTI% 1130 Top%=Top%+S%:CLOSE#F%:=TRUE 1150 DEF PROCChange 1160 PRINT"Changing up. Wasting ";Top%-Bot%;" bytes." 1170 PTR#H%=Bot%:PROCByte(0):REM Terminate bottom directory 1180 Bot%=Max%:Top%=Max%+Low%:Base%=Max%:L%=FALSE 1190 REM In the pseudo area files grow upward from Top% 1200 ENDPROC 1220 DEF FNType( N$ ) 1230 $Buffer%=N$:X%=Block%:Y%=X%/256:A%=5:X%!0=Buffer% 1240 B%=USR&FFDD:IF (B%AND255) <> 1 THEN PRINT"Not a file":=0 1250 V%=(Block%!3)AND&FFFFFF 1260 IFV%=&FFFFFA THEN =&81 1270 IF((Block%!2AND&FFFF)=&8000)AND((Block%!6AND&FFFF)=&8000)THEN=&82 1280 IFV%=&FFFFF9 THEN =&83 1290 =0 8. Interfaces 1. SWI Podule_ReadID R3 => Podule number R0 <= Podule ID byte 2. SWI Podule_ReadHeader R2 => Pointer to core, 8 or 16 bytes R3 => Podule number 3. SWI Podule_EnumerateChunks R0 => Chunk number (zero to start) R3 => Podule number R0 <= Next chunk number (zero for end) R1 <= Size in bytes R2 <= Type byte R4 <= Pointer to name if an RM else preserved 4. SWI Podule_ReadChunk R0 => Chunk number R2 => Pointer to core, assumed big enough R3 => Podule number 5. SWI Podule_ReadBytes R0 => Psuedo address R1 => Count in bytes R2 => Pointer to core R3 => Podule number 6. SWI Podule_WriteBytes R0 => Psuedo address R1 => Count in bytes R2 => Pointer to core R3 => Podule number 7. SWI Podule_CallLoader R0 => User data R1 => User data R2 => User data R3 => Podule number R0 <= User data R1 <= User data R2 <= User data 8. SWI Podule_RawRead R0 => Podule address (0..&3FFF) R1 => Count in bytes R2 => Pointer to core R3 => Podule number 9. SWI Podule_RawWrite R0 => Podule address (0..&3FFF) R1 => Count in bytes R2 => Pointer to core R3 => Podule number 10. SWI Podule_HardwareAddress R3 => Podule number or Partial hardware address R3 <= Combined hardware address C. Acorn Computers Limited 1988 Within this document the term BBC is used as an abbreviation for British Broadcasting Corporation. The product described in this manual is subject to continuous developments and improvements. All particulars of the product and its use (including the information in this manual) are given by Acorn Computers in good faith. In case of difficulty please contact your supplier. Every step is taken to ensure that the quality of software and documentation is as high as possible. However, it should be noted that software cannot be written to be completely free of errors. To help Acorn rectify future versions, suspected deficiencies in software and documentation should be notified in writing to the following address: Acorn Computers Limited, Fulbourn Road, Cherry Hinton, Cambridge CB1 4JN.