Reading from the 128 Serial Port

2

Comments

  • edited June 2009
    As promised, here are some of the replies that I got from the nice people at Speccy.org.
    If you believe Hyperterminal isn't implementing X-MODEM in a way that the +3 understands, the first thing would be to try another utility.

    What's the speed being used for communication? Anything over 1200 baud will probably be a no-no if it's required to do anything else besides receiving data (like for example printing what's being received).

    What type of control system is being used to synchronize both the PC and the +3? I suggest XON/XOFF, because hardware data control wasn't implemented on the +3 side (or at least not implemented completely). And to try to establish communication without control isn't a good idea either, because of the PC's speed compared to the Spectrum.
    I believe the Spectrum is configured as DCE, not DTE
    I suggest you keep trying with very low speeds. Keep in mind the spectrum doesn't have a dedicated UART like the PC, and for that reason it has to emulate all the signals of the serial port (and their synchronization) via software.
  • edited June 2009
    I would say don't trust Hyperterm

    The original XModem had 128 byte blocks with a single byte checksum, and a single byte counter for the block number

    There where later mods to the XModem spec with CRC large blocks, multiple files, filenames & even windowed blocks.

    From Memory hyperterm tries to be clever and work it's way through all the variations :(

    It got so annoying in the late 80s I used to use Kermit when transferring from a BBC to my CPC, Amiga or ST
  • edited June 2009
    I've done a couple of tests, the spectrum end is indeed wired as DCE.

    the connections to wire a male 9 pin D to allow a null cable to be plugged in:
    [FONT=Courier New][SIZE=3]+---------+---------+--------+
    | BT PLUG | 9 PIN D |  NAME  |
    +---------+---------+--------+
    |    1    |    5    |  GND   |
    |    2    |    2    |  TX    |
    |    3    |    3    |  RX[/SIZE][/FONT][FONT=Courier New][SIZE=3]    |[/SIZE][/FONT]
    [FONT=Courier New][SIZE=3]|    4    |    8    |  DTR*  |
    |    5    |    7    |  CTS   |
    |    6    |         |  12V   |
    +---------+---------+--------+
    [/SIZE][/FONT]
    
    The DTR pin on the spectrum port is wired to CTS on the 9 pin, CTS on the spectrum is wired to RTS on the 9 pin.... I know, it makes no sense! but it works

    I'll write this all up and stick it on my website if/when I get it all working
  • edited June 2009
    I've checked the xmodem sending functionality of zfst now (by typing the control codes 'C' and 0x06 manually into a terminal) and data is coming through.

    looks like we just need to find a terminal that'll do XMODEM transfers with XMODEM checksums.
  • edited June 2009
    I've now done a couple of successful file transfers from the +3 to the PC using "Telix" for windows. I can't get it to work the other way so I'll reboot into linux and try rx and sx later on.
  • edited June 2009
    Nice to see you're having some progress. :)

    I was going through the +3 manual 2 days ago and it seems the +3 BASIC can read data from the port, but the original intention was to be used with serial printers, nothing else.

    I'm eager to see what happens when you try Linux tools!
  • edited June 2009
    I'm still not convinced I've got the cable right, though I'm not sure how it could be wrong.

    I can reliably get data to transfer from the speccy to the PC with no errors with 'rx' running from minicom, but going the other way the speccy seems to ignore the PC entirely and not send any acknowledgements etc.

    it's starting to do my head in to be honest, any suggestions of what silly mistake I'm making?

    another interesting(?) observation is that the DTR (RTS) signal from the speccy is toggling on and off all the time, whereas the CTS signal going into the speccy is constantly on...
  • edited June 2009
    All good stuff, thanks guys.

    I haven't forgotten about this - I've just been a bit busy to do any playing lately. I will pick this up again, though.
  • edited June 2009
    guesser wrote: »
    I can reliably get data to transfer from the speccy to the PC with no errors with 'rx' running from minicom(...)

    Does this mean that with the proper routine we could create .EDSK images over the serial port, or at least .DSK images of non-protected +3 disks? :)

    If I understand the +3 DOS correctly, all we need to send data from the +3 to the PC is to set tokens off on the +3 side, read the disk sector by sector, transfer the whole disk as a big text file and then figure out how to turn that PC file into a +3 .DSK.

    I will keep posting in Speccy.org and let them know guesser's progress.
  • edited June 2009
    zxbruno wrote: »
    Does this mean that with the proper routine we could create .EDSK images over the serial port, or at least .DSK images of non-protected +3 disks? :)

    If I understand the +3 DOS correctly, all we need to send data from the +3 to the PC is to set tokens off on the +3 side, read the disk sector by sector, transfer the whole disk as a big text file and then figure out how to turn that PC file into a +3 .DSK.

    I will keep posting in Speccy.org and let them know guesser's progress.

    if you could write a program that would image a +3 disk to a big binary file stored on say a +3e hard disk, or larger external floppy disk, I think it should transfer via the xmodem thing fine.
    I don't know what the size limit for a file in +3dos is, this might be a problem and you'd have to image each sector to a seperate file and stitch them together on the PC afterwards or something like that.
  • edited June 2009
    Well, if you need, I can provide ROM independent serial routine that will send and receive one byte. It's up to you then to manage reading sectors and wrapping it to DSK file.
  • edited June 2009
    omega wrote: »
    Well, if you need, I can provide ROM independent serial routine that will send and receive one byte. It's up to you then to manage reading sectors and wrapping it to DSK file.
    That would be very useful!
    As mentioned earlier in the thread, reading/writing the disk at sector level is very easy using +3DOS calls - it's all in the manual ;-)
  • edited June 2009
    Yes, it's all in the manual but it involves machine code, something I'm not very familiar with. Not sure about guesser. :)

    @omega: Thanks! That would be great! The next step is to find someone who would like to help with the +3DOS part, but having a machine code routine to send/write is a giant step already.

    @guesser: When sending data from the PC to the +3, do you have the ability to choose the speed?
  • edited June 2009
    zxbruno wrote: »
    @omega: Thanks! That would be great! The next step is to find someone who would like to help with the +3DOS part, but having a machine code routine to send/write is a giant step already.
    http://files.omega.webnode.com/200000500-053b4072ff/rsp.a80

    Look at "bytget" and "bytput" routines. It is fixed for 9600bd.
  • edited June 2009
    zxbruno wrote: »
    @guesser: When sending data from the PC to the +3, do you have the ability to choose the speed?

    yes, before running zfst you execute the FORMAT LINE n commands

    I've done transfers at both 300 baud and 9600 baud, I didn't try higher speeds, but it was rock solid with no retransmissions at 9600 so it might work faster
  • edited June 2009
    guesser wrote: »
    yes, before running zfst you execute the FORMAT LINE n commands

    I've done transfers at both 300 baud and 9600 baud, I didn't try higher speeds, but it was rock solid with no retransmissions at 9600 so it might work faster
    I couldn't get 19200 to work. Even just typing individual characters between HyperTerminal and the +3, I got poopoo at the other end. 9600 was the fastest speed I could get to work properly.
  • edited June 2009
    I just found this, seems like it may be useful if you have an interface2. I have a RAMTurbo, which is the same type of interface. Not sure if I can use it for these cartridges though.

    http://www.fruitcake.plus.com/Sinclair/Interface2/Interface2_RC_New_RS232.htm
  • edited June 2009
    FrankT wrote: »
    I just found this, seems like it may be useful if you have an interface2. I have a RAMTurbo, which is the same type of interface. Not sure if I can use it for these cartridges though.

    http://www.fruitcake.plus.com/Sinclair/Interface2/Interface2_RC_New_RS232.htm

    Any 16kB ROM file for INTERFACE 2 can be used also on DIVIDE or MB02+ interface. It's RS232 ROM for DivIDE:
    http://velesoft.speccy.cz/zx/divide/software/divide-allram-rs232_rom.zip
    LOAD/SAVE from/to serial cable (serial connector on PC <> RS232 connector on ZX128/+2/+3). This program work only on DivIDE with R"GAL chip (with true allram support).

    More info about this RS232 communication:
    http://www.fruitcake.plus.com/Sinclair/Interface2/Interface2_RC_New_RS232.htm

    VELESOFT
  • edited June 2009
    I completely forgot about Paul Farrow's serial port machine code routines! It seems he got everything figured out and used a routine similar to the one by omega. Are there any differences between the 128's serial port and the +3 one?

    I can ask Paul if he could help us modify his routine to allow it to be used on the +3 and without the need for an IF2 and without the need to use the 48K rom. I don't think it's a good idea to page the 48K rom while in +3 DOS. Is it possible?

    His Windows utility is already usable if we could use SAVE under +3 BASIC, but it doesn't help if we want to transfer a disk sector by sector. Ideally it should allow what it currently allows, but also have the option to receive a binary file of custom size or a complete disk dump.

    The bit about the cable length and the screen conductor also seems important!

    edit:

    I've sent an e-mail to Paul. Quoting part of it here:
    (...) -Are you aware of any difference between the 128K's serial port and the one used on the +2A and +3?
    -Could you please provide a disassembly of your LOAD/SAVE patches?
    -What speed did you use for your experiments?
    -In future versions of your Windows utility, could you allow it to receive binary files of any custom size, even if they're not being sent via a SAVE command under BASIC? Let's say I have a machine code routine that allows me to dump a complete 3" disk for preservation purposes. Right now the only way to do it is to source an extra 3" drive and connect it to a PC. But if I have a machine code routine that accesses the low-level +3 DOS routine and reads a disk sector by sector, I could send an entire disk to the PC, receive it via your utility and save it as filename.DSK. I would also be able to send custom size binary files (rom dump, ram dump, dump of a certain ram area) to the PC. Is this possible?

    Thanks in advance.

    I forgot to ask him questions about sending data from the PC to the +3. I'll leave that for the next e-mail. :P
  • edited June 2009
    heh, my cable is about 7 feet long, and it's not screened at all.

    it's just a tatty old length of "spectrastrip" a kind of flat ribbon cable but with twisted pairs (not that I'm using that fact mind)
    it was the only cable with enough cores I has when I thrw my null cable together, and it works fine up to insanely high speeds, 9600 is no problem at all with it :)
  • edited June 2009
    Paul has replied to my e-mail and I'll quote some of his ideas soon. Meanwhile, I would humbly ask Omega if he could create a small routine for +3 users to to receive data from Hyperterminal (or his own app if possible) and another routine to send a complete 3" to the PC side, with comments together with the assembler code, if possible.
  • edited June 2009
    I remember reading a post by Death where he provided a way to write a disk sector level on a real +3 from a disk image loaded from tape. Maybe that will be of use.
  • edited June 2009
    zxbruno wrote: »
    Meanwhile, I would humbly ask Omega if he could create a small routine for +3 users to to receive data from Hyperterminal (or his own app if possible) and another routine to send a complete 3" to the PC side, with comments together with the assembler code, if possible.
    Should not be difficult from technical side, anyone can do it. I can try, but don't expect it quickly (no +3, no +3DOS knowledge, no time)...
  • edited June 2009
    My HC2000 (clone) has RS232 similar to IF1. With the correct wire I can transfer files to and from PC (Hyperterminal) up to a speed of 19200 Baud. Cable length is 3 meters. Reliability in reading on Spectrum is not optimal when >4800 Baud. I got the impression that there exists a relation with the (timing) peculiarities of the BASIC loop.
    The Baud-rate only tells us the time between the individual bits of a 'character' and holds no indication whatsoever for the speed of the complete transfer. Also, the reading and writing of successive characters under BASIC could be slowed down at will with a PAUSE statement.
    Moving a screen (6912) from PC to Spectrum using
    . 10 FOR 16384 TO 23295
    . 20 POKE f, CODE INKEY$#4
    . 30 NEXT f
    took 300 sec.s at 300 Baud
    . 110 sec.s at 2400 ,,
    . 90 sec.s at 9600 ,,
    . 90 sec.s at 19200 ,,
    The loop as such (reading from #0) takes 80 sec.s. Apperently each character is synchonised by hardware signals CTS and TRD, which as I see it, also takes a considerable amount of time.
    The question arises how fast data actually can be transferred in MC.
    Here the number of T-states available for handling a data bit, for a number of Baud rates
    (Z80 clock = 3.500 kHz):
    9600 = 364 Ts
    19200 = 182 Ts
    38400 = 91 Ts
    57600 = 60 Ts
    115200= 30 Ts

    Hmmm....
  • edited June 2009
    omega wrote: »
    Should not be difficult from technical side, anyone can do it. I can try, but don't expect it quickly (no +3, no +3DOS knowledge, no time)...
    Should be very easy based on your serial routines and the +3DOS "OPEN DRIVE" function. You can then sequentially read (or write) the entire disk as if it were a sequential file. You'd probably want to add some kind of checksum for, say, each track, just in case of transmission errors.
    I'd also do it, if I had the time.

    (There are also +3DOS calls to read/write sectors directly, but these looked more complicated and require an understanding of XDPBs, which I don't. If you're only interested in shifting around complete disk images, OPEN DRIVE should do the trick.)
  • edited June 2009
    trellis wrote: »
    Should be very easy based on your serial routines and the +3DOS "OPEN DRIVE" function. You can then sequentially read (or write) the entire disk as if it were a sequential file..... I'd also do it, if I had the time.
    This looks feasible, I hope there are no other hooks. Well, let's see, maybe someone will do it faster than us :-)
  • edited June 2009
    115200 Baud is indeed possible for transferring files from PC to Spectrum.
    I used a test file holding 6912 times CHR$ 51, and "Splitcom" found at:
    www.propix.hu/share/SplitCom/SplitCom.html
    Baud rate 115200, 8 data bits, no parity, 2 stop bits.
    The routine waits for the PC to start sending, and synchronizes on the start bits.
    The MC:
    : * TORNADO *  serial 115200 baud 
    ;============================================================
               ORG  40000
               DUMP 40000
    
    ;TxD input from PC is on port 247, bit 7 
    ;The CTS signal for PC is on bit 4 on port 239 
    ; DE  = memaddr
    ; DE' = len
    
    setvals    EXX
               LD   DE,6912
               EXX
               LD   DE,16384          ;screen$
    
    start      DI
               DEC  DE                ;accomodate the coming INC
               LD   BC,239            ;port for CTS
               LD   A,255
               OUT  (C),A             ;signal CTS =1
               LD   C,247             ;now TXD port
    
    loopaddr   IN   A,(C)             ;12
               JP   P,loopaddr        ;10   loop if <128
    
    prep       LD   A,0               ;7 (spend some Ts here)
               INC  DE                ;6   total 35 Ts   
    
    bitloop    IN   L,(C)             ;12
               RL   L                 ;8
               RRA                    ;4
               INC  HL                ;6 delay, total 30 Ts
    b1         IN   L,(C)
               RL   L
               RRA
               INC  HL                ;6 delay, total 30 Ts
    b2         IN   L,(C)
               RL   L
               RRA
               INC  HL                ;6 delay, total 30 Ts
    b3         IN   L,(C)
               RL   L
               RRA
               CP   1                 ;7 delay, total 31 Ts
    b4         IN   L,(C)
               RL   L
               RRA
               INC  HL                ;6 delay, total 30 Ts
    b5         IN   L,(C)
               RL   L
               RRA
               INC  HL                ;6 delay, total 30 Ts
    b6         IN   L,(C)
               RL   L
               RRA
               INC  HL                ;6 delay, total 30 Ts
    b7         IN   L,(C)
               RL   L
               RRA			  ;24 Ts, no further delay
    
    storebyte  CPL                    ;4 invert all bits(!)
               LD   (DE),A            ;7  store
               EXX                    ;4
               DEC  DE                ;6  count
               LD   A,D               ;4
               OR   E                 ;4
               EXX                    ;4
               JP   NZ,loopaddr       ;10  total 43
    
    exit       LD   C,239
               LD   A,239
               OUT  (C),A             ;CTS = 0
               EI
               RET
    
    
    Calculations as follows: the detecting loop for the startbit takes 22 T-states, while each 'bit duration' is 3500.000/115200 = 30.3 Ts (say 30). For reading in the max. 'middle' of each data bit, the first bit read must come after 30 + (30 - 22)/2= 34 Ts. The interval between following bits must be as close as possible to 30.3 Ts. Therefore an extra delay of 1 Tstate is provided two times. Two stopbits were chosen for creating the time for storing etc., which time now is max 65 Ts. With only one stopbit the available time would be max. 34 Ts.
    Spectrums working on other frequency than 3.5 MHz may need dedicated calculations.
  • edited June 2009
    Hi Roelof,

    I'm George from RHC.
    The gain in speed is amazing! I have to try it myself.
    I only used standard BASIC commands with up to 19200 baud and had no errors.
    As terminal on PC side I use TeraTerm.

    Great news, thanks!
  • edited June 2009
    Hi Gheorghe!
    Please note that I wrote the routine just as a test to see whether my hands
    could still make what my brains were thinking, and for encouraging others
    to do the same or better. For example there is no time out when start pulses fail to come. Under 57600 one could make room for that.

    Indeed for HC it works 'as is', full screen in less than a second.
    The counterpart on PC is still on the 'wanted' list! (subtile hint....)
  • edited June 2009
    This keeps getting better and better. :)
Sign In or Register to comment.