home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
420.lha
/
Example_device
/
Ex_Support.asm
< prev
next >
Wrap
Assembly Source File
|
1990-09-29
|
12KB
|
220 lines
;*********************************************************************
;* *
;* 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