The MASM Forum

General => The Workshop => Topic started by: jimg on June 02, 2017, 02:18:51 AM

Title: Serial I/O communications (terminal) code
Post by: jimg on June 02, 2017, 02:18:51 AM
I've been trying to find some code to write a terminal program to embed in an app I want to write.  After staring at various version of C stuff for a week, I think I'm ready to start.  I read a lot of rhetoric about different ways to implement this.  The problem seems to be that windows nt doesn't have any simple callbacks for i/o routines.  Anyway, I think I'm going to do the 1995 version of things, based upon starting two threads, one to read and one to write (https://msdn.microsoft.com/en-us/library/ms810467.aspx (https://msdn.microsoft.com/en-us/library/ms810467.aspx)).  It seems the simplest (although, not what I would call simple).

Before I start trying to convert C, I thought I'd see if someone already has masm code for this stashed away somewhere, or if anyone has some other masm code for a terminal program or just some thoughts they would like to share.
Title: Re: Serial I/O communications (terminal) code
Post by: anunitu on June 02, 2017, 04:34:53 AM
You might try the wayback machine. There is a LOT of data and old sites now gone. If you are lucky,you might find some old code..I think a lot of the old protocols were done in assembly.

Check here.
https://en.wikipedia.org/wiki/List_of_file_transfer_protocols

Wayback is here.
http://archive.org/web/
Title: Re: Serial I/O communications (terminal) code
Post by: Siekmanski on June 02, 2017, 04:39:28 AM
Try this one, if it suits your needs then i'll clean up the code and do some dutch english translations.
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 02, 2017, 06:21:32 AM
Thanks. Looks like it worked :t
I'd love to have the source!
Title: Re: Serial I/O communications (terminal) code
Post by: Siekmanski on June 02, 2017, 06:27:26 AM
Found a later version, check if it works for you. Then I'll translate this one for you.
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 02, 2017, 08:52:29 AM
Works good, I really appreciate it :biggrin:
Title: Re: Serial I/O communications (terminal) code
Post by: Siekmanski on June 02, 2017, 10:10:22 AM
Pffff, done translating to english...  :biggrin:
Here are the sources, have fun with it.

Are you going to use this to communicate with the WiFi esp8266 module?
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 02, 2017, 10:25:24 AM
That's the plan.  Thanks much, I really appreciate it :t
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 02, 2017, 12:56:28 PM
I put this here rather than the campus since it came from our good friend Siekmanski's code he just gave us.

I've never used RECORD before, so I spent an hour trying to figure this out.  Other than being entered in the reverse order from what I thought it would be, I don't see anything wrong with the code but I'm getting an error.

DCB_New                 DCB <?>
;  this bitrecord def is from windows.inc
; BITRECORD RECORD fBinary:1,fParity:1,fOutxCtsFlow:1,fOutxDsrFlow:1,fDtrControl:2,fDsrSensitivity:1,
;  fTXContinueOnXoff:1,fOutX:1,fInX:1,fErrorChar:1,fNull:1,fRtsControl:2,fAbortOnError:1,fDummy2:17

        mov     DCB_New.fbits,BITRECORD<NULL,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,\
                FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>

gives:  Error A2150: Missing operator in expression

I've counted 20 times at least, and it looks like the right number of entries.  Anyone see what's wrong with this?  I'm getting the same complaint from all the assemblers from 615 to uasm.
Title: Re: Serial I/O communications (terminal) code
Post by: anunitu on June 02, 2017, 01:04:46 PM
Wondering if that backslash is supposed to continue to the next line,might it need to be a forward slash? Might need a space before the BS,might be seeing it as a divide because of the comma first.
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 02, 2017, 02:22:11 PM
Nope.  All on one line made no difference.

Also tried:
xxxttt BITRECORD  < TRUE, NULL, TRUE, TRUE, DTR_CONTROL_HANDSHAKE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, RTS_CONTROL_HANDSHAKE, FALSE, NULL >

        mov     DCB_New.fbits,xxxttt

and got : Error A2049: Invalid instruction operands

I had to reverse the order in this case because it complained about sizes and it was obvious it was just backward.


p.s.

I really don't need to change all this stuff, so I just copied the original DCB and commented this whole section out and it works just fine.   I would, however, like to know the correct way to code this for future reference.  For now, I'm just pressing on.
Title: Re: Serial I/O communications (terminal) code
Post by: Siekmanski on June 02, 2017, 07:22:21 PM
Yeah, it's a bit confusing but the BITRECORD in masm needs to be in reversed order as below. ( it's different as in C )

\ is continue on the next line.

; FlowControle == None
        mov     DCB_New.fbits,BITRECORD <\
                NULL,\  ; fDummy2:17
                FALSE,\ ; fAbortOnError:1
                RTS_CONTROL_DISABLE,\   ; fRtsControl:2
                FALSE,\ ; fNull:1
                FALSE,\ ; fErrorChar:1
                FALSE,\ ; fInX:1
                FALSE,\ ; fOutX:1
                FALSE,\ ; fTXContinueOnXoff:1
                FALSE,\ ; fDsrSensitivity:1
                DTR_CONTROL_DISABLE,\   ; fDtrControl:2
                FALSE,\ ; fOutxDsrFlow:1
                FALSE,\ ; fOutxCtsFlow:1
                NULL,\  ; fParity:1
                TRUE>   ; fBinary:1 Always TRUE !!!

        or      DCB_New.fbits,00000000000000000000000000000010b   ; here I set the right bit for: "fParity"

You can set every bit by hand of course...
Title: Re: Serial I/O communications (terminal) code
Post by: mineiro on June 02, 2017, 10:58:46 PM
Quote from: jimg on June 02, 2017, 02:22:11 PM
I would, however, like to know the correct way to code this for future reference.
Quote from: jimg on June 02, 2017, 12:56:28 PM
I've never used RECORD before,
hello jimg, below is a simple example about how to deal with record, not sure if helps but this is my intention.

descritor RECORD one:1=0,two:3,three:2,four:2      ;0 ??? ?? ??

.data
descr_1 descritor <>            ;0 ??? ?? ??
descr_2 descritor <1,2,3,2>         ;1 010 11 10

.code
or descr_1,( 3 shl two + 1 shl three)      ;0 011 01 ??
mov al,descr_2         ;1 010 11 10
mov bl,width two      ;bits size of field two == 3
and al,mask two         ;mask to deal with that field == 0 111 00 00
mov cl,two         ;displacement of field two inside that record structure == 2+2(four+three) == 4
shr al,cl         ;rotating to get only that value, al=2
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 02, 2017, 11:38:31 PM
Thanks mineiro.

Everyone else, my apologies.   The Record stuff works in ml614 and ml615.  My system for switching between ml and xxwasm was broken, the error is just in wasm and decendants.
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 03, 2017, 04:40:49 AM
S-

Using masm 6.15-

this line is not acceptable, and is the same order as in the program.

yy1 BITRECORD <NULL,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>

I get the errors-
: error A2071:  : fOutxCtsFlow
: error A2071:  : fErrorChar
   So it knows the sizes are wrong


this is is accepted, so masm want them specified in the same order as the record definition.

yy4 BITRECORD <TRUE,0,TRUE,TRUE,DTR_CONTROL_HANDSHAKE,0,0,0,0,0,0,RTS_CONTROL_HANDSHAKE,0,0>


   Both of these lines are acceptable to Masm, which means it is a masm bug,
     it should have caught the size error in the first line here also.

mov DCB_New.fbits,BITRECORD<NULL,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,\
                FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>
               
mov DCB_New.fbits,BITRECORD<TRUE,0,TRUE,TRUE,DTR_CONTROL_HANDSHAKE,0,0,0,0,0,0,RTS_CONTROL_HANDSHAKE,0,0>


       In fact, if I try to force an error by entering a value too big, like this-

mov     DCB_New.fbits,BITRECORD<132000,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,\
                FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>
               
mov DCB_New.fbits,BITRECORD<TRUE,0,TRUE,TRUE,DTR_CONTROL_HANDSHAKE,0,0,0,0,0,0,RTS_CONTROL_HANDSHAKE,0,132000>

      Both are still accepted by masm.


   I really think the second one is the correct one, and the ones in the program are incorrectly reversed,
     but I can't get the program to fail either way, so I don't know how to test it.
Title: Re: Serial I/O communications (terminal) code
Post by: Siekmanski on June 03, 2017, 05:15:24 AM
I know that masm reverses the bits in BITRECORD, call it a quirk.  :dazzled:
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 03, 2017, 05:51:19 AM
Yes, after much more testing, I believe you now.

The big problem is that BITRECORD is defined backward I think.

There is no way to use it in the normal manner and get the correct results-

This-
yy1 BITRECORD <NULL,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>
is not accepted by masm in the data section, even though that's the order it has to be in storage.

doing-
mov     DCB_New.fbits,BITRECORD<0,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,         FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>

is incorrectly accepted by masm but gives the right results. 
It should have been rejected which means .... what?
the wasm decendents will never accept that when they are fixed, so BITRECORD needs to be fixed, but that would break a lot of programs I'm guessing.

In any case, thank you for your patience, I think I have this figured out and will try not to bug you for a while.

Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 03, 2017, 09:45:30 AM
I'm not the only one to notice this!
http://www.asmcommunity.net/forums/topic/?id=21057 (http://www.asmcommunity.net/forums/topic/?id=21057)

Odd it never went anywhere.  I'll bet anyone who uses bitrecord only does so with the mov.  That's the only way it could work, by taking advantage of a bug in masm.

And now I'm done.  Really.
Title: Re: Serial I/O communications (terminal) code
Post by: anunitu on June 03, 2017, 10:07:39 AM
It was common in the "Early" programming days to use "special" code tricks with undocumented chip level code.

here:
https://en.wikipedia.org/wiki/Illegal_opcode

An illegal opcode, also called an undocumented instruction, is an instruction to a CPU that is not mentioned in any official documentation released by the CPU's designer or manufacturer, which nevertheless has an effect. Illegal opcodes were common on older CPUs designed during the 1970s, such as the MOS Technology 6502, Intel 8086, and the Zilog Z80. They exist as a side effect of the wiring of transistors in the CPU, and usually combine functions of the CPU that were not intended to be combined.

While most illegal instructions have useless or even highly undesirable effects (such as crashing the computer), a few might by accident do something that can be useful in certain situations. Such instructions were sometimes exploited in computer games of the 1970s and 1980s to speed up certain time-critical sections. Another common use of them was in the ongoing battle between copy protection implementations and cracking. Here, they were a form of security through obscurity, and their secrecy usually did not last very long.

Title: Re: Serial I/O communications (terminal) code
Post by: jj2007 on June 03, 2017, 10:36:33 AM
Jim,

Check this old thread (http://www.masmforum.com/board/index.php?topic=16253.0).

If that doesn't solve the problem, we can write a macro that works correctly and in the same way in ML and the Watcom family.

@Anunitu: corrected, thanks!

@Jim: What is the expected value for the BITRECORD example? I am working on a macro but am confused about the order...
Title: Re: Serial I/O communications (terminal) code
Post by: anunitu on June 03, 2017, 11:13:40 AM
Thread link not working JJ
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 03, 2017, 12:00:41 PM
Quote
@Jim: What is the expected value for the BITRECORD example? I am working on a macro but am confused about the order...

just reversed.
I would rather just have a correct definition for BITRECORD.  No one could be using it in a data statement, because the results would be wrong and not work.  The only way it could be being used at all is in the mov command, and that only works because of a masm bug.  It would work with the old or corrected definition just the same, it just places them in the order specified in the mov, so why not correct it.
Choice number two would be to just make a new correct definition with a new name (I'm currently using xBITRECORD which is kinda lame).
I can understand the lure of a macro, but that would take a lot more code, and current code would have to be changed anyway to use it.
Of course, there is always the chance that I am totally misunderstanding what's going on, but I don't think so.
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 03, 2017, 12:12:29 PM
So I just looked through that old link, and the only way fbits is set is with the mov op.

The obvious way to set it would be something like;

.data
yy BITRECORD  < TRUE, NULL, TRUE, TRUE, DTR_CONTROL_HANDSHAKE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, RTS_CONTROL_HANDSHAKE, FALSE, NULL >
.code
mov eax,yy
mov DCBNew.fbits,eax

but that doesn't work with the current definition of BITRECORD, the fields come out reversed.



Title: Re: Serial I/O communications (terminal) code
Post by: Siekmanski on June 03, 2017, 02:13:12 PM
Quote from: jimg on June 03, 2017, 12:12:29 PM
So I just looked through that old link, and the only way fbits is set is with the mov op.

The obvious way to set it would be something like;

.data
yy BITRECORD  < TRUE, NULL, TRUE, TRUE, DTR_CONTROL_HANDSHAKE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, RTS_CONTROL_HANDSHAKE, FALSE, NULL >
.code
mov eax,yy
mov DCBNew.fbits,eax

but that doesn't work with the current definition of BITRECORD, the fields come out reversed.

Thus, the solution is to reverse the order.

BITRECORD<NULL,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>

And you're going to use it to communicate with modules that only use RX and TX which need to be "No FlowControl"

BITRECORD<NULL,FALSE,RTS_CONTROL_DISABLE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_DISABLE,FALSE,FALSE,NULL,TRUE>

Title: Re: Serial I/O communications (terminal) code
Post by: Siekmanski on June 03, 2017, 03:03:04 PM
BTW, ever considered to use a FTDI chip to do serial I/O communications? They have a robust api, faster and more reliable than the microsoft stuff we are dealing with now. It has an option to have direct communications with other peripherals.
Also an option is to use bitbanging.  8)

I've stopped using the windows method in 2008 and made the step only using FTDI.  :t
Title: Re: Serial I/O communications (terminal) code
Post by: jj2007 on June 03, 2017, 06:36:38 PM
Quote from: jimg on June 03, 2017, 12:00:41 PMI can understand the lure of a macro, but that would take a lot more code, and current code would have to be changed anyway to use it.

Attached BitRecord.mac, judge yourself if that is a lot more code. Here are examples of usage:include \masm32\include\masm32rt.inc
include BitRecord.mac

.code
start:
  crlf equ <13, 10>
  mov eax, 0BAADF00Dh
  print hex$(eax), crlf
  print hex$(@Record(11:4, 10:4, 10:4, 13:4, 15:4, 0:4, 0:4, 13:4)), crlf ; BAADF00D as 4-bit fields
  print hex$(@Record(11:4, 1, 0, 1, 0, 10:4, 13:4, 15:4, 0:4, 0:4, 13:4)), crlf ; BAADF00D, first A as 1-bit fields
  print hex$(_Record(11:4, 10:4, 10:4, 13:4, 15:4, 0:4, 0:4, 13:4)), crlf ; D00FDAAB
  print hex$(_Record(0,FALSE,RTS_CONTROL_HANDSHAKE:2,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE:2,TRUE,TRUE,NULL,TRUE)), crlf
  print hex$(@Record(0,FALSE,RTS_CONTROL_HANDSHAKE:2,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE:2,TRUE,TRUE,NULL,TRUE))
  exit
end start


There are two macros, @Record and _Record. One of them is "reversed". If the arg has e.g. 15:4, it means 4 bits wide; if there is no ":" then it's a one bit field.

Output:BAADF00D
BAADF00D
BAADF00D
D00FDAAB
0000B808
0000202D


So, which one is correct, 0000B808 or 0000202D? What is the hex$(eax) that corresponds to your expectations?
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 03, 2017, 11:43:46 PM
Quote from: Siekmanski on June 03, 2017, 02:13:12 PM
Thus, the solution is to reverse the order.

BITRECORD<NULL,FALSE,RTS_CONTROL_HANDSHAKE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,DTR_CONTROL_HANDSHAKE,TRUE,TRUE,NULL,TRUE>
Yes, I agree, you are correct, that works.
However, I'm going to be a little picky with semantics and say I don't consider that a solution but rather a hack to account for BITRECORD being defined incorrectly.

Regarding FTDI, it's certainly something I might consider for a standalone hardware product, but here I'm just trying to work with what people are most likely to have.
Title: Re: Serial I/O communications (terminal) code
Post by: jimg on June 03, 2017, 11:51:01 PM
JJ-
So far I have only operated on what seemed logical from the descriptions I could find, and what masm actually does.  Yes, we need to do real world testing.  I'll try to actually try out the values of fbits on a comport to see what's correct.  I'll respond in your other thread about this.