home *** CD-ROM | disk | FTP | other *** search
- ;*********************************************************************
- ;* *
- ;* All changes I made are hereby in the Public Domain. Commodore *
- ;* retains its copyright, if any, of the original code in the Rom *
- ;* Kernel manuals since this is a derivative work. -Jeff Rush *
- ;* *
- ;*********************************************************************
- ;* History *
- ;* *
- ;* 20Sep89 jrr Original crib from Amiga Rom Kernel Manual. *
- ;* 23Jul90 jrr Extensive descriptive prose added. *
- ;* *
- ;*********************************************************************
- TITLE Example Device Driver for Tutorial Use
- SMALLOBJ ; Use PC-Relative Addressing
- OPTIMON ; Enable C.A.P.E. 68K Optimizations
-
- SECTION TheOnlySection
-
- ;************
- ;* Includes *
- ;************
- NOLIST
- INCLUDE "exec/types.i"
- INCLUDE "exec/devices.i"
- INCLUDE "exec/initializers.i"
- INCLUDE "exec/memory.i"
- INCLUDE "exec/resident.i"
- INCLUDE "exec/io.i"
- INCLUDE "exec/ables.i"
- INCLUDE "exec/errors.i"
- INCLUDE "exec/tasks.i"
- INCLUDE "exec/semaphores.i"
- INCLUDE "hardware/intbits.i"
-
- INCLUDE "asmsupp.i"
-
- INCLUDE "Example.i" ; Device-Specific Definitions
- LIST
-
- ;*************
- ;* Constants *
- ;*************
-
- ;******************
- ;* Public Symbols *
- ;******************
- XDEF EndCode ; Label at End of Device Code
- XDEF LockGlobal ; Obtain Exclusive Access to Device Global Data
- XDEF UnlockGlobal ; Release Exclusive Access to Device Global Data
- XDEF PerformIO ; Common Fork or Dispatch to Handle Device Commands
- XDEF TermIO ; Common Join from Device Commands to Do Common Cleanup
-
- ;********************
- ;* External Symbols *
- ;********************
- ; This Name is for Debugging Use, to Annotate Serial-Debug Output
- IFNE INFO_LEVEL ; If Any Debugging Enabled at All
- XREF subSysName
- ENDC
-
- ; Defined in Ex_Main.Asm
- XREF CmdTable ; Device Global Command Dispatch Table
-
- ;*********************************************************************
- ;* LockGlobal Helper Routine (for Open, Close, etc.) *
- ;* *
- ;* This functions uses a semaphore defined in the device global data *
- ;* to obtain exclusive access to the device global data area. It is *
- ;* used by DevOpen and DevClose to setup and takedown items that may *
- ;* break a Forbid(). Its use is optional and is not required if you *
- ;* have very simple opens/closes, *and* multiple copies of your unit *
- ;* tasks are not attempting to alter the device global area *
- ;* concurrently. They may all read it however, as long as no one is *
- ;* actually trying to -change- it while others are reading from it. *
- ;* *
- ;* Inputs: *
- ;* A6 - Ptr to our Device node. *
- ;* *
- ;* Outputs: *
- ;* None *
- ;* *
- ;* * All Registers are Preserved, Including D0-D1/A0-A1 * *
- ;* *
- ;* Notes: *
- ;* Calling task blocks until exclusive access can be granted. *
- ;* *
- ;*********************************************************************
- LockGlobal:
- ;
- ; Lock Device Global Data for Exclusive Access
- MOVEM.L D0-D1/A0-A1,-(SP) ; Preserve Registers During Lock
- LEA.L md_SemLock(A6),A0 ; Pickup Ptr to the Arbitration Semaphore
- LINKSYS ObtainSemaphore,md_SysLib(A6) ; Get Control of Device Node
- MOVEM.L (SP)+,D0-D1/A0-A1 ; Restore Registers
- RTS
-
- ;*********************************************************************
- ;* UnlockGlobal Helper Routine (for Open, Close, etc.) *
- ;* *
- ;* This functions uses a semaphore defined in the device global data *
- ;* to release exclusive access to the device global data area. It *
- ;* is used by DevOpen and DevClose to setup and takedown items that *
- ;* may break a Forbid(). Its use is optional and is not required if *
- ;* you have very simple opens/closes, *and* multiple copies of your *
- ;* unit tasks are not attempting to alter the device global area *
- ;* concurrently. They may all read it however, as long as no one is *
- ;* actually trying to -change- it while others are reading from it. *
- ;* *
- ;* Inputs: *
- ;* A6 - Ptr to our Device node. *
- ;* *
- ;* Outputs: *
- ;* None *
- ;* *
- ;* * All Registers are Preserved, Including D0-D1/A0-A1 * *
- ;* *
- ;* Notes: *
- ;* Calling task blocks until exclusive access can be granted. *
- ;* *
- ;*********************************************************************
- UnlockGlobal:
- ;
- ; Unlock Device Global Data from Exclusive Access
- MOVEM.L D0-D1/A0-A1,-(SP) ; Preserve Registers During Unlock
- LEA.L md_SemLock(A6),A0 ; Pickup Ptr to the Arbitration Semaphore
- LINKSYS ReleaseSemaphore,md_SysLib(A6) ; Release Control of Device Node
- MOVEM.L (SP)+,D0-D1/A0-A1 ; Restore Registers
- RTS
-
- ;*********************************************************************
- ;* PerformIO Helper Routine (for BeginIO) *
- ;* *
- ;* PerformIO actually dispatches an I/O request. It might be called *
- ;* from within the unit task, or directly from BeginIO (and thus on *
- ;* the callers's schedule). *
- ;* *
- ;* Inputs: *
- ;* A6 - Ptr to our Device node. *
- ;* A1 - Ptr to the caller's I/O request block as initialized by *
- ;* OpenDevice(). *
- ;* A3 - Ptr to the Unit Descriptor. *
- ;* *
- ;* (Bounds checking was done on the inputs by the caller) *
- ;* *
- ;* Outputs: *
- ;* IO_ERROR - Error code of operation (zero means success). *
- ;* *
- ;*********************************************************************
- PerformIO:
- IFGE INFO_LEVEL-150
- CLR.L -(SP) ; Allocate and Clear a 32-bit Scratch Word
- MOVE.W IO_COMMAND(A1),2(SP) ; Pick up Command Code
- PUTMSG 150,<'%s/PerformIO -- %ld'> ; Output a Debugging Message
- ADDQ.L #4,SP ; Deallocate the 32-bit Scratch Word
- ENDC
-
- MOVEQ #0,D0
- MOVE.B D0,IO_ERROR(A1) ; Initially Clear the Error Field¨to 'Ok'
- MOVE.B IO_COMMAND+1(A1),D0 ; Pick up Command Byte
- LSL.W #2,D0 ; Multiply by 4 to Get Table Offset
- LEA.L CmdTable(PC),A0 ; Pick up Base of Command Table in A0
- MOVE.L 0(A0,D0.W),A0 ; Index into Table and Get Ptr to Handler Code
- ;
- ; Branch into Appropriate Handler Code for Desired Command
- ; A1 - Ptr to I/O Request Block
- ; A3 - Ptr to Unit Descriptor
- ; A6 - Ptr to Device Node
- JMP (A0)
-
- ;*********************************************************************
- ;* TermIO Helper Routine (for BeginIO) *
- ;* *
- ;* TermIO sends the I/O request back to the user. It knows not to *
- ;* mark the device as inactive if this was an immediate request or *
- ;* if the request was started from the unit task. *
- ;* *
- ;* Inputs: *
- ;* A6 - Ptr to our Device node. *
- ;* A1 - Ptr to the caller's I/O request block as initialized by *
- ;* OpenDevice(). *
- ;* A3 - Ptr to the Unit Descriptor. *
- ;* *
- ;* (Bounds checking was done on the inputs by the caller) *
- ;* *
- ;* Outputs: *
- ;* IO_ERROR - Error code of operation (zero means success). *
- ;* *
- ;*********************************************************************
- TermIO:
- PUTMSG 160,<'%s/TermIO'>
- MOVE.W IO_COMMAND(A1),D0 ; Pick up Command Code in D0
-
- MOVE.L #IMMEDIATES,D1 ; Pick up Immediate Command Classification Mask
- BTST D0,D1 ; Test Command for an Immediate Type
- BNE.S TermIO_Immediate ; I/O was Immediate, Skip Task Handling Code
-
- BTST #UNITB_INTASK,UNIT_FLAGS(A3) ; Did I/O Come from Task?
- BNE.S TermIO_Immediate ; Yes, Don't Clear the Task-Active Flag
-
- BCLR #UNITB_ACTIVE,UNIT_FLAGS(A3) ; Clear the Task-Active Flag
-
- TermIO_Immediate:
- BTST #IOB_QUICK,IO_FLAGS(A1) ; Is the I/O Quick Bit Still Set?
- BNE.S TermIO_End ; Yes, Request Was Not Queued, Skip Reply Process
- ;
- ; Reply the Message Back to the Original Issuing Task
- LINKSYS ReplyMsg,md_SysLib(A6) ; Ptr to Message:A1
- ; Note: The ReplyMsg() Function Sets the LN_TYPE to NT_REPLYMSG
- TermIO_End:
- RTS
-
- ;*********************************************************************
- ;* 'EndCode' is a marker that shows the end of your code. Make sure *
- ;* it does not span hunks and is not before the Romtag. *
- ;*********************************************************************
- EndCode:
- END
-
-