I will take a look at the pasm code (Kye's and fdx) asap - probably will not be till the w/e. I coded soft uarts on the 68705 in the early 80's, so I should be able to find the problem
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
No never tried decreasing the voltage. Though I almost always derate the clock on a Z80 - usually to about 3.6Mhz, as it saves power and games run better (cheating? , moi?). You know, a week ago I'd have been very interested in interfacing a Z80 and Propeller. But now, with the entire thing working in an emulation, it somehow doesn't seem so important.
As an aside, today I also soldered up an old-school Z80 board with a real Z80, eprom etc. The Zicog still isn't quite there yet - next little issue to sort out is the speed of the sd card access, which is about 1/10th of the speed of talking to a ram disk on the N8VEM. I've got used to MBASIC booting instantly. But this will come. Meanwhile,
Working things are:
The triblade running a Z80/CPM emulation using just 5 chips.
SD card with multiple disk drive emulations
Xmodem file transfers from any terminal program
Wordstar working
MBASIC working
SBASIC working
BDS C working
Assembly compiler working
Things I'd really like:
More serial ports
VGA and keyboard and the zicog on one propeller (even if it sacrifices a little speed)
Battery backed ram disk like on the N8VEM for faster file access on drive A
An expansion bus with 8 digital lines, 3 address lines and /WR and /RD for talking to external latches/input chips (373 and 240)
A 20x4 LCD display like on the N8VEM for a portable solution (running as well as the vga terminal, like on the N8VEM)
The N8VEM forum has brainstormed hybrid Propeller and real Z80 systems. I think soon we are entering a very exciting time when it can all be done inside an emulation. Or at worst, two propeller chip emulations.
See humanoido's thread for a photo and text printout of some programming on the triblade/zicog.
Running a Z80 at 3.3V? Thinking about that more, I wonder if that would work?
Ihave a "Blade 2" sat in front of me which sits above a larger board with the "Buffered Z80 MK1" and an "arduino esque" demoboard board. so I could do a sort of Blade1 / Blade2. I got as far as the 1MB test and lost track of all the compiler changes, played with other thing and now have come back to revisit it all.
If I could do plated thru holes I am sure the Nascom would be alive by now, I will have to stop chasing perfect ideals, and achieve something. Hey-Ho.
The slowed up real Z80 might happen. The two Prop CP/M is still a cute solution, if you can get the Props.
I noticed a QP/M by Microcode, I think, on a search a while ago, which said it did timestamps on files, if it would help.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Style and grace : Nil point
Dr_A said "...a week ago I'd have been very interested in interfacing a Z80 and Propeller. But now, with the entire thing working in an emulation, it somehow doesn't seem so important."
You'll never know how happy that makes me. It makes all the effort worthwhile[noparse]:)[/noparse]
Still sorry not to have time to play along. It's a working weekend for me.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Can you try the attached modified FullDuplexSerial in place of Kye's SerialEngine ?
I have added rxavail which returns true (-1) if there is a character available. If this still loses characters with 1 stop bit then I will fix it (make it 2 cogs) for now.
So...
UART.TransmitCharacter --> UART.tx
UART.TransmitCharacters --> UART.str
UART.ReceiveCharacter --> UART.rx
UART.ReceiveNumber --> UART.rxavail (BUT IT RETURNS TRUE=-1 IF CHARACTER AVAILABLE)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
I spent several hours changing the code over to Kye's object, and I know it will take just as long to change it to this new code.
So before I embark on that, can I ask -
Is this already working with the usb/serial chip?
Returning -1 if no byte - yes need to go through each line and check that.
I need to get my head around the PASM code. I find this code so hard to understand as there are some basic concepts I need to grasp. eg, in the Rx bit it has an instruction jmpret rxcode txcode
I don't understand this instruction. Where does it jump to? A label rxcode, but this does not exist. To 'res 1', but what does that do? To another jmpret instruction that also references rxcode? To the 'chunk of transmit code', but that code starts with 'transmit' and the first instruction is to jmpret back to receive. So I can't follow any of the program flow, and thus it is hard to work out exactly what it is doing.
The fundamental problem is to sample the start bit finely enough that you can capture the negative transition fairly soon after it happens, and then put the sample point in the middle of the bit, and then ensure it samples in the middle for the rest of the bits. But also, that puts the last sample point in the middle of the stop bit. Then you need to start sampling finely again to pick the next transition. But how do you then synchronise with sending the bits in the tx? Kye synchronised both together, but it only works because the Rx has one extra stop bit so the Tx ended slightly sooner. What I am trying to work out is the maths of fitting in proper stop bit lengths for the final stop bit on a Tx when the Rx already has shortened that slightly by the slight delay introduced by the time slice delay on the initial start bit.
It is very complicated to work out a formula to do that if you only have one stop bit and there is a continuous stream of Rx bytes and you want to fit in Tx at the same time. The Tx code gradually gets out of synch - and the bigger the time slice on the Rx at the beginning the faster it is out of synch - eg 1/8th of a bit gets out of synch in as little as 8 bytes.
Unless the code can cope with Tx and Rx having their start/stop bits out of synch. That, I think, is the key, but it involves some extra counters to keep track of where it is up to and I can't see those counters in this object.
Unless you accept slightly short stop bits on the Tx. But that is a fudge and assumes the device at the other end can handle that, which assumes the device at the other end is doing things properly like sampling in the middle of the bit. Or you accept slower baud rates. But what if the device at the other end is another propeller?
Someone mentioned on another thread an object that can handle 4 uarts on one cog? I wonder how that would work, and whether the above complexities have been considered?
Also, this is such a complicated thing to explain that it almost needs a drawing at the beginning of the code to explain the waveforms and where the sampling happens and how it shifts back and forth between Tx and Rx.
It is sooo much simpler just to add two stop bits. Which is what Kye said. But I would like to get to understand the pasm code a bit better in order to work out the timing works. And, sorry for the long post!
Addit: Cluso, some time back there was mention of the drives being 32mb ie 8mb drives but only 1mb is available. I think the simh has drives I onwards as 8Mb. I tried putting a blank drive I image on the sd card and then adding the drive in the code
FindDriveBase(8, string("DRIVE__I.DSK")) 'set the SD card drive base(s) 8MB HARD DRIVE
But it gives a whole lot of errors when trying to access the drive. Did you ever get this working by any chance?
Stores the return address into RetInstAddr and then jumps to DestAddress, clear enough.
But consider, if somewhere else in a different routine there is another JMPRET with reversed source and dest.
JMPRET DestAddress, RetInstAddr
That gets you back to where your first JMPRET left off and you first routine continues.
And likewise if the first routine does his JMPRET again execution returns to where ever the second routine left off.
So what we have here is two "threads" of execution that can swap back and forth between each other any time they don't have much to do.
"Cooroutines" I think they are called in the literature. Normally one thinks of "callers" and "subroutines" but here they are both on the same level as it were.
So I guess in this case (I have not looked at the code) the tx loop "calls" the rx loop which "calls" the tx loop and on and on. With each call the one who is called just continues from where he left off.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Heater: Yes, that is precisely what the FDX code is doing.
I am trying to determine if there is a problem requiring 2 stop bits in FDX. I don't have anything to send it a string of characters fast enough to test.
James: You can globally replace the UART.xxx as I showed above (Ctrl-F) in the demo spin module. There are 4 types of calls. There is only 1 call that requires a fix for the -1 response. This should be a simple test. Like I said, if there is a real problem with FDX it is worth fixing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
Sorry for the long delays - working all this weekend. They do give me internet access at work though.
Lots of things could give you a continuous stream of RS232 data but maybe this hasn't come up because most people are using the USB to serial chips and those chips are putting in longer stop bits? A dedicated cog ought to be able to produce the right waveform though - just make it a Tx only so as not to confuse things. This is a very complex problem to solve though - and it isn't quite a cut and paste job going back and forth in the code between different serial objects, eg Kye's code doesn't have a hex output print, so you have to put that in the main code instead. Maybe all input output could go through just a few subroutines in the main program first - I might look at that (also would solve the 13,10 vs 10 issue). Otherwise it might be heading towards ifdef hell. At least the 2 stop bits is a practical solution.
Cluso, did you say at one stage you had dropped characters in CP/M3? If so, then maybe you have seen this problem too?
Oh, and testing it, you can replicate it on xmodem but can't see the problem in action. Better to do it by running wordstar, open a document and then send some text into that document as a continuous serial stream. Then you can see it dropping characters with one stop bit but not with two.
I was pondering a cog to do 4 asynchronous inputs, and another cog to do 4 outputs. At least it might be easier to understand. jmpret makes sense now, but it is still very hard to trace out the exact timing.
I think this problem is going to be harder to solve than some of the other problems that still need looking at. Is it possible to look at getting the 8mb hard drives working, and also dropping in the faster sd card routines?
I think I've fixed the problem with my code. I've spent all day rewriting it and making it much faster and much more precise.
Most of the changes are under the hood but I've tested it out on a few 256 byte hex dumps at different baud rates and I've had no problems. Once I finish the timing calculations for full duplex mode at 250_000 BPS I'll test the driverb out on a much larger data set looking for errors.
... The code is even more complicated now. Unless you really know what your doing please don't ask me to try to tell you how it works. I've used alot of implict tricks from knowledge on how the processor works to lower the maximum transmiter execution time to 61 clock cycles - its minimum is 20 clock cyels.
...
The reason I don't have hex output in my code is because all hex output should be in a central library of code. It is wasteful to give each interface piece of code hex/bin/dec rountines. It is better to have one rountine in a central library. That rountine then can return a string for the string transmit rountine to use.
... I'll post the code later when I finish. I've spent all day working to make the code as fast as possible to eanble 250_000 BPS mode. (I had to make the driver execute stuff in less than 80 cycles at worst case).
Brilliant - can't wait to give it a try. And I agree re the hex thing - otherwise the objects end up with too much 'bloatware'. Will the new code be available in the next 24h?
Great work Kye Look forward to seeing the code, and I agree the hex code, etc should be in a module of it's own.
A suggestion... you are using TransmitCharacter/s and ReceiveCharacter, ReceiveNumber. This is yet another naming. TV has out, FDX has tx and str. It would be nice if all these had the same named calls so interchanging them would be easy. I run a modified version of FDX that has also has an out call but of course it wastes code/speed. Also, the call names are too long.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
I'll shorten the names for you guys. But in general the names will be long. I'll just change the names in the version I give you.
I should be done within the next 24 hours. I'm kinda done now, but I'm still trying to ensure 250_000 BPS mode. Its really hard to get some parts of the code to execute in less than 80 clock cycles.
James: Can you give this a try? It is your last posted code with a modified FDX with Kye's calls added for simplicity, so you should only have to compile.
Unfortunately, in my haste, I left my box of props and parts in Qld. I have blank TriBlade pcbs here with no parts - wo is me!·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
Ok, will do when I get home. (I'm busy suturing lacerations at the moment). I'd also looking forward to testing that half duplex code. And then Kye's new code as well.
I did add a lot of Spin code for emulating SIMH compatible 8MB Hard drives to zicog_demo a long time ago.
That code emulates the SIMH Direct Memory Access interface with the hard drives.
I have only ever been able to test that code on my PropDemo board so it does not go through any FAT file system. Straight from CP/M to sectors (blocks) on the SD card.
I got as far as confirming that I could DIR the hard drive and "type" text files from it. I could also PIP files in and out of it from a floppy drive. However the PIP would crash when complete. So the sequence was something like:
1) PIP a file from drive A to hard drive.
2) It crashes/hangs
3) Reboot CP/M
4) Type the new file copy from the hard drive. It's there OK.
Possibly PIP hangs because hard drive support really needs more CP/M memory than I have. Or it could be a big in the emulation. But at least it was seen to read and write.
There were some posts about this on the ZiCog thread.
Not sure how far Cluso got with adapting/testing that code to TriBlade with FAT system.
By the way: I just noticed that over on the N8VEM group someone has lashed a Z80 to a Prop and is having trouble with double characters coming out of CP/M to the VGA. That has also been reported for the ZiCog, CP/M, WordStar, VGA combination. I had expected you might be one to see it again.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Oh forgot to mention, you may need a recent CP/M BIOS for getting hard disks to work if you are running the emulation in 8080 mode. There was a bug in the SIMH BIOS CPU detection code that I reported to Peter Schorn which he promptly fixed.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Cluso, re that post about 6 back, those files work perfectly with 1 stop bit. I don't know how you did it but, YIPPEE!
Tested with Wordstar - all perfect.
Tested with xmodem - all perfect.
Right, now I guess we need to package that up into a working zip and tidy up all those mods I made along the way. Any chance you could pls re-release this with a few simple mods?
* No need to include my name in the file now this works.
* My baud rate was 38400 but I think most people would prefer 115k so change that.
* Do we go 13,10? Or (here is an idea), add a simple subroutine PUB/PRI CRLF and just call it after each line, and you just modify that one PUB if you only want a 13?
* Change that signon message re the serial settings to 1 stop bit. (it is kind of useful in case someone accidentally turned hardware flow control on or something, at least by searching the source code they would get a clue)
* I got sick of typing 'yes' every time it booted to enable the sd card. I always wanted the sd card. So I disabled that message. Is that ok?
* do a quick search for the term N8VEM for all the instances I added traps for N8VEM I/O calls. Maybe add these to comments in the revision list.
* When I moved over to Kye's code I had to comment out lots of the TV.hex calls. Now there is the PUB PrintHex(value) at the end of the program, maybe uncomment them all so it calls that pub instead. Find with a search for tv.hex.
* in 'out_constat ' I print out the port number rather than the byte. Useful to see what is going on. There seem to be some ^C (&H03) characters going out from time to time, eg just before the A> prompt. Not sure what is creating those. Eventually maybe find what is sending those, or comment out the line printing it (though maybe not yet as it still could be useful)
Hopefully the next series of mods will be done in a bit more structured way (ie, memo to self - make more comments along the way!)
However, that code is what I was using - there was no fix ! It is the FullDuplexSerial with the added calls to make it simulate Kye's calls. But I needed to know that the standard FDX object·did not have a bug with stop bits, so thanks for confirming. I think that you switched to Kye's code before you actually fixed the problem in the emulation thereby introducing another bug.
re your comments...
would you please resend me your latest code (in case the code I sent you was not your latest)·so that I can combine your fixes.
v093 had a fix for baudrate so it was set only once.
v093 had a fix for the crlf issue in the driver, so only 1 change was required. I will think about a cleaner way to do this.
can now change the signon messages and Y reply (#define option)
agreed with the other comments also.
I think I need a top level wrapper for the FDX/UART or whatever, so that it will be easy to substitute Serial,·Keyboard,·TV, etc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
Yes, I have about 8 folders now with different versions. Very confusing. Some of the things you sent were added and some were not. The key with Kye's code was to greatly simplify the way bytes were captured and this in turn uncovered the bug talking to CP/M.
Anyway, the good news is that it now seems impossible to break. Stuff just seems to work. So, let's just go with that last code you posted.
What next? The faster sd access (is the current one 100khz?). Or the 8mb drives (maybe heater can help with that 8mb code). All very exciting!
Ah, you guys didn't wait. Here's my next version. I've only tested it with a few 255 byte hex dumps and it seems to work great.
If you can also give it a try that would be great. I think I have fixed the problems. It would be a help to me to know that it works somewhere else.
I spent alot of time getting the receiving and transmiting code perfect and down to the few nano seconds of accuracy. The driver now samples within 4 clocks of the correct time and sends bits out within 8 clocks of the correct time.
I only increased the size by 4 longs. So its 148 longs with 130 longs of var space. Everything I think is operational with the 256 byte in and out buffers.
Also not that the receive check function allows you to check the last received byte that enters the serial buffers. This is usefull for using the buffers to hold an entered string of characters until some key like enter is hit. Then you can dump the buffer and do what you want with it.
Yes, Cluso rushed off and got a whole lot of things working yesterday. Not sure how he does it! I'll plug in the serial engine code tonight and give it a test run.
James: It was a 5 second mod to add the call names like Kye's. You are reading way too much complexity into all this
Granted that Kye's code let you look for the actual problem.
Kye: Thanks for your code - it helped solve the real bug of dropping characters.
I think there is a bug in the·rxavail call.
PUB rxavail '' 3 Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the number of characters in the receiver buffer. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
return ((inputHead - inputTail) & $FF)
·Should be...
PUB rxavail '' 3??? Stack Longs
'' ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
'' │ Returns the number of characters in the receiver buffer. │
'' └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
if inputHead >= inputTail
return ((inputHead - inputTail) & $FF)
else
return ((inputHead + $FF - inputTail)) & $FF)
Is it necessary to know the number of received characters in the buffer? If not, then this may be simpler..
PUB rxavail : truefalse
'' Check if byte(s) available
'' returns true (-1) if bytes available
truefalse := rx_tail <> rx_head
BTW can you use a constant to define the length of the buffers like I did with the recent posting of the modified FDX for James·(also pasm needs to use the constant also)
CON
bufsiz = 256 '16 'buffer size (16, 32, 64, 128, 256, 512) must be factor of 2, max is 512
bufmsk = bufsiz - 1 'buffer mask used for wrap-around ($00F, $01F, $03F, $07F, $0FF, $1FF)
VAR
byte rx_buffer[noparse][[/noparse]bufsiz] 'transmit and receive buffers
byte tx_buffer[noparse][[/noparse]bufsiz]
rx_tail := (rx_tail + 1) & bufmsk 'example of use
Kye, we should probably continue this under your SerialEngine post as there may be input from others. I also have some other ideas for you.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Links to other interesting threads:
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
Life would be simpler if the prop and the Z80 could connect dirrectly and as it is a 10MHz (@5v) would 4MHz ish work ?
Resistors and other "logics" could be ditched.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Style and grace : Nil point
As an aside, today I also soldered up an old-school Z80 board with a real Z80, eprom etc. The Zicog still isn't quite there yet - next little issue to sort out is the speed of the sd card access, which is about 1/10th of the speed of talking to a ram disk on the N8VEM. I've got used to MBASIC booting instantly. But this will come. Meanwhile,
Working things are:
The triblade running a Z80/CPM emulation using just 5 chips.
SD card with multiple disk drive emulations
Xmodem file transfers from any terminal program
Wordstar working
MBASIC working
SBASIC working
BDS C working
Assembly compiler working
Things I'd really like:
More serial ports
VGA and keyboard and the zicog on one propeller (even if it sacrifices a little speed)
Battery backed ram disk like on the N8VEM for faster file access on drive A
An expansion bus with 8 digital lines, 3 address lines and /WR and /RD for talking to external latches/input chips (373 and 240)
A 20x4 LCD display like on the N8VEM for a portable solution (running as well as the vga terminal, like on the N8VEM)
The N8VEM forum has brainstormed hybrid Propeller and real Z80 systems. I think soon we are entering a very exciting time when it can all be done inside an emulation. Or at worst, two propeller chip emulations.
See humanoido's thread for a photo and text printout of some programming on the triblade/zicog.
Running a Z80 at 3.3V? Thinking about that more, I wonder if that would work?
If I could do plated thru holes I am sure the Nascom would be alive by now, I will have to stop chasing perfect ideals, and achieve something. Hey-Ho.
The slowed up real Z80 might happen. The two Prop CP/M is still a cute solution, if you can get the Props.
I noticed a QP/M by Microcode, I think, on a search a while ago, which said it did timestamps on files, if it would help.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Style and grace : Nil point
You'll never know how happy that makes me. It makes all the effort worthwhile[noparse]:)[/noparse]
Still sorry not to have time to play along. It's a working weekend for me.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Can you try the attached modified FullDuplexSerial in place of Kye's SerialEngine ?
I have added rxavail which returns true (-1) if there is a character available. If this still loses characters with 1 stop bit then I will fix it (make it 2 cogs) for now.
So...
UART.TransmitCharacter --> UART.tx
UART.TransmitCharacters --> UART.str
UART.ReceiveCharacter --> UART.rx
UART.ReceiveNumber --> UART.rxavail (BUT IT RETURNS TRUE=-1 IF CHARACTER AVAILABLE)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
I spent several hours changing the code over to Kye's object, and I know it will take just as long to change it to this new code.
So before I embark on that, can I ask -
Is this already working with the usb/serial chip?
Returning -1 if no byte - yes need to go through each line and check that.
I need to get my head around the PASM code. I find this code so hard to understand as there are some basic concepts I need to grasp. eg, in the Rx bit it has an instruction jmpret rxcode txcode
I don't understand this instruction. Where does it jump to? A label rxcode, but this does not exist. To 'res 1', but what does that do? To another jmpret instruction that also references rxcode? To the 'chunk of transmit code', but that code starts with 'transmit' and the first instruction is to jmpret back to receive. So I can't follow any of the program flow, and thus it is hard to work out exactly what it is doing.
The fundamental problem is to sample the start bit finely enough that you can capture the negative transition fairly soon after it happens, and then put the sample point in the middle of the bit, and then ensure it samples in the middle for the rest of the bits. But also, that puts the last sample point in the middle of the stop bit. Then you need to start sampling finely again to pick the next transition. But how do you then synchronise with sending the bits in the tx? Kye synchronised both together, but it only works because the Rx has one extra stop bit so the Tx ended slightly sooner. What I am trying to work out is the maths of fitting in proper stop bit lengths for the final stop bit on a Tx when the Rx already has shortened that slightly by the slight delay introduced by the time slice delay on the initial start bit.
It is very complicated to work out a formula to do that if you only have one stop bit and there is a continuous stream of Rx bytes and you want to fit in Tx at the same time. The Tx code gradually gets out of synch - and the bigger the time slice on the Rx at the beginning the faster it is out of synch - eg 1/8th of a bit gets out of synch in as little as 8 bytes.
Unless the code can cope with Tx and Rx having their start/stop bits out of synch. That, I think, is the key, but it involves some extra counters to keep track of where it is up to and I can't see those counters in this object.
Unless you accept slightly short stop bits on the Tx. But that is a fudge and assumes the device at the other end can handle that, which assumes the device at the other end is doing things properly like sampling in the middle of the bit. Or you accept slower baud rates. But what if the device at the other end is another propeller?
Someone mentioned on another thread an object that can handle 4 uarts on one cog? I wonder how that would work, and whether the above complexities have been considered?
Also, this is such a complicated thing to explain that it almost needs a drawing at the beginning of the code to explain the waveforms and where the sampling happens and how it shifts back and forth between Tx and Rx.
It is sooo much simpler just to add two stop bits. Which is what Kye said. But I would like to get to understand the pasm code a bit better in order to work out the timing works. And, sorry for the long post!
Addit: Cluso, some time back there was mention of the drives being 32mb ie 8mb drives but only 1mb is available. I think the simh has drives I onwards as 8Mb. I tried putting a blank drive I image on the sd card and then adding the drive in the code
FindDriveBase(8, string("DRIVE__I.DSK")) 'set the SD card drive base(s) 8MB HARD DRIVE
But it gives a whole lot of errors when trying to access the drive. Did you ever get this working by any chance?
Post Edited (Dr_Acula) : 8/15/2009 2:22:27 PM GMT
JMPRET RetInstAddr, DestAddress
Stores the return address into RetInstAddr and then jumps to DestAddress, clear enough.
But consider, if somewhere else in a different routine there is another JMPRET with reversed source and dest.
JMPRET DestAddress, RetInstAddr
That gets you back to where your first JMPRET left off and you first routine continues.
And likewise if the first routine does his JMPRET again execution returns to where ever the second routine left off.
So what we have here is two "threads" of execution that can swap back and forth between each other any time they don't have much to do.
"Cooroutines" I think they are called in the literature. Normally one thinks of "callers" and "subroutines" but here they are both on the same level as it were.
So I guess in this case (I have not looked at the code) the tx loop "calls" the rx loop which "calls" the tx loop and on and on. With each call the one who is called just continues from where he left off.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Post Edited (heater) : 8/15/2009 2:35:22 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
I am trying to determine if there is a problem requiring 2 stop bits in FDX. I don't have anything to send it a string of characters fast enough to test.
James: You can globally replace the UART.xxx as I showed above (Ctrl-F) in the demo spin module. There are 4 types of calls. There is only 1 call that requires a fix for the -1 response. This should be a simple test. Like I said, if there is a real problem with FDX it is worth fixing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
What, not even another COG ?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
But no. The cog will most likely disguise the problem James is seeing. I have not seen this problem. James has already fixed another problem.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
Lots of things could give you a continuous stream of RS232 data but maybe this hasn't come up because most people are using the USB to serial chips and those chips are putting in longer stop bits? A dedicated cog ought to be able to produce the right waveform though - just make it a Tx only so as not to confuse things. This is a very complex problem to solve though - and it isn't quite a cut and paste job going back and forth in the code between different serial objects, eg Kye's code doesn't have a hex output print, so you have to put that in the main code instead. Maybe all input output could go through just a few subroutines in the main program first - I might look at that (also would solve the 13,10 vs 10 issue). Otherwise it might be heading towards ifdef hell. At least the 2 stop bits is a practical solution.
Cluso, did you say at one stage you had dropped characters in CP/M3? If so, then maybe you have seen this problem too?
Oh, and testing it, you can replicate it on xmodem but can't see the problem in action. Better to do it by running wordstar, open a document and then send some text into that document as a continuous serial stream. Then you can see it dropping characters with one stop bit but not with two.
I was pondering a cog to do 4 asynchronous inputs, and another cog to do 4 outputs. At least it might be easier to understand. jmpret makes sense now, but it is still very hard to trace out the exact timing.
I think this problem is going to be harder to solve than some of the other problems that still need looking at. Is it possible to look at getting the 8mb hard drives working, and also dropping in the faster sd card routines?
Post Edited (Dr_Acula) : 8/16/2009 1:05:17 AM GMT
I think I've fixed the problem with my code. I've spent all day rewriting it and making it much faster and much more precise.
Most of the changes are under the hood but I've tested it out on a few 256 byte hex dumps at different baud rates and I've had no problems. Once I finish the timing calculations for full duplex mode at 250_000 BPS I'll test the driverb out on a much larger data set looking for errors.
... The code is even more complicated now. Unless you really know what your doing please don't ask me to try to tell you how it works. I've used alot of implict tricks from knowledge on how the processor works to lower the maximum transmiter execution time to 61 clock cycles - its minimum is 20 clock cyels.
...
The reason I don't have hex output in my code is because all hex output should be in a central library of code. It is wasteful to give each interface piece of code hex/bin/dec rountines. It is better to have one rountine in a central library. That rountine then can return a string for the string transmit rountine to use.
... I'll post the code later when I finish. I've spent all day working to make the code as fast as possible to eanble 250_000 BPS mode. (I had to make the driver execute stuff in less than 80 cycles at worst case).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
A suggestion... you are using TransmitCharacter/s and ReceiveCharacter, ReceiveNumber. This is yet another naming. TV has out, FDX has tx and str. It would be nice if all these had the same named calls so interchanging them would be easy. I run a modified version of FDX that has also has an out call but of course it wastes code/speed. Also, the call names are too long.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
I should be done within the next 24 hours. I'm kinda done now, but I'm still trying to ensure 250_000 BPS mode. Its really hard to get some parts of the code to execute in less than 80 clock cycles.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Unfortunately, in my haste, I left my box of props and parts in Qld. I have blank TriBlade pcbs here with no parts - wo is me!·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
I did add a lot of Spin code for emulating SIMH compatible 8MB Hard drives to zicog_demo a long time ago.
That code emulates the SIMH Direct Memory Access interface with the hard drives.
I have only ever been able to test that code on my PropDemo board so it does not go through any FAT file system. Straight from CP/M to sectors (blocks) on the SD card.
I got as far as confirming that I could DIR the hard drive and "type" text files from it. I could also PIP files in and out of it from a floppy drive. However the PIP would crash when complete. So the sequence was something like:
1) PIP a file from drive A to hard drive.
2) It crashes/hangs
3) Reboot CP/M
4) Type the new file copy from the hard drive. It's there OK.
Possibly PIP hangs because hard drive support really needs more CP/M memory than I have. Or it could be a big in the emulation. But at least it was seen to read and write.
There were some posts about this on the ZiCog thread.
Not sure how far Cluso got with adapting/testing that code to TriBlade with FAT system.
By the way: I just noticed that over on the N8VEM group someone has lashed a Z80 to a Prop and is having trouble with double characters coming out of CP/M to the VGA. That has also been reported for the ZiCog, CP/M, WordStar, VGA combination. I had expected you might be one to see it again.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
Cluso, re that post about 6 back, those files work perfectly with 1 stop bit. I don't know how you did it but, YIPPEE!
Tested with Wordstar - all perfect.
Tested with xmodem - all perfect.
Right, now I guess we need to package that up into a working zip and tidy up all those mods I made along the way. Any chance you could pls re-release this with a few simple mods?
* No need to include my name in the file now this works.
* My baud rate was 38400 but I think most people would prefer 115k so change that.
* Do we go 13,10? Or (here is an idea), add a simple subroutine PUB/PRI CRLF and just call it after each line, and you just modify that one PUB if you only want a 13?
* Change that signon message re the serial settings to 1 stop bit. (it is kind of useful in case someone accidentally turned hardware flow control on or something, at least by searching the source code they would get a clue)
* I got sick of typing 'yes' every time it booted to enable the sd card. I always wanted the sd card. So I disabled that message. Is that ok?
* do a quick search for the term N8VEM for all the instances I added traps for N8VEM I/O calls. Maybe add these to comments in the revision list.
* When I moved over to Kye's code I had to comment out lots of the TV.hex calls. Now there is the PUB PrintHex(value) at the end of the program, maybe uncomment them all so it calls that pub instead. Find with a search for tv.hex.
* in 'out_constat ' I print out the port number rather than the byte. Useful to see what is going on. There seem to be some ^C (&H03) characters going out from time to time, eg just before the A> prompt. Not sure what is creating those. Eventually maybe find what is sending those, or comment out the line printing it (though maybe not yet as it still could be useful)
Hopefully the next series of mods will be done in a bit more structured way (ie, memo to self - make more comments along the way!)
However, that code is what I was using - there was no fix ! It is the FullDuplexSerial with the added calls to make it simulate Kye's calls. But I needed to know that the standard FDX object·did not have a bug with stop bits, so thanks for confirming. I think that you switched to Kye's code before you actually fixed the problem in the emulation thereby introducing another bug.
re your comments...
I think I need a top level wrapper for the FDX/UART or whatever, so that it will be easy to substitute Serial,·Keyboard,·TV, etc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
Anyway, the good news is that it now seems impossible to break. Stuff just seems to work. So, let's just go with that last code you posted.
What next? The faster sd access (is the current one 100khz?). Or the 8mb drives (maybe heater can help with that 8mb code). All very exciting!
If you can also give it a try that would be great. I think I have fixed the problems. It would be a help to me to know that it works somewhere else.
I spent alot of time getting the receiving and transmiting code perfect and down to the few nano seconds of accuracy. The driver now samples within 4 clocks of the correct time and sends bits out within 8 clocks of the correct time.
I only increased the size by 4 longs. So its 148 longs with 130 longs of var space. Everything I think is operational with the 256 byte in and out buffers.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Also not that the receive check function allows you to check the last received byte that enters the serial buffers. This is usefull for using the buffers to hold an entered string of characters until some key like enter is hit. Then you can dump the buffer and do what you want with it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Granted that Kye's code let you look for the actual problem.
Kye: Thanks for your code - it helped solve the real bug of dropping characters.
I think there is a bug in the·rxavail call.
·Should be...
Is it necessary to know the number of received characters in the buffer? If not, then this may be simpler..
BTW can you use a constant to define the length of the buffers like I did with the recent posting of the modified FDX for James·(also pasm needs to use the constant also)
Kye, we should probably continue this under your SerialEngine post as there may be input from others. I also have some other ideas for you.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, RamBlade, TwinBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80), MoCog (6809)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm