home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
420.lha
/
Example_device
/
Ex_Main.asm
< prev
next >
Wrap
Assembly Source File
|
1990-09-29
|
14KB
|
251 lines
;*********************************************************************
;* Origin and Purpose *
;* *
;* This device represents things I would liked to have known when *
;* starting out writing devices. I found it hard to get firm data *
;* on device design, and collected everything I could find into this *
;* file. Sure it has lots of comments, but it makes a great basic *
;* skeleton or classroom presentation. *
;* *
;* I apologize in advance for any bugs, oversights or errors. As *
;* always, corrections and design tips are welcome. *
;* *
;* Send comments, flames, etc. to the following: *
;* *
;* Tau Productions *
;* Jeff Rush *
;* BIX: jrush *
;* BBS: (214) 231-1372 Rising Star *
;* Fidonet: 1:124/4206 (Dallas, Tx) *
;* *
;* 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 *
;*************
VERSION EQU 1 ; Version of This Device
REVISION EQU 1 ; Revision of This Device
;******************
;* Public Symbols *
;******************
; This Name is for Debugging Use, to Annotate Serial-Debug Output
IFNE INFO_LEVEL ; If Any Debugging Enabled at All
XDEF subSysName
ENDC
XDEF CmdTable ; Device Global Command Dispatch Table
XDEF MyName ; Name of This Device (for Tagging Ports and Tasks)
;********************
;* External Symbols *
;********************
; Defined in Ex_Support.Asm
XREF EndCode ; Label at End of Device Code
; Defined in Ex_EntryPts.Asm
XREF LoadInitRoutine ; Initialization when Device First Loads into Memory
XREF DevOpen ; Unit Allocation for Each Time Device is Opened
XREF DevClose ; Unit Deallocation for Each Time Device is Opened
XREF DevExpunge ; Remove Device from Memory if No One is Using It
XREF DevNull ; Reserved for Future Expansion
XREF DevBeginIO ; Initiate an I/O Request either Now or Put in Queue
XREF DevAbortIO ; Abort an I/O Request either Active or in Queue
; Defined in Ex_StdCmds.Asm
XREF CmdInvalid ; Handle an Unknown or Out-of-Range Command
XREF CmdReset ; Reset the Device
XREF CmdRead ; Read Data from the Device for Caller
XREF CmdWrite ; Write Data into the Device from Caller
XREF CmdUpdate ; Force Outbound Data from Caches onto Device
XREF CmdClear ; Discard All Pending Unread Data inside Device
XREF CmdStop ; Suspend Device Operations
XREF CmdStart ; Resume Device Operations
XREF CmdFlush ; Discard All Queued but Unprocessed I/O Requests
;*********************************************************************
;* First Executable Location *
;*********************************************************************
MOVEQ #-1,D0 ; Return Failure Result Code
RTS ; (In case user tried to execute us as a program)
;*********************************************************************
;* ROMTAG Structure *
;* *
;* This ROMTAG is used by Exec to construct a device node in memory *
;* when the device code is loaded. The setup sequence appears to be *
;* as follows: (Assuming a standard AUTOINIT-flag environment) *
;* *
;* 1) Exec receives a request to open a device. *
;* 2) Exec realizes it is not in memory at this time. *
;* 3) Exec locates it on disk in the global directory DEVS:. *
;* 4) Exec scatter-loads it into memory as a Segment List (seglist) *
;* 5) Exec scans the first hunk loaded for a ROMTAG signature and *
;* invokes an InitResident() Exec function on it. InitResident() *
;* performs steps 6, 7 and 8 below. *
;* 6) Exec examines the Initialization Table pointed to in the *
;* ROMTAG and allocates a device node structure of the correct *
;* size in memory. This is performed by the Exec function *
;* MakeLibrary() which also performs step 7 below. *
;* 7) Continuing to use the Initialization Table, Exec then *
;* a) copies the function vector table into the device node, *
;* using MakeFunctions(). *
;* b) initializes the device's global data space according *
;* to the INITSTRUCTs detailed in the DataTable, using the *
;* function InitStruct(). *
;* c) calls the loadtime initialization code (if the code ptr is *
;* non-NULL). *
;* 8) If the loadtime initialization code returns a zero (NULL) in *
;* D0, Exec unloads the device and fails the caller's original *
;* open request. Otherwise the loadtime initialization code *
;* returns the address of the device node structure. *
;* 9) Exec then links the device node into the global system list *
;* of known Exec devices. *
;* 10) Lastly, Exec invokes the device's open routine using the *
;* vector table setup earlier in the device node. *
;* *
;* In the case of an OpenDevice() request where the device is *
;* already in memory, either because someone else has it open or *
;* because someone used it recently, only step 10 above is executed. *
;* *
;* High Memory *
;* +-----------------------------------+ *
;* | Device's Global Data Area | *
;* | (Contents specific to device) | *
;* +-----------------------------------+ *
;* Device Ptr ===>| Library Node Structure: | *
;* | Version, Revision | *
;* | Various Flags | *
;* | NegSize | *
;* | PosSize | *
;* | IdString | *
;* | OpenCnt | *
;* +-----------------------------------+ *
;* | Vector (Jump) Table: | *
;* | OPEN (Device Ptr Offset -6) | *
;* | CLOSE ( " " " -12) | *
;* | EXPUNGE ( " " " -18) | *
;* | NULLFUNC ( " " " -24) | *
;* | BEGINIO ( " " " -30) | *
;* | ABORTIO ( " " " -36) | *
;* +-----------------------------------+ *
;* Low Memory *
;*********************************************************************
MyRomTag:
DC.W RTC_MATCHWORD ; UWORD RT_MATCHWORD (Signature)
DC.L MyRomTag ; APTR RT_MATCHTAG (Back Ptr to Myself)
DC.L EndCode ; APTR RT_ENDSKIP (Ptr to End of This Hunk)
DC.B RTF_AUTOINIT ; UBYTE RT_FLAGS (Flags)
DC.B VERSION ; UBYTE RT_VERSION (Major Version#)
DC.B NT_DEVICE ; UBYTE RT_TYPE (Type of Module)
DC.B 0 ; BYTE RT_PRI (Initialization Priority)
DC.L MyName ; APTR RT_NAME (Ptr to Node Name)
DC.L MyID ; APTR RT_IDSTRING (Ptr to ID String)
DC.L InitTable ; APTR RT_INIT (Ptr to Initialization Table)
; This Name is for Debugging Use, to Annotate Serial-Debug Output
IFNE INFO_LEVEL ;If any debugging enabled at all
subSysName:
DC.B 'Example',0
ENDC
MyID: DC.B 'Example 1.2 (25 Jul 1990)',13,10,0
MyName: DC.B 'Example.device',0 ; Name of My Device
;*****************************************************************
;* The Romtag specified above states that we were RTF_AUTOINIT. *
;* This means that the RT_INIT structure member points to one of *
;* these tables below. If the AUTOINIT bit was not set then *
;* RT_INIT would point to a routine to run. *
;*****************************************************************
CNOP 0,4 ; Force Long Word Alignment
InitTable:
DC.L MyDev_Sizeof ; Size of My Device's Global Data Space
DC.L CodeTable ; Ptr to Table of Function Vectors
DC.L DataTable ; Ptr to Table of Data Initializers
DC.L LoadInitRoutine ; Loadtime Initialization Routine to Execute
CodeTable: ; These Function Pointers are Order-Dependent
DC.L DevOpen ; Open a Unit of the Device
DC.L DevClose ; Close a Unit of the Device
DC.L DevExpunge ; Expunge (Remove from Memory) the Device
DC.L DevNull ; Reserved¨for Future Use
DC.L DevBeginIO ; Begin (either now or put in queue) an I/O Request
DC.L DevAbortIO ; Abort an Existing I/O Request
DC.L -1 ; End of Table
;***********************************************************************
;* The data table initializes static data structures. The format is *
;* specified in exec/InitStruct routine's manual pages. The INITBYTE/ *
;* INITWORD/INITLONG macros are in the file "exec/initializers.i". The *
;* first argument is the offset from the device base for this byte/ *
;* word/long. The second argument is the value to put in that cell. *
;***********************************************************************
CNOP 0,4 ; Force Long Word Alignment
DataTable:
INITBYTE LN_TYPE,NT_DEVICE ; Set Node Type to 'Device'
INITLONG LN_NAME,MyName ; Set Node Name Ptr to My Name
INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
INITWORD LIB_VERSION,VERSION ; Set Device Major Version
INITWORD LIB_REVISION,REVISION ; Set Device Minor Version
INITLONG LIB_IDSTRING,MyID ; Set ID String Ptr to My ID
DC.L 0 ; End of Table
;******************************************
;* Device-Specific Command Dispatch Table *
;******************************************
CmdTable:
DC.L CmdInvalid ;$00000001 ;0 CMD_INVALID Signal Invalid Command
DC.L CmdReset ;$00000002 ;1 CMD_RESET Reset Device to Initialized State
DC.L CmdRead ;$00000004 ;2 CMD_READ Read Data from Device
DC.L CmdWrite ;$00000008 ;3 CMD_WRITE Write Data to Device
DC.L CmdUpdate ;$00000010 ;4 CMD_UPDATE Flush Device Caches Out
DC.L CmdClear ;$00000020 ;5 CMD_CLEAR Discard Queued Input Data
DC.L CmdStop ;$00000040 ;6 CMD_STOP Restart Device Operations
DC.L CmdStart ;$00000080 ;7 CMD_START Suspend Device Operations
DC.L CmdFlush ;$00000100 ;8 CMD_FLUSH Discard Queued Write Requests
;*********************************************************************
;* *
;*********************************************************************
END