Path: utzoo!attcan!uunet!cbmvax!dan From: dan@cbmvax.UUCP (Dan Baker CATS) Newsgroups: comp.sys.amiga.tech Subject: Re: Resources Message-ID: <5218@cbmvax.UUCP> Date: 12 Nov 88 00:06:02 GMT References: <13249@oberon.USC.EDU> Reply-To: dan@cbmvax.UUCP (Dan Baker CATS) Organization: Commodore Technology, West Chester, PA Lines: 131 In article <13249@oberon.USC.EDU> papa@pollux.usc.edu (Marco Papa) writes: > >This is from a fellow with bad news feed... > >If you want to claim the serial port (or parallel or some such) without >the supplied driver, you are supposed to use resources.lib to >get it exclusively. The RKM's are short of being crystal clear on how this >works. Anybody care to clarify how to claim the serial port for example? > This question is covered in more detail in an upcoming article in Amiga Mail. Until then, here is a quick summary of the topic. In order to get direct access to the parallel/serial hardware in a way that is compatible with multi-tasking, you should use the GetMiscResource() and FreeMiscResource() routines. These two routines let you temporarily bar other tasks from using the resource. You may then use the associated hardware directly for your special purposes and then return the resource back to the system for other tasks to use. (!!!) GetMiscResource() and FreeMiscResource() are descirbed in Appendix C of the ROM Kernel Manual: Libraries and Devices. Since these two routines do not have a library base pointer name, they can only be called from an assembly language program. Here's a working example that gets one of the two miscellaneous resources. Code courtesy of Bryce Nesbitt. * * Assembly language fragment that grabs the serial port registers * (using the misc.resource), and never gives them back. Of course * a real program would ALWAYS return a resource that it has taken over * after it was all done using it. This program never ends. It waits * forever. This is also a bad thing to do in your programs. JSRLIB MACRO XREF _LVO\1 JSR_LVO\1(A6) ENDM XREF _AbsExecBase INCLUDE "resources/misc.i" move.l _AbsExecBase,a6 lea.l MiscName(pc),a1 JSRLIB OpenResource tst.l d0 beq.s no_open move.l d0,a6 ;resource base in A6 ; ; The resource is now open. Call one of it's library-like vectors. ; move.l #MR_SERIALBITS,d0 lea.l MyName(pc),a1 jsr MR_ALLOCMISCRESOURCE(a6) tst.l d0 bne.s no_get ;Someone else got it ; ; We just stole the serial port registers. Wait forever. ; Nobody else can use the serial port, including the serial.device! ; move.l _AbsExecBase,a6 moveq #0,d0 ;Wait for nothing (forever) JSRLIB Wait ; ; INSTEAD OF WAITING FOREVER, YOU COULD PUT YOUR OWN ; CODE HERE. AFTER YOU ARE ALL DONE, RETURN THE ; RESOURCE WITH FREE_MISC_RESOURCE() !! THANK YOU. ; no_get no_open moveq #21,d0 rts MiscName dc.b 'misc.resource',0 MyName dc.b 'Serial Port hog',0 END Note that there are two serial.device resources to take over, MR_SERIALBITS and MR_SERIALPORT. You should get both resources when you take over the serial port to prevent other tasks from using them. The parallel.device also has two resources to take over. See the resources/misc.h include file for the relevant C definitions and structures. Under V1.3 and earlier versions of the Amiga system software, there is a bug in the way the the serial and parallel port resources are handled. That is, the GetMiscResource() routine will always fail if the serial.device has been used at all by another task - even if that task is done using the resource. In other words, once a printer driver has been activated, it will keep the associated resource locked up preventing your task from using it. One way around this is to cause a 'memory panic' with the Exec call AllocMem(0x7FFFFFFFL,0L). This will cause libraries and resources not currently in use to be flushed. However this method has some drawbacks. It is unfriendly to other tasks that may be running in the system. If the user goes back to a library-based task after a general memory expunge, the user might be required to reload large libraries from floppy disk. What is needed is a less drastic way to get a resource back from a device driver which has a hold on it. The code shown below will do this: /* * A safe way to expunge ONLY a certain device. The serial.device holds * on to the misc serial resource until a general expunge occurs. * This code attempts to flush ONLY the named device out of memory and * nothing else. If it fails, no status is returned since it would have * no valid use after the Permit(). Code by Bryce Nesbitt. */ #include "exec/types.h" #include "exec/execbase.h" void FlushDevice(char *); extern struct ExecBase *SysBase; void FlushDevice(name) char *name; { struct Device *devpoint; Forbid(); if( devpoint=(struct Device *)FindName(&SysBase->DeviceList,name) ) RemDevice(devpoint); Permit(); } Hope this helps. -- Dan Baker, CATS