Parallel Programming #5

Blitz3D Forums/Blitz3D Beginners Area/Parallel Programming #5

None(Posted 2004) [#1]
Thanks again to soja and now Arbitrage!

Did you mean for me to read the BASIC tutorials with Blitz3D entitled types1.bb and types2.bb for the documentation on (custom) types?

Anyway, I made the following changes:
1. moved Type definition outside of the loop (all of it, I think.);
2. sorry about showing * with GetPortVal -- I had already changed it to % when I saw it did not work, but I sent you an older version of the .decls file;
3. term definition:
A) ...analogous to structs in C... Does that mean constructs?
B) OK, now I know that the WinIo documentation is expressing C language (You mentioned that BB int% is equated to Bool in C.), but what is the "Bank thing"? Is it another way to reference custom typing?

So... where am I at? The program again runs but the results are embedded in the past -- all the loop (still) returns me is a value of 0! Help again! Following is the updated versions:


.lib "winio.dll"


;Initializes the WinIo library (boolean).  Does not have to be used with Windows XP.
InitializeWinIo%():"InitializeWinIo"

;Performs shutdown of the WinIo library.  Must be called before terminiating an application or when no longer using the WinIo library.
ShutdownWinIo():"ShutdownWinIo"

;Calls the WinIo driver (boolean).  Parameters: (Points to a null-terminated string to specify the winio.sys driver path, Set to false).
InstallWinIoDriver%(WinIoDriverPath$, IsDemandLoaded):"InstallWinIoDriver"

;Removes the WinIo driver (boolean).  
RemoveWinIoDriver%():"RemoveWinIoDriver"

;Reads a 1, 2, or 4 byte value from specifies I/O port (pointer).  Parameters: (Input port $379, DWORD variable, BYTE = 1).  
GetPortVal%(PortAddr, PortVal, Size):"GetPortVal"

;Writes a 1, 2, or 4 byte value to an I/O port (boolean).  Parameters: (Output port $378, Hex value written to port, BYTE = 1).
SetPortVal%(PortAddr, PortVal, Size):"SetPortVal"



and...



;The BlitzBASIC code for:
;Direct Port access from BlitzBASIC using WinIo.

;Set graphics mode.
Graphics 800, 600, 16, 2
SetBuffer BackBuffer()

;Initializes the WinIo library.
;InitializeWinIo()

;Call the WinIo driver
If Not InstallWinIoDriver(".\", False) Then
	Print "Initialization failed."
	End
EndIf

;Create Custom Type.
Type PortVal
	Field val
End Type
p.PortVal = New PortVal
DebugLog p\val

Repeat

;Read a 1 byte value from the specified port and place in variable DWORD.
GetPortVal($379, PortVal, 1)

;Print variable p
Print PortVal

Until KeyDown(1)

;Removes the WinIo driver.
RemoveWinIoDriver()

;Shutsdown the WinIo library.
;ShutdownWinIo()

End



Whenever this is over I am going to create a tutorial for beginners on using WinIo for simple parallel port operations... The next project is the serial buss. Why? Because it is a universal method (educational-wise) of controlling training robotic equipment.

Thanks, again!


None(Posted 2004) [#2]
PS. How come the text is "out-of-bounds"? I am running 800 X 600.


GfK(Posted 2004) [#3]
Have you seen the "post reply to topic" box at the bottom of each thread?

You don't need to start a new thread every time.


jhocking(Posted 2004) [#4]
That's what I was just about to point out. You must know about that functionality though since the second post in this thread is you replying.


soja(Posted 2004) [#5]
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.


None(Posted 2004) [#6]
With regards to Gfk & jhocking I will try the "post reply to topic" method instead of starting a new thread...

soja... thanks for all the help! Of course the situation is no better (Murphy's Law -- an excuse to blame something!); the program runs but I still get is a 0 result. I REALLY appreciate the detail that you go into to explain things -- you definately get credit.

Life suddenly got in the way of programming and I am not sure when I can again get on the forum, it could be tomorrow or whenever. Here is where I am now...


.DECLS FILE

.lib "winio.dll"

;Initializes the WinIo library (boolean). Does not have to be used with Windows XP.
InitializeWinIo%():"InitializeWinIo"

;Performs shutdown of the WinIo library. Must be called before terminiating an application or when no longer using the WinIo library.
ShutdownWinIo():"ShutdownWinIo"

;Calls the WinIo driver (boolean). Parameters: (Points to a null-terminated string to specify the winio.sys driver path, Set to false).
InstallWinIoDriver%(WinIoDriverPath$, IsDemandLoaded):"InstallWinIoDriver"

;Removes the WinIo driver (boolean).
RemoveWinIoDriver%():"RemoveWinIoDriver"

;Reads a 1, 2, or 4 byte value from specifies I/O port (pointer). Parameters: (Input port $379, DWORD variable, BYTE = 1).
GetPortVal%(PortAddr, PortVal*, Size):"GetPortVal"

;Writes a 1, 2, or 4 byte value to an I/O port (boolean). Parameters: (Output port $378, Hex value written to port, BYTE = 1).
SetPortVal%(PortAddr, PortVal, Size):"SetPortVal"


.BB PROGRAM

;The BlitzBASIC code for:
;Direct Port access from BlitzBASIC using WinIo.

;Set graphics mode.
Graphics 800, 600, 16, 2
SetBuffer BackBuffer()

;Initializes the WinIo library.
;InitializeWinIo()

;Call the WinIo driver
If Not InstallWinIoDriver(".\", False) Then
Print "Initialization failed."
End
EndIf

;Create Custom Type.
Type PortVal
Field val
End Type
p.PortVal = New PortVal
DebugLog p\val

Repeat

;Read a 1 byte value from the specified port and place in variable p.
GetPortVal($379, p, 1)

;Print variable p
Print p\val

Until KeyDown(1)

;Removes the WinIo driver.
RemoveWinIoDriver()

;Shutsdown the WinIo library.
;ShutdownWinIo()

End


By the way... I noticed that you mentioned that you do not have a hardware device available to plug into your parallel port!? I thought all programmers had parallel PIO cards (homemade, of course) for experimentation!!! Why, I even have access to a MicroBot (edu training) robot for serial port work!

All kidding aside... the first thing I want to impress on you is that I do not take kindly for others doing my work for me. As you can tell by now I believe in Plug & Chug. But there comes a time... I can easily lend you a PIO card and cable to use for testing.

It's your call.

Thanks, again

DES