Parallel Programming #5

Blitz3D Forums/Blitz3D Beginners Area/Parallel Programming #5

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Did you mean for me to read the BASIC tutorials with Blitz3D entitled types1.bb and types2.bb for the documentation on (custom) types?
Not really, just to read the documentation for the keyword "Type" (though the tutorials certainly wouldn't hurt). It's internally the same as "Struct" in C.

...but what is the "Bank thing"? Is it another way to reference custom typing?

A (Blitz) bank is simply a chunk of memory to use in whatever manner you want. It is allocated for you with the CreateBank. You can read and write to it with the Peek and Poke commands (e.g. PeekByte). Look in the documentation under "2D Category -> Bank".

Let me try to explain why we had to get into banks and (custom) types in the first place. Do you see in the WinIo documentation where the second parameter of GetPortVal requires a "Pointer to a DWORD variable that receives the value obtained from the port"? If it just said "DWORD variable" (only), then what you have in the decls file is ok:
GetPortVal%(PortAddr, PortVal, Size):"GetPortVal"
...because PortVal is the same as Portval% and a DWORD is the same as an int. (The % is implied if no type is explicitly specified.) BUT, since it requires a pointer to a dword (or in other words, an integer value containing the actual memory address of the actual DWORD value), you have to specify it like this:
GetPortVal%(PortAddr, PortVal*, Size):"GetPortVal"
Notice the * type of the second parameter (PortVal).

Now, since you've declared a type as * in the decls file, that means you must use a custom type OR bank when as the second parameter in the actual Blitz program. Custom type _instances_ and banks are both constructs for a basically a pointer pointing to a block of memory. So when you create a custom type instance or a bank and pass it as the parameter, AND that parameter is defined as * in the decls file, then Blitz automatically passes the address of the memory block to the DLL, which is exactly what's required (see the WinIo docs). Here's what you're doing:

You're defining a custom type, which is good:
Type PortVal
	Field val
End Type

You're also creating a single instance of that type (type "PortVal"), called "p", which is good:
p.PortVal = New PortVal

So now essentially p is a pointer to a chunk of memory that contains 4 bytes (enough space to hold the single integer field "val").

But, later, you call GetPortVal like this:
GetPortVal($379, PortVal, 1)

What's happening here is that PortVal, since it's undefined previously, has the value 0. So, you're essientially just saying this:
GetPortVal($379, 0, 1)
. And when WinIo gets this, it's expecting the second parameter to be a pointer to the chunk of memory it's going to use. So it treats the 0 as "address 0" and looks at memory address 0 for the DWORD, which would generate a memory access violation or at least a failure. This is why it's not working for you. As a note, I wonder if you were attempting to pass the custom type in. Well, if that's the case, portval is the name of the defined type. It would be the same as if you tried to pass in simply "%" or "$" in as a parameter. This doesn't make sense, so it treats it as an undefined integer.

What you need to do is (a) change the decls PortVal parameter to PortVal*, and (b) pass in p instead of PortVal as the second parameter in the Blitz call to GetPortVal.

Then in the next line, instead of
Print PortVal
, you need to
Print p\val
... Again. You must pass in the *instance* of the PortVal custom type. Type Portval is really just a blueprint. When you use the New keyword, then it creates a variable of that type (in this case called "p", with a field of "val"). Try these changes and see if it works. I can't test it, becuase I don't have anything to plug into my serial/parallel ports.

BTW, I don't expect you to grasp all of this at once, but if you can grasp half of it now, you're doing good. We can work on the rest. This is more advanced than "beginner" stage. =)

PS: Just for kicks, instead of this:
Type PortVal
	Field val
End Type
p.PortVal = New PortVal
GetPortVal($379, p, 1)
Print p\val

...you could use this:
p = CreateBank(4)
GetPortVal($379, p, 1)
Print PeekByte(p, 0)

...and you would get the exact same results. It's just the difference of using a custom type intance as the parameter versus a bank. I'm just including it here because I'm not sure which one would be intuitively easier for you to grasp. Before you ask questions, though, read the documentation for Banks and Types.