15 November 2020, 17:10 | #1 |
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Exec style Devices (and DOS Devices)
Hi all,
Believe it or not, but in all my years of Amiga coding, I’ve managed to side step using devices to any great degree. I’m ashamed to admit, I tended to use OpenDevice() to just “lock” a piece of hardware and then hit the chipset regs directly. I hope to be able to resume work on my much neglected Amiga projects in the not too distant future, and one thing that I will probably need to do is write a Exec style device. Now I need to make sure I’ve got a few things clear in my head (and all documentation covering Devices is rubbish), I’ll write here my understanding and some of the AmigaOS experts can correct me where I’m wrong! From a user point of view the only interaction one has with a device is via IORequestStructures and, IORequest structures are just extended Exec style messages. So as a theoretical example, to read some data from a device one would create an iorequest structure then OpenDevice() the device you are interested in, specifying the unit number you want. The iorequest is now a shared block of memory between your program and the device. Now we call the BeginIO(iorequest) Exec function and wait for a reply to whatever message port you set in your iorequest. As I understand it devices have their own iorequest structures which include the standard fields (command/length/error/etc), so when the reply is received I can expect it to contain the requested data or whatever. As long as I have possession of the iorequest (i.e. it has been replied to), I may alter the fields of the iorequest, so as to issue new commands. Then call BeginIO(). When I’m finished with the device, I just call CloseDevice(iorequest). Points to note, there is no way to find out what devices are available other than to probe execbase’s deviceList (with appropriate locking), or to read the system disk/Devs: dir. This is no standard way to establish how many units a device may have without trying to open a particular unit and check for success/failure? From a device developer point of view, a device is essentially just a library with two extra “standard functions” to initiate and abort an i/o operation. A device may spawn a task to handle the request, if it doesn’t spawn its own task, I assume this is only vaild for simple devices and it does its processing in the context of the exec (the calling task?). When a task calls exec’s BeginIO(iorequest), exec will then call the device’s BeginIO() which then Handles the command. From the documentation it seems devices may have other functions, but it isn’t clear how the calling task is supped to obtain the devicebase... unless it is permitted to use the address placed into the iorequest structure during the OpenDevice() call. Like most structures in AmigaOS it isn’t clear just how opaque it’s supposed to be. Ok, I think that all makes sense! It seems to me that given how robust it is, the intention was that the device interface was meant to be the normal “high level” AmigaOS interface, with libraries, signals, and messages all supposed to be the hidden lower levels. I guess it just didn’t work out that way Last edited by bloodline; 22 November 2020 at 12:18. Reason: Updated the title to better reflect the thread |
15 November 2020, 19:58 | #2 | ||||||||||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,302
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
In short: Allow the user to pick a device by name. Do not rely on NSD, it doesn't solve that problem. Quote:
The ramdrive device is such a device, to give an example. Quote:
Quote:
Quote:
The Amiga device interface is supposed to provide asynchronous command interfaces, typical for IO operations. Libraries provide synchronous helper functions. |
||||||||||
15 November 2020, 23:31 | #3 | |||||||
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Many thanks for you reply here, I do really appreciate you taking the time to clean up my knowledge! It does seem that, broadly, I understand how this works.
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
I'm reading Wendal's guide right now... not sure it really helps me : http://wandel.ca/homepage/execdis/devices_doc.txt Last edited by bloodline; 15 November 2020 at 23:45. |
|||||||
16 November 2020, 11:32 | #4 |
Moderator
Join Date: Nov 2001
Location: Germany
Posts: 873
|
Maybe it should be noted that BeginIO/DoIO will clear all io_Flags and so make it impossible to deliver any flags to the device. If this is needed (e.g. IOTDF_INDEXSYNC/WORDSYNC for trackdisk.device) you need to call DEV_BEGINIO manually.
|
16 November 2020, 15:14 | #5 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,302
|
BeginIO() does not clear any flags. DoIO() does, and SendIO() does.
|
16 November 2020, 15:51 | #6 |
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Ok, so I've been using Scout to examine real devices, I notice that the input.device attendant task has the top two signals set (30 and 31), does each of these signals relate to keyboard and the mouse interrupt handlers? I've always been reluctant to set a signal during an interrupt... as IIRC signal causes an immediate reschedule.
|
16 November 2020, 17:57 | #7 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,053
|
Yup, what Thomas said. I've been doing some experiments with trackdisk.device and raw MFM data recently and ran into that particular "problem". DoIO() sets them to IOF_QUICK, SendIO() clears them. If you are linking with amiga.lib you can simply call BeginIO()/WaitIO() and be done with it, otherwise you have to go down to device's BeginIO() and handle eventual specifics.
|
16 November 2020, 18:53 | #8 | ||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,302
|
Quote:
Quote:
Signal() can be called within an interrupt without any problem. Just to give one example: The graphics.library vertical blank interrupt calls Signal() to wake up tasks waiting in WaitTOF(). PutMsg() is also interrupt-callable. It would be very bad for any IO device implementation if it wouldn't. |
||
16 November 2020, 19:49 | #9 | ||
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Quote:
Quote:
I hope that makes sense? |
||
17 November 2020, 07:04 | #10 | ||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,302
|
Quote:
Quote:
|
||
17 November 2020, 10:21 | #11 | ||
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Quote:
Though I've always been curious about the "signals reserved for system usage"... Quote:
I've never really understood about software interrupts, as I've never had cause (excuse the pun) to use them. I'll devote a bit of time tonight to read about them. |
||
17 November 2020, 11:10 | #12 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,302
|
The signals 0-15 are reserved for system usage. Signals 16-31 are just what AllocSignal() returns, and this is what the input device uses for its ports.
|
19 November 2020, 13:33 | #13 |
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
I accidentally stumbled across DOS's concept of devices. I wondered if I could write a Device which would expose an interface that could be accessed via a command line, like SER: for example...
I'm totally lost, DOS is another world... |
19 November 2020, 15:10 | #14 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,637
|
Yes, conceptually you can interface almost anything using amiga OS devices and handlers, but figuring out how to write them is not an easy task, unfortunately.
|
19 November 2020, 16:43 | #15 | |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,302
|
Quote:
That is the tripos version of a "device", which is a horse of a different color. Sorry, "colour", as Tripos comes from GB, not US. So, such a "device" is essentially a HUNK executable that is launched as a standard dos process, and finds in proc->pr_MsgPort "DosPackets" as command packages. These DosPackets encode what to do and on which data to operate. So the concepts are related, but evolved in parallel and independent of each other. What is an "IORequest" in the exec world is a "DosPacket" in the Tripos world. What "DoIO()" is in the exec world is "DoPkt()" in the Tripos world. Unfortunately, documentation about Tripos "Devices" aka "Handlers" is weak. The "best" first hand source is the AmigaDos Manual, 3rd Edition, by Bantam Books, which is more or less an evolved version of the Tripos manual. The best, and most recommended source for this business is Ralph Babel's "Guru Book", and you would typically want to look into this source, and not into the Bantam book. |
|
20 November 2020, 19:51 | #16 | ||
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Quote:
Quote:
|
||
22 November 2020, 10:57 | #17 | |
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Quote:
Say I created a simple piece of hardware (imagine a simple 5v tolerant uC which exposes an SD card and a serial port, connected via the A1200 clock port), I could easily write an exec Device to interface with it using IORequests. The Exec interface is really clean I like it. Now if I want to expose the two hardware features (the serial port and the SD card interface) via DOS, I would need to write a pair of handlers. One for the serial port would seem to be quite simple as it is a simple in/out device... write a stream of bytes to it, read a stream of bytes from it. The one for the SD card would be more complex, firstly because the SDCard exposes a filesystem, and secondary the SDCard spec requires that cards use the FAT file system (I’m aware that AOS3.0 supports FAT12 at least), but would expect to write ExFAT support into my handler. Am I correct that the responsibility of dealing with the filesystem is with the handler (that’s the impression I get looking at the packet types), this way the exec device can just deal with the data stream and DOS can just deal with human readable paths. I’m having difficulty conceptualising is the chain of responsibility here. If I’m picturing this correctly, DOS is only aware of the handlers, of which it maintains a list, called the DOSList. At some point handlers are added to this list via the DOS function AddEntry (a mount list at boot time? The mount command at run time?). Upon opening (mounting), the handler opens the exec style device which it needs to interface with the hardware, and exposes a DOSpacket interface to DOS. So a handler is essentially a virtual device which acts as a go between DOS and the exec style device? Now I see that handlers are to be found in the Sys:L dir (I guess a TripOS legacy)and their configuration files in DevsOSDrivers. It also seems that I could write a single handler for my device, and have two “DOSDriver” configuration files for each of the features provided by my device. Again sorry if this is time wastingly simple/naïve... I’m just trying to get a handle (excuse the pun) on all of this. -edit- also it seems some exec devices can accept DOSPackets directly!? i.e. the trackdisk.device doesn’t seem to have a handler between dos and the device. Last edited by bloodline; 22 November 2020 at 11:03. |
|
22 November 2020, 11:33 | #18 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
|
22 November 2020, 14:50 | #19 | ||||||||||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,302
|
Quote:
exec devices provide block I/O, on top of them sit dos type handlers which provide file access by organizing the blocks. Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Yes, of course. What sits between them is the FastFileSystem. So DF0: has a port that communicates to the fast file system, and the fast file system communicates to the trackdisk.device. |
||||||||||
22 November 2020, 16:49 | #20 |
Registered User
Join Date: Jan 2017
Location: London, UK
Posts: 433
|
Thomas & phx, Many thanks guys I finally feel like I’m understanding this now.
At first it felt like a really messy design, but the more I think about it, the more elegant it seems, at least in concept if not implementation |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Exec library codes | millis | support.Other | 2 | 21 July 2017 19:22 |
LVO tables in exec libraries | bloodline | Coders. System | 2 | 25 February 2017 15:35 |
CDTV exec.library | Arnie | support.WinUAE | 19 | 18 February 2016 13:11 |
debugging session with exec lib | pixel | Coders. Asm / Hardware | 4 | 20 May 2014 23:49 |
exec.library problem with VisualPrefs | oldpx | support.Apps | 4 | 29 August 2002 00:18 |
|
|