Path: utzoo!attcan!uunet!mcvax!nikhefh!gert From: gert@nikhefh.hep.nl (Gert Poletiek) Newsgroups: comp.sys.atari.st Subject: A scheme for updating/patching gemdos Keywords: gemdos,patch,rom Message-ID: <531@nikhefh.hep.nl> Date: 23 Aug 88 20:53:34 GMT Organization: Nikhef-H, Amsterdam (the Netherlands). Lines: 113 I seem to have created a bit of confusion with my posting to this group on how system calls may be patched in GemDos if Atari were to adopt a slightly modified system call trap handler. In my original posting on this subject I referred to the method used in the operating system of the Macintosh. Let me explain how this method works. Assumptions: 68000 (or 68070) system (not an 68010/20/30) Rom located at addresses 0x0 through 0x7 at reset time and shortly thereafter (reset program counter and initial supervisor mode stack pointer are fetched from these addresses) Ram locations 0x8 and up Operating system in Rom somewhere high up in memory. This description fits the Atari 520, 1040, Mega 2 and 4, and the Macintosh 512K, Plus and SE. A user program may call the operating system for some service by issuing the appropriate trap call (i.e. on the ST trap 14 for Xbios, 13 for Bios, trap 1 for GemDos and trap 2 for GEM; and one of the lineA emulator calls on the Macintosh). All these calls cause the 68000 to fetch an exception processing vector (the address at which the OS trap dispatcher starts) from low memory in the address range 0x8 throug 0x3ff. The address from which the exception vectors are fetched are fixed on the 68000 (though not on the 680[12]0 which have a register called the Vector Base Register which holds the start address of the exception vector table). On the Atari ST the process calling the OS must have pushed an operation code for the requested system call onto the active stack prior to executing the trap. This operation code (the number of the system call) is used as an index into a table of addresses. This table holds the addresses of the first instruction for each system call. Hence the assembler code in the OS dispatcher could look something like this (oversimplified): OSEntryPoint: move.w opCode(sp),d0 # get operation code lea dispatchTable,a0 # get dispatch table address movea.l (a0,d0.w),a0 # get pointer to requested function jsr (a0) # jump to requested function On the Macintosh user programs do not issue a trap instruction to get to the operating system. Instead they incorporate an unimplemented 68000 instruction into their program. This unimplemented instruction starts with 0xa and is 16 bits wide. The lower 12 bits of that word encode the number of the system call (hence the Mac may have 16 times as many system calls tied to the same exception vector as the ST). Whenever the unimplemented instruction (line A instruction) is executed (well, only decoded by the 68000 instruction decoding logic) the 68000 starts exception processing in much the same (though not exactly the same) way as when a trap instruction is executed. The Macintosh operating system uses (schematically) the same trap dispatcher routine as the ST. The ONLY difference is the address of the 'dispatchTable' variable shown in the assembly example above. On the ST the dispatchTable is located in ROM, on the Macintosh it is located in RAM (low memory address). Sure, its safer to have the dispatchTable in ROM, you would say. True, it cannot be overwritten by a program going nuts. However, having the dispatchTable in ROM has one major drawback (and, consequently, having it in RAM has an advantage). When an operating system routine is found to contain a bug (e.g. Malloc and others on the ST) and the dispatchTable is located in RAM it is quite easy to fix the erroneous routine. During system startup a patch for the erroneous routine could be read from disk and be applied by placing the new routine in RAM and have the appropriate pointer from the dispatchTable point to the newly loaded routine instead of the erroneous one in ROM. On the Macintosh two routines exist to manipulate the dispatchTable. They are: GetTrapAddress and SetTrapAddress. GetTrapAddress is used to get the start address for a certain system call service routine from the dispatchTable. SetTrapAddress is used to change the value of one of the entries in the dispatchTable. SetTrapAddress is used by the resources of type 'PTCH' in the Macintosh 'System' file, which are loaded into memory as soon as the system is bootstrapped. Normally (at least in the more recent versions of the System file), there are PTCH resource for all kinds of Macs: the patches may be applied to different roms (remember there are 3 differently sized roms in Macs: 64KB(old Macs), 128KB(Plus and SE) and 256KB (MacII)) and to different rom releases (there are at least three different rom releases for the 128KB version alone) and for different hardware configuarions (Note that the Plus, SE and II have an NCR SCSI controller while the older 512K Mac does not). In each case the PTCH resource, once loaded into RAM, finds out all it needs to know for deciding whether or not to apply the patch. All this is made possible by one simple fact: the dispatchTable is located in RAM. With my original posting I intended to explain this to the net, and I wish that Atari would adopt such a scheme in the next ROM release. It makes upgrading the OS so much easier since you don't need to ship new roms every once in a while when a bug is found... Gert Poletiek NIKHEF-H, Dutch National Institute for Nuclear and High Energy Physics Kruislaan 409, P.O.Box 41882, 1009 DB Amsterdam, The Netherlands UUCP: {decvax,cernvax,unido,seismo}!mcvax!nikhefh!gert bitnet: nikhefh!gert@mcvax.bitnet, U00025@hasara5.bitnet From september 1st 1988: Gert Poletiek Dept. of Math. and Computing Science, University of Amsterdam, Kruislaan 409, NL-1098 SJ Amsterdam, The Netherlands UUCP: {decvax,cernvax,unido,seismo}!mcvax!uva!gert bitnet: uva!gert@mcvax.bitnet, U00025@hasara5.bitnet