Mastering Sideways ROM & RAM - Module 12 - Absolute workspace ------------------------------------------------------------- Private workspace is exclusive to the ROM claiming it. Absolute workspace can also be claimed by paged ROMs. Absolute workspace, unlike private workspace, is a single block of memory which is shared between all the ROMs but is only allocated to one ROM at a time. Absolute workspace can be claimed in user memory when it runs from &E00 to the highest address asked for by any of the ROMs. The Master computer can also claim the alternative paged memory absolute workspace. Claiming and using paged memory absolute workspace will be explained after dealing with user memory absolute workspace. In order to claim absolute workspace your SWR interpreter has to intercept the absolute workspace service call. To demonstrate the absolute workspace service call load the object code generated by the program TRACE into SWR and press the Break key (Ctrl+Break on the Master). A list of service calls similar to the one in figure 12.1 will be printed on the screen. Unless you use a BBC B with an Acorn 6502 Second Processor, Acorn DNFS and sideways RAM in socket &0F your trace will be different from the one in figure 12.1, but in all BBC computers you will find service call 1, the absolute workspace claim, somewhere in the list. A=19 X=0F Y=FF SPOOL/EXEC file closure A=0F X=0F Y=FF Vectors claimed A=FF X=0F Y=FF Tube system main init. A=01 X=0F Y=0E Abs. workspace claim A=02 X=0F Y=17 Private workspace claim A=FE X=0F Y=FF Tube system post init. A=11 X=0F Y=1F Font implode/explode Acorn TUBE 6502 64K A=03 X=0F Y=08 Auto-boot Acorn DFS A=10 X=0F Y=EE SPOOL/EXEC file closure A=0F X=0F Y=30 Vectors claimed A=0A X=0F Y=D4 Claim static workspace BASIC > Figure 12.1 Service call trace after Break ------------------------------------------- In figure 12.1 you can see that the absolute workspace claim, service call 1, is made with Y=&0E. This indicates that no absolute workspace has yet been claimed. If the trace is run from a lower priority ROM than the Acorn DFS ROM then service call 1 is made with Y=&17 indicating that 9 pages of absolute workspace are claimed by the DFS. When service call 1 is made the Y register contains the current upper limit of the absolute workspace. This starts at &0E and each ROM should compare the value in the Y register with the upper limit of absolute workspace required by the ROM and, if necessary, increase it to the level required by the ROM. Your software must never decrement the Y register when it intercepts either service call 1 or 2. In order to use the absolute workspace effectively it is necessary for your SWR program to claim private workspace as well. One reason for this is that your ROM will need to keep a flag indicating whether or not it has control of the absolute workspace. This flag should be located in private workspace. It is also a good idea to keep a copy of any vital data from absolute workspace in private workspace where you can be sure that it will not be corrupted. If you intend to write SWR software that uses absolute workspace you should think of the absolute workspace as a temporary extension to the private workspace and not as a substitute for private workspace. When you want your ROM to use the absolute workspace it has to issue service call &0A to inform the other ROMs of its intention. Service call &0A is issued by calling Osbyte &8F with X = service type and Y = argument for service. In this case make X=&0A and Y=&FF. The ROM is then free to use the absolute workspace and the zero page locations from &B0 to &CF until its interpreter intercepts a service call &0A issued by another ROM. The interpreter must intercept service call &0A which instructs it to release the absolute workspace to the ROM issuing the call, usually the DFS. I have not written an example program which uses absolute workspace but I have included a outline program, ABSOL, which includes all the coding you need to write your own. ABSOL intercepts service call 1 to claim absolute workspace, service call 2 to claim private workspace, sevice call &0A to release absolute workspace, and service call 4 to recognise the new * command *STATIC. It uses the one-command interpreter (lines 570-780) used in the earlier modules of the course. The example program ABSOL ensures that at least one page of absolute workspace is available (lines 300-360) and claims one page of private workspace (lines 410-450). These are the minimum meaningful amounts if the program is to use absolute workspace. The program recognises service call &0A (lines 470-500). After recognising service call &0A the program would have to copy any vital data from absolute to private workspace and adjust a flag kept in private workspace to indicate that it no longer had control of the absolute workspace. When the interpreter recognises the new command *STATIC it issues service call &0A (lines 800-830) to inform the other ROMs that it intends to use the absolute workspace. When it has control of the absolute workspace it can also use the zero page locations from &B0 to &CF, but it must be prepared to give up control of both these zero page locations and the absolute workspace when the interpreter intercepts a service call &0A issued by another ROM. Although using absolute workspace is fairly straightforward if you use this outline program, it is an unnecessary complication if you really don't need it. You will probably only need to use it if your program uses large amounts of data for a short time. 10 REM: ABSOL 20 MODE7 30 HIMEM=&3C00 40 DIM save 50 50 diff=&8000-HIMEM 60 address=&A8 70 comvec=&F2 80 ROMnumber=&F4 90 workspace=&DF0 100 gsread=&FFC5 110 osbyte=&FFF4 120 oscli=&FFF7 130 FOR pass = 0 TO 2 STEP 2 140 P%=HIMEM 150 [ OPT pass 160 BRK 170 BRK 180 BRK 190 JMP service+diff 200 OPT FNequb(&82) 210 OPT FNequb((copyright+diff) MOD 256) 220 BRK 230 .title 240 OPT FNequs("STATIC") 250 .copyright 260 BRK 270 OPT FNequs("(C)1987 Gordon Horsington") 280 BRK 290 .service 300 CMP #1 310 BNE trytwo 320 CPY #&0F 330 BCS carryon 340 INY \ claim 1 page of abs. workspace 350 .carryon 360 RTS 370 .trytwo 380 PHA 390 CMP #2 400 BNE tryten 410 TYA 420 STA workspace,X 430 INY \ 256 bytes of private workspace 440 PLA 450 RTS 460 .tryten 470 CMP #&0A 480 BNE tryfour 490 \ Prepare to release 500 \ absolute workspace 510 .enough 520 PLA 530 RTS 540 .tryfour 550 CMP #4 560 BNE enough 570 TXA 580 PHA 590 TYA 600 PHA 610 LDX #&FF 620 .comloop 630 INX 640 LDA title+diff,X 650 BEQ found 660 LDA (comvec),Y 670 INY 680 CMP #ASC(".") 690 BEQ found 700 AND #&DF 710 CMP title+diff,X 720 BEQ comloop 730 PLA 740 TAY 750 PLA 760 TAX 770 PLA 780 RTS 790 .found 800 LDA #&8F 810 LDX #&0A \ service call &0A 820 LDY #&FF 830 JSR osbyte \ Claim absolute workspace 840 \ Use zero page from &B0 to &CF 850 \ and absolute workspace as well 860 \ as private workspace. 870 PLA 880 PLA 890 PLA 900 LDA #0 910 RTS 920 .lastbyte 930 ] 940 NEXT 950 INPUT'"Save filename? : "filename$ 960 IF filename$="" END 970 $save="SAVE "+filename$+" "+STR$~(HIMEM)+" "+STR$~(las tbyte)+" FFFF8000 FFFF8000" 980 X%=save 990 Y%=X% DIV 256 1000 *OPT1,2 1010 CALL oscli 1020 *OPT1,0 1030 END 1040 DEFFNequb(byte) 1050 ?P%=byte 1060 P%=P%+1 1070 =pass 1080 DEFFNequw(word) 1090 ?P%=word 1100 P%?1=word DIV 256 1110 P%=P%+2 1120 =pass 1130 DEFFNequd(double) 1140 !P%=double 1150 P%=P%+4 1160 =pass 1170 DEFFNequs(string$) 1180 $P%=string$ 1190 P%=P%+LEN(string$) 1200 =pass In order to use the alternative paged memory absolute workspace on the Master computer it is necessary to intercept service call &23 instead of service call 1. Your program must not claim user memory absolute workspace as well as paged memory absolute workspace. Paged memory absolute workspace in the Master starts at &C000 and has an upper limit of &DBFF. The upper limit of the absolute workspace must not exceed &DBFF under any circumstances. If you intend to use paged memory absolute workspace the outline program ABSOL will need to be modified. The interpreter will no longer need to intercept service calls 1 and 2 but it will need to intercept service call &23 to claim paged memory absolute workspace and service calls &24 and &22 to claim paged memory private workspace. Suitable modifications for ABSOL are shown in figure 12.2 .service CMP #&23 \ paged absolute workspace claim? BNE try24 \ branch if no CPY #&C1 \ is 1 page already available? BCS carryon \ branch if yes INY \ claim 1 page of absolute workspace .carryon RTS .try24 CMP #&24 \ paged private workspace claim? BNE try22 \ branch if no INY \ request 1 page of private workspace RTS .try22 CMP #&22 \ paged private workspace claim? BNE try10 \ branch if no PHA \ store accumulator TYA \ most sig. byte of start address STA &DF0,X \ store start of private workspace PLA \ restore accumulator RTS .try10 Figure 12.2 Modificatins needed for the Master ---------------------------------------------- In Module 11 I explained how to switch the paged workspace memory in and out of the main memory map. It is necessary to use the same techniques described in Module 11 when using paged memory absolute workspace. Before attempting to read or write the contents of the paged memory absolute workspace, the SWR program must first set bit 3 of the paged memory select register at &FE34 to switch the paged memory into the main memory map. To set bit 3 of &FE34 load the accumulator with &08 (0000 1000 binary), and use TSB &FE34. To switch the paged memory absolute workspace out of the main memory map it is necessary to clear bit 3 of the paged memory select register. To clear bit 3 of &FE34 load the accumulator with &08 (0000 1000 binary), and use TRB &FE34. If you use the subroutines illustrated in figure 12.3 the paged memory can be switched in and out of the main memory map without altering any of the other bits in the paged memory select register. JSR pagein \ switch paged workspace in LDA &C000 \ Read first byte of absolute workspace JSR pageout \ switch paged workspace out . . . .pagein PHA LDA #8 \ 0000 1000 binary TSB &FE34 \ set bit 3 of &FE34 PLA \ restore accumulator RTS .pageout PHA LDA #&08 \ 0000 1000 binary TSB &FE34 \ clear bit 3 of &FE34 PLA \ restore accumulator RTS Figure 12.3 Reading paged absolute workspace on the Master. ----------------------------------------------------------- Figure 12.3 illustrates how the two subroutines, pagein and pageout, should be used to switch the paged memory in and out of the main memory map when reading the contents of the paged memory absolute workspace in the Master series computers. Unlike private workspace, absolute workspace always has a fixed start address and can be addressed directly. After switching the paged memory into the main memory map you must be very careful about using MOS subroutines because the bottom 8K of the MOS has been replaced with the paged memory. You would be wise not to use the MOS at all until it has been restored by calling pageout. The "legal" use of service call 1 has been explained above but a much more common "illegal" use is also made of this service call. Look again at figure 12.1, the list of service calls issued after pressing the Break key. Some of these calls, including service call 1, are always issued on the BBC B when the Break key is pressed and also when the computer is switched on. (Service call 1 is only issued on Ctrl-Break on the Master but service call &FE can be used instead because it is always issued when the Break key is pressed on the Master computer). Service call 1 or service call &FE can be intercepted to carry out almost any function required at reset if, and only if, all the registers are preserved. Imagine, for example, that you want the video interlace to stay switched off. Your SWR interpreter could intercept service call 1 (or &FE), push all the registers on the stack, switch off the interlace, pull all the registers back off the stack and return control to the MOS. This idea has been implemented in the program INTLACE. Load the object code generated by INTLACE into SWR, press the Break key and select Mode 6. The interlace will remain switched off until you select Mode 7 or press Ctrl+Break. It will switch back off when you next select one of the modes 0-6. This type of illegal use of service call 1 (or &FE) will be used again in Module 22 when designing the software for auto-booting ROM cartridges is covered. It will be used then to ensure that the ROM cartridge is always the language booted after a soft reset. 10 REM: INTLACE 20 MODE7 30 HIMEM=&3C00 40 DIM save 50 50 diff=&8000-HIMEM 60 osbyte=&FFF4 70 oscli=&FFF7 80 FOR pass = 0 TO 2 STEP 2 90 P%=HIMEM 100 [ OPT pass 110 BRK 120 BRK 130 BRK 140 JMP service+diff 150 OPT FNequb(&82) 160 OPT FNequb((copyright+diff) MOD 256) 170 BRK 180 OPT FNequs("INTERLACE") 190 .copyright 200 BRK 210 OPT FNequs("(C)1987 Gordon Horsington") 220 BRK 230 .service 240 CMP #&FE 250 BEQ autoboot 260 RTS 270 .autoboot 280 PHA 290 TXA 300 PHA 310 TYA 320 PHA 330 LDA #&90 340 LDX #&FF 350 LDY #1 360 JSR osbyte \ *TV255,1 370 PLA 380 TAY 390 PLA 400 TAX 410 PLA 420 RTS 430 .lastbyte 440 ] 450 NEXT 460 INPUT'"Save filename = "filename$ 470 IF filename$="" END 480 $save="SAVE "+filename$+" "+STR$~(HIMEM)+" "+STR$~(las tbyte)+" FFFF8000 FFFF8000" 490 X%=save 500 Y%=X% DIV 256 510 *OPT1,2 520 CALL oscli 530 *OPT1,0 540 END 550 DEFFNequb(byte) 560 ?P%=byte 570 P%=P%+1 580 =pass 590 DEFFNequw(word) 600 ?P%=word 610 P%?1=word DIV 256 620 P%=P%+2 630 =pass 640 DEFFNequd(double) 650 !P%=double 660 P%=P%+4 670 =pass 680 DEFFNequs(string$) 690 $P%=string$ 700 P%=P%+LEN(string$) 710 =pass