Error compiling with RS232 library

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Error compiling with RS232 library

Post by Lecun »

First of all, forgive my bad english.

I am new to z88dk and i want to use the rs232 port in a Zx Spectrum +2.

I has started with the rs232 example.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <rs232.h>

char byte[1];
int f;

int main()
{
        printf ("%cChecking basic RS232 capabilities...\n",12);
        if (rs232_params(RS_BAUD_1200, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  1200 baud, N, 8, 1\n");
        
        if (rs232_params(RS_BAUD_2400, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  2400 baud, N, 8, 1\n");

        if (rs232_params(RS_BAUD_4800, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  4800 baud, N, 8, 1\n");

        if (rs232_params(RS_BAUD_9600, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  9600 baud, N, 8, 1\n");

        if (rs232_params(RS_BAUD_19200, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  19200 baud, N, 8, 1\n");
                
        printf ("\nInitializing at 1200 baud:");
        if (rs232_params(RS_BAUD_1200, RS_PAR_NONE) != RS_ERR_OK) {
                printf ("  Error setting baud rate.  Exiting...\n");
                exit(0);
        }
        if (rs232_init() != RS_ERR_OK) {
                printf ("  Initialization error.  Exiting...\n");
                exit(0);
        }
        printf ("  Done.\n");


        rs232_put('-');
        rs232_put('>');
        
        printf ("\nEchoing 10 bytes to console: ");
        for (f=0; f<10; f++) {
                while (rs232_get(&byte[0]) != RS_ERR_OK);
                //printf ("%c",byte[0]);
                fputc_cons (byte[0]);
        }

        rs232_put('.');

        printf ("\n\nClosing RS232 port:\n");
        if (rs232_close() != RS_ERR_OK) {
                printf ("  Error.  Exiting...\n");
                exit(0);
        }
}
Compile with:

zcc +zx -lp3 -ndos -lm -create-app serial.c>build.txt

And get this error

Code: Select all

Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_INIT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PUT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PUT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_GET'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PUT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_CLOSE'
12 errors occurred during assembly
Key to filenames:
serial.o = serial.c
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PARAMS'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_INIT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PUT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PUT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_GET'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_PUT'
Error at file 'serial.asm' module 'SERIAL': Symbol not defined in expression 'RS232_CLOSE'
Any help would be appreciated.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

I think you missed to include the rs232lib.
just use also -lrs232p3
(rs232if1 is available as well but I don't think it is your case)
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

stefano wrote:I think you missed to include the rs232lib.
just use also -lrs232p3
(rs232if1 is available as well but I don't think it is your case)
It is working now thanks! :D
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

The example compiles fine now, but does not work well.

I can send from Spectrum to PC but not from PC to Spectrum.

I've tried with a program in Basic and works well in both directions.

What can be wrong?

I am using z88dk-win32-latest.zip, October 10.
Last edited by Lecun on Sat Oct 11, 2014 10:30 am, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

It could be the libraries to be buggy, perhaps we can fix them
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

Ok, thanks.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Could you please post the C code you wrote to receive the data ?
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <rs232.h>

char byte[1];
int f;

int main()
{
        printf ("%cChecking basic RS232 capabilities...\n",12);
        if (rs232_params(RS_BAUD_1200, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  1200 baud, N, 8, 1\n");
        
        if (rs232_params(RS_BAUD_2400, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  2400 baud, N, 8, 1\n");

        if (rs232_params(RS_BAUD_4800, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  4800 baud, N, 8, 1\n");

        if (rs232_params(RS_BAUD_9600, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  9600 baud, N, 8, 1\n");

        if (rs232_params(RS_BAUD_19200, RS_PAR_NONE) == RS_ERR_OK)
                printf ("  19200 baud, N, 8, 1\n");
                
        printf ("\nInitializing at 1200 baud:");
        if (rs232_params(RS_BAUD_1200, RS_PAR_NONE) != RS_ERR_OK) {
                printf ("  Error setting baud rate.  Exiting...\n");
                exit(0);
        }
        if (rs232_init() != RS_ERR_OK) {
                printf ("  Initialization error.  Exiting...\n");
                exit(0);
        }
        printf ("  Done.\n");


        rs232_put('-');
        rs232_put('>');
        
        printf ("\nEchoing 10 bytes to console: ");
        for (f=0; f<10; f++) {
                while (rs232_get(&byte[0]) != RS_ERR_OK); <---------IT IS STUCK HERE
                //printf ("%c",byte[0]);
                fputc_cons (byte[0]);
        }

        rs232_put('.');

        printf ("\n\nClosing RS232 port:\n");
        if (rs232_close() != RS_ERR_OK) {
                printf ("  Error.  Exiting...\n");
                exit(0);
        }
}
Last edited by Lecun on Sun Oct 12, 2014 7:04 pm, edited 1 time in total.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I've just run through the code, and it looks like there was an extra push in the code so you'll end up at a weird location in memory - which may explain the hang you're seeing.

I've removed it so could you verify that it works?
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

Bad news.

Now, it is not stuck there, but it leaves the "while" although not send anything from the PC.
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

If it's any help, here is the source code in assembler of a program that uses the serial port in +3.

http://8bits.rinconweb.com/vdr/ymodem.zip
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

I'll have a quick look at this today. It looks like Stef and Dom are busy atm.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

Are you running in 128 mode?

The rs232 output routine is using the ROM to output a byte. To make sure the right rom is in place it is resetting bit 2 of port $1ffd. I don't think that's enough to make sure the right rom is in. Port $7ffd controls the least significant bit of the ROM selection and that could be 0 or 1, meaning the ROM selected in could be the 128k syntax checker. This can happen if you run in 48k mode, I think. Because it interacts with the rom, it's also keeping the page state in the system variable at $5b67. If you're using that for something else, you can't.

I think we're better off eliminating the ROM usage completely. The program you posted contains self-contained rs232 input / output that isn't much bigger. Maybe dom or stef can look at that?

Code: Select all

a = char to output, carry set on success

RS232OUT:        PUSH        AF
                LD        C,$FD
                LD        D,$FF
                LD        E,$BF
                LD        B,D
                LD        A,$0E
                OUT        (C),A
WAITSINC:        CALL        SPCKEY
                JP        C,ERROU
                IN        A,(C)
                AND        $40
                JR        NZ,WAITSINC
                LD        HL,(BAUDIOS)
                LD        DE,$0002
                OR        A
                SBC        HL,DE
                EX        DE,HL
                POP        AF
                CPL
                SCF
                LD        B,$0B
LOOPSEND1:        PUSH        BC
                PUSH        AF
                LD        A,$FE
                LD        H,D
                LD        L,E
                LD        BC,AY_WRITE
                JP        NC,BRKSEND
                AND        $F7
                OUT        (C),A
                JR        LOOPSEND2
BRKSEND:        OR        $08
                OUT        (C),A
                JR        LOOPSEND2
LOOPSEND2:        DEC        HL
                LD        A,H
                OR        L
                JR        NZ,LOOPSEND2
                NOP
                NOP
                NOP
                POP        AF
                POP        BC
                OR        A
                RRA
                DJNZ        LOOPSEND1
                SCF
                RET

ERROU:                POP        AF
                AND        A
                RET
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Thank you for spotting it ! I think it is a good idea, perhaps we can squeeze it and make it also run at higher baud rates. The biggest problem as usual is to find someone willing to test it in a real environment, but perhaps we have one now :P. Yet another thing to consider is the risk to loose the capability to run the generated programs on crap emulators (by "crap" I'm referring to the common way to emulate serial and parallel ports by simply trapping the service routine location), which is perfectly fine if we document it. Let's also remember to stay away from the contended memory area.
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

alvin wrote:Are you running in 128 mode?
Yes, I am.
stefano wrote:The biggest problem as usual is to find someone willing to test it in a real environment, but perhaps we have one now
I don't know anything about Assembly and only a little about z88dk, but I can do all the tests you want.
Last edited by Lecun on Wed Oct 22, 2014 1:43 pm, edited 1 time in total.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Ok, I work on it. Both the 'in' and 'out' functions need to be rewritten, though.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

stefano wrote:Yet another thing to consider is the risk to loose the capability to run the generated programs on crap emulators (by "crap" I'm referring to the common way to emulate serial and parallel ports by simply trapping the service routine location), which is perfectly fine if we document it. Let's also remember to stay away from the contended memory area.
That's a really good point stef. As an m/c programmer I want to stay away from the rom as much as possible but making the rs232 output visible to the emulators is important too. Maybe a compile-time switch is an option?

When sections are completely introduced we can probably arrange to stay away from contended memory for time critical code.

In the standalone rs232 routines, a simple loop counter with bc=loop count is used to generate the delays for bit timing. Another possibility is to use the exact T-state delay routine.

Lecun can you try both 128 and 48 mode for your test routine? If that's not the problem we'd have to look at whether the rom is being called properly.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

The weird thing is that it works one way, but not the other so presumably the ROM is being paged in correctly.

I took the ROM address calls from zfst (the modem bit) so I presume they work, looking at the (ROM) code that's called it looks ok.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

If so I think we should fisrt try to fix the existing code.

There's also a little size optimization possible by moving the break key detection in a common module.

Be aware that the 19200 baud rate has never been tested but I think it will work.
If it will and you feel adventurous you can try with 38400 in this way:

; cp 13 ; max 19200 baud
cp 14 ; max 34800 baud <---- CHANGE THIS


defw 4 ;RS_BAUD_19200 ; experimental
defw $0001 ;RS_BAUD_38400 ; <--- ADD THIS


Consider that the real speed will be quite different; my empyrical formula based on the known values was (3500000/(25.7*BaudRate))-3) so don't expect much, if I'm right the real values for the two higher rates will be 19455 bps and 34047 bps
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

dom wrote:I took the ROM address calls from zfst (the modem bit) so I presume they work, looking at the (ROM) code that's called it looks ok.
Where can I find 'zfst' in tap format?

Thanks


I had done all tests with the rom + 3e and have tried the original +2a rom this afternoon.

With + 3e rom I can send but not receive and with + 2a rom can neither send nor receive.

I am a newbie but I think we should eliminate the rom usage as @alvin proposed.
Last edited by Lecun on Thu Oct 23, 2014 7:17 pm, edited 1 time in total.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

You can find zfst at: ftp://ftp.nvg.ntnu.no/pub/sinclair/util ... zfst01.zip

You'll need to use appmake to convert it into a .tap file:

appmake +zx --binfile zfst.bin --org 32768 -o zfst.tap

The .tap file can then be loaded - I've tested that it loads using fuse, but that's about all I can do.

Similarly, I've not got a serial cable so can't actually test it out on real hardware. Thanks for bearing with us on this one.
Lecun
Member
Posts: 25
Joined: Thu Oct 09, 2014 9:20 pm

Post by Lecun »

I have tested zfst with +3e rom and it works fine. With the +2a rom I get to see the terminal screen but it throws an error "J Invalid I/O device".
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

Good. Basing on the past posts I assume the code to sent data over the rs232 port is correct, even if I did not understand fully this line:

pop bc ;remove implicit push
ret

..or better, I presume that since the function is wrapped in C code we have to deal with an extra element in stack even if we're __FASTCALL__ing.

Also the +2 ROM does not seem to have the same code at position $205b: are we sure it is sending data ?



I had a look at the ZX plus ROM disassemblies and I noticed that the code to read a byte from the RS232 on the +2 is on ROM0.
here's what I did on the "input" part:


;push af
LIB brkcheck
call brkcheck

ld a,(romrecv2)
cp 33
jr nz,p3mode
call romrecv2
jr p2mode

.p3mode
LIB rs232_page_romin
call rs232_page_romin
;pop af

call romrecv

.p2mode
(...)
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

After a second glance I decided to sort all the stuff a bit more.
The new library includes a ROM detection routine making compatible with more (all?) the plus models, an attempt to support the 38400 baud rate mode, and shouldn't bounce to BASIC (or crash) when BREAK is pressed. I chose not to react with an error message because it is always possible to check for the BREAK key in an external loop.

It is all untested, I'm hoping in a small miracle :/
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

This look relevant too:
http://www.fruitcake.plus.com/Sinclair/ ... embly4.htm

"Amstrad released English and Spanish language editions of the Spectrum +2A/+3. There were two versions of the English language ROM, known as version 4.0 and 4.1. No attempt to maintain ROM routine entry points with the Spectrum 128 or Spectrum +2 was made and so programs that directly access the ROM, e.g. Hisoft 128 BASIC Compiler, will fail. "

So there might be little more work to do, but it is the kind of stuff I like.
Post Reply