??? 05/16/07 07:50 Read: times |
#139307 - there are many ways... Responding to: ???'s previous message |
Hello Russ,
Thanks for your comments. Here are some comments on your comments :-). Russ Cooper said:
What happens when a DEL character (0FFh) comes along? I don't know about 0FFh, but on some of the terminals a 07Fh character is sent if the Delete button is pressed on the keyboard. Whether this is formally DEL or not I don't know nor have intention to investigate - in this case I prefer to work with the real implementations of terminal emulators rather than the obsolete or even nonexistent (for VTxxx - compatibility) standards. The present implementation will simply throw 07Fh into the buffer and echo it, whatever it might result in. In the more complex example of line editor (which our ReadString definitively is), it behaves as you would expect - BS (08h) eats the character to the left of the cursor (note that as there the horisontal cursor movement is implemented, there might be characters right to the cursor, too, so they need to be moved around, too); DEL (7Fh) eats the character the cursor sits on. In fact, both result in the same operation after having moved the cursor appropriately for one of them; subject to various funny boundary cases. Russ Cooper said:
Since you went to the trouble of making the TxChar subroutine, is there any reason you didn't call it from inside of ReceiveString? Yes, there is. First, I wouldn't call writing 4 lines of trivial asm code "a trouble" :-) Although this barely applies in this case, as the line editor is expected to be called from some very basic "main" loop; I (often subconsciously) tend to optimize '51 routines for minimum RAM/stack usage. RAM/stack is a precious commodity in '51's (especially in the vanilla types), while code memory is usually abundant. Here, two bytes of RAM/stack are spared NOT using a TxBuff call, whereas two or three bytes of code memory is wasted per each usage. This also converts to the "let's make it universal" approach. I _decided_ not to make it "universal", but compact. In the real world, this is a "gets" C-library (stdio) routine, but it then would be expected to return a pointer to the received string etc. so it's not a fully-grown gets anyway. If it would be, it would be expected that it calls a putch/getch or similar library routine itself to get the simple characters handled in "universal way" (that it is still not universal enough and fgets is needed etc. is another matter). You can never make it universal enough, but you can make it as compact as possible - so I went this way. Russ Cooper said:
I've always written TxChar as MOV SBUF/JNB TI,$/CLR TI instead of the way you have it. It seems like that takes care of the "security measure" that you address at the beginning of ReceiveString. Is there something wrong with my way? It's slower. Again, I exchanged some of the (cheap) program memory for speed. I would omit the "security measure" in my own programs - I KNOW in what state TI is in my programs, of course. Again, this is not critical for this example at all; it's just my usual way of doing things. Russ Cooper said:
In TxCRLF your program uses decimal constants for the CR and LF characters, but in other places it uses hex constants for various control characters. Maybe this inconsistency is part of what led to the original "13h" error in the first place :) Most probably yes. In most of my programs (including PC programs) I use the decimal value. This is something stuck in my head I don't know why. I just somehow cannot get myself to be absolutely perfect in every respect... ;-) Russ Cooper said:
Better yet I think would be to EQU some names for the characters so you can forget about the actual numerical values. This is again matter of personal preference - I did this several times and somehow did not felt it appropriate, I don't know why, it's just a feeling. (Sounds strange, behaving instictively in engineering, huh? That's me...) Russ Cooper said:
Somehow it seems nasty to me that TxHexa falls through into TxChar. Hey, but I've left a comment, saying just that, there! :-) Yes it's nasty. This is a leftover from my earlier times, when BOTH RAM and ROM was a precious commodity... :-) Sure I do even nastier things but I try to consciously control myself in this respect. Russ Cooper said:
Is it fair that the test program magically knows about R0's value on return from ReceiveString? This is just a q'n'd test, remember? I did not intend to spend more time on that than absolutely necessary. I thought to myself to fancy it out, printing both the R0-based value and a character count performed in test; enclosing the printed string into asterisks or doublequotes or so (so that the spaces can be seen)... but it was around midnight and I have to wake up, dress, feed then drive my older son each morning into the kindergarten then run into my paid (sometimes) job... :-( At the moment, I see no reason for the routine to return anything. It's simply spoiling R0 that's all. Forget about the test. Russ Cooper said:
I was amused that the "C hater" changed the spec to put a zero at the end of the string instead of a CR ASCIIZ is at least some sort of defacto "standard", whereas ASCIICR is none. My preference is for the string plus it's length (Pascal showing through... :-) ). Russ Cooper said:
[...] and also that the "C hater" thinks its okay to clobber R0 and ACC because the C compler won't care! :) I see no difference between "caller saves" and "callee saves" nor even have I problem with mix of them, in asm, as long as it is clear for each routine what's the case. My usual assumption is "callee may spoil everything", on the premise, that it is generally more effective to make short routines and let the caller determine what has to be saved. It's logical that the compilers work in this way, but for to be sure I've verified it is so for these two. And, IMHO, with minimum effort, we could contribute this routine to the SDCC (or any other compiler's) library, once we agree on it's final form; which is a good thing to do. :-) JW |