How to structure device driver software? I'm asking here for both the scientific, programmatic, and structural format of a device driver. What does that mean? Basically, I'm not asking how to write a driver in general ... I'm asking how to structure one to behave as software that can act as the "middleware" between higher-level code and the hardware itself. I've decided to embark on a journey of low-level computer programming (e.g. systems programming)
to develop reusable software that can "expose" accessibility of hardware memory access by driver calls. 

I basically run a freelance group of a small programming team/company, and I've decided to take on development across various retro-gaming platforms from the ground up (those which have decent documentation, or reverse engineering will endue). What I'm asking here is how would one envision the development or structure of software that can act as a intermediary between the application software and the hardware; developmentally, structurally, and programmatically. My choice of console was originally the Nintendo 64's GPU (which I have documentation for). The issue isn't with writing the code to access the GPU, it's with developing a reusable driver/graphics engine (I'm new to it).

I would have asked this at Programmers.SE, but they reject these kind of questions since they're not about specific programming issues, but about careful design methodologies, modularity, and structuring.

So I'll ask again with hope to receive a somewhat explanatory answer on this process ... how do I go about the design methodology, structural format, or developmental logic to create a piece of software that can be accessed by other software to enable device access modularly? In other words, how do I structure and design a driver (i.e. what procedure should I take in creating such software)?



Again, to clarify, I am not asking how to write a driver, but how to go about structuring the system, methodology, and behavior of a driver. Are there any specific ways of going about this that prove successful (e.g. certain data types to define behavior for accessibility, methods used in accessing parts of a driver independently, etc.)?
That very, very much depends on the kernel for which you are writing your driver. I'm (a bit) familiar with Linux. There are structures defined into which your drver has to hook. Those structures define most of the structure you are looking for, the driver itself just hooks into the kernel's structures on startup, gets its marching orders through a structure to be filled with function pointers for the relevant operations on the hardware. See Corbet, Rubini, Kroah-Harman "Linux Device Drivers" (3rd edition, get it here). It is somewhat dated, but the fundamentals haven't changed that much. The Linux Drivers Project gathers people trying to write drivers.

For a graphics card, the picture is quite different, I believe you'll find the above split between the kernel and X.org.

(The above general picture, with the kernel defining the overall architecture and the driver filling in the details of what object-oriented programming fans would call an "object" in an operating system defined device type "class" is the only reasonable way of structuring a non-toy, non-one-machine-only operating system. Most of the time written in C, not C++ or ($deity forbid) Java, but OO all the same.)