Mastering Sideways ROM & RAM - Module 01 - Introduction ------------------------------------------------------- It is possible to write sideways RAM software on a BBC B or B+ 64K without sideways RAM but, if you use one of these machines, it will save you a great deal of time blowing and erasing EPROMs if SWR is available to test the software as it is being developed. Adding SWR to the BBC B+ 64K is very straightforward as Acorn produce a 64K SWR upgrade which can be fitted by Acorn dealers. Don't attempt to fit it yourself unless you are absolutely sure you have the skill needed to complete the job. Fitting an SWR upgrade to the BBC B is a job most users can attempt without incuring a dealer's service charge. There are many sideways RAM and ROM boards available which can be fitted without soldering any components. You should look carefully at the facilities offered by the various manufacturers of SWR boards and choose the board that best suits your needs. I recommend that you consider the following points when you look for a SWR board. 1. A mimimum of 16K of sideways RAM is required. 32K or 64K is useful but not essential. Most boards which use static RAMs do so because the design is much simpler. There is an old designer's joke that the difference between static and dynamic RAM is that static RAM works. Don't let this nonsense prevent you buying a dynamic RAM board. 2. Physical switching for read and write protection of the SWR is highly desirable. Read protection will be used to switch out the offending memory when you load an invalid ROM image which causes the computer to hang up. Write protection is useful if you want to develop ROM images that are protected against running in SWR. Software switching of read and write protection is a poor substitute for real switches that click. 3. Look carefully at the way in which flying leads are attached to the main computer circuit board. Compare the different methods manufacturers use. Some boards use quite unprofessional design techniques. 4. Battery backup of SWR is useful, but not essential. 5. Many SWR boards have sockets for extra ROMs. The BBC B MOS will support up to sixteen sideways ROM or RAM banks. The main circuit board has only four sideways ROM sockets, two of which are taken up with BASIC and the DFS. The extra sockets on a sideways RAM/ROM board will be useful if you have more ROMs than ROM sockets. There are a number of manufacturers who produce boards which meet these requirements to a greater or lesser extent. Which manufacturer you choose is up to you. You can be sure that all the boards produced by reputable companies will perform adequately but it is not possible to recommend one board as better in every respect than any other. When you have fitted the upgrade board into your computer you might want to store the programs contained in your ROMs on disc or tape and then load and run the ROM images in SWR. All Acorn supported languages will run in unprotected SWR and most ROM images will run in write protected SWR. Where the copyright of the software contained in a ROM is not owned by Acorn, specific permission must be obtained from the owner of the copyright before copying it onto disc or tape. In Acorn's User Guide (Part no. 408000, Issue no. 2, March 1984, page 20) it states "... you can keep a library of paged ROMs on disc, which can be called up in the same way as ROMs installed inside the BBC Microcomputer. However, in using this facility you must ensure that you do not infringe the rights of the owner of the copyright of the program contained in the ROM". As long as you do not infringe the rights of the owner of the copyright of the program, ROMs can be saved onto a library disc and run in RAM. Some software producers take a less enlightened view than Acorn take to running their ROMs in SWR and attempt to protect them against it. Most of this protection does little to deter professional software pirates but it should be taken as an indicator of the copyright owner's unwillingness to allow his or her work to be used in SWR. If you want to ensure that your own work will only run in EPROMs and not in SWR there are a number of techniques you can try. An 8K ROM image is duplicated from &A000 and one of the methods of protecting 8K ROM images is to add &2000 to the subroutine and jump addresses. Another, far less common, method is to prevent the ROM image running in socket &0F. This socket is commonly used for SWR on ROM boards and the only way to get these ROM images to run in socket &0F is to disassemble and modify them. When you have completed this course you will certainly know what to look for in a ROM disassembly if you wanted to do this but it is quite a good way of detering most amateur ROM pilferers. I will now begin to explore the programming techniques needed to use SWR. There are a number of MOS subroutines, memory locations and registers associated with SWR. Rather than examine them all now I will consider the calls and locations as they arise throughout the course. In this module I will look at the paged ROM select register at &FE30, the paged memory select register at &FE34, the MOS subroutine Osrdrm, and Osbytes &AA and &AA. There are differences in the way in which the paged ROM select register and the paged memory select register are used in the BBC B, the BBC B+ and the Master computers. The reason for the differences can be seen by examining the memory maps of these machines (figures 1.1, 1.2 and 1.3). &FFFF +-------+ &FFFF ! ! ! MOS ! ! ! &BFFF --+-------+-------+-------+-------+ &C000 ! ROM &C! ROM &D! ROM &E! ROM &F! ! ! ! ! ! ! ! ! DFS ! BASIC ! &8000 --+-------+-------+-------+-------+ &7FFF Up to 16 sideways ROM/RAM banks ! ! ! User ! ! memory! ! ! ! ! &1900 +-------+ Oshwm ! ! &0000 +-------+ &0000 Figure 1.1 Memory map of the BBC B ---------------------------------- The BBC B MOS supports up to sixteen paged ROMs although an expansion board is required if more than four ROMs are to be used. The paged ROM select register at &FE30 is a 4 bit write only register which determines which of the 16 ROMs is switched into the main memory map. If you want to read the contents of this register you should read the zero page copy of it at &F4. The most significant nybble of the paged ROM select register is not used on the BBC B. &FFFF +-------+ &FFFF ! ! ! MOS ! ! ! &BFFF --+-------+-------+-------+-------+ &C000 ! ROM &C! ROM &D! ROM &E! ROM &F+-------+ &AFFF ! ! ! ! ! Paged ! ! ! ! DFS ! BASIC ! memory! &8000 --+-------+-------+-------+-------+-------+ &8000 Up to 16 sideways ROM/RAM banks ! ! ! ! User ! Shadow! ! memory! RAM ! ! ! ! ! +-------+ &3000 &1900 +-------+ Oshwm ! ! &0000 +-------+ &0000 Figure 1.2 Memory map of the BBC B+ ----------------------------------- The BBC B+ has a similar memory map to the BBC B but in addition to the paged ROMs it also supports paged or shadow memory. The paged memory (shadow RAM) select register at &FE34 is used to determine whether or not the shadow RAM is used as screen memory. This register should only be altered using Osbyte &72 (*FX114) or the command *SHADOW. The BBC B+ has a "spare" 12K of paged memory from &8000 to &AFFF. This can be switched in or out of the main memory map using the most significant bit of the paged ROM select register at &FE30. Setting the most significant bit of the paged ROM select register has no effect on the BBC B but on the BBC B+ it switches the paged memory from &8000 to &AFFF into the main memory map. BBC Telesoftware has broadcast a program that uses this technique to allow BBC B+ 64K computer users to load and run 8K service ROMs in this area of paged memory. The Master computer uses a slightly different memory map to the B series. The "spare" 12K of paged memory has now been split into two areas, one from &8000 to &8FFF and the other from &C000 to &DFFF. The paged RAM from &8000 to &8FFF is used by the MOS as a soft key buffer, character font, and VDU workspace. The paged RAM from &C000 to &DCFF is available as paged ROM workspace and the paged RAM from &DD00 to &DFFF is used as MOS workspace. &FFFF +-------+ &FFFF ! ! ! MOS +-------+ &DFFF ! !Wkspace! &BFFF --+-------+-------+-------+-------+-------+ &C000 ! ROM &C! ROM &D! ROM &E! ROM &F! ! ! ! ! ! ! BASIC ! ADFS ! View ! Term. +-------+ &8FFF &8000 --+-------+-------+-------+-------+-------+ &8000 Up to 16 Sideways ROM/RAM banks ! ! ! ! User ! Shadow! ! memory! RAM ! ! ! ! ! +-------+ &3000 ! ! &0E00 +-------+ Oshwm &0000 +-------+ &0000 Figure 1.3 Memory map of the BBC Master --------------------------------------- Paged ROM workspace on the BBC B and B+ is just below the user memory. The BBC B DFS claims 2.75K of workspace from &0E00 to &1900. This workspace can be in paged memory on the Master series allowing Oshwm to stay at &0E00 with all filing systems. Bit 3 of the paged memory select register at &FE34 is used to overlay the paged ROM workspace onto the Master MOS so that it appears above the paged ROM using it. Bit 3 of the paged memory select register can be toggled directly but you must not directly alter any other bit in this register. This topic will be covered in more detail in modules 11 and 12 which deal with paged ROM workspace. The use of the least significant nybble of the paged ROM select register at is common to all BBC micros. The operating system uses this register, and the zero page copy of it at &F4, to keep track of which paged ROM is being used at any time. If you want to alter this register directly you can only do so from machine code. If you alter it from BASIC or any other language ROM you will cause the computer to hang up. The order in which the paged ROM select register and its copy at &F4 are altered is important. You must store the same number in both locations and alter &F4 first. Immediatly after altering &F4 you must store the same value in &FE30. For example: LDA #&0A STA &F4 STA &FE30 This code will switch bank &0A into the main memory map. If you reverse the order of the last two instructions you will find that 99% of the time everything works properly but, sooner or later, an interupt occuring between the two store instructions will cause to computer to hang up. Switching a paged ROM into the main memory map in this way can be quite useful if you want to transfer the contents of a ROM into user memory or transfer the contents of user memory into a particular sideways RAM. There is an official way to read a byte of memory from any paged ROM. This uses the operating system call Osrdrm at &FFB9 with the relevant paged ROM number in the Y register and the address of the byte in the paged ROM in locations &F6 and &F7 (the paged ROM pointers). The value of the byte read by Osrdrm is returned in the accumulator. The X, Y and status registers will be undefined after the call. Both these techniques are demonstrated in the program READROM. When the program is running it uses Osrdrm to read the title string in every ROM socket that has an active ROM image and then pROMpts the user to choose which ROM number, from 0-15, to switch into the main memory map. The chosen ROM is switched in and copied from &8000 to &3C00 and then switched back out again. The ROM image can then be examined and, if required, saved to the currently active filing system. Although some of the program is in BASIC the switching and copying can only be done in machine code. The program uses Osbyte &72 to find the start of the ROM information table. This call returns the origin of a 16 byte table containing one byte per paged ROM. Each byte contains the ROM type byte contained in location &8006 of the ROM or contains zero if an active ROM is not present. ROM type bytes are an important part of the ROM header and will be dealt with in more detail when ROM headers are considered in module 2. Chain the program READROM and satisfy yourself that it works properly. It must run in the I/O processor and will not work in a second processor. There are two machine code routines used in the program. The first (lines 200-430) is called once for each possible ROM number from 0 to 15. It looks up the address of the start of the ROM information table with Osbyte &72 (lines 210-240) and then uses the number of the ROM as an offset in the Y register to see if there is a valid ROM in the socket being considered (line 280). If there is a valid ROM image present the routine reads the title of the ROM using Osrdrm and displays it on the screen (lines 340-430). The ROM title always starts at &8009 in a valid ROM image and always ends with a binary zero. The second machine code routine is in lines 440-700. This stores the current ROM number (lines 450-460) before switching the chosen ROM into the main memory map (lines 470-490). It then copies the chosen ROM image into user memory (lines 500-660), and finally switches the original ROM back into the main memory map (lines 670-690). The BASIC part of the program is mainly concerned with displaying the copy of the ROM image on the screen (lines 860-990) and, if required, with saving a copy of the ROM image onto disc or tape (PROCsave, lines 1000-1190). Before it makes a copy of the ROM image onto disc the program compares the first &100 bytes of the image with &100 bytes 8K higher in memory (lines 1090-1110). If every pair of &100 bytes is identical the ROM is recognised as an 8K image and only the first &2000 bytes are saved. The program READROM, as well as illustrating the techniques described above, will be useful in later modules when you will want to examine or save the contents of sideways RAM banks. The program can be modified to produce another program to load ROM images into any sideways RAM bank, including the paged memory bank of the BBC B+. This has been left as an exercise for you to complete. 10 REM: READROM 20 MODE7 30 HIMEM=&3C00 40 DIM mcode &100 50 select=&FE30 60 osrdrm=&FFB9 70 osasci=&FFE3 80 osbyte=&FFF4 90 oscli=&FFF7 100 copy=&A8 110 temp=&A9 120 read=&AA 130 write=&74 140 ROMnumber=&F4 150 ROMpoint=&F6 160 ON ERROR PRINT : END 170 FOR pass=0 TO 2 STEP 2 180 P%=mcode 190 [ OPT pass 200 .number 210 LDA #&AA 220 LDX #0 230 LDY #&FF 240 JSR osbyte \ Find ROM table 250 STX read 260 STY read+1 270 LDY copy 280 LDA (read),Y 290 BEQ finish 300 LDA #8 310 STA ROMpoint 320 LDA #&80 330 STA ROMpoint+1 340 .readname 350 INC ROMpoint 360 LDY copy 370 JSR osrdrm 380 CMP #ASC(" ") 390 BCC finish 400 JSR osasci 410 JMP readname 420 .finish 430 RTS 440 .move 450 LDA ROMnumber 460 STA temp 470 LDA copy 480 STA ROMnumber 490 STA select 500 LDA #&80 510 STA read+1 520 LDA #&3C 530 STA write+1 540 LDY #0 550 STY read 560 STY write 570 .relocate 580 LDA (read),Y 590 STA (write),Y 600 INY 610 BNE relocate 620 INC read+1 630 INC write+1 640 LDA read+1 650 CMP #&C0 660 BNE relocate 670 LDA temp 680 STA ROMnumber 690 STA select 700 RTS 710 ] 720 NEXT 730 FOR socket=0 TO 15 740 ?copy=socket 750 IF socket<10 PRINT;" "; 760 PRINT;socket;" "; 770 CALL number 780 PRINT 790 NEXT 800 VDU14 810 REPEAT 820 INPUT'"Which ROM &(0-15) "socket 830 UNTIL socket >= 0 AND socket < 16 840 ?copy=socket 850 CALL move 860 PRINT'" to scroll, to exit" 870 ON ERROR PROCsave 880 FOR block=&3C00 TO &7BFF STEP 8 890 PRINT';~block+&4400;" "; 900 FOR memory=0 TO 7 910 byte=block?memory 920 IF byte<16 VDU48 930 PRINT;~byte;" "; 940 NEXT 950 FOR memory=0 TO 7 960 byte=memory?block 970 IF byte>31 AND byte<127 VDUbyte ELSE VDU46 980 NEXT 990 NEXT 1000 PROCsave 1010 END 1020 DEFPROCsave 1030 ON ERROR PRINT : END 1040 VDU15 1050 INPUT''"Save ROM? (Y/N) "yes$ 1060 REPEAT 1070 IF yes$="Y" INPUT"Filename? : "filename$ ELSE INPUT"An other? (Y/N) "yes$ : IF yes$<>"Y" END ELSE RUN 1080 size=FALSE 1090 FOR block=&3C00 TO &3D00 1100 IF ?block <> ?(block+&2000) size= TRUE 1110 NEXT 1120 IF size=TRUE size=&4000 ELSE size=&2000 1130 $mcode="SAVE "+filename$+" 3C00+"+STR$~(size)+" FFFF80 00 FFFF8000" 1140 X%=mcode 1150 Y%=X% DIV 256 1160 CALL oscli 1170 yes$="" 1180 UNTIL FALSE 1190 ENDPROC