Difference between revisions of "Paged ROM"
m (1 revision) |
(→Master Compact) |
||
(11 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:MOS API]] | [[Category:MOS API]] | ||
[[Category:Hardware]] | [[Category:Hardware]] | ||
− | '''Paged ROM''' is a system used in all 8 bit BBC series computers and in the Electron, whereby a large pool of ROM-based software can be used all at once by dividing it into 16K ''slots'' and paging one at a time into the address space. | + | '''Paged ROM''' is a system used in all 8 bit BBC series computers and in |
+ | the Electron, whereby a large pool of ROM-based software can be used all at | ||
+ | once by dividing it into 16K ''slots'' and paging one at a time into the | ||
+ | address space. Depending on the hardware the pool may be 64K up to 256K in | ||
+ | size. The MOS manages paged ROMs automatically and provides an extensive API | ||
+ | to ROM-based software. There are very few problems in practice, as nearly | ||
+ | all applications stick to the API. | ||
− | In a diagram of memory where the address space runs from bottom to top, the paged ROM slots appear parallel to the main memory map, extending away to the side. | + | In a diagram of memory where the address space runs from bottom to top, the |
+ | paged ROM slots appear parallel to the main memory map, extending away to | ||
+ | the side. For this reason the system is also known as '''sideways ROM'''. | ||
+ | Later models and custom machines have RAM fitted in some slots and this is | ||
+ | usually called '''sideways RAM''' rather than 'paged RAM'. | ||
The equivalent system in the Archimedes series are Modules. | The equivalent system in the Archimedes series are Modules. | ||
== Rationale == | == Rationale == | ||
− | It is clear that the BBC Micro was designed with paged ROMs in mind from the start. | + | It is clear that the BBC Micro was designed with paged ROMs in mind from the |
+ | start. As the [[6502]] CPU cannot address more than 64K, a way was needed to | ||
+ | fit in all current and future firmware (such as disc filing systems, ROM | ||
+ | filing systems, device drivers and applications) without taking up too much | ||
+ | of the address space. | ||
− | In addition, some classes of application (termed 'languages' by Acorn but not necessarily languages) needed to spare as much RAM as possible for the user. | + | In addition, some classes of application (termed 'languages' by Acorn but |
+ | not necessarily languages) needed to spare as much RAM as possible for the | ||
+ | user. In an education environment they had to load up faster and more | ||
+ | reliably than cassettes but require less capital outlay than floppy discs. | ||
+ | (Drives and interfaces were prohibitively expensive at the time, especially | ||
+ | for local education authorities.) | ||
− | Acorn found that most of these pieces of firmware were loosely coupled and so could share the address space. | + | Acorn found that most of these pieces of firmware were loosely coupled and |
+ | so could share the address space. EPROMs also made a good choice for | ||
+ | distributing 'languages', given the needs of the market. | ||
== Features of paged ROM == | == Features of paged ROM == | ||
=== Languages === | === Languages === | ||
− | ''Languages'' are ROM based applications that take control of the computer on power-up and interface between the user and the operating system. | + | ''Languages'' are ROM based applications that take control of the computer |
+ | on power-up and interface between the user and the operating system. BASIC, | ||
+ | LISP and FORTH are examples of language ROMs released at the time. In modern | ||
+ | terms they would be called ''shells'', and so they need not be programming | ||
+ | languages, or command line based (such as the word processors ''View'' and | ||
+ | ''Wordwise''). They may even be user applications. | ||
− | Exactly one language is active at any time. | + | Exactly one language is active at any time. The MOS starts one automatically |
+ | on power up, and can invoke another on command by its slot number, but the | ||
+ | usual way of starting a language is by name, through a *command passed to | ||
+ | its service entry point by the MOS. At the very least, each language allows | ||
+ | the user to enter *commands to select another language (the cue is | ||
+ | <code>*</code> by convention, although a language may use another character | ||
+ | or interface.) | ||
− | On power up and hard reset the Models A, B and B+ and Electron will select the language in the highest logical slot number. | + | On power up and hard reset the Models A, B and B+ and Electron will select |
+ | the language in the highest logical slot number. The Master and Master | ||
+ | Compact store the slot number of the current language in non-volatile memory | ||
+ | and restore it on power up and hard reset. On soft reset the 'current | ||
+ | language' is re-selected. | ||
=== Service ROMs === | === Service ROMs === | ||
− | The service routine, which must be present in all ROMs except for BASIC, answers a query or performs some function for the MOS and then returns. | + | The service routine, which must be present in all ROMs except for BASIC, |
+ | answers a query or performs some function for the MOS and then returns. The | ||
+ | service routine may vary in size and complexity up to 100 per cent of the | ||
+ | ROM. A valid ROM that has no language entry point is termed a | ||
+ | ''service ROM'' (although languages are free to offer extensive service | ||
+ | routines as well.) | ||
− | This class of ROM includes all disc filing systems, utility ROMs and device drivers, as these do not interface continually with the user but are invoked by programs, languages and the MOS. | + | This class of ROM includes all disc filing systems, utility ROMs and device |
+ | drivers, as these do not interface continually with the user but are invoked | ||
+ | by programs, languages and the MOS. | ||
=== ROM filing system === | === ROM filing system === | ||
− | ''RFS ROMs'' are a special class of service ROM that hosts data files. | + | ''RFS ROMs'' are a special class of service ROM that hosts data files. These |
+ | ROMs act as a virtual tape loop, read by the ROM Filing System (RFS) built | ||
+ | into the MOS. The MOS can search for files automatically but each file is | ||
+ | serially accessed and of course, read only. | ||
− | The service routine is small, typically implementing just the two relevant RFS calls, to save as much space as possible for the data itself. | + | The service routine is small, typically implementing just the two relevant |
+ | RFS calls, to save as much space as possible for the data itself. (A larger | ||
+ | service routine can decompress the data transparently; | ||
+ | [http://regregex.bbcmicro.net/ such a ROM has recently been developed].) | ||
+ | Since the Cassette and ROM Filing Systems share most of their code, the data | ||
+ | consists of a stream of bytes in a variation of the [[Acorn cassette format]]. | ||
− | RFS ROMs allow BASIC programs and machine code to be loaded from EPROM into main memory, so that ROM based machine code versions do not need to be assembled. | + | RFS ROMs allow BASIC programs and machine code to be loaded from EPROM into |
+ | main memory, so that ROM based machine code versions do not need to be | ||
+ | assembled. | ||
=== Sideways RAM === | === Sideways RAM === | ||
{{main|Sideways RAM}} | {{main|Sideways RAM}} | ||
− | The B+ 128K and Master 128 provide 64 kilobytes of sideways RAM in slots 4 to 7. | + | The B+ 128K and Master 128 provide 64 kilobytes of sideways RAM: in slots |
+ | 12, 13 and the two highest or lowest slots in the B+, and in slots 4 to 7 in | ||
+ | the Master. These slots behave like sideways ROMs in every respect except | ||
+ | that they are writeable. They can therefore provide all the above features, | ||
+ | or serve as general purpose RAM to suitably aware programs. | ||
− | Note that some commercial ROM-based software attempts to overwrite itself so that it cannot be copied and run from sideways RAM. Care must also be taken that a valid ROM is not corrupted so as to hang the machine on the next ROM service call. | + | Note that some commercial ROM-based software attempts to overwrite itself so |
+ | that it cannot be copied and run from sideways RAM. Other titles expect to | ||
+ | see a power-up state before they will function, in the hope that a preceding | ||
+ | power-down erased volatile RAM devices, except that data can persist in | ||
+ | static RAM for some time and all types of reset can be | ||
+ | [[Reset from software|simulated in software]]. Care must also be taken | ||
+ | that a valid ROM is not corrupted so as to hang the machine on the next ROM | ||
+ | service call. If such an event occurs the computer must be powered down to | ||
+ | clear the memory. | ||
==== Extended addressing ==== | ==== Extended addressing ==== | ||
− | These machines also provide ''extended addressing'' so that sideways RAM can be handled by any MOS call that takes a 32-bit address, thereby providing a continuous 64K of extra memory. | + | These machines also provide ''extended addressing'' so that sideways RAM can |
+ | be handled by any MOS call that takes a 32-bit address, thereby providing a | ||
+ | continuous 64K of extra memory. A version of BASIC named '''BAS128''' has a | ||
+ | similar but independent feature. BAS128 puts the display into shadow mode, | ||
+ | runs in main memory and uses sideways RAM for the user's program and | ||
+ | variables. Machine code can be assembled and executed there, as the | ||
+ | assembler translates virtual addresses to their actual locations in sideways | ||
+ | RAM – provided that no references are made between sideways RAM | ||
+ | slots.<ref name="bas128-appnotes">Acorn Computers, Application Notes 030, | ||
+ | 033 and 041</ref> Code can also be assembled there to run in main memory | ||
+ | under [[OPT]]ions 4 to 7. | ||
== Hardware == | == Hardware == | ||
− | In all these machines, paged ROMs appear in a 16K window from &8000 to &BFFF. | + | In all these machines, paged ROMs appear in a 16K window from &8000 to |
+ | &BFFF. Each paged ROM is therefore assembled to an absolute address of | ||
+ | &8000. ROMs smaller than 16K are duplicated until they fill the address | ||
+ | space. The top 16K (&C000..&FFFF) of memory is reserved for the MOS, | ||
+ | [[FRED]], [[JIM]], [[SHEILA]] (and [[HAZEL]]), which are permanently | ||
+ | available. | ||
=== Models [[Model A|A]] and [[Model B|B]] === | === Models [[Model A|A]] and [[Model B|B]] === | ||
− | These computers are fitted with five sockets for 16K ROMs. At first all the sockets were taken up by the MOS, in 4K EPROMs, and BASIC; but once the MOS matured and was released as a mask ROM, the jumpers were reconfigured to provide paged ROM service. | + | These computers are fitted with five sockets for 16K ROMs. At first all the |
+ | sockets were taken up by the MOS, in 4K EPROMs, and BASIC; but once the MOS | ||
+ | matured and was released as a mask ROM, the jumpers were reconfigured to | ||
+ | provide paged ROM service. The MOS sits in its own dedicated socket, and | ||
+ | BASIC in one of the other four. BASIC need not be present; it can be | ||
+ | replaced by any other 'language' which will take control of the machine and | ||
+ | (hopefully) provide all the same functionality. | ||
− | The heart of the paged ROM system is IC 76, a 74LS163 quad latch known as '''ROMSEL'''. | + | The heart of the paged ROM system is IC 76, a 74LS163 quad latch known as |
+ | '''ROMSEL'''. It appears in [[SHEILA]] in the low four bits of address | ||
+ | &FE30. It is a write-only register but the MOS maintains a copy of the | ||
+ | current ROM selection, in RAM at address &F4. A paged ROM can therefore | ||
+ | discover its slot number by reading this address. | ||
− | Only the low two outputs of ROMSEL are connected, to a quad decoder in IC 20 which provides Chip Select signals to four of the ROM sockets. | + | Only the low two outputs of ROMSEL are connected, to a quad decoder in IC 20 |
+ | which provides Chip Select signals to four of the ROM sockets. The | ||
+ | [[Orientation|easternmost]] of these is assigned slot number 15, which has | ||
+ | highest priority for all ROM service calls and resources. The others are | ||
+ | assigned slot numbers 14 13, and 12; the fifth, [[Orientation|westernmost]] | ||
+ | socket contains the MOS. The table below lists the slot assignments | ||
+ | according to the circuit diagram, though it was later recommended to put the | ||
+ | DFS in the lowest slot: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 91: | Line 188: | ||
|} | |} | ||
− | Homemade ROM expansions can connect spare address lines to the upper two outputs of ROMSEL and deliver multiple slots from one socket; the MOS does not need to be modified as it will assign lower numbers to the extra applications found. | + | Homemade ROM expansions can connect spare address lines to the upper two |
+ | outputs of ROMSEL and deliver multiple slots from one socket; the MOS does | ||
+ | not need to be modified as it will assign lower numbers to the extra | ||
+ | applications found. | ||
− | A large number of commercial ROM expansion boards have also been produced; these connect to the motherboard in various ways and some offer extra features, such as [[shadow RAM]] which inspired the feature in the [[Model B plus|Model B+]]. | + | A large number of commercial ROM expansion boards have also been produced; |
+ | these connect to the motherboard in various ways and some offer extra | ||
+ | features, such as [[shadow RAM]] which inspired the feature in the | ||
+ | [[Model B plus|Model B+]]. The largest has sixteen sockets so as to fill all | ||
+ | available slots, four of these replacing the motherboard sockets that have | ||
+ | been covered over. These boards either tap the unused outputs of ROMSEL or | ||
+ | replicate the entire latch. For the most part they are compatible but | ||
+ | reliability can be a problem (due to the mechanical difficulties and to | ||
+ | overheating.) | ||
− | Certain commercial ROM titles (notably ''Mini Office II'' and ''SPELL-MASTER'') were supplied on their own carrier boards and used custom circuits and protocols to deliver more than 16 KB from their one assigned slot. | + | Certain commercial ROM titles (notably ''Mini Office II'' and |
+ | ''SPELL-MASTER'') were supplied on their own carrier boards and used custom | ||
+ | circuits and protocols to deliver more than 16 KB from their one assigned | ||
+ | slot. These systems are self contained and independent of ROMSEL. | ||
=== [[Electron]] === | === [[Electron]] === | ||
− | A paged ROM system was retained to allow expansion modules to supply firmware, but as an entry level machine | + | A paged ROM system was retained to allow expansion modules to supply |
+ | firmware, but as an entry level machine few modules were expected to be | ||
+ | present at once, and so efficient allocation of ROM slots was sacrificed for | ||
+ | economy. The table below lists the standard slot assignments: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 136: | Line 250: | ||
|} | |} | ||
− | The ULA exposes a ROM selection register in [[SHEILA]] at address &FE05. | + | The ULA exposes a ROM selection register in [[SHEILA]] at address &FE05. It |
+ | is a write-only register but the MOS maintains a copy of the current ROM | ||
+ | selection, in RAM at address &F4. A paged ROM can therefore discover its | ||
+ | slot number by reading this address. Expansion modules with ROMs must | ||
+ | partially emulate (track) the ULA and, if providing multiple ROM sockets, | ||
+ | must supply their own selection register at address &FE05. | ||
− | The ULA can either be in 'external ROM mode' or 'internal ROM mode'. | + | The ULA can either be in 'external ROM mode' or 'internal ROM mode'. |
+ | External ROM mode is enabled when a value between 12 and 15 is written to | ||
+ | &FE05. In this mode the keyboard and BASIC are disabled, and it is up to an | ||
+ | expansion module to supply paged ROM content. Internal ROM mode is enabled | ||
+ | when a value between 8 and 11 is written to &FE05. This also selects the | ||
+ | keyboard (slots 8 or 9) or BASIC ROM (10 or 11, both the same image); the | ||
+ | relevant device will stay enabled | ||
+ | ''even if a value of 0 to 7 is later written to &FE05''. If the expansion | ||
+ | module responds to paged ROM addresses at this time there will be bus | ||
+ | contention, and a corrupted value will appear on the data bus. | ||
− | Certain expansion modules (such as those fitted with Slogger's Electron Expansion 2.0) can host ROMs in slots 12 to 15, and languages in these slots can start up automatically. | + | Certain expansion modules (such as those fitted with Slogger's Electron |
+ | Expansion 2.0) can host ROMs in slots 12 to 15, and languages in these slots | ||
+ | can start up automatically. Languages in slots 0 to 7 can only be entered by | ||
+ | their *command or by <code>*FX 142,n</code>, as the MOS must disable the | ||
+ | internal ROM. | ||
=== [[Model B plus|Model B+]] === | === [[Model B plus|Model B+]] === | ||
− | The Model B's motherboard was redesigned to make use of the newer ICs available, and issued as the Model B+. | + | The Model B's motherboard was redesigned to make use of the newer ICs |
+ | available, and issued as the Model B+. There are six 32K sockets on the | ||
+ | [[Orientation|west]] side of the motherboard. One of these is permanently | ||
+ | assigned to BASIC and the MOS; the other five can accept 32K devices (in | ||
+ | which case each half appears in a separate 16K slot) or any smaller device | ||
+ | (in which case the contents are duplicated to fill the two slots.) A jumper | ||
+ | is provided for each socket to support 16K or 32K ROMs, and another jumper | ||
+ | allows BASIC to be moved to a low slot to allow another language to take | ||
+ | priority. In the B+ 128K, a total of 64K of sideways RAM can be mapped into | ||
+ | slots that have no corresponding ROM socket. The DFS recognises this on hard | ||
+ | reset and increases the memory size displayed in the banner. | ||
− | From the B+ User Guide: "The sockets are numbered, counting anticlockwise from the MOS/BASIC socket at the top right, 14/15, 10/11, 8/9, 2/3, 4/5, and 6/7." The table below lists the standard slot assignments: | + | From the B+ User Guide: "The sockets are numbered, counting anticlockwise |
+ | from the MOS/BASIC socket at the top right, 14/15, 10/11, 8/9, 2/3, 4/5, and | ||
+ | 6/7." The table below lists the standard slot assignments: | ||
{| class="wikitable" | {| class="wikitable" | ||
! Socket number (hex) !! colspan="2" | Assigned device and contents | ! Socket number (hex) !! colspan="2" | Assigned device and contents | ||
|- | |- | ||
− | | F || rowspan="2" colspan="2" | IC 71, BASIC II | + | | F || rowspan="2" colspan="2" | IC 71, BASIC II or sideways RAM (B+ 128K only) |
|- | |- | ||
| E | | E | ||
Line 183: | Line 327: | ||
|} | |} | ||
− | The upper 12K of [[shadow RAM]] appears at locations &8000 to &AFFF when a value above 127 is written to ROMSEL. | + | The upper 12K of [[shadow RAM]] appears at locations &8000 to &AFFF when a |
+ | value above 127 is written to ROMSEL. The memory is also accessible via | ||
+ | [[OSWORD]] calls 5 and 6 (q.v.) Code executed from the top 4K of this | ||
+ | memory also 'sees' and can manipulate video RAM, i.e. shadow RAM in shadow mode or main RAM in non-shadow mode.<ref>[https://stardot.org.uk/forums/viewtopic.php?f=3&t=11892&p=166377 stardot discussion of B+ private 12K]</ref> | ||
+ | The MOS will not search for languages or service ROMs in shadow | ||
+ | RAM. | ||
=== [[Master]] === | === [[Master]] === | ||
− | Further advances meant that the Master firmware was embedded in one 128K device. | + | Further advances meant that the Master firmware was embedded in one 128K |
+ | device. This is assigned the highest seven ROM slots; the MOS takes up the | ||
+ | remaining 16K and spills into spare space in the paged ROMs. Incidentally | ||
+ | the ROM, a custom chip known as EROS, is 'too big for its boots'; users | ||
+ | wanting to patch bugs in the firmware are forced to replace the chip with a | ||
+ | 32 pin EPROM on a carrier board to emulate the non-standard pinout. | ||
− | There is one 16K socket on the motherboard, operating like the ones in the Model B and serving slot 8; and two 32K sockets like those in the Model B+ serving slots 4 to 7. | + | There is one 16K socket on the motherboard, operating like the ones in the |
+ | Model B and serving slot 8; and two 32K sockets like those in the Model B+ | ||
+ | serving slots 4 to 7. These last four slots are normally turned over to | ||
+ | sideways RAM, deactivating the sockets. Slots 0 to 3 are assigned (again in | ||
+ | pairs) to the cartridge sockets on top of the machine. The table below lists | ||
+ | the standard slot assignments: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 226: | Line 385: | ||
|} | |} | ||
− | Since alternative languages and filing systems cannot be placed 'above' the Acorn firmware to take priority, the MOS provides a 'soft unplugging' feature. <code>*UNPLUG n</code> and <code>*INSERT n</code> update the non-volatile memory so that the MOS will ignore or consider, respectively, firmware in slot <code>n</code>. | + | Since alternative languages and filing systems cannot be placed 'above' the |
+ | Acorn firmware to take priority, the MOS provides a 'soft unplugging' | ||
+ | feature. <code>*UNPLUG n</code> and <code>*INSERT n</code> update the | ||
+ | non-volatile memory so that the MOS will ignore or consider, respectively, | ||
+ | firmware in slot <code>n</code>. The commands take effect on the next hard | ||
+ | reset. | ||
− | ROMSEL in this machine is a read-write latch at &FE30, but a RAM copy is still maintained at &F4 for compatibility. | + | ROMSEL in this machine is a read-write latch at &FE30, but a RAM copy is |
+ | still maintained at &F4 for compatibility. | ||
− | The upper 12K of shadow RAM, which was available to the user in the B+, is split in two and allocated to the MOS (as [[ANDY]]) and paged ROMs (as [[HAZEL]], which lies outside the paged ROM address space). | + | The upper 12K of shadow RAM, which was available to the user in the B+, is |
+ | split in two and allocated to the MOS (as [[ANDY]]) and paged ROMs (as | ||
+ | [[HAZEL]], which lies outside the paged ROM address space). The B+ User | ||
+ | Guide warns: "''Note: references to this 12K of memory which are made in | ||
+ | this manual are not necessarily applicable to other Acorn products.''" | ||
=== [[Master Compact]] === | === [[Master Compact]] === | ||
− | This machine follows the Master layout but the firmware is reduced to 64K. | + | This machine follows the Master layout but the firmware is reduced to 64K. |
+ | The ROM is usually soldered in and carries the MOS and three paged ROM slots | ||
+ | with utilities, ADFS and BASIC. There is also a 64K socket and Acorn issued | ||
+ | a ROM for it containing applications. This ROM is optional and so not | ||
+ | considered part of the firmware. | ||
− | There are three 16K sockets and one 32K socket for the user's devices. | + | There are three 16K sockets and one 32K socket for the user's devices. None |
+ | of these are 'hidden' by sideways RAM, which is permanently available. | ||
{| class="wikitable" | {| class="wikitable" | ||
! Socket number (hex) !! colspan="2" | Assigned device and contents | ! Socket number (hex) !! colspan="2" | Assigned device and contents | ||
|- | |- | ||
− | | F || rowspan="3" | IC | + | | F || rowspan="3" | IC 49, MOS & PL 12 on north || Utilities |
|- | |- | ||
| E || BASIC IV | | E || BASIC IV | ||
Line 246: | Line 420: | ||
| D || ADFS 2.10 | | D || ADFS 2.10 | ||
|- | |- | ||
− | | C || rowspan="4" | IC 49 | + | | C || rowspan="4" | IC 49 & PL 12 on south || top 16K |
|- | |- | ||
| B || second 16K | | B || second 16K | ||
Line 268: | Line 442: | ||
| 2 || colspan="2" | IC 23 | | 2 || colspan="2" | IC 23 | ||
|- | |- | ||
− | | 1 || rowspan="2" | IC 38 or expansion port || top 16K | + | | 1 || rowspan="2" | IC 38 & PL 11 on south or expansion port & PL 11 on north || top 16K |
|- | |- | ||
| 0 || bottom 16K | | 0 || bottom 16K | ||
Line 274: | Line 448: | ||
== Operation == | == Operation == | ||
− | + | Any code may change the ROM paging register at will. However, a routine | |
+ | that returns to its caller is expected to preserve the ROM selection on | ||
+ | exit, unless changing the selection is its purpose. This includes system | ||
+ | calls, interrupt service routines and code called from an interpreted | ||
+ | language. | ||
− | As is often mentioned | + | Conversely, all code must mirror changes to ROMSEL in the RAM copy so that |
+ | the routines that serve or interrupt it may restore the ROM slot it expects | ||
+ | to see. As is often mentioned, the MOS runs under constant interrupts. | ||
+ | Many of these may result in service calls and the OS will page in ROMs | ||
+ | unexpectedly to issue them. It is therefore essential that code that | ||
+ | accesses paged ROMs directly keep the RAM copy of the paging register up to | ||
+ | date. | ||
− | + | To select a ROM slot, its number must ''first'' be written to the RAM copy | |
+ | at &F4. If the machine is an Electron, and the target slot number is 7 or | ||
+ | less, a value between 12 and 15 must be written to &FE05 to turn off | ||
+ | internal ROM. Then the number is written to ROMSEL, &FE05 (Electron) or | ||
+ | &FE30 (other machines.) When code running in the paged ROM area changes | ||
+ | between slots, the op-code after the instruction that stores ROMSEL should | ||
+ | be the same in the old and new slots so that the address bus and Chip Select | ||
+ | signals may stabilise without ill effect. | ||
− | An alternative (and less intensive) method is to have a language resident in one 16K slot, and pass user MOS calls (usually [[OSWORD]]) which are handled by one or more of the other slots. | + | A paged ROM slot may also be selected platform-independently, as a side |
+ | effect of [[OSRDSC]] or [[OSBYTE &8F]]. Use of these system calls | ||
+ | eliminates the aforementioned stabilisation delay. | ||
+ | |||
+ | There is nothing to prevent a language or service software taking up more | ||
+ | than 16K; when the firmware has control it can page in another part of | ||
+ | itself with a ''revolving bookcase'' subroutine (identical and at the same | ||
+ | location in all slots; for example in ''Inter-WORD''.) Languages need not | ||
+ | save the old slot number except for reference; service routines must push | ||
+ | the slot number (or private latch setting) on the stack, and pop it on exit. | ||
+ | The only caveat is that a service routine must be available to the MOS at | ||
+ | all times. | ||
+ | |||
+ | An alternative (and less intensive) method is to have a language resident in | ||
+ | one 16K slot, and pass user MOS calls (usually [[OSWORD]]) which are handled | ||
+ | by one or more of the other slots. | ||
== API == | == API == | ||
=== ROM headers === | === ROM headers === | ||
− | On power up or hard reset the MOS scans all slots for a valid ROM header, disabling slots where no header is found. | + | On power up or hard reset the MOS scans all slots for a valid ROM header, |
+ | disabling slots where no header is found. This is to prevent hangups caused | ||
+ | by jumping into empty sockets or uninitialised RAM. It does not however | ||
+ | protect against malfunctions due to a slightly corrupted ROM image. | ||
− | Every language or service ROM must provide the following header at addresses &8000 onwards. This is also used for code loaded and executed in second processor memory | + | Every language or service ROM must provide the following header at addresses |
+ | &8000 onwards. This is also used for code loaded and executed in second | ||
+ | processor memory. See also [[Code header]]. | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 339: | Line 550: | ||
=== Language entry === | === Language entry === | ||
− | A ROM offering a language must set bit 6 of its ROM type byte and must provide an entry point at an address appropriate for the target CPU. A ROM header is also checked for with code loaded executed in second processor memory. The entry point is at an offset from the start of the ROM code or from the execution address of a file. | + | A ROM offering a language must set bit 6 of its ROM type byte and must |
+ | provide an entry point at an address appropriate for the target CPU. A ROM | ||
+ | header is also checked for with code loaded executed in second processor | ||
+ | memory. The entry point is at an offset from the start of the ROM code or | ||
+ | from the execution address of a file. | ||
− | With careful selection of opcodes the language entry can be executed as 6502 code and by the target CPU, see [[Multiple CPU language entry]]. | + | With careful selection of opcodes the language entry can be executed as 6502 |
+ | code and by the target CPU, see [[Multiple CPU language entry]]. | ||
− | Only the MOS should call the language entry point. The MOS provides the <code>[[OSBYTE &8E|*FX 142,n]]</code> command to invoke a language by its ROM number. Paged ROMs, upon recognising the *command for their language within their service routine, should issue OSBYTE call 142 with X equal to their ROM number, found in location &F4 and also in X on entry to the service entry. | + | Only the MOS should call the language entry point. The MOS provides the |
+ | <code>[[OSBYTE &8E|*FX 142,n]]</code> command to invoke a language by its | ||
+ | ROM number. Paged ROMs, upon recognising the *command for their language | ||
+ | within their service routine, should issue OSBYTE call 142 with X equal to | ||
+ | their ROM number, found in location &F4 and also in X on entry to the | ||
+ | service entry. | ||
− | The official way to enter BASIC is by the <code>*BASIC</code> command. The MOS recognises it on the language's behalf, and selects the ROM in which BASIC was found (the highest priority valid ROM with a language entry but no service entry). If there is no BASIC ROM, it treats the *command as unrecognised and offers it to the sideways ROMs and then the current filing system. In this way third parties can replace BASIC with an extended version on disk or in other ROMs, or can select a BASIC appropriate for a non-6502 second processor. | + | The official way to enter BASIC is by the <code>*BASIC</code> command. The |
+ | MOS recognises it on the language's behalf, and selects the ROM in which | ||
+ | BASIC was found (the highest priority valid ROM with a language entry but no | ||
+ | service entry). If there is no BASIC ROM, it treats the *command as | ||
+ | unrecognised and offers it to the sideways ROMs and then the current filing | ||
+ | system. In this way third parties can replace BASIC with an extended version | ||
+ | on disk or in other ROMs, or can select a BASIC appropriate for a non-6502 | ||
+ | second processor. | ||
− | When language code is executed, it is entered at the entry point appropriate for the code indicated by the ROM type. This entry point is at an offset from the code's start address. The start address is &8000 for a ROM being executed in the I/O processor, either &8000 or the Tube transfer address for a ROM copied to a second processor, a file's execution address for a file loaded and executed in a second processor, or the target address of a <code>*GO</code> command. Note that this means that to get expected results, ROM images must be saved with the execution address the same as the load address. | + | When language code is executed, it is entered at the entry point appropriate |
+ | for the code indicated by the ROM type. This entry point is at an offset | ||
+ | from the code's start address. The start address is &8000 for a ROM being | ||
+ | executed in the I/O processor, either &8000 or the Tube transfer address for | ||
+ | a ROM copied to a second processor, a file's execution address for a file | ||
+ | loaded and executed in a second processor, or the target address of a | ||
+ | <code>*GO</code> command. Note that this means that to get expected results, | ||
+ | ROM images must be saved with the execution address the same as the load | ||
+ | address. | ||
− | The ROM type byte at ''start + 6'' indicates what CPU the language code is intended to execute on. This also indicates where the code is entered to execute it. If there is no ROM header (indicated by there being no copyright string), then code is always entered at the start address. | + | The ROM type byte at ''start + 6'' indicates what CPU the language code is |
+ | intended to execute on. This also indicates where the code is entered to | ||
+ | execute it. If there is no ROM header (indicated by there being no copyright | ||
+ | string), then code is always entered at the start address. | ||
==== 6502 Code (types 0-2) ==== | ==== 6502 Code (types 0-2) ==== | ||
− | 6502 code is entered at the start address with A=1. Note that 6502 BASIC is special in that the ROM type byte is &60, indicating a language with no service entry. | + | 6502 code is entered at the start address with A=1. Note that 6502 BASIC is |
+ | special in that the ROM type byte is &60, indicating a language with no | ||
+ | service entry. | ||
A 6502 language entry point is entered with registers set as following: | A 6502 language entry point is entered with registers set as following: | ||
Line 368: | Line 609: | ||
|} | |} | ||
− | Prior to MOS 3.50, a 6502 language ROM could either be assembled to run at &8000, and work on either side of the Tube (eg BASIC), or could be assembled at a different address, and only run as a language on the host 6502 (eg HIBASIC). | + | Prior to MOS 3.50, a 6502 language ROM could either be assembled to run at |
+ | &8000, and work on either side of the Tube (eg BASIC), or could be assembled | ||
+ | at a different address, and only run as a language on the host 6502 (eg | ||
+ | HIBASIC). | ||
− | MOS 3.50 supports relocation tables that allow one ROM to operate at either &8000 on the host 6502 or a higher address on the second processor, by performing address relocation as it is copied across. In MOS 3.50, BASIC, EDIT and View have relocation tables. | + | MOS 3.50 supports relocation tables that allow one ROM to operate at either |
+ | &8000 on the host 6502 or a higher address on the second processor, by | ||
+ | performing address relocation as it is copied across. In MOS 3.50, BASIC, | ||
+ | EDIT and View have relocation tables. | ||
− | Note that no range checks are made: the host transfers the entire 16K of ROM space for all second processor types, and the 6502 Tube OS in RAM at &F800 does not prevent itself being overwritten. This means that the highest possible Tube relocation address is &B800; a <16K ROM image, or a ROM image with unwanted data like the relocation tables, cannot be placed in the second processor at a higher address to increase HIMEM. | + | Note that no range checks are made: the host transfers the entire 16K of ROM |
+ | space for all second processor types, and the 6502 Tube OS in RAM at &F800 | ||
+ | does not prevent itself being overwritten. This means that the highest | ||
+ | possible Tube relocation address is &B800; a <16K ROM image, or a ROM image | ||
+ | with unwanted data like the relocation tables, cannot be placed in the | ||
+ | second processor at a higher address to increase HIMEM. | ||
==== PDP-11 Code (type 7) ==== | ==== PDP-11 Code (type 7) ==== | ||
− | PDP-11 code is entered at the offset from the start address specified after the Tube transfer address. If there is no Tube transfer address, the code is entered at the start address. | + | PDP-11 code is entered at the offset from the start address specified after |
+ | the Tube transfer address. If there is no Tube transfer address, the code is | ||
+ | entered at the start address. | ||
==== Z80 Code (type 8) ==== | ==== Z80 Code (type 8) ==== | ||
Line 381: | Line 635: | ||
==== 32016 Code (type 9) ==== | ==== 32016 Code (type 9) ==== | ||
− | 32016 code is entered at the offset from the start address specified after the Tube transfer address. If the ROM type byte indicates that there is no Tube transfer address, the offset is still used, and a dummy Tube transfer address must be present. Code is entered with R1=1. | + | 32016 code is entered at the offset from the start address specified after |
+ | the Tube transfer address. If the ROM type byte indicates that there is no | ||
+ | Tube transfer address, the offset is still used, and a dummy Tube transfer | ||
+ | address must be present. Code is entered with R1=1. | ||
==== 80186 Code (type 11) ==== | ==== 80186 Code (type 11) ==== | ||
− | 80186 code is entered at the start address with AL=&01 if DOS has not been booted, and AL<>&01 if DOS has been booted. | + | 80186 code is entered at the start address with AL=&01 if DOS has not been |
+ | booted, and AL<>&01 if DOS has been booted. | ||
==== ARM Code (type 13) ==== | ==== ARM Code (type 13) ==== | ||
− | If bit 7 of the ROM type byte is set (ie, &CD or &ED), indicating the presence of a service entry, then bytes start+0 to start+2 are a 24-bit | + | If bit 7 of the ROM type byte is set (ie, &CD or &ED), indicating the |
+ | presence of a service entry, then bytes start+0 to start+2 are a 24-bit | ||
+ | entry address. | ||
− | If bit 7 of the ROM type byte is clear (ie, &4D), indicating the absence of a service entry, then bytes start+0 to start+3 are a 32-bit execution address, overlapping the service entry point which does not exist.<ref>[http://mdfs.net/Docs/Comp/Acorn/RomFS.txt ROMFS Manual] (OCR by J.G.Harston)</ref> When stored as a RomFS file, the Tube transfer address is the file's load address (even though the ROM type byte indicates no tranfer address exists), and is followed by the file's length. | + | If bit 7 of the ROM type byte is clear (ie, &4D), indicating the absence of |
+ | a service entry, then bytes start+0 to start+3 are a 32-bit execution | ||
+ | address, overlapping the service entry point which does not | ||
+ | exist.<ref>[http://mdfs.net/Docs/Comp/Acorn/RomFS.txt ROMFS Manual] (OCR by | ||
+ | J.G.Harston)</ref> When stored as a RomFS file, the Tube transfer address is | ||
+ | the file's load address (even though the ROM type byte indicates no tranfer | ||
+ | address exists), and is followed by the file's length. | ||
− | If byte at start+0 is &4C, then the Sprow ARMCoPro uses bytes start+1 to start+2 as the 16-bit entry address. | + | If byte at start+0 is &4C, then the Sprow ARMCoPro uses bytes start+1 to |
+ | start+2 as the 16-bit entry address. | ||
=== Language memory allocation === | === Language memory allocation === | ||
Line 410: | Line 677: | ||
=== Service memory allocation === | === Service memory allocation === | ||
− | Service ROMs can claim pages of shared and private workspace (1 page = 256 bytes) in the I/O processor. Service code is only ever executed in the 6502 I/O processor. | + | Service ROMs can claim pages of shared and private workspace (1 page = 256 |
+ | bytes) in the I/O processor. Service code is only ever executed in the 6502 | ||
+ | I/O processor. Workspace will be in main memory, unless the machine is a | ||
+ | Master and the ROMs have been written to use [[HAZEL]]. | ||
− | Different categories of service (such as filing systems, interrupt handlers and utilities) are permitted to used certain fixed memory areas depending on the purpose. | + | Different categories of service (such as filing systems, interrupt handlers |
+ | and utilities) are permitted to used certain fixed memory areas depending on | ||
+ | the purpose. For full details please see The New Advanced User Guide. | ||
− | Certain service code uses I/O processor memory between OSHWM and HIMEM to function, either necessarily or optionally for speed. Examples are *COMPACT or *SRLOAD. Such usage should be avoided where possible, and must be documented, as such commands can lead to user data loss. | + | Certain service code uses I/O processor memory between OSHWM and HIMEM to |
+ | function, either necessarily or optionally for speed. Examples are | ||
+ | <code>*COMPACT</code> or <code>*SRLOAD</code>. Such usage should be avoided | ||
+ | where possible, and must be documented, as such commands can lead to user | ||
+ | data loss. | ||
=== Tube memory allocation === | === Tube memory allocation === | ||
− | When the Tube is active, the host Tube support code uses all the memory below OSHWM in the I/O processor that would otherwise be allocated to a host-based language. OSHWM to HIMEM remains available for application or user use. Specialised Tube-aware languages or utilities can make use of this area using OS calls, such as the printer buffer utility supplied with the 65C102 coprocessor. Such use is ultimately under the control of the language processor | + | When the Tube is active, the host Tube support code uses all the memory |
+ | below OSHWM in the I/O processor that would otherwise be allocated to a | ||
+ | host-based language. OSHWM to HIMEM remains available for application or | ||
+ | user use. Specialised Tube-aware languages or utilities can make use of this | ||
+ | area using OS calls, such as the printer buffer utility supplied with the | ||
+ | 65C102 coprocessor. Such use is ultimately under the control of the language | ||
+ | processor – as in a non-Tube system, service code in the I/O processor | ||
+ | should not normally use the region without permission. | ||
=== Paged ROM service calls === | === Paged ROM service calls === | ||
{{main|Paged ROM service calls}} | {{main|Paged ROM service calls}} | ||
− | Whenever a service is required from paged ROMs, the MOS pages in each valid slot in descending order and calls the service entry point at &8003. Every ROM must have a JMP instruction at this address except for BASIC, which the MOS treats specially. | + | Whenever a service is required from paged ROMs, the MOS pages in each valid |
+ | slot in descending order and calls the service entry point at &8003. Every | ||
+ | ROM must have a JMP instruction at this address except for BASIC, which the | ||
+ | MOS treats specially. | ||
− | This daisy-chaining means that a service call must always return; if a ROM does not recognise the call it must return with all registers preserved, and if it has responded to it completely then it must return with A=0 so that all lower ROMs are passed a null service call. | + | This daisy-chaining means that a service call must always return; if a ROM |
+ | does not recognise the call it must return with all registers preserved, and | ||
+ | if it has responded to it completely then it must return with A=0 so that | ||
+ | all lower ROMs are passed a null service call. | ||
=== Extended vectors === | === Extended vectors === | ||
− | The MOS call vectors cannot point directly into the paged ROM space, as its contents may be incorrect at the time a vector is followed. Instead, they must point to one of the extended vector routines in the MOS. These are stubs that call an intriguing common routine, which pages in the appropriate ROM, calls the actual address and restores the old ROM slot on exit. | + | The MOS call vectors cannot point directly into the paged ROM space, as its |
+ | contents may be incorrect at the time a vector is followed. Instead, they | ||
+ | must point to one of the extended vector routines in the MOS. These are | ||
+ | stubs that call an intriguing common routine, which pages in the appropriate | ||
+ | ROM, calls the actual address and restores the old ROM slot on exit. | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 436: | Line 729: | ||
! Name !! Address !! Name !! Address !! Routine !! Vector !! (MOS 1.20) !! ROM slot !! (MOS 1.20) | ! Name !! Address !! Name !! Address !! Routine !! Vector !! (MOS 1.20) !! ROM slot !! (MOS 1.20) | ||
|- | |- | ||
− | | | + | | – || – || IND3V || &0234 || &FF4E || ''evt''+&4E || (&0DED) || ''evt''+&50 || (&0DEF) |
|- | |- | ||
− | | | + | | – || – || IND2V || &0232 || &FF4B || ''evt''+&4B || (&0DEA) || ''evt''+&4D || (&0DEC) |
|- | |- | ||
− | | | + | | – || – || IND1V || &0230 || &FF48 || ''evt''+&48 || (&0DE7) || ''evt''+&4A || (&0DE9) |
|- | |- | ||
− | | | + | | – || – || CNPV || &022E || &FF45 || ''evt''+&45 || (&0DE4) || ''evt''+&47 || (&0DE6) |
|- | |- | ||
− | | | + | | – || – || REMV || &022C || &FF42 || ''evt''+&42 || (&0DE1) || ''evt''+&44 || (&0DE3) |
|- | |- | ||
− | | | + | | – || – || INSV || &022A || &FF3F || ''evt''+&3F || (&0DDE) || ''evt''+&41 || (&0DE0) |
|- | |- | ||
− | | | + | | – || – || KEYV || &0228 || &FF3C || ''evt''+&3C || (&0DDB) || ''evt''+&3E || (&0DDD) |
|- | |- | ||
− | | | + | | – || – || [[VDUV]] || &0226 || &FF39 || ''evt''+&39 || (&0DD8) || ''evt''+&3B || (&0DDA) |
|- | |- | ||
− | | | + | | – || – || NETV || &0224 || &FF36 || ''evt''+&36 || (&0DD5) || ''evt''+&38 || (&0DD7) |
|- | |- | ||
− | | | + | | – || – || UPTV || &0222 || &FF33 || ''evt''+&33 || (&0DD2) || ''evt''+&35 || (&0DD4) |
|- | |- | ||
− | | | + | | – || – || EVNTV || &0220 || &FF30 || ''evt''+&30 || (&0DCF) || ''evt''+&32 || (&0DD1) |
|- | |- | ||
− | | | + | | – || – || [[FSCV]] || &021E || &FF2D || ''evt''+&2D || (&0DCC) || ''evt''+&2F || (&0DCE) |
|- | |- | ||
| [[OSFIND]] || &FFCE || FINDV || &021C || &FF2A || ''evt''+&2A || (&0DC9) || ''evt''+&2C || (&0DCB) | | [[OSFIND]] || &FFCE || FINDV || &021C || &FF2A || ''evt''+&2A || (&0DC9) || ''evt''+&2C || (&0DCB) | ||
Line 482: | Line 775: | ||
| [[OSCLI]] || &FFF7 || CLIV || &0208 || &FF0C || ''evt''+&0C || (&0DAB) || ''evt''+&0E || (&0DAD) | | [[OSCLI]] || &FFF7 || CLIV || &0208 || &FF0C || ''evt''+&0C || (&0DAB) || ''evt''+&0E || (&0DAD) | ||
|- | |- | ||
− | | | + | | – || – || IRQ2V || &0206 || &FF09 || ''evt''+&09 || (&0DA8) || ''evt''+&0B || (&0DAA) |
|- | |- | ||
− | | | + | | – || – || IRQ1V || &0204 || &FF06 || ''evt''+&06 || (&0DA5) || ''evt''+&08 || (&0DA7) |
|- | |- | ||
− | | | + | | – || – || BRKV || &0202 || &FF03 || ''evt''+&03 || (&0DA2) || ''evt''+&05 || (&0DA4) |
|- | |- | ||
− | | | + | | – || – || USERV || &0200 || &FF00 || ''evt''+&00 || (&0D9F) || ''evt''+&02 || (&0DA1) |
|} | |} | ||
− | ''evt'', the base address of the extended vector table, can be found by calling OSBYTE &A8; the LSB is returned in X and the MSB in Y. In all operating systems its value is &0D9F. | + | ''evt'', the base address of the extended vector table, can be found by |
+ | calling [[OSBYTE &A8]]; the LSB is returned in X and the MSB in Y. In all | ||
+ | operating systems its value is &0D9F. | ||
− | For instance, a ROM may execute the following to redirect OSFILE to its routine at &B000: | + | For instance, a ROM may execute the following to redirect OSFILE to its |
+ | routine at &B000: | ||
<pre>... | <pre>... | ||
PHP \ save interrupt state | PHP \ save interrupt state | ||
Line 519: | Line 815: | ||
...</pre> | ...</pre> | ||
− | If filing system vectors are claimed, after they are changed the ROM should issue [[Paged ROM service calls|service call]] &0F. | + | If filing system vectors are claimed, after they are changed the ROM should |
+ | issue [[Paged ROM service calls|service call]] &0F. | ||
== References == | == References == |
Latest revision as of 18:39, 2 August 2023
Paged ROM is a system used in all 8 bit BBC series computers and in the Electron, whereby a large pool of ROM-based software can be used all at once by dividing it into 16K slots and paging one at a time into the address space. Depending on the hardware the pool may be 64K up to 256K in size. The MOS manages paged ROMs automatically and provides an extensive API to ROM-based software. There are very few problems in practice, as nearly all applications stick to the API.
In a diagram of memory where the address space runs from bottom to top, the paged ROM slots appear parallel to the main memory map, extending away to the side. For this reason the system is also known as sideways ROM. Later models and custom machines have RAM fitted in some slots and this is usually called sideways RAM rather than 'paged RAM'.
The equivalent system in the Archimedes series are Modules.
Contents
Rationale
It is clear that the BBC Micro was designed with paged ROMs in mind from the start. As the 6502 CPU cannot address more than 64K, a way was needed to fit in all current and future firmware (such as disc filing systems, ROM filing systems, device drivers and applications) without taking up too much of the address space.
In addition, some classes of application (termed 'languages' by Acorn but not necessarily languages) needed to spare as much RAM as possible for the user. In an education environment they had to load up faster and more reliably than cassettes but require less capital outlay than floppy discs. (Drives and interfaces were prohibitively expensive at the time, especially for local education authorities.)
Acorn found that most of these pieces of firmware were loosely coupled and so could share the address space. EPROMs also made a good choice for distributing 'languages', given the needs of the market.
Features of paged ROM
Languages
Languages are ROM based applications that take control of the computer on power-up and interface between the user and the operating system. BASIC, LISP and FORTH are examples of language ROMs released at the time. In modern terms they would be called shells, and so they need not be programming languages, or command line based (such as the word processors View and Wordwise). They may even be user applications.
Exactly one language is active at any time. The MOS starts one automatically
on power up, and can invoke another on command by its slot number, but the
usual way of starting a language is by name, through a *command passed to
its service entry point by the MOS. At the very least, each language allows
the user to enter *commands to select another language (the cue is
*
by convention, although a language may use another character
or interface.)
On power up and hard reset the Models A, B and B+ and Electron will select the language in the highest logical slot number. The Master and Master Compact store the slot number of the current language in non-volatile memory and restore it on power up and hard reset. On soft reset the 'current language' is re-selected.
Service ROMs
The service routine, which must be present in all ROMs except for BASIC, answers a query or performs some function for the MOS and then returns. The service routine may vary in size and complexity up to 100 per cent of the ROM. A valid ROM that has no language entry point is termed a service ROM (although languages are free to offer extensive service routines as well.)
This class of ROM includes all disc filing systems, utility ROMs and device drivers, as these do not interface continually with the user but are invoked by programs, languages and the MOS.
ROM filing system
RFS ROMs are a special class of service ROM that hosts data files. These ROMs act as a virtual tape loop, read by the ROM Filing System (RFS) built into the MOS. The MOS can search for files automatically but each file is serially accessed and of course, read only.
The service routine is small, typically implementing just the two relevant RFS calls, to save as much space as possible for the data itself. (A larger service routine can decompress the data transparently; such a ROM has recently been developed.) Since the Cassette and ROM Filing Systems share most of their code, the data consists of a stream of bytes in a variation of the Acorn cassette format.
RFS ROMs allow BASIC programs and machine code to be loaded from EPROM into main memory, so that ROM based machine code versions do not need to be assembled.
Sideways RAM
See also the main article: Sideways RAM
The B+ 128K and Master 128 provide 64 kilobytes of sideways RAM: in slots 12, 13 and the two highest or lowest slots in the B+, and in slots 4 to 7 in the Master. These slots behave like sideways ROMs in every respect except that they are writeable. They can therefore provide all the above features, or serve as general purpose RAM to suitably aware programs.
Note that some commercial ROM-based software attempts to overwrite itself so that it cannot be copied and run from sideways RAM. Other titles expect to see a power-up state before they will function, in the hope that a preceding power-down erased volatile RAM devices, except that data can persist in static RAM for some time and all types of reset can be simulated in software. Care must also be taken that a valid ROM is not corrupted so as to hang the machine on the next ROM service call. If such an event occurs the computer must be powered down to clear the memory.
Extended addressing
These machines also provide extended addressing so that sideways RAM can be handled by any MOS call that takes a 32-bit address, thereby providing a continuous 64K of extra memory. A version of BASIC named BAS128 has a similar but independent feature. BAS128 puts the display into shadow mode, runs in main memory and uses sideways RAM for the user's program and variables. Machine code can be assembled and executed there, as the assembler translates virtual addresses to their actual locations in sideways RAM – provided that no references are made between sideways RAM slots.[1] Code can also be assembled there to run in main memory under OPTions 4 to 7.
Hardware
In all these machines, paged ROMs appear in a 16K window from &8000 to &BFFF. Each paged ROM is therefore assembled to an absolute address of &8000. ROMs smaller than 16K are duplicated until they fill the address space. The top 16K (&C000..&FFFF) of memory is reserved for the MOS, FRED, JIM, SHEILA (and HAZEL), which are permanently available.
Models A and B
These computers are fitted with five sockets for 16K ROMs. At first all the sockets were taken up by the MOS, in 4K EPROMs, and BASIC; but once the MOS matured and was released as a mask ROM, the jumpers were reconfigured to provide paged ROM service. The MOS sits in its own dedicated socket, and BASIC in one of the other four. BASIC need not be present; it can be replaced by any other 'language' which will take control of the machine and (hopefully) provide all the same functionality.
The heart of the paged ROM system is IC 76, a 74LS163 quad latch known as ROMSEL. It appears in SHEILA in the low four bits of address &FE30. It is a write-only register but the MOS maintains a copy of the current ROM selection, in RAM at address &F4. A paged ROM can therefore discover its slot number by reading this address.
Only the low two outputs of ROMSEL are connected, to a quad decoder in IC 20 which provides Chip Select signals to four of the ROM sockets. The easternmost of these is assigned slot number 15, which has highest priority for all ROM service calls and resources. The others are assigned slot numbers 14 13, and 12; the fifth, westernmost socket contains the MOS. The table below lists the slot assignments according to the circuit diagram, though it was later recommended to put the DFS in the lowest slot:
Socket number (hex) | Assigned device and contents |
---|---|
F | IC 101, "AUX ROM", typically containing BASIC or BASIC II |
E | IC 100, "AUX ROM", typically empty |
D | IC 88, "DISC&NET ROM", typically empty |
C | IC 52, "BASIC ROM", typically containing the DFS |
B | Mapped to slot &F |
A | Mapped to slot &E |
9 | Mapped to slot &D |
8 | Mapped to slot &C |
7 | Mapped to slot &F |
6 | Mapped to slot &E |
5 | Mapped to slot &D |
4 | Mapped to slot &C |
3 | Mapped to slot &F |
2 | Mapped to slot &E |
1 | Mapped to slot &D |
0 | Mapped to slot &C |
Homemade ROM expansions can connect spare address lines to the upper two outputs of ROMSEL and deliver multiple slots from one socket; the MOS does not need to be modified as it will assign lower numbers to the extra applications found.
A large number of commercial ROM expansion boards have also been produced; these connect to the motherboard in various ways and some offer extra features, such as shadow RAM which inspired the feature in the Model B+. The largest has sixteen sockets so as to fill all available slots, four of these replacing the motherboard sockets that have been covered over. These boards either tap the unused outputs of ROMSEL or replicate the entire latch. For the most part they are compatible but reliability can be a problem (due to the mechanical difficulties and to overheating.)
Certain commercial ROM titles (notably Mini Office II and SPELL-MASTER) were supplied on their own carrier boards and used custom circuits and protocols to deliver more than 16 KB from their one assigned slot. These systems are self contained and independent of ROMSEL.
Electron
A paged ROM system was retained to allow expansion modules to supply firmware, but as an entry level machine few modules were expected to be present at once, and so efficient allocation of ROM slots was sacrificed for economy. The table below lists the standard slot assignments:
Socket number (hex) | Assigned device and contents |
---|---|
F | External ROM (+ disables internal devices) |
E | |
D | |
C | |
B | IC 2, BASIC II |
A | |
9 | Keyboard |
8 | |
7 | External ROM (internal devices must first be disabled) |
6 | |
5 | |
4 | |
3 | |
2 | |
1 | |
0 |
The ULA exposes a ROM selection register in SHEILA at address &FE05. It is a write-only register but the MOS maintains a copy of the current ROM selection, in RAM at address &F4. A paged ROM can therefore discover its slot number by reading this address. Expansion modules with ROMs must partially emulate (track) the ULA and, if providing multiple ROM sockets, must supply their own selection register at address &FE05.
The ULA can either be in 'external ROM mode' or 'internal ROM mode'. External ROM mode is enabled when a value between 12 and 15 is written to &FE05. In this mode the keyboard and BASIC are disabled, and it is up to an expansion module to supply paged ROM content. Internal ROM mode is enabled when a value between 8 and 11 is written to &FE05. This also selects the keyboard (slots 8 or 9) or BASIC ROM (10 or 11, both the same image); the relevant device will stay enabled even if a value of 0 to 7 is later written to &FE05. If the expansion module responds to paged ROM addresses at this time there will be bus contention, and a corrupted value will appear on the data bus.
Certain expansion modules (such as those fitted with Slogger's Electron
Expansion 2.0) can host ROMs in slots 12 to 15, and languages in these slots
can start up automatically. Languages in slots 0 to 7 can only be entered by
their *command or by *FX 142,n
, as the MOS must disable the
internal ROM.
Model B+
The Model B's motherboard was redesigned to make use of the newer ICs available, and issued as the Model B+. There are six 32K sockets on the west side of the motherboard. One of these is permanently assigned to BASIC and the MOS; the other five can accept 32K devices (in which case each half appears in a separate 16K slot) or any smaller device (in which case the contents are duplicated to fill the two slots.) A jumper is provided for each socket to support 16K or 32K ROMs, and another jumper allows BASIC to be moved to a low slot to allow another language to take priority. In the B+ 128K, a total of 64K of sideways RAM can be mapped into slots that have no corresponding ROM socket. The DFS recognises this on hard reset and increases the memory size displayed in the banner.
From the B+ User Guide: "The sockets are numbered, counting anticlockwise from the MOS/BASIC socket at the top right, 14/15, 10/11, 8/9, 2/3, 4/5, and 6/7." The table below lists the standard slot assignments:
Socket number (hex) | Assigned device and contents | |
---|---|---|
F | IC 71, BASIC II or sideways RAM (B+ 128K only) | |
E | ||
D | Sideways RAM (B+ 128K only) | |
C | ||
B | IC 68, DFS 2.26 + SRAM 1.05 | |
A | ||
9 | IC 62 | top 16K |
8 | bottom 16K | |
7 | IC 57 | top 16K |
6 | bottom 16K | |
5 | IC 44 | top 16K |
4 | bottom 16K | |
3 | IC 35 | top 16K |
2 | bottom 16K | |
1 | Sideways RAM (B+ 128K only) or BASIC II (alternative location) | |
0 |
The upper 12K of shadow RAM appears at locations &8000 to &AFFF when a value above 127 is written to ROMSEL. The memory is also accessible via OSWORD calls 5 and 6 (q.v.) Code executed from the top 4K of this memory also 'sees' and can manipulate video RAM, i.e. shadow RAM in shadow mode or main RAM in non-shadow mode.[2] The MOS will not search for languages or service ROMs in shadow RAM.
Master
Further advances meant that the Master firmware was embedded in one 128K device. This is assigned the highest seven ROM slots; the MOS takes up the remaining 16K and spills into spare space in the paged ROMs. Incidentally the ROM, a custom chip known as EROS, is 'too big for its boots'; users wanting to patch bugs in the firmware are forced to replace the chip with a 32 pin EPROM on a carrier board to emulate the non-standard pinout.
There is one 16K socket on the motherboard, operating like the ones in the Model B and serving slot 8; and two 32K sockets like those in the Model B+ serving slots 4 to 7. These last four slots are normally turned over to sideways RAM, deactivating the sockets. Slots 0 to 3 are assigned (again in pairs) to the cartridge sockets on top of the machine. The table below lists the standard slot assignments:
Socket number (hex) | Assigned device and contents | |
---|---|---|
F | IC 24, EROS | Terminal 1.20 + Tube host + CFS + character set |
E | View B3.0 + MOS code[3] | |
D | Acorn ADFS 1.50 | |
C | BASIC IV | |
B | Edit IV 1.00 | |
A | ViewSheet B1.0 | |
9 | DFS 2.24 + SRAM 1.04 | |
8 | IC 27 | Often used for ANFS |
7 | Sideways RAM or IC 37 | top 16K |
6 | bottom 16K | |
5 | Sideways RAM or IC 41 | top 16K |
4 | bottom 16K | |
3 | SK4, Front cartridge slot | top 16K |
2 | bottom 16K | |
1 | SK3, Rear cartridge slot | top 16K |
0 | bottom 16K |
Since alternative languages and filing systems cannot be placed 'above' the
Acorn firmware to take priority, the MOS provides a 'soft unplugging'
feature. *UNPLUG n
and *INSERT n
update the
non-volatile memory so that the MOS will ignore or consider, respectively,
firmware in slot n
. The commands take effect on the next hard
reset.
ROMSEL in this machine is a read-write latch at &FE30, but a RAM copy is still maintained at &F4 for compatibility.
The upper 12K of shadow RAM, which was available to the user in the B+, is split in two and allocated to the MOS (as ANDY) and paged ROMs (as HAZEL, which lies outside the paged ROM address space). The B+ User Guide warns: "Note: references to this 12K of memory which are made in this manual are not necessarily applicable to other Acorn products."
Master Compact
This machine follows the Master layout but the firmware is reduced to 64K. The ROM is usually soldered in and carries the MOS and three paged ROM slots with utilities, ADFS and BASIC. There is also a 64K socket and Acorn issued a ROM for it containing applications. This ROM is optional and so not considered part of the firmware.
There are three 16K sockets and one 32K socket for the user's devices. None of these are 'hidden' by sideways RAM, which is permanently available.
Socket number (hex) | Assigned device and contents | |
---|---|---|
F | IC 49, MOS & PL 12 on north | Utilities |
E | BASIC IV | |
D | ADFS 2.10 | |
C | IC 49 & PL 12 on south | top 16K |
B | second 16K | |
A | third 16K | |
9 | bottom 16K | |
8 | IC 29 | |
7 | 64 KB sideways RAM | |
6 | ||
5 | ||
4 | ||
3 | IC 17 | |
2 | IC 23 | |
1 | IC 38 & PL 11 on south or expansion port & PL 11 on north | top 16K |
0 | bottom 16K |
Operation
Any code may change the ROM paging register at will. However, a routine that returns to its caller is expected to preserve the ROM selection on exit, unless changing the selection is its purpose. This includes system calls, interrupt service routines and code called from an interpreted language.
Conversely, all code must mirror changes to ROMSEL in the RAM copy so that the routines that serve or interrupt it may restore the ROM slot it expects to see. As is often mentioned, the MOS runs under constant interrupts. Many of these may result in service calls and the OS will page in ROMs unexpectedly to issue them. It is therefore essential that code that accesses paged ROMs directly keep the RAM copy of the paging register up to date.
To select a ROM slot, its number must first be written to the RAM copy at &F4. If the machine is an Electron, and the target slot number is 7 or less, a value between 12 and 15 must be written to &FE05 to turn off internal ROM. Then the number is written to ROMSEL, &FE05 (Electron) or &FE30 (other machines.) When code running in the paged ROM area changes between slots, the op-code after the instruction that stores ROMSEL should be the same in the old and new slots so that the address bus and Chip Select signals may stabilise without ill effect.
A paged ROM slot may also be selected platform-independently, as a side effect of OSRDSC or OSBYTE &8F. Use of these system calls eliminates the aforementioned stabilisation delay.
There is nothing to prevent a language or service software taking up more than 16K; when the firmware has control it can page in another part of itself with a revolving bookcase subroutine (identical and at the same location in all slots; for example in Inter-WORD.) Languages need not save the old slot number except for reference; service routines must push the slot number (or private latch setting) on the stack, and pop it on exit. The only caveat is that a service routine must be available to the MOS at all times.
An alternative (and less intensive) method is to have a language resident in one 16K slot, and pass user MOS calls (usually OSWORD) which are handled by one or more of the other slots.
API
ROM headers
On power up or hard reset the MOS scans all slots for a valid ROM header, disabling slots where no header is found. This is to prevent hangups caused by jumping into empty sockets or uninitialised RAM. It does not however protect against malfunctions due to a slightly corrupted ROM image.
Every language or service ROM must provide the following header at addresses &8000 onwards. This is also used for code loaded and executed in second processor memory. See also Code header.
Start address (hex) | Value(s) (hex) | Meaning |
---|---|---|
8000 | .. .. .. |
Language entry point |
8003 | .. .. .. |
Service entry point |
8006 | tt |
ROM type byte:
b7 = ROM contains a service entry 0 6502 BASIC 8 Z80 1 Turbo6502 9 32016 2 6502 10 - 3 68000 11 80186 4 - 12 80286 5 - 13 ARM 6 - 14 - 7 PDP-11 15 - |
8007 | cc |
Offset to copyright string |
8008 | bb |
Binary version number, for user inspection only |
8009 | .. .. ..
|
ROM title, displayed before entering language |
00 .. .. |
(Optional) Version string in the format NUL + "n.nn (dd mmm yyyy)" | |
00 .. .. |
(Optional) Other data here is ignored. | |
8000+cc
|
00 28 43 29
|
NUL and "(C)", required for MOS acceptance, name of author, etc |
ll ml hm hh
|
(Optional) Tube transfer address. +pointer to 6502 relocation bit-map descriptor table (MOS 3.50) | |
ll ml hm hh
|
(Optional) Offset from start of ROM to 32016 Tube execution address.[4] Offset from start of ROM to PDP-11 Tube execution address.[5] |
Language entry
A ROM offering a language must set bit 6 of its ROM type byte and must provide an entry point at an address appropriate for the target CPU. A ROM header is also checked for with code loaded executed in second processor memory. The entry point is at an offset from the start of the ROM code or from the execution address of a file.
With careful selection of opcodes the language entry can be executed as 6502 code and by the target CPU, see Multiple CPU language entry.
Only the MOS should call the language entry point. The MOS provides the
*FX 142,n
command to invoke a language by its
ROM number. Paged ROMs, upon recognising the *command for their language
within their service routine, should issue OSBYTE call 142 with X equal to
their ROM number, found in location &F4 and also in X on entry to the
service entry.
The official way to enter BASIC is by the *BASIC
command. The
MOS recognises it on the language's behalf, and selects the ROM in which
BASIC was found (the highest priority valid ROM with a language entry but no
service entry). If there is no BASIC ROM, it treats the *command as
unrecognised and offers it to the sideways ROMs and then the current filing
system. In this way third parties can replace BASIC with an extended version
on disk or in other ROMs, or can select a BASIC appropriate for a non-6502
second processor.
When language code is executed, it is entered at the entry point appropriate
for the code indicated by the ROM type. This entry point is at an offset
from the code's start address. The start address is &8000 for a ROM being
executed in the I/O processor, either &8000 or the Tube transfer address for
a ROM copied to a second processor, a file's execution address for a file
loaded and executed in a second processor, or the target address of a
*GO
command. Note that this means that to get expected results,
ROM images must be saved with the execution address the same as the load
address.
The ROM type byte at start + 6 indicates what CPU the language code is intended to execute on. This also indicates where the code is entered to execute it. If there is no ROM header (indicated by there being no copyright string), then code is always entered at the start address.
6502 Code (types 0-2)
6502 code is entered at the start address with A=1. Note that 6502 BASIC is special in that the ROM type byte is &60, indicating a language with no service entry.
A 6502 language entry point is entered with registers set as following:
Accumulator | Function |
---|---|
0 | Enter Tube environment with no language selected. |
1 | Enter language. |
2 | Return in Y the next character of the soft key expansion set up by call 3. |
3 | Set up soft key expansion for the key in Y, and return its length in Y. |
Prior to MOS 3.50, a 6502 language ROM could either be assembled to run at &8000, and work on either side of the Tube (eg BASIC), or could be assembled at a different address, and only run as a language on the host 6502 (eg HIBASIC).
MOS 3.50 supports relocation tables that allow one ROM to operate at either &8000 on the host 6502 or a higher address on the second processor, by performing address relocation as it is copied across. In MOS 3.50, BASIC, EDIT and View have relocation tables.
Note that no range checks are made: the host transfers the entire 16K of ROM space for all second processor types, and the 6502 Tube OS in RAM at &F800 does not prevent itself being overwritten. This means that the highest possible Tube relocation address is &B800; a <16K ROM image, or a ROM image with unwanted data like the relocation tables, cannot be placed in the second processor at a higher address to increase HIMEM.
PDP-11 Code (type 7)
PDP-11 code is entered at the offset from the start address specified after the Tube transfer address. If there is no Tube transfer address, the code is entered at the start address.
Z80 Code (type 8)
Z80 code is entered at the start address with A=1.
32016 Code (type 9)
32016 code is entered at the offset from the start address specified after the Tube transfer address. If the ROM type byte indicates that there is no Tube transfer address, the offset is still used, and a dummy Tube transfer address must be present. Code is entered with R1=1.
80186 Code (type 11)
80186 code is entered at the start address with AL=&01 if DOS has not been booted, and AL<>&01 if DOS has been booted.
ARM Code (type 13)
If bit 7 of the ROM type byte is set (ie, &CD or &ED), indicating the presence of a service entry, then bytes start+0 to start+2 are a 24-bit entry address.
If bit 7 of the ROM type byte is clear (ie, &4D), indicating the absence of a service entry, then bytes start+0 to start+3 are a 32-bit execution address, overlapping the service entry point which does not exist.[7] When stored as a RomFS file, the Tube transfer address is the file's load address (even though the ROM type byte indicates no tranfer address exists), and is followed by the file's length.
If byte at start+0 is &4C, then the Sprow ARMCoPro uses bytes start+1 to start+2 as the 16-bit entry address.
Language memory allocation
The current language is allocated memory in the language processor.
- 6502 code is allocated fixed memory at &400 to &7FF, zero page workspace from &00 to &8F and a variable amount of memory from the bottom of memory returned by OSBYTE &83 ("OSHWM") to the top of memory returned by OSBYTE &84 ("HIMEM"). Some languages reserve part of this allocation for their user; for example BASIC sets aside zero page &70 to &8F.
- PDP-11 code is allocated memory from &100 to the top of memory returned by OSBYTE &84.
- Z80 code is allocated memory from &100 to the top of memory returned by OSBYTE &84.
- 32016 code is allocated memory from &100 to the top of memory returned by OSBYTE &84.
- ARM code on the ARM Evaluation System is allocated memory from &1000 to the top of memory returned by SWI "OS_GetEnv".
- ARM code on the Sprow ARM Copro is allocated memory from &8000 to the top of memory returned by SWI "OS_GetEnv".
Service memory allocation
Service ROMs can claim pages of shared and private workspace (1 page = 256 bytes) in the I/O processor. Service code is only ever executed in the 6502 I/O processor. Workspace will be in main memory, unless the machine is a Master and the ROMs have been written to use HAZEL.
Different categories of service (such as filing systems, interrupt handlers and utilities) are permitted to used certain fixed memory areas depending on the purpose. For full details please see The New Advanced User Guide.
Certain service code uses I/O processor memory between OSHWM and HIMEM to
function, either necessarily or optionally for speed. Examples are
*COMPACT
or *SRLOAD
. Such usage should be avoided
where possible, and must be documented, as such commands can lead to user
data loss.
Tube memory allocation
When the Tube is active, the host Tube support code uses all the memory below OSHWM in the I/O processor that would otherwise be allocated to a host-based language. OSHWM to HIMEM remains available for application or user use. Specialised Tube-aware languages or utilities can make use of this area using OS calls, such as the printer buffer utility supplied with the 65C102 coprocessor. Such use is ultimately under the control of the language processor – as in a non-Tube system, service code in the I/O processor should not normally use the region without permission.
Paged ROM service calls
See also the main article: Paged ROM service calls
Whenever a service is required from paged ROMs, the MOS pages in each valid slot in descending order and calls the service entry point at &8003. Every ROM must have a JMP instruction at this address except for BASIC, which the MOS treats specially.
This daisy-chaining means that a service call must always return; if a ROM does not recognise the call it must return with all registers preserved, and if it has responded to it completely then it must return with A=0 so that all lower ROMs are passed a null service call.
Extended vectors
The MOS call vectors cannot point directly into the paged ROM space, as its contents may be incorrect at the time a vector is followed. Instead, they must point to one of the extended vector routines in the MOS. These are stubs that call an intriguing common routine, which pages in the appropriate ROM, calls the actual address and restores the old ROM slot on exit.
Routine | Vector | Extended vector | ||||||
---|---|---|---|---|---|---|---|---|
Name | Address | Name | Address | Routine | Vector | (MOS 1.20) | ROM slot | (MOS 1.20) |
– | – | IND3V | &0234 | &FF4E | evt+&4E | (&0DED) | evt+&50 | (&0DEF) |
– | – | IND2V | &0232 | &FF4B | evt+&4B | (&0DEA) | evt+&4D | (&0DEC) |
– | – | IND1V | &0230 | &FF48 | evt+&48 | (&0DE7) | evt+&4A | (&0DE9) |
– | – | CNPV | &022E | &FF45 | evt+&45 | (&0DE4) | evt+&47 | (&0DE6) |
– | – | REMV | &022C | &FF42 | evt+&42 | (&0DE1) | evt+&44 | (&0DE3) |
– | – | INSV | &022A | &FF3F | evt+&3F | (&0DDE) | evt+&41 | (&0DE0) |
– | – | KEYV | &0228 | &FF3C | evt+&3C | (&0DDB) | evt+&3E | (&0DDD) |
– | – | VDUV | &0226 | &FF39 | evt+&39 | (&0DD8) | evt+&3B | (&0DDA) |
– | – | NETV | &0224 | &FF36 | evt+&36 | (&0DD5) | evt+&38 | (&0DD7) |
– | – | UPTV | &0222 | &FF33 | evt+&33 | (&0DD2) | evt+&35 | (&0DD4) |
– | – | EVNTV | &0220 | &FF30 | evt+&30 | (&0DCF) | evt+&32 | (&0DD1) |
– | – | FSCV | &021E | &FF2D | evt+&2D | (&0DCC) | evt+&2F | (&0DCE) |
OSFIND | &FFCE | FINDV | &021C | &FF2A | evt+&2A | (&0DC9) | evt+&2C | (&0DCB) |
OSGBPB | &FFD1 | GBPBV | &021A | &FF27 | evt+&27 | (&0DC6) | evt+&29 | (&0DC8) |
OSBPUT | &FFD4 | BPUTV | &0218 | &FF24 | evt+&24 | (&0DC3) | evt+&26 | (&0DC5) |
OSBGET | &FFD7 | BGETV | &0216 | &FF21 | evt+&21 | (&0DC0) | evt+&23 | (&0DC2) |
OSARGS | &FFDA | ARGSV | &0214 | &FF1E | evt+&1E | (&0DBD) | evt+&20 | (&0DBF) |
OSFILE | &FFDD | FILEV | &0212 | &FF1B | evt+&1B | (&0DBA) | evt+&1D | (&0DBC) |
OSRDCH | &FFE0 | RDCHV | &0210 | &FF18 | evt+&18 | (&0DB7) | evt+&1A | (&0DB9) |
OSWRCH | &FFEE | WRCHV | &020E | &FF15 | evt+&15 | (&0DB4) | evt+&17 | (&0DB6) |
OSWORD | &FFF1 | WORDV | &020C | &FF12 | evt+&12 | (&0DB1) | evt+&14 | (&0DB3) |
OSBYTE | &FFF4 | BYTEV | &020A | &FF0F | evt+&0F | (&0DAE) | evt+&11 | (&0DB0) |
OSCLI | &FFF7 | CLIV | &0208 | &FF0C | evt+&0C | (&0DAB) | evt+&0E | (&0DAD) |
– | – | IRQ2V | &0206 | &FF09 | evt+&09 | (&0DA8) | evt+&0B | (&0DAA) |
– | – | IRQ1V | &0204 | &FF06 | evt+&06 | (&0DA5) | evt+&08 | (&0DA7) |
– | – | BRKV | &0202 | &FF03 | evt+&03 | (&0DA2) | evt+&05 | (&0DA4) |
– | – | USERV | &0200 | &FF00 | evt+&00 | (&0D9F) | evt+&02 | (&0DA1) |
evt, the base address of the extended vector table, can be found by calling OSBYTE &A8; the LSB is returned in X and the MSB in Y. In all operating systems its value is &0D9F.
For instance, a ROM may execute the following to redirect OSFILE to its routine at &B000:
... PHP \ save interrupt state SEI \ disable interrupts LDA #&A8 \ set up OSBYTE call LDX #0 \ to get base address LDY #&FF \ of extended vector table. JSR &FFF4 \ call OSBYTE STX &AA \ store base address in zero page STY &AB \ X=low byte, Y=high byte LDY #&1B \ offset of FILEV's entry in ext.vec. table LDA #&00 \ LSB of our OSFILE routine's address STA (&AA),Y \ store in extended vector table INY \ add 1 to offset; Y=&1C LDA #&B0 \ MSB of our OSFILE routine's address STA (&AA),Y \ store after LSB INY \ add 1 to offset; Y=&1D LDA &F4 \ get our ROM slot number STA (&AA),Y \ store after MSB LDA #&1B \ set A=LSB of FILEV's ext.vec. handler STA &0212 \ store in FILEV LDA #&FF \ set A=MSB of FILEV's ext.vec. handler STA &0213 \ store in FILEV PLP \ restore interrupt state ...
If filing system vectors are claimed, after they are changed the ROM should issue service call &0F.
References
- ↑ Acorn Computers, Application Notes 030, 033 and 041
- ↑ stardot discussion of B+ private 12K
- ↑ Layout of MOS 3.20 ROM by J.G.Harston
- ↑ PanOS Technical Reference (OCR by J.G.Harston)
- ↑ PDP11 Technical Reference
- ↑ ROMFS Manual (OCR by J.G.Harston)
- ↑ ROMFS Manual (OCR by J.G.Harston)
- John Kortink's STH Forums post with details of the Electron's paged ROM system
- Sprow's sideways ROM authoring notes (PDF)
- Slogger Electron Expansion 2.0 User Guide (Word document)
-- beardo 00:31, 24 October 2007 (BST) -- jgharston 03:54, 12 August 2008 (BST)